From 2cf31914ddf569db6739fde56363ddfc857f22ce Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Mon, 6 Jul 2015 15:48:43 +0200 Subject: [PATCH] Refactor: Separate concerns. --- .../ZaaImporter/LaurisItemTest.cs} | 27 +-- .../ZaaImporter}/LaurisParagraphTest.cs | 5 +- .../ZaaImporter}/TimePointTest.cs | 29 +-- Tests/Tests.csproj | 13 +- Tests/zaaReloaded2.pfx | Bin 0 -> 1764 bytes zaaReloaded2/Dictionaries/IItemDictionary.cs | 2 +- zaaReloaded2/Dictionaries/ItemDictionary.cs | 2 +- .../Dictionaries/ParameterDictionary.cs | 4 +- zaaReloaded2/Importer/IImporter.cs | 39 ++++ .../ZaaImporter/LaurisItem.cs} | 207 ++---------------- .../ZaaImporter}/LaurisParagraph.cs | 7 +- .../ZaaImporter/LaurisTimePoint.cs} | 51 ++--- .../Importer/ZaaImporter/ZaaImporter.cs | 54 +++++ zaaReloaded2/LabModel/LabItem.cs | 204 +++++++++++++++++ zaaReloaded2/LabModel/Laboratory.cs | 36 +++ zaaReloaded2/{Models => LabModel}/Material.cs | 2 +- zaaReloaded2/LabModel/TimePoint.cs | 52 +++++ zaaReloaded2/Properties/AssemblyInfo.cs | 1 + zaaReloaded2/zaaReloaded2.csproj | 16 +- 19 files changed, 492 insertions(+), 259 deletions(-) rename Tests/{LabItemTest.cs => Importer/ZaaImporter/LaurisItemTest.cs} (89%) rename Tests/{ => Importer/ZaaImporter}/LaurisParagraphTest.cs (93%) rename Tests/{ => Importer/ZaaImporter}/TimePointTest.cs (66%) create mode 100755 Tests/zaaReloaded2.pfx create mode 100755 zaaReloaded2/Importer/IImporter.cs rename zaaReloaded2/{Models/LabItem.cs => Importer/ZaaImporter/LaurisItem.cs} (53%) rename zaaReloaded2/{Models => Importer/ZaaImporter}/LaurisParagraph.cs (94%) rename zaaReloaded2/{Models/TimePoint.cs => Importer/ZaaImporter/LaurisTimePoint.cs} (86%) create mode 100755 zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs create mode 100755 zaaReloaded2/LabModel/LabItem.cs create mode 100755 zaaReloaded2/LabModel/Laboratory.cs rename zaaReloaded2/{Models => LabModel}/Material.cs (98%) create mode 100755 zaaReloaded2/LabModel/TimePoint.cs diff --git a/Tests/LabItemTest.cs b/Tests/Importer/ZaaImporter/LaurisItemTest.cs similarity index 89% rename from Tests/LabItemTest.cs rename to Tests/Importer/ZaaImporter/LaurisItemTest.cs index 3226d50..458d203 100755 --- a/Tests/LabItemTest.cs +++ b/Tests/Importer/ZaaImporter/LaurisItemTest.cs @@ -1,4 +1,4 @@ -/* LabItemTest.cs +/* LaurisItemTest.cs * part of zaaReloaded2 * * Copyright 2015 Daniel Kraus @@ -20,12 +20,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; -using zaaReloaded2.Models; +using zaaReloaded2.LabModel; +using zaaReloaded2.Importer.ZaaImporter; -namespace Tests +namespace Tests.Importer.ZaaImporter { [TestFixture] - class LabItemTest + class LaurisItemTest { [Test] [TestCase("Natrium: 139 [135 - 145] mmol/l", "Natrium", 139, "mmol/l", 135, 145, true)] @@ -34,7 +35,7 @@ namespace Tests string laurisString, string name, double value, string unit, double lowerLimit, double upperLimit, bool isNormal) { - LabItem i = new LabItem(laurisString); + LaurisItem i = new LaurisItem(laurisString); Assert.AreEqual(name, i.Name, "Name"); Assert.AreEqual(unit, i.Unit, "Unit"); Assert.IsTrue(i.IsNumerical, "IsNumerical"); @@ -52,7 +53,7 @@ namespace Tests string laurisString, string name, double value, string unit, double lowerLimit, bool isNormal) { - LabItem i = new LabItem(laurisString); + LaurisItem i = new LaurisItem(laurisString); Assert.AreEqual(name, i.Name, "Name"); Assert.AreEqual(unit, i.Unit, "Unit"); Assert.IsTrue(i.IsNumerical, "IsNumerical"); @@ -69,7 +70,7 @@ namespace Tests string laurisString, string name, double value, string unit, double upperLimit, bool isNormal) { - LabItem i = new LabItem(laurisString); + LaurisItem i = new LaurisItem(laurisString); Assert.AreEqual(name, i.Name, "Name"); Assert.AreEqual(unit, i.Unit, "Unit"); Assert.IsTrue(i.IsNumerical, "IsNumerical"); @@ -87,7 +88,7 @@ namespace Tests string laurisString, string name, double value, string unit) { - LabItem i = new LabItem(laurisString); + LaurisItem i = new LaurisItem(laurisString); Assert.AreEqual(name, i.Name, "Name"); Assert.AreEqual(unit, i.Unit, "Unit"); Assert.IsTrue(i.IsNumerical, "IsNumerical"); @@ -101,14 +102,14 @@ namespace Tests public void ParseLaurisNonNumericNoNormal( string laurisString, string name, string value) { - LabItem i = new LabItem(laurisString); + LaurisItem i = new LaurisItem(laurisString); Assert.AreEqual(name, i.Name, "Name"); Assert.AreEqual(value, i.Value, "Value"); Assert.IsTrue(String.IsNullOrEmpty(i.Unit), "Unit should be a null string"); Assert.IsFalse(i.HasLimits, "HasLimits"); Assert.IsFalse(i.HasLowerLimit, "HasLowerLimit"); Assert.IsFalse(i.HasUpperLimit, "HasUpperLimit"); - // TODO: Define the behavior of LabItem.IsNormal if no normal value known + // TODO: Define the behavior of LaurisItem.IsNormal if no normal value known } [TestCase("Erythrozyten (U): + [negativ]", "Erythrozyten (U)", "+", "negativ", false)] @@ -116,7 +117,7 @@ namespace Tests public void ParseLaurisNonNumericWithNormal( string laurisString, string name, string value, string normal, bool isNormal) { - LabItem i = new LabItem(laurisString); + LaurisItem i = new LaurisItem(laurisString); Assert.AreEqual(name, i.Name, "Name"); Assert.AreEqual(value, i.Value, "Value"); Assert.AreEqual(normal, i.Normal, "Normal"); @@ -124,7 +125,7 @@ namespace Tests Assert.IsFalse(i.HasLimits, "HasLimits"); Assert.IsFalse(i.HasLowerLimit, "HasLowerLimit"); Assert.IsFalse(i.HasUpperLimit, "HasUpperLimit"); - // TODO: Define the behavior of LabItem.IsNormal if no normal value known + // TODO: Define the behavior of LaurisItem.IsNormal if no normal value known } [TestCase("Albumin (SU)/die: 149.9 [<= 30] mg/d; ", Material.SU)] @@ -132,7 +133,7 @@ namespace Tests [TestCase("Cystatin C (N Latex): 2.37 [0.57 - 0.96] mg/l; ", Material.B)] public void ParseLaurisMaterial(string laurisString, Material expectedMaterial) { - LabItem i = new LabItem(laurisString); + LaurisItem i = new LaurisItem(laurisString); Assert.AreEqual(expectedMaterial, i.Material); } } diff --git a/Tests/LaurisParagraphTest.cs b/Tests/Importer/ZaaImporter/LaurisParagraphTest.cs similarity index 93% rename from Tests/LaurisParagraphTest.cs rename to Tests/Importer/ZaaImporter/LaurisParagraphTest.cs index 3a8ca7c..e08b037 100755 --- a/Tests/LaurisParagraphTest.cs +++ b/Tests/Importer/ZaaImporter/LaurisParagraphTest.cs @@ -16,9 +16,10 @@ * limitations under the License. */ using NUnit.Framework; -using zaaReloaded2.Models; +using zaaReloaded2.LabModel; +using zaaReloaded2.Importer.ZaaImporter; -namespace Tests +namespace Tests.Importer.ZaaImporter { [TestFixture] class LaurisParagraphTest diff --git a/Tests/TimePointTest.cs b/Tests/Importer/ZaaImporter/TimePointTest.cs similarity index 66% rename from Tests/TimePointTest.cs rename to Tests/Importer/ZaaImporter/TimePointTest.cs index cfd3091..409e273 100755 --- a/Tests/TimePointTest.cs +++ b/Tests/Importer/ZaaImporter/TimePointTest.cs @@ -1,4 +1,4 @@ -/* TimePointTest.cs +/* LaurisTimePointTest.cs * part of zaaReloaded2 * * Copyright 2015 Daniel Kraus @@ -20,47 +20,48 @@ using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; -using zaaReloaded2.Models; +using zaaReloaded2.LabModel; +using zaaReloaded2.Importer.ZaaImporter; -namespace Tests +namespace Tests.Importer.ZaaImporter { [TestFixture] - class TimePointTest + class LaurisTimePointTest { [Test] - public void ParseValidTimePoint() + public void ParseValidLaurisTimePoint() { - TimePoint tp = new TimePoint( + LaurisTimePoint tp = new LaurisTimePoint( "[22.10.2013 12:30:00]" + Environment.NewLine + "Klinische Chemie: Natrium: 139 [135 - 145] mmol/l;  Kalium: 5.2 [3.5 - 5] mmol/l;"); Assert.IsTrue(tp.IsValidTimePoint); } [Test] - public void ParseInvalidTimePoints() + public void ParseInvalidLaurisTimePoints() { - TimePoint tp = new TimePoint("Aerobe Kultur: Enterokokken ;  Wachstum: 10 ;"); + LaurisTimePoint tp = new LaurisTimePoint("Aerobe Kultur: Enterokokken ;  Wachstum: 10 ;"); Assert.IsFalse(tp.IsValidTimePoint, - "Bogus paragraph should be invalid TimePoint"); + "Bogus paragraph should be invalid LaurisTimePoint"); tp.LaurisText = "[22.10.2013 12:30:00]"; Assert.IsFalse(tp.IsValidTimePoint, - "TimePoint should be invalid if it consists of time stamp only."); + "LaurisTimePoint should be invalid if it consists of time stamp only."); } [Test] - public void ParseTimePointWithDuplicateItems() + public void ParseLaurisTimePointWithDuplicateItems() { - TimePoint tp = new TimePoint( + LaurisTimePoint tp = new LaurisTimePoint( "[22.10.2013 12:30:00]" + Environment.NewLine + "Klinische Chemie: Natrium: 139 [135 - 145] mmol/l;  Kalium: 5.2 [3.5 - 5] mmol/l;" + Environment.NewLine + "Klinische Chemie: Natrium: 142 [135 - 145] mmol/l;  Kalium: 3.7 [3.5 - 5] mmol/l;" ); Assert.IsTrue(tp.Items.ContainsKey("Kalium"), - "TimePoint should contain 'Kalium' item."); + "LaurisTimePoint should contain 'Kalium' item."); Assert.AreEqual(3.7, tp.Items["Kalium"].NumericalValue, - "TimePoint does not use last occurrence of 'Kalium'."); + "LaurisTimePoint does not use last occurrence of 'Kalium'."); } } } diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 8a3aaa5..cf3472c 100755 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -34,6 +34,12 @@ prompt 4 + + true + + + zaaReloaded2.pfx + False @@ -58,16 +64,17 @@ - - + + - + + diff --git a/Tests/zaaReloaded2.pfx b/Tests/zaaReloaded2.pfx new file mode 100755 index 0000000000000000000000000000000000000000..a8d32ffb90d596ac3f5dae3df2b944bead587761 GIT binary patch literal 1764 zcmY+DcU03^7RO&g2t^3eTY#toClZu|Rf5ZaB7!VUkr|~3iWmcf7^DtGgorR;K#Gd= zCKE&mH3^|PA}wG-HMB*_!l2ktB4k2f_UD}4nKS2|``-6{?z`{2KkgS#Mb5)vQg|w| z5GiMz?2x>v2$O-8QjzHhDl!$qxA9ad*567}bOcqZ0>ULw6d-r~uS-E51}~+;S$HbE z5sya7{~tq-qY$z}^;eppABjMg-=PrlIK3i`<~P zkIlEN$ljPBF3BPfy&N&yjjOe%8`xYx4NMtOJgyxLy>hMzg|pa&t9RBu?}9^X#mKfa zIL0vjy{j~S+hR;MvQ?JF3zVJ4BB5tVaXaVVg&Cq|^NqpHapfeRNQ5oNmam8@yo=wqYV|5}whLzvfT* zw^yf{AY=cazG>*QcPNQ@z(H~De0(y~>Ki4&LCOAC-%M4Co;q|G^5%2>RAaEp3m-zd zr$f3T)*d+%vX_`v+LJmz51i+DPVF>Ykb^(FF6+S>sq=o=H~X3X&)#U!#);EEvvn2k zv}1BsTa)5HIo`$I-nDMN5Vb-By-d&O56^cBEp!4>x(=I`XZ9SS-AnBEV7umpO?>h$ zdgJs(clBFSJEmu;tM2QeSoeY%VQ-S(!upwPt1(uhtn-sLURZWnbl0$t{E*`PoH^NU zT4i`&Oj(7mioLQC72&9e_kAs0qaI9CU4KrjN(_70OsZNiBpDO!(>ANU_~n-myv$lj z8yWP}2x{E-ue4c*7c{rdPo`a@*Bsrq(x+bYrGkYgl{s@vGC1@40)cOwY9)<44U`UNf@hvQ?XYivQ6@!$Q&r=9`pf;#$bg zt{cOWjRTwCviy4vI$t_&D?4WVAg5;A;p#m?x=q}CLXJt+`L!`2Jfvi6Zo<0NIx8^l zaX1#;e~FMdf>-@>%;nSxNCW}~0Kj|y1=R?y`pzI0*aI6t02TlbjzH&eZ~#*Fzz!US z)FEIFEjvgZ2Sg}rAoUN3oPd-CLKB9ry&Z}8!K4UcoRuc!M_guG4^VyPcx}KANiHgc( z!D?zMhh`oew&l2NYPeg5kX6Qf71G-ZPqphwPw$jaEJt^adNR7-Wlo{jBF*<0>f0X+C=eyHp#kfdvdXrZBPQQd*kRVydSJH zBjOQ08unxvn=p%8#x~X>3%U06TNHlQQp+NvHa+2S3DK*xi`w_D)=x00*eOpB>ONvE zJCir9bw1|$sG1~&U65JOtMfL%=WNQd;Tv>teYE5p_eRAgbN6~7=d4%0YmRHI3BSBF zva+e}JrecdF1CM`#((-zq08*ctM%S(y#4JTc=5xX$1EyMsj;4IhtVdaN&a^z9Jy+M zEIg@w$-^a+HNCg_$dpzeC)hl)X5P*|_gVkK@0L4yL92XJFgJQWFvD+rbt~y+ z?cQd+0+#^m>dY6isdue7T{lz0%|B)aVz0zTWovdkvd-*==Llmvj#pJr&^JBWeELHQ z;StR;8hr7SpZNRoS{8bWItUf8{nP|WUREn6QeSX&;s@2irB8x!l0uDBP~M_U3f>ZL zfR{l^<4{s?9fTTB{y#*=@@MpS=a_>ACnM#`a%oElwU^nxq3+xOZ|=Z@!p>83;p5Iu ItzQTDzctVqJ^%m! literal 0 HcmV?d00001 diff --git a/zaaReloaded2/Dictionaries/IItemDictionary.cs b/zaaReloaded2/Dictionaries/IItemDictionary.cs index 9d96c1e..7d530be 100755 --- a/zaaReloaded2/Dictionaries/IItemDictionary.cs +++ b/zaaReloaded2/Dictionaries/IItemDictionary.cs @@ -25,7 +25,7 @@ namespace zaaReloaded2.Dictionaries /// /// A dictionary of s. /// - public interface IItemDictionary : IDictionary + public interface IItemDictionary : IDictionary { void Merge(IItemDictionary otherItemDictionary); } diff --git a/zaaReloaded2/Dictionaries/ItemDictionary.cs b/zaaReloaded2/Dictionaries/ItemDictionary.cs index 56d7482..131f88d 100755 --- a/zaaReloaded2/Dictionaries/ItemDictionary.cs +++ b/zaaReloaded2/Dictionaries/ItemDictionary.cs @@ -19,7 +19,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; -using zaaReloaded2.Models; +using zaaReloaded2.LabModel; namespace zaaReloaded2.Dictionaries { diff --git a/zaaReloaded2/Dictionaries/ParameterDictionary.cs b/zaaReloaded2/Dictionaries/ParameterDictionary.cs index bf5a7b1..81ae0cf 100755 --- a/zaaReloaded2/Dictionaries/ParameterDictionary.cs +++ b/zaaReloaded2/Dictionaries/ParameterDictionary.cs @@ -21,7 +21,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.IO; -using zaaReloaded2.Models; +using zaaReloaded2.LabModel; namespace zaaReloaded2.Dictionaries { @@ -49,7 +49,7 @@ namespace zaaReloaded2.Dictionaries /// Looks up the material for a given . /// /// Lauris item name to look up. - /// enum; if no material is + /// enum; if no material is /// found in the dictionary, the default material "S" (serum) is returned. public Material GetMaterial(string laurisName) { diff --git a/zaaReloaded2/Importer/IImporter.cs b/zaaReloaded2/Importer/IImporter.cs new file mode 100755 index 0000000..7da8fe3 --- /dev/null +++ b/zaaReloaded2/Importer/IImporter.cs @@ -0,0 +1,39 @@ +/* IImporter.cs + * part of zaaReloaded2 + * + * Copyright 2015 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.Linq; +using System.Text; +using zaaReloaded2.LabModel; + +namespace zaaReloaded2.Importer +{ + public interface IImporter + { + /// + /// Gets the Laboratory resulting from the data import. + /// + Laboratory Laboratory { get; set; } + + /// + /// Imports laboratory data contained in a string. + /// + /// String with laboratory data. + void Import(string text); + } +} diff --git a/zaaReloaded2/Models/LabItem.cs b/zaaReloaded2/Importer/ZaaImporter/LaurisItem.cs similarity index 53% rename from zaaReloaded2/Models/LabItem.cs rename to zaaReloaded2/Importer/ZaaImporter/LaurisItem.cs index d321ab5..27e05b0 100755 --- a/zaaReloaded2/Models/LabItem.cs +++ b/zaaReloaded2/Importer/ZaaImporter/LaurisItem.cs @@ -18,183 +18,26 @@ using System; using System.Globalization; using System.Text.RegularExpressions; +using zaaReloaded2.LabModel; -namespace zaaReloaded2.Models +namespace zaaReloaded2.Importer.ZaaImporter { /// /// Represents a single laboratory item (e.g., sodium or creatinine). /// - public class LabItem + public class LaurisItem : LabItem { #region Properties - /// - /// Gets or sets the original name of the item (as known by Lauris). - /// - public string Name { get; set; } - - /// - /// Gets or sets the unit of the item (as known by Lauris). - /// - public string Unit { get; set; } - - /// - /// Gets or sets the value of the item. This may be a number or a string. - /// - public string Value { get; set; } - - public double NumericalValue - { - get - { - if (IsNumerical) - { - return _numericalValue; - } - else - { - throw new InvalidOperationException( - String.Format("Value '{0}' is not numerical.", Value)); - } - } - private set - { - _numericalValue = value; - } - } - - public bool IsNumerical - { - get - { - return (Double.TryParse(Value, - NumberStyles.Any, - CultureInfo.InvariantCulture, - out _numericalValue)); - } - } - - /// - /// Gets or sets the normal value of the item. Need not be set. This is - /// used for items with nominal values (as opposed to numbers). - /// - public string Normal { get; set; } - - /// - /// Gets or sets the lower limit of normal. - /// - public double LowerLimit - { - get - { - return _lowerLimit; - } - set - { - _lowerLimit = value; - HasLowerLimit = true; - } - } - - /// - /// Is true if the item has a lower limit of normal. - /// - public bool HasLowerLimit { get; private set; } - - /// - /// Gets or sets the upper limit of normal. - /// - public double UpperLimit - { - get - { - return _upperLimit; - } - set - { - _upperLimit = value; - HasUpperLimit = true; - } - } - - /// - /// Is true if the item has an upper limit of normal. - /// - public bool HasUpperLimit { get; private set; } - - /// - /// Is true if is normal. - /// - public bool IsNormal - { - get - { - if (HasLimits) - { - if (HasLowerLimit && HasUpperLimit) - { - return (LowerLimit <= NumericalValue && - NumericalValue <= UpperLimit); - } - else - { - if (HasLowerLimit) - { - return (LowerLimit <= NumericalValue); - } - return (NumericalValue <= UpperLimit); - } - } - else - { - return (Value == Normal); - } - } - } - - /// - /// Is true if the item has lower and/or upper limits. Is false if the - /// item does not have limits but a value. - /// - public bool HasLimits - { - get { return (HasLowerLimit || HasUpperLimit); } - } - /// /// The original Lauris string from which this lab item was created. /// - public string Lauris { get; private set; } + public string LaurisText { get; private set; } /// - /// The canonical name of this item, or the Lauris - /// of the item if no canonical name is known. + /// The original name of this item as known by Lauris /// - public string CanonicalName { get; private set; } - - /// - /// Returns the canonical name prefixed with the abbreviation - /// for the material, e.g. "U-Na" for sodium in the spot urine, - /// but only if the material is not blood. - /// - public string QualifiedCanonicalName - { - get - { - if (Material == Models.Material.B) - { - return CanonicalName; - } - else - { - return String.Format("{0}-{1}", Material.ToString(), CanonicalName); - } - } - } - - public bool AlwaysPrintLimits { get; private set; } - - public Material Material { get; private set; } + public string OriginalName { get; private set; } #endregion @@ -203,11 +46,12 @@ namespace zaaReloaded2.Models /// /// Creates an empty LabItem object. /// - public LabItem() { } + public LaurisItem() : base() { } - public LabItem(string laurisString) + public LaurisItem(string laurisString) + : this() { - Lauris = laurisString; + LaurisText = laurisString; ParseLauris(); DetectMaterial(); } @@ -222,20 +66,16 @@ namespace zaaReloaded2.Models /// ParameterDictionary that is used /// to look up the canonical name, material type, and whether or /// not to always print the reference interval - public LabItem(string laurisString, + public LaurisItem(string laurisString, Dictionaries.ParameterDictionary parameterDictionary, Dictionaries.UnitDictionary unitDictionary) : this(laurisString) { if (parameterDictionary != null) { - CanonicalName = parameterDictionary.GetCanonicalName(Name); + Name = parameterDictionary.GetCanonicalName(OriginalName); AlwaysPrintLimits = parameterDictionary.GetForceReferenceDisplay(Name); } - else - { - CanonicalName = Name; - } if (unitDictionary != null) { Unit = unitDictionary.TranslateLaurisUnit(Unit); @@ -248,7 +88,7 @@ namespace zaaReloaded2.Models /// /// Parses the original Lauris string contained in - /// . + /// . /// void ParseLauris() { @@ -264,19 +104,20 @@ namespace zaaReloaded2.Models @"(?[^:]+):\s*(?[\d.]+)\s*(?\[[^\]]+])?\s*(?[^;]+)?"); Regex categoricalRegex = new Regex( @"(?[^:]+):\s*(?[^[;]+)\s*(\[(?[^\]]+)])?"); - if (numericalRegex.IsMatch(Lauris)) + if (numericalRegex.IsMatch(LaurisText)) { - match = numericalRegex.Match(Lauris); + match = numericalRegex.Match(LaurisText); ParseLimits(match); } else { - match = categoricalRegex.Match(Lauris); + match = categoricalRegex.Match(LaurisText); Normal = match.Groups["normal"].Value.Trim(); } if (match != null) { - Name = match.Groups["name"].Value.Trim(); + OriginalName = match.Groups["name"].Value.Trim(); + Name = OriginalName; Value = match.Groups["value"].Value.Trim(); Unit = match.Groups["unit"].Value.Trim(); } @@ -333,16 +174,19 @@ namespace zaaReloaded2.Models /// void DetectMaterial() { - Match m = _materialRegex.Match(Name); + // The material is encoded in the original name of the item + // that was produced by Lauris (eg. "Natrium (PU)" for spot + // urine). + Match m = _materialRegex.Match(OriginalName); if (m.Success) { switch (m.Groups["material"].Value.ToUpper()) { case "SU": - Material = Models.Material.SU; + Material = LabModel.Material.SU; break; case "PU": - Material = Models.Material.U; + Material = LabModel.Material.U; break; } } @@ -352,9 +196,6 @@ namespace zaaReloaded2.Models #region Fields - double _numericalValue; - double _lowerLimit; - double _upperLimit; static readonly Regex _materialRegex = new Regex(@"\((?(SU|PU))\)"); #endregion diff --git a/zaaReloaded2/Models/LaurisParagraph.cs b/zaaReloaded2/Importer/ZaaImporter/LaurisParagraph.cs similarity index 94% rename from zaaReloaded2/Models/LaurisParagraph.cs rename to zaaReloaded2/Importer/ZaaImporter/LaurisParagraph.cs index 01937b9..d03baac 100755 --- a/zaaReloaded2/Models/LaurisParagraph.cs +++ b/zaaReloaded2/Importer/ZaaImporter/LaurisParagraph.cs @@ -22,8 +22,9 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using zaaReloaded2.Dictionaries; +using zaaReloaded2.LabModel; -namespace zaaReloaded2.Models +namespace zaaReloaded2.Importer.ZaaImporter { /// /// Parses an entire Lauris paragraph (such as "Klinische Chemie: ...") @@ -106,8 +107,8 @@ namespace zaaReloaded2.Models foreach (Capture itemCapture in m.Groups["items"].Captures) { - LabItem i = new LabItem(itemCapture.Value, _parameterDictionary, _unitDictionary); - Items.Add(i.QualifiedCanonicalName, i); + LaurisItem i = new LaurisItem(itemCapture.Value, _parameterDictionary, _unitDictionary); + Items.Add(i.QualifiedName, i); } IsLaurisParagraph = Items.Count > 0; } diff --git a/zaaReloaded2/Models/TimePoint.cs b/zaaReloaded2/Importer/ZaaImporter/LaurisTimePoint.cs similarity index 86% rename from zaaReloaded2/Models/TimePoint.cs rename to zaaReloaded2/Importer/ZaaImporter/LaurisTimePoint.cs index f7f2705..64a2941 100755 --- a/zaaReloaded2/Models/TimePoint.cs +++ b/zaaReloaded2/Importer/ZaaImporter/LaurisTimePoint.cs @@ -1,4 +1,4 @@ -/* TimePoint.cs +/* LaurisTimePoint.cs * part of zaaReloaded2 * * Copyright 2015 Daniel Kraus @@ -23,16 +23,28 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using zaaReloaded2.Dictionaries; +using zaaReloaded2.LabModel; -namespace zaaReloaded2.Models +namespace zaaReloaded2.Importer.ZaaImporter { /// - /// Represents all Lauris items for a given time point. + /// Holds all laboratory items for a given time point. /// - public class TimePoint + class LaurisTimePoint : TimePoint { #region Properties + /// + /// Gets an array of paragraphs in this LaurisText. + /// + public string[] Paragraphs { get; private set; } + + /// + /// Is true if the LaurisText has time stamp in the first + /// paragraph and s in the others. + /// + public bool IsValidTimePoint { get; private set; } + /// /// Gets or sets the original Lauris text for this timepoint. /// @@ -55,38 +67,13 @@ namespace zaaReloaded2.Models } } - /// - /// Gets an array of paragraphs in this LaurisText. - /// - public string[] Paragraphs { get; private set; } - - /// - /// Is true if the LaurisText has time stamp in the first - /// paragraph and s in the others. - /// - public bool IsValidTimePoint { get; private set; } - - /// - /// Gets the date and time information for this TimePoint. - /// If IsValidTimePoint is false, the value of TimeStamp - /// is undefined. - /// - public DateTime TimeStamp { get; private set; } - - /// - /// Returns a sorted dictionary of all s found in - /// the . If a laboratory parameter occurs more - /// than once, only the last occurrence is saved. - /// - public IItemDictionary Items { get; private set; } - #endregion #region Constructors - public TimePoint() { } + public LaurisTimePoint() { } - public TimePoint(string laurisTest) + public LaurisTimePoint(string laurisTest) : this() { _parameterDictionary = null; @@ -94,7 +81,7 @@ namespace zaaReloaded2.Models LaurisText = laurisTest; } - public TimePoint( + public LaurisTimePoint( string laurisTest, ParameterDictionary parameterDictionary, UnitDictionary unitDictionary) diff --git a/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs b/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs new file mode 100755 index 0000000..8e9f9e4 --- /dev/null +++ b/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs @@ -0,0 +1,54 @@ +/* ZaaImporter.cs + * part of zaaReloaded2 + * + * Copyright 2015 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 zaaReloaded2.LabModel; + +namespace zaaReloaded2.Importer.ZaaImporter +{ + /// + /// Imports laboratory items by parsing the Lauris data from a + /// physician's letter. + /// + public class ZaaImporter : IImporter + { + #region IImporter implementation + + public Laboratory Laboratory + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + + public void Import(string text) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/zaaReloaded2/LabModel/LabItem.cs b/zaaReloaded2/LabModel/LabItem.cs new file mode 100755 index 0000000..4ec7aa8 --- /dev/null +++ b/zaaReloaded2/LabModel/LabItem.cs @@ -0,0 +1,204 @@ +/* LabItem.cs + * part of zaaReloaded2 + * + * Copyright 2015 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.Globalization; +using System.Text.RegularExpressions; + +namespace zaaReloaded2.LabModel +{ + /// + /// Represents a single laboratory item (e.g., sodium or creatinine). + /// + public class LabItem + { + #region Properties + + /// + /// Gets or sets the original name of the item (as known by Lauris). + /// + public string Name { get; protected set; } + + /// + /// Gets or sets the unit of the item (as known by Lauris). + /// + public string Unit { get; protected set; } + + /// + /// Gets or sets the value of the item. This may be a number or a string. + /// + public string Value { get; protected set; } + + public double NumericalValue + { + get + { + if (IsNumerical) + { + return _numericalValue; + } + else + { + throw new InvalidOperationException( + String.Format("Value '{0}' is not numerical.", Value)); + } + } + private set + { + _numericalValue = value; + } + } + + public bool IsNumerical + { + get + { + return (Double.TryParse(Value, + NumberStyles.Any, + CultureInfo.InvariantCulture, + out _numericalValue)); + } + } + + /// + /// Gets the normal value of the item. Need not be set. This is + /// used for items with nominal values (as opposed to numbers). + /// + public string Normal { get; protected set; } + + /// + /// Gets or sets the lower limit of normal. + /// + public double LowerLimit + { + get + { + return _lowerLimit; + } + protected set + { + _lowerLimit = value; + HasLowerLimit = true; + } + } + + /// + /// Is true if the item has a lower limit of normal. + /// + public bool HasLowerLimit { get; protected set; } + + /// + /// Gets or sets the upper limit of normal. + /// + public double UpperLimit + { + get + { + return _upperLimit; + } + set + { + _upperLimit = value; + HasUpperLimit = true; + } + } + + /// + /// Is true if the item has an upper limit of normal. + /// + public bool HasUpperLimit { get; protected set; } + + /// + /// Is true if is normal. + /// + public bool IsNormal + { + get + { + if (HasLimits) + { + if (HasLowerLimit && HasUpperLimit) + { + return (LowerLimit <= NumericalValue && + NumericalValue <= UpperLimit); + } + else + { + if (HasLowerLimit) + { + return (LowerLimit <= NumericalValue); + } + return (NumericalValue <= UpperLimit); + } + } + else + { + return (Value == Normal); + } + } + } + + /// + /// Is true if the item has lower and/or upper limits. Is false if the + /// item does not have limits but a value. + /// + public bool HasLimits + { + get { return (HasLowerLimit || HasUpperLimit); } + } + + /// + /// Returns the canonical name prefixed with the abbreviation + /// for the material, e.g. "U-Na" for sodium in the spot urine, + /// but only if the material is not blood. + /// + public string QualifiedName + { + get + { + if (Material == LabModel.Material.B) + { + return Name; + } + else + { + return String.Format("{0}-{1}", Material.ToString(), Name); + } + } + } + + public bool AlwaysPrintLimits { get; protected set; } + + public Material Material { get; protected set; } + + #endregion + + #region Constructor + + public LabItem() { } + + #endregion + + #region Fields + + double _numericalValue; + double _lowerLimit; + double _upperLimit; + + #endregion + } +} diff --git a/zaaReloaded2/LabModel/Laboratory.cs b/zaaReloaded2/LabModel/Laboratory.cs new file mode 100755 index 0000000..624a3d3 --- /dev/null +++ b/zaaReloaded2/LabModel/Laboratory.cs @@ -0,0 +1,36 @@ +/* Laboratory.cs + * part of zaaReloaded2 + * + * Copyright 2015 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.Linq; +using System.Text; + +namespace zaaReloaded2.LabModel +{ + /// + /// Holds laboratory items grouped by time points. + /// + public class Laboratory + { + #region Properties + + public SortedDictionary TimePoints { get; set; } + + #endregion + } +} diff --git a/zaaReloaded2/Models/Material.cs b/zaaReloaded2/LabModel/Material.cs similarity index 98% rename from zaaReloaded2/Models/Material.cs rename to zaaReloaded2/LabModel/Material.cs index e634519..c1bf1fe 100755 --- a/zaaReloaded2/Models/Material.cs +++ b/zaaReloaded2/LabModel/Material.cs @@ -21,7 +21,7 @@ using System.ComponentModel; using System.Linq; using System.Text; -namespace zaaReloaded2.Models +namespace zaaReloaded2.LabModel { /// /// Enumerates the known materials. diff --git a/zaaReloaded2/LabModel/TimePoint.cs b/zaaReloaded2/LabModel/TimePoint.cs new file mode 100755 index 0000000..7336bca --- /dev/null +++ b/zaaReloaded2/LabModel/TimePoint.cs @@ -0,0 +1,52 @@ +/* TimePoint.cs + * part of zaaReloaded2 + * + * Copyright 2015 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.Dictionaries; + +namespace zaaReloaded2.LabModel +{ + /// + /// Holds laboratory items for a given time point. + /// + public class TimePoint + { + #region Properties + + /// + /// Gets the date and time information for this TimePoint. + /// If IsValidTimePoint is false, the value of TimeStamp + /// is undefined. + /// + public DateTime TimeStamp { get; set; } + + /// + /// Returns a sorted dictionary of all s found in + /// the . If a laboratory parameter occurs more + /// than once, only the last occurrence is saved. + /// + public IItemDictionary Items { get; set; } + + #endregion + } +} diff --git a/zaaReloaded2/Properties/AssemblyInfo.cs b/zaaReloaded2/Properties/AssemblyInfo.cs index 9814dc6..1b66dcf 100755 --- a/zaaReloaded2/Properties/AssemblyInfo.cs +++ b/zaaReloaded2/Properties/AssemblyInfo.cs @@ -14,6 +14,7 @@ using System.Security; [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: InternalsVisibleTo("Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010061ecc0718277dee13e7dae2dad33787a981c9883ba80a659bebbdbec76563e201a7a3a6a5852e01bb5eb328d24d5889244b4626da9af9f93db663565441a3120e3985789e6f2a39289f4eed063725b84152cbef472d9dd2f7495f51dad6c91f4dc6fb7c72cb6bd9381335ac9878ec0a6369e880f35b8eca3063e16468d7704eb")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from diff --git a/zaaReloaded2/zaaReloaded2.csproj b/zaaReloaded2/zaaReloaded2.csproj index fdd98af..1c09455 100755 --- a/zaaReloaded2/zaaReloaded2.csproj +++ b/zaaReloaded2/zaaReloaded2.csproj @@ -166,10 +166,15 @@ - - - - + + + + + + + + + Code @@ -207,6 +212,9 @@ + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)