Add importer for clinic system.
- Neu: Laborwerte, die vom Ambulanzsystem ausgegeben wurden, können jetzt auch verarbeitet werden.
This commit is contained in:
@ -208,7 +208,8 @@ namespace zaaReloaded2
|
||||
{
|
||||
Logger.Info("DoFormat: Attempting to auto-detect");
|
||||
Word.Document doc = activeWindow.Document;
|
||||
if (!AutoDetect.Detect(doc))
|
||||
Importer.AutoDetector autoDetector = new Importer.AutoDetector();
|
||||
if (!autoDetector.Detect(doc))
|
||||
{
|
||||
Logger.Info("DoFormat: Automatic detection failed");
|
||||
NotificationAction a = new NotificationAction();
|
||||
|
Binary file not shown.
@ -20,11 +20,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using zaaReloaded2.Importer.ZaaImporter;
|
||||
using zaaReloaded2.Importer.ClinicImporter;
|
||||
|
||||
namespace zaaReloaded2.Importer.ZaaImporter
|
||||
namespace zaaReloaded2.Importer
|
||||
{
|
||||
static class AutoDetect
|
||||
class AutoDetector
|
||||
{
|
||||
#region Public methods
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to automatically detect laboratory data in the Word
|
||||
/// document.
|
||||
@ -34,7 +38,7 @@ namespace zaaReloaded2.Importer.ZaaImporter
|
||||
/// <returns>True if laboratory data was detected, false if not.</returns>
|
||||
/// <exception cref="ArgumentNullException">if <paramref name="document"/>
|
||||
/// is null.</exception>
|
||||
public static bool Detect(Document document)
|
||||
public bool Detect(Document document)
|
||||
{
|
||||
if (document == null)
|
||||
{
|
||||
@ -89,17 +93,68 @@ namespace zaaReloaded2.Importer.ZaaImporter
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a paragraph is a time stamp line.
|
||||
/// </summary>
|
||||
private bool IsTimeStampParagraph(Paragraph paragraph)
|
||||
{
|
||||
string text = paragraph.Range.Text;
|
||||
bool isCinicTimePoint = ClinicTimePoint.IsTimeStampLine(text);
|
||||
bool isZaaTimePoint = LaurisTimePoint.IsTimeStampLine(text);
|
||||
// If the line is a ZAA time point, but not a clinic timepoint, we can deduct that
|
||||
// the lab mode *must* be ZAA, because it will be a line in the form
|
||||
// "(17.09.2015-201710:44:00) Cyclosporin-A vor Gabe: 130 µg/l;" which does not
|
||||
// occur in the clinic format.
|
||||
if ((_mode == Mode.Undefined) && isZaaTimePoint && !isCinicTimePoint)
|
||||
{
|
||||
_mode = Mode.Zaa;
|
||||
}
|
||||
return isCinicTimePoint || isZaaTimePoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a paragraph is either a time stamp line
|
||||
/// or a paragraph with laboratory items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method determines the mode: either ZAA-generated output or clinic system-generated
|
||||
/// output. ZAA is given priority over clinic. Once a mode is detected, it will stick to
|
||||
/// that mode.
|
||||
/// </remarks>
|
||||
/// <param name="paragraph"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsLabParagraph(Paragraph paragraph)
|
||||
private bool IsLabParagraph(Paragraph paragraph)
|
||||
{
|
||||
string text = paragraph.Range.Text;
|
||||
return (LaurisParagraph.ResemblesLaurisParagraph(text)
|
||||
|| LaurisTimePoint.IsTimeStampLine(text));
|
||||
bool isLabParagraph = false;
|
||||
switch (_mode)
|
||||
{
|
||||
case Mode.Undefined:
|
||||
if (LaurisParagraph.ResemblesLaurisParagraph(text) || LaurisTimePoint.IsTimeStampLine(text))
|
||||
{
|
||||
_mode = Mode.Zaa;
|
||||
isLabParagraph = true;
|
||||
}
|
||||
else if (ClinicLine.ResemblesClinicLine(text) || ClinicTimePoint.IsTimeStampLine(text))
|
||||
{
|
||||
_mode = Mode.Clinic;
|
||||
isLabParagraph = true;
|
||||
}
|
||||
break;
|
||||
case Mode.Zaa:
|
||||
isLabParagraph = LaurisParagraph.ResemblesLaurisParagraph(text) || LaurisTimePoint.IsTimeStampLine(text);
|
||||
break;
|
||||
case Mode.Clinic:
|
||||
isLabParagraph = ClinicLine.ResemblesClinicLine(text) || ClinicTimePoint.IsTimeStampLine(text);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return isLabParagraph;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -110,9 +165,24 @@ namespace zaaReloaded2.Importer.ZaaImporter
|
||||
/// </remarks>
|
||||
/// <param name="paragraph">Paragraph whose index to return.</param>
|
||||
/// <returns>Index of the paragraph.</returns>
|
||||
private static int GetParagraphIndex(Document document, Paragraph paragraph)
|
||||
private int GetParagraphIndex(Document document, Paragraph paragraph)
|
||||
{
|
||||
return document.Range(0, paragraph.Range.Start).Paragraphs.Count;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
private enum Mode
|
||||
{
|
||||
Undefined,
|
||||
Zaa,
|
||||
Clinic
|
||||
}
|
||||
|
||||
private Mode _mode;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
170
zaaReloaded2/Importer/BaseImporter.cs
Executable file
170
zaaReloaded2/Importer/BaseImporter.cs
Executable file
@ -0,0 +1,170 @@
|
||||
/* ZaaImporter.cs
|
||||
* part of zaaReloaded2
|
||||
*
|
||||
* Copyright 2017 Daniel Kraus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Bovender.Extensions;
|
||||
using zaaReloaded2.LabModel;
|
||||
using zaaReloaded2.Thesaurus;
|
||||
|
||||
namespace zaaReloaded2.Importer
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for certain importers such as ZaaImporter, ClinicImporter.
|
||||
/// </summary>
|
||||
public class BaseImporter : IImporter
|
||||
{
|
||||
#region IImporter implementation
|
||||
|
||||
public Laboratory Laboratory
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
if (_laboratory == null)
|
||||
{
|
||||
_laboratory = new Laboratory();
|
||||
}
|
||||
return _laboratory;
|
||||
}
|
||||
[DebuggerStepThrough]
|
||||
set
|
||||
{
|
||||
_laboratory = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Success
|
||||
{
|
||||
get
|
||||
{
|
||||
return Laboratory.TimePoints.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Splits the <paramref name="text"/> into individual time points
|
||||
/// and creates <see cref="TimePoint"/> objects from them.
|
||||
/// </summary>
|
||||
public void Import(string text)
|
||||
{
|
||||
Logger.Info("Import: \"{0}\"", text.TruncateWithEllipsis(120));
|
||||
string[] paragraphs = Helpers.SplitParagraphs(text);
|
||||
Logger.Info("Import: {0} paragraph(s)", paragraphs.Length);
|
||||
TimePoint timePoint = null;
|
||||
|
||||
foreach (string paragraph in paragraphs)
|
||||
{
|
||||
Logger.Info("Import: \"{0}\"", paragraph.TruncateWithEllipsis(40));
|
||||
// If the current paragraph looks like a time stamp,
|
||||
// create a new time point.
|
||||
if (IsTimeStamp(paragraph))
|
||||
{
|
||||
Logger.Info("Import: Time stamp detected", paragraph);
|
||||
timePoint = CreateTimePoint(paragraph, _parameters, _units);
|
||||
// Add the time point to the laboratory only if none
|
||||
// with the same time stamp exists yet.
|
||||
TimePoint existing = null;
|
||||
if (Laboratory.TryGetTimePoint(timePoint.TimeStamp, ref existing))
|
||||
{
|
||||
timePoint = existing;
|
||||
}
|
||||
else
|
||||
{
|
||||
Laboratory.AddTimePoint(timePoint);
|
||||
}
|
||||
}
|
||||
// If the current paragraph looks like a paragraph with
|
||||
// laboratory items, add it to the current time point;
|
||||
// if no time point exists yet, create one.
|
||||
else if (IsItemsParagraph(paragraph))
|
||||
{
|
||||
Logger.Info("Import: Paragraph with lab items detected");
|
||||
if (timePoint == null)
|
||||
{
|
||||
timePoint = CreateTimePoint(paragraph, _parameters, _units);
|
||||
Laboratory.AddTimePoint(timePoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
timePoint.Parse(paragraph);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("Import: Neither time stamp, nor Lauris paragraph");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public BaseImporter()
|
||||
{
|
||||
_parameters = Parameters.Default;
|
||||
_units = Units.Default;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Virtual methods
|
||||
|
||||
protected virtual TimePoint CreateTimePoint(string paragraph, Parameters parameters, Units units)
|
||||
{
|
||||
NotImplementedException e = new NotImplementedException("Cannot create TimePoint in base class - derived class must override CreateTimePoint");
|
||||
Logger.Fatal(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
protected virtual bool IsTimeStamp(string paragraph)
|
||||
{
|
||||
NotImplementedException e = new NotImplementedException("Cannot test time stamp in base class - derived class must override IsTimeStamp");
|
||||
Logger.Fatal(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
protected virtual bool IsItemsParagraph(string paragraph)
|
||||
{
|
||||
NotImplementedException e = new NotImplementedException("Cannot test items in base class - derived class must override IsItemsParagraph");
|
||||
Logger.Fatal(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
Laboratory _laboratory;
|
||||
Parameters _parameters;
|
||||
Units _units;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class logger
|
||||
|
||||
private static NLog.Logger Logger { get { return _logger.Value; } }
|
||||
|
||||
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
68
zaaReloaded2/Importer/ClinicImporter/ClinicImporter.cs
Executable file
68
zaaReloaded2/Importer/ClinicImporter/ClinicImporter.cs
Executable file
@ -0,0 +1,68 @@
|
||||
/* ZaaImporter.cs
|
||||
* part of zaaReloaded2
|
||||
*
|
||||
* Copyright 2017 Daniel Kraus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Bovender.Extensions;
|
||||
using zaaReloaded2.LabModel;
|
||||
using zaaReloaded2.Thesaurus;
|
||||
|
||||
namespace zaaReloaded2.Importer.ClinicImporter
|
||||
{
|
||||
/// <summary>
|
||||
/// Imports laboratory items by parsing the Lauris data from a
|
||||
/// physician's letter.
|
||||
/// </summary>
|
||||
public class ClinicImporter : BaseImporter
|
||||
{
|
||||
#region Constructor
|
||||
|
||||
public ClinicImporter() : base() { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class logger
|
||||
|
||||
private static NLog.Logger Logger { get { return _logger.Value; } }
|
||||
|
||||
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of BaseImporter
|
||||
|
||||
protected override TimePoint CreateTimePoint(string paragraph, Parameters parameters, Units units)
|
||||
{
|
||||
return new ClinicTimePoint(paragraph, parameters, units);
|
||||
}
|
||||
|
||||
protected override bool IsTimeStamp(string paragraph)
|
||||
{
|
||||
return ClinicTimePoint.IsTimeStampLine(paragraph);
|
||||
}
|
||||
|
||||
protected override bool IsItemsParagraph(string paragraph)
|
||||
{
|
||||
return ClinicLine.ResemblesClinicLine(paragraph);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
138
zaaReloaded2/Importer/ClinicImporter/ClinicLine.cs
Executable file
138
zaaReloaded2/Importer/ClinicImporter/ClinicLine.cs
Executable file
@ -0,0 +1,138 @@
|
||||
/* ClinicLine.cs
|
||||
* part of zaaReloaded2
|
||||
*
|
||||
* Copyright 2017 Daniel Kraus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using zaaReloaded2.Thesaurus;
|
||||
using zaaReloaded2.LabModel;
|
||||
using zaaReloaded2.Importer.ZaaImporter;
|
||||
using Bovender.Extensions;
|
||||
|
||||
namespace zaaReloaded2.Importer.ClinicImporter
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses a line in a lab section produced by the outpatients clinic system,
|
||||
/// and creates a list of <see cref="zaaReloaded2.Importer.BaseImporter.LabItem"/>s.
|
||||
/// </summary>
|
||||
public class ClinicLine
|
||||
{
|
||||
#region Static methods
|
||||
|
||||
/// <summary>
|
||||
/// Investigates a paragraph and determines whether it looks
|
||||
/// like a clinic laboratory items line.
|
||||
/// </summary>
|
||||
public static bool ResemblesClinicLine(string line)
|
||||
{
|
||||
return _expectedFormat.IsMatch(line);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
|
||||
public LaurisItem Item { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the original line that this object was constructed from.
|
||||
/// </summary>
|
||||
public string OriginalLine{ get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is true if the <see cref="OriginalLine"/> matches the expected
|
||||
/// format and contains <see cref="LabItem"/>s.
|
||||
/// </summary>
|
||||
public bool IsClinicLine{ get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public ClinicLine(string line)
|
||||
{
|
||||
OriginalLine = line;
|
||||
Parse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="ClinicLine"/> object from a given line,
|
||||
/// using a <paramref name="parameterDictionary"/> and a
|
||||
/// <paramref name="unitDictionary"/> to translate the individual
|
||||
/// items' properties.
|
||||
/// </summary>
|
||||
/// <param name="line">line to parse.</param>
|
||||
/// <param name="parameterDictionary">ParameterDictionary that contains
|
||||
/// canonical names and material types.</param>
|
||||
/// <param name="unitDictionary">Unit dictionary that contains canonical
|
||||
/// unit names.</param>
|
||||
public ClinicLine(string line,
|
||||
Thesaurus.Parameters parameterDictionary,
|
||||
Thesaurus.Units unitDictionary)
|
||||
{
|
||||
OriginalLine = line;
|
||||
_parameterDictionary = parameterDictionary;
|
||||
_unitDictionary = unitDictionary;
|
||||
Parse();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to parse a line.
|
||||
/// </summary>
|
||||
void Parse()
|
||||
{
|
||||
Logger.Info("Parse: \"{0}\"", OriginalLine.TruncateWithEllipsis(40).Replace("\t", " "));
|
||||
Match m = _expectedFormat.Match(OriginalLine);
|
||||
if (m.Success)
|
||||
{
|
||||
Logger.Info("Parse: Matches clinic line format");
|
||||
Item = new LaurisItem(m.Groups["item"].Value, _parameterDictionary, _unitDictionary);
|
||||
IsClinicLine = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info("Parse: Does not match clinic line format");
|
||||
IsClinicLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
static readonly Regex _expectedFormat = new Regex(@"\t(?<item>[^:]+:(\t[^\t]+){3})");
|
||||
Thesaurus.Parameters _parameterDictionary;
|
||||
Thesaurus.Units _unitDictionary;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class logger
|
||||
|
||||
private static NLog.Logger Logger { get { return _logger.Value; } }
|
||||
|
||||
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
258
zaaReloaded2/Importer/ClinicImporter/ClinicTimePoint.cs
Executable file
258
zaaReloaded2/Importer/ClinicImporter/ClinicTimePoint.cs
Executable file
@ -0,0 +1,258 @@
|
||||
/* ClinicTimePoint.cs
|
||||
* part of zaaReloaded2
|
||||
*
|
||||
* Copyright 2017 Daniel Kraus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using zaaReloaded2.Thesaurus;
|
||||
using zaaReloaded2.LabModel;
|
||||
|
||||
namespace zaaReloaded2.Importer.ClinicImporter
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds all laboratory items for a given time point.
|
||||
/// </summary>
|
||||
class ClinicTimePoint : TimePoint
|
||||
{
|
||||
#region Static methods
|
||||
|
||||
/// <summary>
|
||||
/// Examines a string and returns true if it resembles
|
||||
/// a time stamp line in the clinic output.
|
||||
/// </summary>
|
||||
/// <param name="line">Line to examine.</param>
|
||||
/// <returns>True if line resembles a time stamp line
|
||||
/// in the clinic output.</returns>
|
||||
static public bool IsTimeStampLine(string line)
|
||||
{
|
||||
return _timeStampRegex.IsMatch(line);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Regex object that matches a clinic time stamp
|
||||
/// line.
|
||||
/// </summary>
|
||||
static public Regex TimeStampRegex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _timeStampRegex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of lines in this ClinicText.
|
||||
/// </summary>
|
||||
public IList<String> Lines
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
if (_lines == null)
|
||||
{
|
||||
_lines = new List<String>();
|
||||
}
|
||||
return _lines;
|
||||
}
|
||||
set
|
||||
{
|
||||
_lines = value;
|
||||
ParseLines();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is true if the LaurisText has time stamp in the first
|
||||
/// paragraph and <see cref="LabItem"/>s in the others.
|
||||
/// </summary>
|
||||
public bool IsValidTimePoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return Items.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original Lauris text for this timepoint.
|
||||
/// </summary>
|
||||
public string ClinicText
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
return String.Join(Environment.NewLine, Lines);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
{
|
||||
Lines = value.Split(
|
||||
new string[] { Environment.NewLine },
|
||||
StringSplitOptions.None).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public ClinicTimePoint() { }
|
||||
|
||||
public ClinicTimePoint(
|
||||
string clinicText,
|
||||
Parameters parameterDictionary,
|
||||
Units unitDictionary)
|
||||
: this()
|
||||
{
|
||||
_parameterDictionary = parameterDictionary;
|
||||
_unitDictionary = unitDictionary;
|
||||
ClinicText = clinicText;
|
||||
}
|
||||
|
||||
public ClinicTimePoint(string clinicText)
|
||||
: this(clinicText, null, null)
|
||||
{ }
|
||||
|
||||
public ClinicTimePoint(
|
||||
IList<String> lines,
|
||||
Parameters parameterDictionary,
|
||||
Units unitDictionary)
|
||||
: this(parameterDictionary, unitDictionary)
|
||||
{
|
||||
Lines = lines;
|
||||
}
|
||||
|
||||
public ClinicTimePoint(IList<String> lines)
|
||||
: this(lines, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public ClinicTimePoint(
|
||||
Parameters parameterDictionary,
|
||||
Units unitDictionary)
|
||||
: this()
|
||||
{
|
||||
_parameterDictionary = parameterDictionary;
|
||||
_unitDictionary = unitDictionary;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new line to this time point by parsing
|
||||
/// the line for a laboratory item.
|
||||
/// </summary>
|
||||
/// <param name="paragraph">Line to add.</param>
|
||||
public override void Parse(string paragraph)
|
||||
{
|
||||
Lines.Add(paragraph);
|
||||
ParseLine(paragraph);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Analyzes each clinic line in this time point, sets the date
|
||||
/// and time, and collects LabItem data.
|
||||
/// </summary>
|
||||
void ParseLines()
|
||||
{
|
||||
if (Lines != null)
|
||||
{
|
||||
foreach (string paragraph in Lines)
|
||||
{
|
||||
ParseLine(paragraph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseLine(string line)
|
||||
{
|
||||
Match m = _timeStampRegex.Match(line);
|
||||
if (m.Success)
|
||||
{
|
||||
Logger.Info("ParseLine: Matches time stamp");
|
||||
DateTime dt;
|
||||
if (DateTime.TryParseExact(
|
||||
m.Groups["datetime"].Value,
|
||||
"dd.MM.yyyy HH:mm",
|
||||
CultureInfo.InvariantCulture,
|
||||
DateTimeStyles.AllowWhiteSpaces,
|
||||
out dt))
|
||||
{
|
||||
TimeStamp = dt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info("ParseLine: Not a time stamp");
|
||||
ClinicLine clinicLine = new ClinicLine(
|
||||
line,
|
||||
_parameterDictionary,
|
||||
_unitDictionary);
|
||||
if (clinicLine.IsClinicLine)
|
||||
{
|
||||
Logger.Debug("ParseParagraph: Merging Lauris paragraph");
|
||||
Items[clinicLine.Item.QualifiedName] = clinicLine.Item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddItems(IItemDictionary items)
|
||||
{
|
||||
Items.Merge(items);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private fields
|
||||
|
||||
/// <summary>
|
||||
/// A regular expression that matches the time stamp in the first
|
||||
/// paragraph of a LaurisText.
|
||||
/// </summary>
|
||||
static readonly Regex _timeStampRegex = new Regex(
|
||||
@"^(Labor:?)?\s*\(?\s*(?<datetime>\d\d\.\d\d\.\d\d\d\d\s+\d\d:\d\d)(:00)?\)\s*$");
|
||||
IList<String> _lines;
|
||||
Parameters _parameterDictionary;
|
||||
Units _unitDictionary;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class logger
|
||||
|
||||
private static NLog.Logger Logger { get { return _logger.Value; } }
|
||||
|
||||
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -169,7 +169,7 @@ namespace zaaReloaded2.Importer.ZaaImporter
|
||||
/// the paragraph for laboratory items.
|
||||
/// </summary>
|
||||
/// <param name="paragraph">Paragraph to add.</param>
|
||||
public void AddParagraph(string paragraph)
|
||||
public override void Parse(string paragraph)
|
||||
{
|
||||
Paragraphs.Add(paragraph);
|
||||
ParseParagraph(paragraph);
|
||||
|
@ -30,106 +30,30 @@ namespace zaaReloaded2.Importer.ZaaImporter
|
||||
/// Imports laboratory items by parsing the Lauris data from a
|
||||
/// physician's letter.
|
||||
/// </summary>
|
||||
public class ZaaImporter : IImporter
|
||||
public class ZaaImporter : BaseImporter
|
||||
{
|
||||
#region IImporter implementation
|
||||
|
||||
public Laboratory Laboratory
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
if (_laboratory == null)
|
||||
{
|
||||
_laboratory = new Laboratory();
|
||||
}
|
||||
return _laboratory;
|
||||
}
|
||||
[DebuggerStepThrough]
|
||||
set
|
||||
{
|
||||
_laboratory = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Success
|
||||
{
|
||||
get
|
||||
{
|
||||
return Laboratory.TimePoints.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Splits the <paramref name="text"/> into individual time points
|
||||
/// and creates <see cref="LaurisTimePoint"/> objects from them.
|
||||
/// </summary>
|
||||
/// <param name="text">ZAA-formatted Lauris output to import.</param>
|
||||
public void Import(string text)
|
||||
{
|
||||
Logger.Info("Import: \"{0}\"", text.TruncateWithEllipsis(120));
|
||||
string[] paragraphs = Helpers.SplitParagraphs(text);
|
||||
Logger.Info("Import: {0} paragraph(s)", paragraphs.Length);
|
||||
LaurisTimePoint timePoint = null;
|
||||
|
||||
foreach (string paragraph in paragraphs)
|
||||
{
|
||||
Logger.Info("Import: \"{0}\"", paragraph.TruncateWithEllipsis(40));
|
||||
// If the current paragraph looks like a Lauris time stamp,
|
||||
// create a new time point.
|
||||
if (LaurisTimePoint.IsTimeStampLine(paragraph))
|
||||
{
|
||||
Logger.Info("Import: Time stamp detected", paragraph);
|
||||
timePoint = new LaurisTimePoint(paragraph, _parameters, _units);
|
||||
// Add the time point to the laboratory only if none
|
||||
// with the same time stamp exists yet.
|
||||
TimePoint existing = null;
|
||||
if (Laboratory.TryGetTimePoint(timePoint.TimeStamp, ref existing))
|
||||
{
|
||||
timePoint = existing as LaurisTimePoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
Laboratory.AddTimePoint(timePoint);
|
||||
}
|
||||
}
|
||||
// If the current paragraph looks like a paragraph with
|
||||
// laboratory items, add it to the current time point;
|
||||
// if no time point exists yet, create one.
|
||||
else if (LaurisParagraph.ResemblesLaurisParagraph(paragraph))
|
||||
{
|
||||
Logger.Info("Import: Lauris paragraph detected");
|
||||
if (timePoint == null)
|
||||
{
|
||||
timePoint = new LaurisTimePoint(_parameters, _units);
|
||||
Laboratory.AddTimePoint(timePoint);
|
||||
}
|
||||
timePoint.AddParagraph(paragraph);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("Import: Neither time stamp, nor Lauris paragraph");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public ZaaImporter()
|
||||
{
|
||||
_parameters = Parameters.Default;
|
||||
_units = Units.Default;
|
||||
}
|
||||
public ZaaImporter() : base() { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
#region Implementation of BaseImporter
|
||||
|
||||
Laboratory _laboratory;
|
||||
Parameters _parameters;
|
||||
Units _units;
|
||||
protected override TimePoint CreateTimePoint(string paragraph, Parameters parameters, Units units)
|
||||
{
|
||||
return new LaurisTimePoint(paragraph, parameters, units);
|
||||
}
|
||||
|
||||
protected override bool IsTimeStamp(string paragraph)
|
||||
{
|
||||
return LaurisTimePoint.IsTimeStampLine(paragraph);
|
||||
}
|
||||
|
||||
protected override bool IsItemsParagraph(string paragraph)
|
||||
{
|
||||
return LaurisParagraph.ResemblesLaurisParagraph(paragraph);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -68,6 +68,7 @@ namespace zaaReloaded2.LabModel
|
||||
{
|
||||
if (String.IsNullOrEmpty(item.QualifiedName))
|
||||
{
|
||||
Logger.Fatal("Cannot add item without QualifiedName!");
|
||||
throw new ArgumentException("Cannot add item that has no qualified name.");
|
||||
}
|
||||
Items.Add(item.QualifiedName, item);
|
||||
@ -84,8 +85,10 @@ namespace zaaReloaded2.LabModel
|
||||
public void MergeItems(TimePoint otherTimePoint)
|
||||
{
|
||||
if (otherTimePoint == null)
|
||||
{
|
||||
Logger.Fatal("Cannot merge null!");
|
||||
throw new ArgumentNullException("otherTimePoint");
|
||||
|
||||
}
|
||||
Items.Merge(otherTimePoint.Items);
|
||||
}
|
||||
|
||||
@ -101,6 +104,21 @@ namespace zaaReloaded2.LabModel
|
||||
return Items.ContainsKey(item);
|
||||
}
|
||||
|
||||
public virtual void Parse(string paragraph)
|
||||
{
|
||||
NotImplementedException e = new NotImplementedException("Cannot parse paragraph in base class - derived class must override Parse");
|
||||
Logger.Fatal(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class logger
|
||||
|
||||
private static NLog.Logger Logger { get { return _logger.Value; } }
|
||||
|
||||
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +204,11 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Commands.cs" />
|
||||
<Compile Include="Helpers.cs" />
|
||||
<Compile Include="Importer\ZaaImporter\AutoDetect.cs" />
|
||||
<Compile Include="Importer\ClinicImporter\ClinicLine.cs" />
|
||||
<Compile Include="Importer\ClinicImporter\ClinicTimePoint.cs" />
|
||||
<Compile Include="Importer\ClinicImporter\ClinicImporter.cs" />
|
||||
<Compile Include="Importer\BaseImporter.cs" />
|
||||
<Compile Include="Importer\AutoDetector.cs" />
|
||||
<Compile Include="Controller\Comments\CommentPool.cs" />
|
||||
<Compile Include="Controller\Elements\ControlElementBase.cs" />
|
||||
<Compile Include="Controller\Elements\FormatElementBase.cs" />
|
||||
@ -466,6 +470,7 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Icons\mm.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
Reference in New Issue
Block a user