diff --git a/analyzers/GeneXpert/.vscode/settings.json b/analyzers/GeneXpert/.vscode/settings.json
new file mode 100644
index 0000000..890c247
--- /dev/null
+++ b/analyzers/GeneXpert/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "java.project.sourcePaths": [
+ "src/main/java"
+ ]
+}
\ No newline at end of file
diff --git a/analyzers/GeneXpert/pom.xml b/analyzers/GeneXpert/pom.xml
index 6ef1f51..f22725d 100644
--- a/analyzers/GeneXpert/pom.xml
+++ b/analyzers/GeneXpert/pom.xml
@@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.openelisglobal.plugins
- GeneXpert
+ GeneXpertAnalyzer
org.openelisglobal
openelisglobal-plugins
@@ -11,7 +11,7 @@
../../pom.xml
- 0.3
+ 0.4
UTF-8
2.3
@@ -25,14 +25,9 @@
provided
- ca.uhn.hapi
- hapi-hl7overhttp
- ${hapi.version}
-
-
- ca.uhn.hapi
- hapi-structures-v25
- ${hapi.version}
+ commons-fileupload
+ commons-fileupload
+ 1.4
org.springframework
diff --git a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzer.java b/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzer.java
index bc4e54d..4898cfb 100644
--- a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzer.java
+++ b/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzer.java
@@ -5,7 +5,7 @@
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * basis, WITHOUT WARRANTY OF ANY KIND, either eXNLress or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
@@ -20,39 +20,165 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
import org.openelisglobal.common.services.PluginAnalyzerService;
import org.openelisglobal.plugin.AnalyzerImporterPlugin;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
+import org.openelisglobal.common.log.LogEvent;
public class GeneXpertAnalyzer implements AnalyzerImporterPlugin {
+
+ public static final String ANALYZER_NAME = "GeneXpertAnalyzer";
- @Override
- public boolean connect() {
+ @Override
+ public boolean connect() {
List nameMapping = new ArrayList<>();
nameMapping.add(
- new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HBV, "HEPATITIS B VIRAL LOAD",
- GeneXpertAnalyzerImplementation.HBV_LOINC));
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_WBC, "White Blood Cells Count (WBC)",
+ GeneXpertAnalyzerImplementation.LOINC_WBC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_RBC, "Red Blood Cells Count (RBC)",
+ GeneXpertAnalyzerImplementation.LOINC_RBC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_HGB, "Hemoglobin",
+ GeneXpertAnalyzerImplementation.LOINC_HGB));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_HCT, "Hematocrit",
+ GeneXpertAnalyzerImplementation.LOINC_HCT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MCV, "Medium corpuscular volum",
+ GeneXpertAnalyzerImplementation.LOINC_MCV));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HCV, "HEPATITIS C VIRAL LOAD",
- GeneXpertAnalyzerImplementation.HCV_LOINC));
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MCH, "",
+ GeneXpertAnalyzerImplementation.LOINC_MCH));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MCHC, "",
+ GeneXpertAnalyzerImplementation.LOINC_MCHC));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_RDWSD, "",
+ GeneXpertAnalyzerImplementation.LOINC_RDWSD));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HIV_QUAL, "Xpert HIV-1 Qual",
- GeneXpertAnalyzerImplementation.HIV_QUAL_LOINC));
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_RDWCV, "",
+ GeneXpertAnalyzerImplementation.LOINC_RDWCV));
nameMapping
- .add(new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HIV_VIRAL, "HIV VIRAL LOAD",
- GeneXpertAnalyzerImplementation.HIV_VIRAL_LOINC));
+ .add(new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_PLT, "Platelets",
+ GeneXpertAnalyzerImplementation.LOINC_PLT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MPV, "",
+ GeneXpertAnalyzerImplementation.LOINC_MPV));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_NEUT_COUNT, "Neutrophiles",
+ GeneXpertAnalyzerImplementation.LOINC_NEUT_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_NEUT_PERCENT, "Neutrophiles (%)",
+ GeneXpertAnalyzerImplementation.LOINC_NEUT_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_LYMPH_COUNT, "Lymphocytes (Abs)",
+ GeneXpertAnalyzerImplementation.LOINC_LYMPH_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_LYMPH_PERCENT, "Lymphocytes (%)",
+ GeneXpertAnalyzerImplementation.LOINC_LYMPH_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MONO_COUNT, "Monocytes (Abs)",
+ GeneXpertAnalyzerImplementation.LOINC_MONO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MONO_PERCENT, "Monocytes (%)",
+ GeneXpertAnalyzerImplementation.LOINC_MONO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_EO_COUNT, "Eosinophiles",
+ GeneXpertAnalyzerImplementation.LOINC_EO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_EO_PERCENT, "Eosinophiles (%)",
+ GeneXpertAnalyzerImplementation.LOINC_EO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_BASO_COUNT, "Basophiles",
+ GeneXpertAnalyzerImplementation.LOINC_BASO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_BASO_PERCENT, "Basophiles (%)",
+ GeneXpertAnalyzerImplementation.LOINC_BASO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_IG_COUNT, "",
+ GeneXpertAnalyzerImplementation.LOINC_IG_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_IG_PERCENT, "",
+ GeneXpertAnalyzerImplementation.LOINC_IG_PERCENT));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.COV_2, "COVID-19 PCR",
- GeneXpertAnalyzerImplementation.COV_2_LOINC));
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_RET_COUNT, "",
+ GeneXpertAnalyzerImplementation.LOINC_RET_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_RET_PERCENT, "",
+ GeneXpertAnalyzerImplementation.LOINC_RET_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_IRF, "",
+ GeneXpertAnalyzerImplementation.LOINC_IRF));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_RETHE, "",
+ GeneXpertAnalyzerImplementation.LOINC_RETHE));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_WBCBF, "",
+ GeneXpertAnalyzerImplementation.LOINC_WBCBF));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_RBCBF, "",
+ GeneXpertAnalyzerImplementation.LOINC_RBCBF));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MN_COUNT, "",
+ GeneXpertAnalyzerImplementation.LOINC_MN_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_MN_PERCENT, "",
+ GeneXpertAnalyzerImplementation.LOINC_MN_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_PMN_COUNT, "",
+ GeneXpertAnalyzerImplementation.LOINC_PMN_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_PMN_PERCENT, "",
+ GeneXpertAnalyzerImplementation.LOINC_PMN_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.ANALYZER_TEST_TCBF_COUNT, "",
+ GeneXpertAnalyzerImplementation.LOINC_TCBF_COUNT));
getInstance().addAnalyzerDatabaseParts("GeneXpertAnalyzer", "GeneXpertAnalyzer", nameMapping, true);
getInstance().registerAnalyzer(this);
return true;
}
@Override
- // this plugin does not work for flat files, so we disable it in that workflow
public boolean isTargetAnalyzer(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(GeneXpertAnalyzerImplementation.HEADER_RECORD_IDENTIFIER)) {
+ String[] headerRecord = line.split(Pattern.quote(GeneXpertAnalyzerImplementation.FD));
+ if (headerRecord.length < 5) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not GeneXpert: header record not long enough");
+ return false;
+ }
+ String[] senderNameFields = headerRecord[4].split(Pattern.quote(GeneXpertAnalyzerImplementation.CD));
+ if (senderNameFields.length < 2) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not GeneXpert: sender name field not long enough");
+ return false;
+ }
+ String systemName = senderNameFields[1].trim();
+
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message analyzer name is " + systemName);
+ if (systemName.equalsIgnoreCase("GeneXpert")) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is GeneXpert ");
+ return true;
+ }
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not GeneXpert: sender name doesn't match");
+ return false;
+ }
+ }
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not GeneXpert: no header line");
+ return false;
+ }
+
+ @Override
+ public boolean isAnalyzerResult(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(GeneXpertAnalyzerImplementation.RESULT_RECORD_IDENTIFIER)) {
+ return true;
+ }
+ }
+ LogEvent.logDebug(this.getClass().getSimpleName(), "isAnalyzerResult", "no result recoord identifier located");
return false;
}
@@ -61,4 +187,9 @@ public AnalyzerLineInserter getAnalyzerLineInserter() {
return new GeneXpertAnalyzerImplementation();
}
+ @Override
+ public AnalyzerResponder getAnalyzerResponder() {
+ return new GeneXpertAnalyzerImplementation();
+ }
+
}
diff --git a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java b/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
index 504d316..dc1cc62 100644
--- a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
+++ b/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
@@ -14,56 +14,211 @@
* Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
*/
-package oe.plugin.analyzer;
+ package oe.plugin.analyzer;
import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+import java.util.Optional;
+import org.apache.commons.validator.GenericValidator;
import org.openelisglobal.analyzer.service.AnalyzerService;
import org.openelisglobal.analyzer.valueholder.Analyzer;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerReaderUtil;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
+import org.openelisglobal.analyzerimport.util.AnalyzerTestNameCache;
+import org.openelisglobal.analyzerimport.util.MappedTestName;
import org.openelisglobal.analyzerresults.valueholder.AnalyzerResults;
+import org.openelisglobal.common.services.PluginAnalyzerService;
import org.openelisglobal.spring.util.SpringContext;
import org.openelisglobal.test.service.TestService;
+import org.openelisglobal.sample.service.SampleService;
+import org.openelisglobal.samplehuman.service.SampleHumanService;
+import org.openelisglobal.analysis.service.AnalysisService;
import org.openelisglobal.test.valueholder.Test;
+import org.openelisglobal.analysis.valueholder.Analysis;
+import org.openelisglobal.person.valueholder.Person;
+import org.openelisglobal.patient.valueholder.Patient;
+import org.openelisglobal.sample.valueholder.Sample;
+import org.openelisglobal.common.util.DateUtil;
+import org.openelisglobal.common.log.LogEvent;
+
+public class GeneXpertAnalyzerImplementation extends AnalyzerLineInserter implements AnalyzerResponder {
+
+ static final String ANALYZER_TEST_WBC = "WBC";
+ static final String ANALYZER_TEST_RBC = "RBC";
+ static final String ANALYZER_TEST_HGB = "HGB";
+ static final String ANALYZER_TEST_HCT = "HCT";
+ static final String ANALYZER_TEST_MCV = "MCV";
+ static final String ANALYZER_TEST_MCH = "MCH";
+ static final String ANALYZER_TEST_MCHC = "MCHC";
+ static final String ANALYZER_TEST_RDWSD = "RDW-CD";
+ static final String ANALYZER_TEST_RDWCV = "RDW-CV";
+ static final String ANALYZER_TEST_PLT = "PLT";
+ static final String ANALYZER_TEST_MPV = "MPV";
+ static final String ANALYZER_TEST_IPF = "IPF";
+ static final String ANALYZER_TEST_IPF_COUNT = "IPF#";
+ static final String ANALYZER_TEST_NEUT_COUNT = "NEUT#";
+ static final String ANALYZER_TEST_NEUT_PERCENT = "NEUT%";
+ static final String ANALYZER_TEST_LYMPH_COUNT = "LYMPH#";
+ static final String ANALYZER_TEST_LYMPH_PERCENT = "LYMPH%";
+ static final String ANALYZER_TEST_MONO_COUNT = "MONO#";
+ static final String ANALYZER_TEST_MONO_PERCENT = "MONO%";
+ static final String ANALYZER_TEST_EO_COUNT = "EO#";
+ static final String ANALYZER_TEST_EO_PERCENT = "EO%";
+ static final String ANALYZER_TEST_BASO_COUNT = "BASO#";
+ static final String ANALYZER_TEST_BASO_PERCENT = "BASO%";
+ static final String ANALYZER_TEST_IG_COUNT = "IG#";
+ static final String ANALYZER_TEST_IG_PERCENT = "IG%";
+ static final String ANALYZER_TEST_PDW = "PDW"; // flagging only
+ static final String ANALYZER_TEST_PLCR = "P-LCR"; // flagging only
+ static final String ANALYZER_TEST_PCT = "PCT"; // flagging only
+ static final String ANALYZER_TEST_RET_PERCENT = "RET%";
+ static final String ANALYZER_TEST_RET_COUNT = "RET#";
+ static final String ANALYZER_TEST_IRF = "IRF";
+ static final String ANALYZER_TEST_LFR = "LFR"; // flagging only
+ static final String ANALYZER_TEST_MFR = "MFR"; // flagging only
+ static final String ANALYZER_TEST_HFR = "HFR"; // flagging only
+ static final String ANALYZER_TEST_LWBC = "LWBC"; // flagging only
+ static final String ANALYZER_TEST_RETHE = "RET-HE";
+ static final String ANALYZER_TEST_WBCBF = "WBC-BF";
+ static final String ANALYZER_TEST_RBCBF = "RBC-BF";
+ static final String ANALYZER_TEST_MN_COUNT = "MN#";
+ static final String ANALYZER_TEST_MN_PERCENT = "MN%";
+ static final String ANALYZER_TEST_PMN_COUNT = "PMN#";
+ static final String ANALYZER_TEST_PMN_PERCENT = "PMN%";
+ static final String ANALYZER_TEST_TCBF_COUNT = "TC-BF#";
+
+ static final String LOINC_WBC = "6690-2";
+ static final String LOINC_RBC = "789-8";
+ static final String LOINC_HGB = "718-7";
+ static final String LOINC_HCT = "4544-3";
+ static final String LOINC_MCV = "787-2";
+ static final String LOINC_MCH = "785-6";
+ static final String LOINC_MCHC = "786-4";
+ static final String LOINC_RDWSD = "21000-5";
+ static final String LOINC_RDWCV = "788-0";
+ static final String LOINC_PLT = "777-3";
+ static final String LOINC_MPV = "32623-1";
+ static final String LOINC_NEUT_COUNT = "751-8";
+ static final String LOINC_NEUT_PERCENT = "770-8";
+ static final String LOINC_LYMPH_COUNT = "731-0";
+ static final String LOINC_LYMPH_PERCENT = "736-9";
+ static final String LOINC_MONO_COUNT = "742-7";
+ static final String LOINC_MONO_PERCENT = "5905-5";
+ static final String LOINC_EO_COUNT = "711-2";
+ static final String LOINC_EO_PERCENT = "713-8";
+ static final String LOINC_BASO_COUNT = "704-7";
+ static final String LOINC_BASO_PERCENT = "706-2";
+ static final String LOINC_IG_COUNT = "53115-2";
+ static final String LOINC_IG_PERCENT = "71695-1";
+ // static final String LOINC_PDW = ""; // flagging only
+ // static final String LOINC_PLCR = ""; // flagging only
+ // static final String LOINC_PCT = ""; // flagging only
+ static final String LOINC_RET_PERCENT = "17849-1";
+ static final String LOINC_RET_COUNT = "60474-4";
+ static final String LOINC_IRF = "33516-6";
+ // static final String LOINC_LFR = ""; // flagging only
+ // static final String LOINC_MFR = ""; // flagging only
+ // static final String LOINC_HFR = ""; // flagging only
+ // static final String LOINC_LWBC = ""; // flagging only
+ static final String LOINC_RETHE = "71694-4";
+ static final String LOINC_WBCBF = "57845-0";
+ static final String LOINC_RBCBF = "23860-0";
+ static final String LOINC_MN_COUNT = "71689-4";
+ static final String LOINC_PMN_COUNT = "71698-5";
+ static final String LOINC_MN_PERCENT = "71697-7";
+ static final String LOINC_PMN_PERCENT = "71696-9";
+ static final String LOINC_TCBF_COUNT = "71690-2";
+
+ protected static final String HEADER_RECORD_IDENTIFIER = "H";
+ protected static final String QUERY_RECORD_IDENTIFIER = "Q";
+ protected static final String PATIENT_RECORD_IDENTIFIER = "P";
+ protected static final String ORDER_RECORD_IDENTIFIER = "O";
+ protected static final String RESULT_RECORD_IDENTIFIER = "R";
+ protected static final String END_RECORD_IDENTIFIER = "L";
+ protected static final String FD = "|"; //DEFAULT_FIELD_DELIMITER
+ protected static final String RD = "@"; //DEFAULT_REPEATER_DELIMITER
+ protected static final String CD = "^"; //DEFAULT_COMPONENT_DELIMITER
+ protected static final String ED = "\\"; //DEFAULT_ESCAPE_DELIMITER
+ protected static final String TEST_COMMUNICATION_IDENTIFIER = "M|1|106";
-public class GeneXpertAnalyzerImplementation extends AnalyzerLineInserter {
+ private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+
private TestService testService = SpringContext.getBean(TestService.class);
+ private SampleService sampleService = SpringContext.getBean(SampleService.class);
+ private SampleHumanService sampleHumanService = SpringContext.getBean(SampleHumanService.class);
private AnalyzerService analyzerService = SpringContext.getBean(AnalyzerService.class);
-
-
- static final String HBV = "Xpert HBV Viral Load";
- static final String HCV = "Xpert HCV Viral Load";
- static final String HIV_QUAL = "Xpert HIV-1 Qual";
- static final String HIV_VIRAL = "Xpert HIV-1 viral Load";
- static final String COV_2 = "Xpert Xpress SARS-CoV-2 assay";
-
- static final String HBV_LOINC = "29615-2";
- static final String HCV_LOINC = "11011-4";
- static final String HIV_QUAL_LOINC = "";
- static final String HIV_VIRAL_LOINC = "10351-5";
- static final String COV_2_LOINC = "94500-6";
-
+ private AnalysisService analysisService = SpringContext.getBean(AnalysisService.class);
+
private String ANALYZER_ID;
- private HashMap> testLoincMap = new HashMap<>();
-
+ private Map testToLoincMap = new HashMap<>();
+ private Map loincToTestCodeMap = new HashMap<>();
+ private Map> testCodeToTestsMap = new HashMap<>();
+
private AnalyzerReaderUtil readerUtil = new AnalyzerReaderUtil();
-
+
public GeneXpertAnalyzerImplementation() {
- testLoincMap.put(HBV_LOINC, testService.getTestsByLoincCode(HBV_LOINC));
- testLoincMap.put(HCV_LOINC, testService.getTestsByLoincCode(HCV_LOINC));
- testLoincMap.put(HIV_QUAL_LOINC, testService.getTestsByLoincCode(HIV_QUAL_LOINC));
- testLoincMap.put(HIV_VIRAL_LOINC, testService.getTestsByLoincCode(HIV_VIRAL_LOINC));
- testLoincMap.put(COV_2_LOINC, testService.getTestsByLoincCode(COV_2_LOINC));
+ testToLoincMap.put(ANALYZER_TEST_WBC, LOINC_WBC);
+ testToLoincMap.put(ANALYZER_TEST_RBC, LOINC_RBC);
+ testToLoincMap.put(ANALYZER_TEST_HGB, LOINC_HGB);
+ testToLoincMap.put(ANALYZER_TEST_HCT, LOINC_HCT);
+ testToLoincMap.put(ANALYZER_TEST_MCV, LOINC_MCV);
+ testToLoincMap.put(ANALYZER_TEST_MCH, LOINC_MCH);
+ testToLoincMap.put(ANALYZER_TEST_MCHC, LOINC_MCHC);
+ testToLoincMap.put(ANALYZER_TEST_RDWSD, LOINC_RDWSD);
+ testToLoincMap.put(ANALYZER_TEST_RDWCV, LOINC_RDWCV);
+ testToLoincMap.put(ANALYZER_TEST_PLT, LOINC_PLT);
+ testToLoincMap.put(ANALYZER_TEST_MPV, LOINC_MPV);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_COUNT, LOINC_NEUT_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_PERCENT, LOINC_NEUT_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_COUNT, LOINC_LYMPH_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_PERCENT, LOINC_LYMPH_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_COUNT, LOINC_MONO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_PERCENT, LOINC_MONO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_EO_COUNT, LOINC_EO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_EO_PERCENT, LOINC_EO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_COUNT, LOINC_BASO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_PERCENT, LOINC_BASO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_IG_COUNT, LOINC_IG_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_IG_PERCENT, LOINC_IG_PERCENT);
+ // testToLoincMap.put(ANALYZER_TEST_PDW, LOINC_PDW);
+ // testToLoincMap.put(ANALYZER_TEST_PLCR, LOINC_PLCR);
+ // testToLoincMap.put(ANALYZER_TEST_PCT, LOINC_PCT);
+ testToLoincMap.put(ANALYZER_TEST_RET_COUNT, LOINC_RET_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_RET_PERCENT, LOINC_RET_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_IRF, LOINC_IRF);
+ // testToLoincMap.put(ANALYZER_TEST_LFR, LOINC_LFR);
+ // testToLoincMap.put(ANALYZER_TEST_MFR, LOINC_MFR);
+ // testToLoincMap.put(ANALYZER_TEST_HFR, LOINC_HFR);
+ // testToLoincMap.put(ANALYZER_TEST_LWBC, LOINC_LWBC);
+ testToLoincMap.put(ANALYZER_TEST_RETHE, LOINC_RETHE);
+ testToLoincMap.put(ANALYZER_TEST_WBCBF, LOINC_WBCBF);
+ testToLoincMap.put(ANALYZER_TEST_RBCBF, LOINC_RBCBF);
+ testToLoincMap.put(ANALYZER_TEST_MN_COUNT, LOINC_MN_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_PMN_COUNT, LOINC_PMN_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MN_PERCENT, LOINC_MN_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_TCBF_COUNT, LOINC_TCBF_COUNT);
+ for (Entry entry : testToLoincMap.entrySet()) {
+ loincToTestCodeMap.put(entry.getValue(), entry.getKey());
+ testCodeToTestsMap.put(entry.getKey(), testService.getTestsByLoincCode(entry.getValue()));
+ }
+
Analyzer analyzer = analyzerService.getAnalyzerByName("GeneXpertAnalyzer");
ANALYZER_ID = analyzer.getId();
}
-
+
+ // example message:
/*
* (non-Javadoc)
*
@@ -73,40 +228,156 @@ public GeneXpertAnalyzerImplementation() {
*/
@Override
public boolean insert(List lines, String currentUserId) {
- return false;
+
+ String patientRecord = null;
+ String orderRecord = null;
+
+ List results = new ArrayList<>();
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "insert", "this is a test communication record for GeneXpert");
+ }
+ if (line.startsWith(PATIENT_RECORD_IDENTIFIER)) {
+ if (patientRecord != null) {
+ patientRecord = null;
+ orderRecord = null;
+ }
+ patientRecord = line;
+ }
+ if (line.startsWith(ORDER_RECORD_IDENTIFIER)) {
+ orderRecord = line;
+ }
+ if (line.startsWith(RESULT_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "insert", "adding result");
+
+ addRecordsToResults(patientRecord, orderRecord, line, results, currentUserId);
+ }
+ if (line.startsWith(END_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "insert", "end Aquios of record");
+ break;
+ }
+ }
+ return persistImport(currentUserId, results);
}
-
+
@Override
public String getError() {
- return "GeneXpert analyzer unable to write to database";
+ return "GeneXpertAnalyzer analyzer unable to write to database";
+ }
+
+ private Test findMatchingTest(Sample sample, String resultTestCode) {
+ if (sample != null) {
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ List possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // if ((possibleTests == null || possibleTests.size() == 0) && resultTestCode.contains("+")) {
+ // possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // }
+ if (possibleTests != null) {
+ for (Test curTest : possibleTests) {
+ if (curTest.getLoinc() != null && curTest.getLoinc().equals(curAnalysis.getTest().getLoinc())) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "findMatchingTest", "found test in sample for code: " + resultTestCode);
+ return curAnalysis.getTest();
+ }
+ }
+ }
+ }
+ }
+ return null;
}
- public void addResult(List resultList, List notMatchedResults, String resultType,
+ private void addRecordsToResults(String patientRecord, String orderRecord, String resultRecord,
+ List results, String currentUserId) {
+ String[] patientRecordFields = patientRecord.split(Pattern.quote(FD));
+ String[] orderRecordFields = orderRecord.split(Pattern.quote(FD));
+ String[] orderTestIdFields = orderRecordFields[4].split(Pattern.quote(RD));
+ String[] orderIdFields = orderRecordFields[3].split(Pattern.quote(CD));
+ String[] resultRecordFields = resultRecord.split(Pattern.quote(FD));
+ String[] resultTestIdField = resultRecordFields[2].split(Pattern.quote(CD));
+ String resultRecordAbnormalFlag = resultRecordFields[6];
+ List orderTestIds = new ArrayList<>();
+ for (String orderIdField : orderTestIdFields) {
+ String[] orderIds = orderIdField.split(Pattern.quote(CD));
+ String orderTestId = orderIds.length >= 5 ? orderIds[4] : "";
+ if (GenericValidator.isBlankOrNull(orderTestId)) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis parameter name is not present");
+ }
+ orderTestIds.add(orderTestId);
+ }
+ if (orderTestIds.size() <= 0) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis has no tests specified");
+ }
+ String resultTestId = resultTestIdField.length >= 4 ? resultTestIdField[3] : "";
+
+ String currentAccessionNumber = orderIdFields[2].trim();
+ Sample sample = sampleService.getSampleByAccessionNumber(currentAccessionNumber);
+ Test test = findMatchingTest(sample, resultTestId);
+
+ if (test == null) {
+ LogEvent.logError(this.getClass().getName(), "addRecordsToResults",
+ "can't import a result if order does not have that test ordered");
+ return;
+ }
+
+ switch (resultRecordAbnormalFlag) {
+ case "<": //below absolute low
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "below absolute low");
+ break;
+ case ">": //above absolute high
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "above absolute high");
+ break;
+ case "N": //normal
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "normal");
+ break;
+ case "A": //abnormal
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "abnormal");
+ break;
+ default:
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "abnormal flag not understood");
+ }
+ AnalyzerResults analyzerResults = addResult(results, null, "N", resultRecordFields[3],
+ DateUtil.convertStringDateToTimestampWithPattern(resultRecordFields[12], "yyyyMMddHHmmss"),
+ currentAccessionNumber, false, resultRecordFields[4], test);
+ LogEvent.logDebug(this.getClass().getName(), "addResultLine", "***" + analyzerResults.getAccessionNumber() + " "
+ + analyzerResults.getCompleteDate() + " " + analyzerResults.getResult());
+ }
+
+ public AnalyzerResults addResult(List resultList, List notMatchedResults, String resultType,
String resultValue, Date date, String accessionNumber, boolean isControl, String resultUnits,
- String analyzerTestId) {
+ Test test) {
+ LogEvent.logDebug(this.getClass().getName(), "addResult",
+ "adding result for lab Number: " + accessionNumber);
AnalyzerResults analyzerResults = createAnalyzerResult(resultType, resultValue, resultUnits, date,
- accessionNumber, isControl, analyzerTestId);
+ accessionNumber, isControl, test);
if (analyzerResults.getTestId() != null) {
addValueToResults(resultList, analyzerResults);
} else {
+ LogEvent.logWarn(this.getClass().getName(), "addResult",
+ "no matching result for " + accessionNumber);
notMatchedResults.add(analyzerResults);
}
+ return analyzerResults;
}
-
+
private void addValueToResults(List resultList, AnalyzerResults result) {
resultList.add(result);
-
+ LogEvent.logDebug(this.getClass().getName(), "addValueToResults",
+ "searching for matching analysis for " + result.getAccessionNumber());
AnalyzerResults resultFromDB = readerUtil.createAnalyzerResultFromDB(result);
if (resultFromDB != null) {
+ LogEvent.logWarn(this.getClass().getName(), "addValueToResults",
+ "no resultFromDB for " + result.getAccessionNumber());
resultList.add(resultFromDB);
}
-
+
}
-
+
private AnalyzerResults createAnalyzerResult(String resultType, String resultValue, String resultUnits, Date date,
- String accessionNumber, boolean isControl, String analyzerTestId) {
+ String accessionNumber, boolean isControl, Test test) {
+ LogEvent.logDebug(this.getClass().getName(), "createAnalyzerResult",
+ "creating analyzer result for " + accessionNumber);
+
AnalyzerResults analyzerResults = new AnalyzerResults();
-
+
analyzerResults.setAnalyzerId(ANALYZER_ID);
analyzerResults.setResult(resultValue);
analyzerResults.setUnits(resultUnits);
@@ -114,17 +385,99 @@ private AnalyzerResults createAnalyzerResult(String resultType, String resultVal
analyzerResults.setCompleteDate(new Timestamp(date.getTime()));
}
analyzerResults.setAccessionNumber(accessionNumber);
- analyzerResults.setTestId(
- testLoincMap.get(analyzerTestId).size() > 0 ? testLoincMap.get(analyzerTestId).get(0).getId() : "");
+ analyzerResults.setTestId(test.getId());
analyzerResults.setIsControl(isControl);
- analyzerResults.setTestName(testLoincMap.get(analyzerTestId).size() > 0
- ? testLoincMap.get(analyzerTestId).get(0).getLocalizedTestName().getLocalizedValue()
- : "");
+ analyzerResults.setTestName(test.getLocalizedTestName().getLocalizedValue());
return analyzerResults;
}
-
+
public void persistImport(List resultList) {
this.persistImport("1", resultList);
}
-}
+ public String buildResponse(List lines) {
+
+ String queryRecord = null;
+
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "buildResponse", "this is a test communication record for " + GeneXpertAnalyzer.ANALYZER_NAME);
+ }
+ if (line.startsWith(QUERY_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "buildResponse", "request contains query record");
+ String response = generateQueryResponse(line);
+ return response;
+ }
+ }
+ LogEvent.logWarn(this.getClass().getName(), "buildResponse", "no response could be created, no query identifier supplied");
+ return "";
+ }
+
+ private String generateQueryResponse(String queryRecord) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "generating query response");
+ String[] queryRecordFields = queryRecord.split(Pattern.quote(FD));
+
+ String[] startingRangeIdNumber = queryRecordFields[2].split(Pattern.quote(CD));
+ String sampleIdNo = startingRangeIdNumber[1].trim();
+ String sampleNoAttribute = startingRangeIdNumber[3];
+
+ StringBuilder msgBuilder = new StringBuilder();
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "searching for sample with lab Number: " + sampleIdNo);
+
+ Sample sample = sampleService.getSampleByAccessionNumber(sampleIdNo.trim());
+ if (sample == null) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "generateQueryResponse", "no sample found with lab Number: " + sampleIdNo);
+ //return could not find sample messager
+ return msgBuilder.append("H|")
+ .append(RD)
+ .append(CD)
+ .append(ED)
+ .append("|\r\n")
+ .append("P|1|\r\n")
+ .append("O|1||||||||||||||||||||||||Y\r\n") //"Y" is no order exists marker
+ .append("L|1|N\r\n").toString();
+ }
+ Patient patient = sampleHumanService.getPatientForSample(sample);
+ Person person = patient.getPerson();
+ msgBuilder.append("H|")
+ .append(RD)
+ .append(CD)
+ .append(ED)
+ .append("|||||||||||1394-97\r\n");
+ msgBuilder.append("P|1|||")
+ .append(patient.getNationalId()) //patient identifier
+ .append("|")
+ .append(CD)
+ .append(person.getFirstName())
+ .append(CD)
+ .append(person.getLastName()) //names
+ .append("||").append(patient.getBirthDate() == null ? "": dateFormat.format(patient.getBirthDate())) //birthdate
+ .append("|").append(patient.getGender()) //gender M F U
+ .append("|||||")
+ .append("")//DR id
+ .append("||||||||||||\r\n");
+
+
+ int i = 0;
+
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ Optional testCode = Optional.ofNullable(loincToTestCodeMap.get(curAnalysis.getTest().getLoinc()));
+ if (testCode.isPresent()) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "found supported test in sample with test code: " + testCode.get());
+ msgBuilder.append("O|").append(++i).append("|")
+ .append(sampleIdNo).append("||")
+ .append(CD + CD + CD)
+ .append(testCode.get());
+ msgBuilder.append("|R|")
+ .append(sample.getEnteredDate() == null ? "" : dateTimeFormat.format(sample.getEnteredDate()))
+ .append("|||||")
+ .append("A").append("||||ORH||||||||||Q\r\n");
+ }
+ }
+ msgBuilder.append("L|1|F\r\n");
+ return msgBuilder.toString();
+ }
+
+
+ }
+
\ No newline at end of file
diff --git a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerMenu.java b/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerMenu.java
new file mode 100644
index 0000000..b306dcd
--- /dev/null
+++ b/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerMenu.java
@@ -0,0 +1,57 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import java.util.Locale;
+
+import org.openelisglobal.common.services.PluginMenuService;
+import org.openelisglobal.common.services.PluginMenuService.KnownMenu;
+import org.openelisglobal.menu.valueholder.Menu;
+import org.openelisglobal.plugin.MenuPlugin;
+
+public class GeneXpertAnalyzerMenu extends MenuPlugin {
+
+ @Override
+ protected void insertMenu() {
+ PluginMenuService service = PluginMenuService.getInstance();
+ Menu menu = new Menu();
+
+ menu.setParent(PluginMenuService.getInstance().getKnownMenu(KnownMenu.ANALYZER, "menu_results"));
+ // The order this analyzer will show on the menu relative to other analyzers
+ menu.setPresentationOrder(10);
+ // The id needs to be unique in the system
+ menu.setElementId(GeneXpertAnalyzer.ANALYZER_NAME + "_plugin");
+ // This will always be "/AnalyzerResults?type=Analyzer->" + GeneXpertAnalyzer.ANALYZER_NAME);
+ Role role = service.getSystemRole( "Results" );
+ return service.bindRoleToModule( role, module );
+ }
+}
diff --git a/analyzers/GeneXpert/src/main/resources/GeneXpertAnalyzer.xml b/analyzers/GeneXpert/src/main/resources/GeneXpertAnalyzer.xml
new file mode 100644
index 0000000..689d3fb
--- /dev/null
+++ b/analyzers/GeneXpert/src/main/resources/GeneXpertAnalyzer.xml
@@ -0,0 +1,22 @@
+
+
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzer.java b/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzer.java
index 74d28f1..292b8b6 100644
--- a/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzer.java
+++ b/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzer.java
@@ -27,7 +27,8 @@
public class GeneXpertAnalyzer implements AnalyzerImporterPlugin {
-
+
+ public static final String ANALYZER_NAME = "GeneXpertAnalyzer";
@Override
public boolean connect(){
@@ -48,7 +49,7 @@ public boolean connect(){
nameMapping.add(
new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.COV_2, "COVID-19 PCR",
GeneXpertAnalyzerImplementation.COV_2_LOINC));
- getInstance().addAnalyzerDatabaseParts("GeneXpertAnalyzer", "Plugin for GeneXpertAnalyzer", nameMapping);
+ getInstance().addAnalyzerDatabaseParts(ANALYZER_NAME, "Plugin for " + ANALYZER_NAME, nameMapping);
getInstance().registerAnalyzer(this);
return true;
}
diff --git a/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java b/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
index 854ec6a..1055ded 100644
--- a/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
+++ b/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
@@ -106,7 +106,7 @@ public GeneXpertAnalyzerImplementation() {
resultMap.put(COV_2_ANALYZER_POS.toLowerCase(), COV_2_DB_POS.toLowerCase());
resultMap.put(COV_2_ANALYZER_INV.toLowerCase(), COV_2_DB_INV.toLowerCase());
- Analyzer analyzer = analyzerService.getAnalyzerByName("GeneXpertAnalyzer");
+ Analyzer analyzer = analyzerService.getAnalyzerByName(GeneXpertAnalyzer.ANALYZER_NAME);
ANALYZER_ID = analyzer.getId();
}
@@ -257,6 +257,6 @@ private AnalyzerResults createAnalyzerResult(String resultType, String resultVal
@Override
public String getError() {
- return "GeneXpertAnalyzer unable to write to database";
+ return GeneXpertAnalyzer.ANALYZER_NAME + " unable to write to database";
}
}
diff --git a/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerPermission.java b/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerPermission.java
index f0c298a..1e6a2e4 100644
--- a/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerPermission.java
+++ b/analyzers/GeneXpertFile/src/oe/plugin/analyzer/GeneXpertAnalyzerPermission.java
@@ -27,8 +27,8 @@ public class GeneXpertAnalyzerPermission extends PermissionPlugin {
@Override
protected boolean insertPermission(){
PluginPermissionService service = new PluginPermissionService();
- SystemModule module = service.getOrCreateSystemModule("AnalyzerResults", "GeneXpertAnalyzer",
- "Results->Analyzer->GeneXpertAnalyzer");
+ SystemModule module = service.getOrCreateSystemModule("AnalyzerResults", GeneXpertAnalyzer.ANALYZER_NAME,
+ "Results->Analyzer->" + GeneXpertAnalyzer.ANALYZER_NAME);
Role role = service.getSystemRole( "Results" );
return service.bindRoleToModule( role, module );
}
diff --git a/analyzers/GeneXpert/ORU_R30.txt b/analyzers/GeneXpertHL7/ORU_R30.txt
similarity index 100%
rename from analyzers/GeneXpert/ORU_R30.txt
rename to analyzers/GeneXpertHL7/ORU_R30.txt
diff --git a/analyzers/GeneXpert/QBP_Z03.txt b/analyzers/GeneXpertHL7/QBP_Z03.txt
similarity index 100%
rename from analyzers/GeneXpert/QBP_Z03.txt
rename to analyzers/GeneXpertHL7/QBP_Z03.txt
diff --git a/analyzers/GeneXpert/QCN_J01.txt b/analyzers/GeneXpertHL7/QCN_J01.txt
similarity index 100%
rename from analyzers/GeneXpert/QCN_J01.txt
rename to analyzers/GeneXpertHL7/QCN_J01.txt
diff --git a/analyzers/GeneXpertHL7/pom.xml b/analyzers/GeneXpertHL7/pom.xml
new file mode 100644
index 0000000..2ff7ac3
--- /dev/null
+++ b/analyzers/GeneXpertHL7/pom.xml
@@ -0,0 +1,94 @@
+
+ 4.0.0
+ org.openelisglobal.plugins
+ GeneXpertHL7
+
+ org.openelisglobal
+ openelisglobal-plugins
+ 1.0
+ ../../pom.xml
+
+
+ 0.3
+
+ UTF-8
+ 2.3
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 4.0.1
+ provided
+
+
+ ca.uhn.hapi
+ hapi-hl7overhttp
+ ${hapi.version}
+
+
+ ca.uhn.hapi
+ hapi-structures-v25
+ ${hapi.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${springframework.version}
+
+
+
+
+ src/main/java
+
+
+ src/main/filtered-resources
+ true
+
+
+ src/main/resources
+
+
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+
+ 1.8
+
+
+
+ maven-resources-plugin
+ 2.4.3
+
+
+ copy-resources
+
+ install
+
+ copy-resources
+
+
+ ${project.basedir}/../../plugins
+
+
+
+ target/
+
+ ${project.build.finalName}.jar
+
+
+ false
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/factory/PluginModelClassFactory.java b/analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/factory/PluginModelClassFactory.java
similarity index 100%
rename from analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/factory/PluginModelClassFactory.java
rename to analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/factory/PluginModelClassFactory.java
diff --git a/analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_ORDER.java b/analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_ORDER.java
similarity index 100%
rename from analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_ORDER.java
rename to analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_ORDER.java
diff --git a/analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_PATIENT.java b/analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_PATIENT.java
similarity index 100%
rename from analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_PATIENT.java
rename to analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/group/RSP_Z02_PATIENT.java
diff --git a/analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/QBP_Z03.java b/analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/QBP_Z03.java
similarity index 100%
rename from analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/QBP_Z03.java
rename to analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/QBP_Z03.java
diff --git a/analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/RSP_Z02.java b/analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/RSP_Z02.java
similarity index 100%
rename from analyzers/GeneXpert/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/RSP_Z02.java
rename to analyzers/GeneXpertHL7/src/main/java/ca/uhn/hl7v2/custom/model/v25/message/RSP_Z02.java
diff --git a/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzer.java b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzer.java
new file mode 100644
index 0000000..7eaf3e9
--- /dev/null
+++ b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzer.java
@@ -0,0 +1,64 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import static org.openelisglobal.common.services.PluginAnalyzerService.getInstance;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
+import org.openelisglobal.common.services.PluginAnalyzerService;
+import org.openelisglobal.plugin.AnalyzerImporterPlugin;
+
+public class GeneXpertAnalyzer implements AnalyzerImporterPlugin {
+
+ @Override
+ public boolean connect() {
+ List nameMapping = new ArrayList<>();
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HBV, "HEPATITIS B VIRAL LOAD",
+ GeneXpertAnalyzerImplementation.HBV_LOINC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HCV, "HEPATITIS C VIRAL LOAD",
+ GeneXpertAnalyzerImplementation.HCV_LOINC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HIV_QUAL, "Xpert HIV-1 Qual",
+ GeneXpertAnalyzerImplementation.HIV_QUAL_LOINC));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.HIV_VIRAL, "HIV VIRAL LOAD",
+ GeneXpertAnalyzerImplementation.HIV_VIRAL_LOINC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(GeneXpertAnalyzerImplementation.COV_2, "COVID-19 PCR",
+ GeneXpertAnalyzerImplementation.COV_2_LOINC));
+ getInstance().addAnalyzerDatabaseParts(GeneXpertAnalyzer.ANALYZER_NAME, GeneXpertAnalyzer.ANALYZER_NAME, nameMapping, true);
+ getInstance().registerAnalyzer(this);
+ return true;
+ }
+
+ @Override
+ // this plugin does not work for flat files, so we disable it in that workflow
+ public boolean isTargetAnalyzer(List lines) {
+ return false;
+ }
+
+ @Override
+ public AnalyzerLineInserter getAnalyzerLineInserter() {
+ return new GeneXpertAnalyzerImplementation();
+ }
+
+}
diff --git a/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
new file mode 100644
index 0000000..df6b351
--- /dev/null
+++ b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertAnalyzerImplementation.java
@@ -0,0 +1,130 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import org.openelisglobal.analyzer.service.AnalyzerService;
+import org.openelisglobal.analyzer.valueholder.Analyzer;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerReaderUtil;
+import org.openelisglobal.analyzerresults.valueholder.AnalyzerResults;
+import org.openelisglobal.spring.util.SpringContext;
+import org.openelisglobal.test.service.TestService;
+import org.openelisglobal.test.valueholder.Test;
+
+public class GeneXpertAnalyzerImplementation extends AnalyzerLineInserter {
+
+ private TestService testService = SpringContext.getBean(TestService.class);
+ private AnalyzerService analyzerService = SpringContext.getBean(AnalyzerService.class);
+
+
+ static final String HBV = "Xpert HBV Viral Load";
+ static final String HCV = "Xpert HCV Viral Load";
+ static final String HIV_QUAL = "Xpert HIV-1 Qual";
+ static final String HIV_VIRAL = "Xpert HIV-1 viral Load";
+ static final String COV_2 = "Xpert Xpress SARS-CoV-2 assay";
+
+ static final String HBV_LOINC = "29615-2";
+ static final String HCV_LOINC = "11011-4";
+ static final String HIV_QUAL_LOINC = "";
+ static final String HIV_VIRAL_LOINC = "10351-5";
+ static final String COV_2_LOINC = "94500-6";
+
+ private String ANALYZER_ID;
+ private HashMap> testLoincMap = new HashMap<>();
+
+ private AnalyzerReaderUtil readerUtil = new AnalyzerReaderUtil();
+
+ public GeneXpertAnalyzerImplementation() {
+ testLoincMap.put(HBV_LOINC, testService.getTestsByLoincCode(HBV_LOINC));
+ testLoincMap.put(HCV_LOINC, testService.getTestsByLoincCode(HCV_LOINC));
+ testLoincMap.put(HIV_QUAL_LOINC, testService.getTestsByLoincCode(HIV_QUAL_LOINC));
+ testLoincMap.put(HIV_VIRAL_LOINC, testService.getTestsByLoincCode(HIV_VIRAL_LOINC));
+ testLoincMap.put(COV_2_LOINC, testService.getTestsByLoincCode(COV_2_LOINC));
+
+ Analyzer analyzer = analyzerService.getAnalyzerByName(GeneXpertAnalyzer.ANALYZER_NAME);
+ ANALYZER_ID = analyzer.getId();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter#insert
+ * (java.util.List, java.lang.String)
+ */
+ @Override
+ public boolean insert(List lines, String currentUserId) {
+ return false;
+ }
+
+ @Override
+ public String getError() {
+ return "GeneXpert analyzer unable to write to database";
+ }
+
+ public void addResult(List resultList, List notMatchedResults, String resultType,
+ String resultValue, Date date, String accessionNumber, boolean isControl, String resultUnits,
+ String analyzerTestId) {
+ AnalyzerResults analyzerResults = createAnalyzerResult(resultType, resultValue, resultUnits, date,
+ accessionNumber, isControl, analyzerTestId);
+ if (analyzerResults.getTestId() != null) {
+ addValueToResults(resultList, analyzerResults);
+ } else {
+ notMatchedResults.add(analyzerResults);
+ }
+ }
+
+ private void addValueToResults(List resultList, AnalyzerResults result) {
+ resultList.add(result);
+
+ AnalyzerResults resultFromDB = readerUtil.createAnalyzerResultFromDB(result);
+ if (resultFromDB != null) {
+ resultList.add(resultFromDB);
+ }
+
+ }
+
+ private AnalyzerResults createAnalyzerResult(String resultType, String resultValue, String resultUnits, Date date,
+ String accessionNumber, boolean isControl, String analyzerTestId) {
+ AnalyzerResults analyzerResults = new AnalyzerResults();
+
+ analyzerResults.setAnalyzerId(ANALYZER_ID);
+ analyzerResults.setResult(resultValue);
+ analyzerResults.setUnits(resultUnits);
+ if (date != null) {
+ analyzerResults.setCompleteDate(new Timestamp(date.getTime()));
+ }
+ analyzerResults.setAccessionNumber(accessionNumber);
+ analyzerResults.setTestId(
+ testLoincMap.get(analyzerTestId).size() > 0 ? testLoincMap.get(analyzerTestId).get(0).getId() : "");
+ analyzerResults.setIsControl(isControl);
+ analyzerResults.setTestName(testLoincMap.get(analyzerTestId).size() > 0
+ ? testLoincMap.get(analyzerTestId).get(0).getLocalizedTestName().getLocalizedValue()
+ : "");
+ return analyzerResults;
+ }
+
+ public void persistImport(List resultList) {
+ this.persistImport("1", resultList);
+ }
+
+}
diff --git a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertMenu.java b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertMenu.java
similarity index 80%
rename from analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertMenu.java
rename to analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertMenu.java
index 10c6745..ab947d9 100644
--- a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertMenu.java
+++ b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertMenu.java
@@ -34,22 +34,22 @@ protected void insertMenu() {
// The order this analyzer will show on the menu relative to other analyzers
menu.setPresentationOrder(10);
// The id needs to be unique in the system
- menu.setElementId("genexpert_analyzer_plugin");
+ menu.setElementId(GeneXpertAnalyzer.ANALYZER_NAME + "_plugin");
// This will always be "/AnalyzerResults?type=Analyzer->GeneXpertAnalyzer");
+ SystemModule module = service.getOrCreateSystemModule("AnalyzerResults", GeneXpertAnalyzer.ANALYZER_NAME,
+ "Results->Analyzer->" + GeneXpertAnalyzer.ANALYZER_NAME);
Role role = service.getSystemRole( "Results" );
return service.bindRoleToModule( role, module );
}
diff --git a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertServlet.java b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertServlet.java
similarity index 88%
rename from analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertServlet.java
rename to analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertServlet.java
index 628a3b9..ea2ce38 100644
--- a/analyzers/GeneXpert/src/main/java/oe/plugin/analyzer/GeneXpertServlet.java
+++ b/analyzers/GeneXpertHL7/src/main/java/oe/plugin/analyzer/GeneXpertServlet.java
@@ -15,7 +15,9 @@
import org.openelisglobal.analysis.service.AnalysisService;
import org.openelisglobal.analysis.valueholder.Analysis;
import org.openelisglobal.analyzerresults.valueholder.AnalyzerResults;
+import org.openelisglobal.common.log.LogEvent;
import org.openelisglobal.patient.valueholder.Patient;
+import org.openelisglobal.patient.service.PatientService;
import org.openelisglobal.plugin.ServletPlugin;
import org.openelisglobal.sample.service.SampleService;
import org.openelisglobal.sample.valueholder.Sample;
@@ -60,6 +62,7 @@ public class GeneXpertServlet extends HohServlet implements ServletPlugin {
private static final String[] LOINC_CODES = { "29615-2", "11011-4", "10351-5", "94500-6" };
SampleService sampleService = SpringContext.getBean(SampleService.class);
AnalysisService analysisService = SpringContext.getBean(AnalysisService.class);
+ PatientService patientService = SpringContext.getBean(PatientService.class);
private GeneXpertAnalyzerImplementation inserter ;
@Override
@@ -86,6 +89,7 @@ private class GeneXpertApplication implements ReceivingApplication {
@Override
public Message processMessage(Message message, @SuppressWarnings("rawtypes") Map theMetadata)
throws ReceivingApplicationException, HL7Exception {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "processMessage", "received an HL7 message for GeneXpert analyzer");
MSH messageHeader = (MSH) message.get("MSH");
Message response = null;
@@ -119,9 +123,8 @@ public Message processMessage(Message message, @SuppressWarnings("rawtypes") Map
private RSP_Z02 instrumentSystemSendsHostQueryStart(QBP_Z03 message,
@SuppressWarnings("rawtypes") Map theMetadata) throws HL7Exception, IOException {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemSendsHostQueryStart", "received an HL7 message for GeneXpert analyzer: Host query");
activeRequests.put(message.getMSH().getMessageControlID().getValue(), message);
-
- // TODO use these to get the right objects
Optional patientId = message.getQPD().getField(3).length > 0
? Optional.of(((Varies) message.getQPD().getField(3, 0)).getData())
: Optional.empty();
@@ -131,13 +134,19 @@ private RSP_Z02 instrumentSystemSendsHostQueryStart(QBP_Z03 message,
: Optional.empty();
List patients = new ArrayList<>();
- patients.add(new Patient());
+ if (patientId.isPresent()) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemSendsHostQueryStart", "looking for patient with id: "+ patientId.get());
+ }
+
+ patientId.ifPresent(p -> patients.add(patientService.get(patientId.toString())));
RSP_Z02 response = instrumentSystemSendsHostQueryStartSuccess(message);
response.getQAK().getQueryTag().setValue(message.getQPD().getQueryTag().getValue());
Sample sample = sampleService.getSampleByAccessionNumber(specimenId.toString());
if (sample != null) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemSendsHostQueryStart", "found sample for: " + specimenId.toString());
+
int pidSeq = 0;
int orcSeq = 0;
int obrSeq = 0;
@@ -225,11 +234,16 @@ private ACK instrumentSystemCancelsHostQuerySuccessACK(QCN_J01 message) throws H
private Message instrumentSystemUploadsTestResults(ORU_R01 message,
@SuppressWarnings("rawtypes") Map theMetadata) throws HL7Exception, IOException {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemUploadsTestResults", "received HL7 result(s) for GeneXpert analyzer: parsing ORU_R01");
+
List resultList = new ArrayList<>();
List notMatchedResults = new ArrayList<>();
for (ORU_R01_PATIENT_RESULT patientResult : message.getPATIENT_RESULTAll()) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemUploadsTestResults", "parsing patient result");
PID pid = patientResult.getPATIENT().getPID();
for (ORU_R01_ORDER_OBSERVATION orderObservation : patientResult.getORDER_OBSERVATIONAll()) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemUploadsTestResults", "parsing order observation");
+
ORC orc = orderObservation.getORC();
OBR obr = orderObservation.getOBR();
Optional orderNTE = orderObservation.getNTEReps() <= 0 ? Optional.empty()
@@ -242,6 +256,8 @@ private Message instrumentSystemUploadsTestResults(ORU_R01 message,
String accessionNumber = spm.getSpecimenID().getPlacerAssignedIdentifier().getEntityIdentifier()
.getValue();
for (ORU_R01_OBSERVATION observation : orderObservation.getOBSERVATIONAll()) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemUploadsTestResults", "parsing observation");
+
OBX obx = observation.getOBX();
Optional resultNTE = observation.getNTEReps() <= 0 ? Optional.empty()
: Optional.of(observation.getNTE());
@@ -260,13 +276,15 @@ private Message instrumentSystemUploadsTestResults(ORU_R01 message,
}
}
}
- inserter.persistImport(resultList);
- // TODO insert the results as analyzer results
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemUploadsTestResults", "parsing order observation");
+ inserter.persistImport(resultList);
return instrumentSystemUploadsTestResultsSuccessACK(message);
}
private ACK instrumentSystemUploadsTestResultsSuccessACK(ORU_R01 message) throws HL7Exception, IOException {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "instrumentSystemUploadsTestResultsSuccessACK", "Sending ACK");
+
ACK response = (ACK) message.generateACK(AcknowledgmentCode.CA, null);
MSH responseMSH = response.getMSH();
responseMSH.getAcceptAcknowledgmentType().setValue("NE");
diff --git a/analyzers/GeneXpert/src/main/resources/GeneXpert.xml b/analyzers/GeneXpertHL7/src/main/resources/GeneXpert.xml
similarity index 100%
rename from analyzers/GeneXpert/src/main/resources/GeneXpert.xml
rename to analyzers/GeneXpertHL7/src/main/resources/GeneXpert.xml
diff --git a/analyzers/SysmexXN-L/pom.xml b/analyzers/SysmexXN-L/pom.xml
index 54b8366..fb3d288 100644
--- a/analyzers/SysmexXN-L/pom.xml
+++ b/analyzers/SysmexXN-L/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 0.3
+ 0.5
UTF-8
2.3
diff --git a/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzer.java b/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzer.java
index ef26799..a596603 100644
--- a/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzer.java
+++ b/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzer.java
@@ -20,26 +20,29 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
import org.openelisglobal.common.services.PluginAnalyzerService;
import org.openelisglobal.plugin.AnalyzerImporterPlugin;
-
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
import org.openelisglobal.common.log.LogEvent;
public class SysmexXNLAnalyzer implements AnalyzerImporterPlugin {
+
+ public static final String ANALYZER_NAME = "SysmexXNLAnalyzer";
@Override
public boolean connect() {
List nameMapping = new ArrayList<>();
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_WBC, "White Blood Cells Count",
+ new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_WBC, "White Blood Cells Count (WBC)",
SysmexXNLAnalyzerImplementation.LOINC_WBC));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_RBC, "Red Blood Cells Count",
+ new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_RBC, "Red Blood Cells Count (RBC)",
SysmexXNLAnalyzerImplementation.LOINC_RBC));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_HGB, "Hemoglobin",
+ new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_HGB, "Hemoglobin",
SysmexXNLAnalyzerImplementation.LOINC_HGB));
nameMapping.add(
new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_HCT, "Hematocrit",
@@ -66,7 +69,7 @@ public boolean connect() {
new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_MPV, "",
SysmexXNLAnalyzerImplementation.LOINC_MPV));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_NEUT_COUNT, "Neutrophiles",
+ new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_NEUT_COUNT, "Neutrophiles",
SysmexXNLAnalyzerImplementation.LOINC_NEUT_COUNT));
nameMapping.add(
new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_NEUT_PERCENT, "Neutrophiles (%)",
@@ -134,7 +137,7 @@ public boolean connect() {
nameMapping.add(
new PluginAnalyzerService.TestMapping(SysmexXNLAnalyzerImplementation.ANALYZER_TEST_TCBF_COUNT, "",
SysmexXNLAnalyzerImplementation.LOINC_TCBF_COUNT));
- getInstance().addAnalyzerDatabaseParts("SysmexXNLAnalyzer", "SysmexXNLAnalyzer", nameMapping, true);
+ getInstance().addAnalyzerDatabaseParts(ANALYZER_NAME, ANALYZER_NAME, nameMapping, true);
getInstance().registerAnalyzer(this);
return true;
}
@@ -143,39 +146,41 @@ public boolean connect() {
public boolean isTargetAnalyzer(List lines) {
for (String line : lines) {
if (line.startsWith(SysmexXNLAnalyzerImplementation.HEADER_RECORD_IDENTIFIER)) {
- String[] headerRecord = line.split(SysmexXNLAnalyzerImplementation.DEFAULT_FIELD_DELIMITER);
+ String[] headerRecord = line.split(Pattern.quote(SysmexXNLAnalyzerImplementation.FD));
if (headerRecord.length < 5) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not SysmexXN: header record not long enough");
return false;
}
- String[] senderName = headerRecord[4].split(SysmexXNLAnalyzerImplementation.DEFAULT_SUBFIELD_DELIMITER);
- if (senderName.length < 1) {
+ String[] senderNameFields = headerRecord[4].split(Pattern.quote(SysmexXNLAnalyzerImplementation.CD));
+ if (senderNameFields.length < 1) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not SysmexXN: sender name field not long enough");
return false;
}
- LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message analyzer name is " + senderName[0]);
- if (senderName[0].equalsIgnoreCase("XN-550")) {
+ String senderName = senderNameFields[0].trim();
+
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message analyzer name is " + senderName);
+ if (senderName.equalsIgnoreCase("XN-550")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XN-530")) {
+ } else if (senderName.equalsIgnoreCase("XN-530")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XN-450")) {
+ } else if (senderName.equalsIgnoreCase("XN-450")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XN-430")) {
+ } else if (senderName.equalsIgnoreCase("XN-430")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XN-350")) {
+ } else if (senderName.equalsIgnoreCase("XN-350")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XN-330")) {
+ } else if (senderName.equalsIgnoreCase("XN-330")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XN-150")) {
+ } else if (senderName.equalsIgnoreCase("XN-150")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XN-110")) {
+ } else if (senderName.equalsIgnoreCase("XN-110")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXN (XN-350)");
return true;
}
@@ -187,9 +192,25 @@ public boolean isTargetAnalyzer(List lines) {
return false;
}
+ @Override
+ public boolean isAnalyzerResult(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(SysmexXNLAnalyzerImplementation.RESULT_RECORD_IDENTIFIER)) {
+ return true;
+ }
+ }
+ LogEvent.logDebug(this.getClass().getSimpleName(), "isAnalyzerResult", "no result recoord identifier located");
+ return false;
+ }
+
@Override
public AnalyzerLineInserter getAnalyzerLineInserter() {
return new SysmexXNLAnalyzerImplementation();
}
+ @Override
+ public AnalyzerResponder getAnalyzerResponder() {
+ return new SysmexXNLAnalyzerImplementation();
+ }
+
}
diff --git a/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerImplementation.java b/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerImplementation.java
index 3639233..bdf3bdb 100644
--- a/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerImplementation.java
+++ b/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerImplementation.java
@@ -17,16 +17,22 @@
package oe.plugin.analyzer;
import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+import java.util.Optional;
import org.apache.commons.validator.GenericValidator;
import org.openelisglobal.analyzer.service.AnalyzerService;
import org.openelisglobal.analyzer.valueholder.Analyzer;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerReaderUtil;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
import org.openelisglobal.analyzerimport.util.AnalyzerTestNameCache;
import org.openelisglobal.analyzerimport.util.MappedTestName;
import org.openelisglobal.analyzerresults.valueholder.AnalyzerResults;
@@ -34,14 +40,17 @@
import org.openelisglobal.spring.util.SpringContext;
import org.openelisglobal.test.service.TestService;
import org.openelisglobal.sample.service.SampleService;
+import org.openelisglobal.samplehuman.service.SampleHumanService;
import org.openelisglobal.analysis.service.AnalysisService;
import org.openelisglobal.test.valueholder.Test;
import org.openelisglobal.analysis.valueholder.Analysis;
+import org.openelisglobal.person.valueholder.Person;
+import org.openelisglobal.patient.valueholder.Patient;
import org.openelisglobal.sample.valueholder.Sample;
import org.openelisglobal.common.util.DateUtil;
import org.openelisglobal.common.log.LogEvent;
-public class SysmexXNLAnalyzerImplementation extends AnalyzerLineInserter {
+public class SysmexXNLAnalyzerImplementation extends AnalyzerLineInserter implements AnalyzerResponder {
static final String ANALYZER_TEST_WBC = "WBC";
static final String ANALYZER_TEST_RBC = "RBC";
@@ -130,69 +139,82 @@ public class SysmexXNLAnalyzerImplementation extends AnalyzerLineInserter {
static final String LOINC_TCBF_COUNT = "71690-2";
protected static final String HEADER_RECORD_IDENTIFIER = "H";
+ protected static final String QUERY_RECORD_IDENTIFIER = "Q";
protected static final String PATIENT_RECORD_IDENTIFIER = "P";
protected static final String ORDER_RECORD_IDENTIFIER = "O";
protected static final String RESULT_RECORD_IDENTIFIER = "R";
protected static final String END_RECORD_IDENTIFIER = "L";
- protected static final String DEFAULT_FIELD_DELIMITER = "\\|";
- protected static final String DEFAULT_SUBFIELD_DELIMITER = "\\^";
- protected static final String DEFAULT_REPEATER_DELIMITER = "\\\\";
+ protected static final String FD = "|"; //DEFAULT_FIELD_DELIMITER
+ protected static final String CD = "^"; //DEFAULT_COMPONENT_DELIMITER
+ protected static final String RD = "\\"; //DEFAULT_REPEATER_DELIMITER
+ protected static final String ED = "&"; //DEFAULT_ESCAPE_DELIMITER
protected static final String TEST_COMMUNICATION_IDENTIFIER = "M|1|106";
+
+ private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+
private TestService testService = SpringContext.getBean(TestService.class);
private SampleService sampleService = SpringContext.getBean(SampleService.class);
+ private SampleHumanService sampleHumanService = SpringContext.getBean(SampleHumanService.class);
private AnalyzerService analyzerService = SpringContext.getBean(AnalyzerService.class);
private AnalysisService analysisService = SpringContext.getBean(AnalysisService.class);
private String ANALYZER_ID;
- private HashMap> testLoincMap = new HashMap<>();
+ private Map testToLoincMap = new HashMap<>();
+ private Map loincToTestCodeMap = new HashMap<>();
+ private Map> testCodeToTestsMap = new HashMap<>();
private AnalyzerReaderUtil readerUtil = new AnalyzerReaderUtil();
public SysmexXNLAnalyzerImplementation() {
- testLoincMap.put(ANALYZER_TEST_WBC, testService.getTestsByLoincCode(LOINC_WBC));
- testLoincMap.put(ANALYZER_TEST_RBC, testService.getTestsByLoincCode(LOINC_RBC));
- testLoincMap.put(ANALYZER_TEST_HGB, testService.getTestsByLoincCode(LOINC_HGB));
- testLoincMap.put(ANALYZER_TEST_HCT, testService.getTestsByLoincCode(LOINC_HCT));
- testLoincMap.put(ANALYZER_TEST_MCV, testService.getTestsByLoincCode(LOINC_MCV));
- testLoincMap.put(ANALYZER_TEST_MCH, testService.getTestsByLoincCode(LOINC_MCH));
- testLoincMap.put(ANALYZER_TEST_MCHC, testService.getTestsByLoincCode(LOINC_MCHC));
- testLoincMap.put(ANALYZER_TEST_RDWSD, testService.getTestsByLoincCode(LOINC_RDWSD));
- testLoincMap.put(ANALYZER_TEST_RDWCV, testService.getTestsByLoincCode(LOINC_RDWCV));
- testLoincMap.put(ANALYZER_TEST_PLT, testService.getTestsByLoincCode(LOINC_PLT));
- testLoincMap.put(ANALYZER_TEST_MPV, testService.getTestsByLoincCode(LOINC_MPV));
- testLoincMap.put(ANALYZER_TEST_NEUT_COUNT, testService.getTestsByLoincCode(LOINC_NEUT_COUNT));
- testLoincMap.put(ANALYZER_TEST_NEUT_PERCENT, testService.getTestsByLoincCode(LOINC_NEUT_PERCENT));
- testLoincMap.put(ANALYZER_TEST_LYMPH_COUNT, testService.getTestsByLoincCode(LOINC_LYMPH_COUNT));
- testLoincMap.put(ANALYZER_TEST_LYMPH_PERCENT, testService.getTestsByLoincCode(LOINC_LYMPH_PERCENT));
- testLoincMap.put(ANALYZER_TEST_MONO_COUNT, testService.getTestsByLoincCode(LOINC_MONO_COUNT));
- testLoincMap.put(ANALYZER_TEST_MONO_PERCENT, testService.getTestsByLoincCode(LOINC_MONO_PERCENT));
- testLoincMap.put(ANALYZER_TEST_EO_COUNT, testService.getTestsByLoincCode(LOINC_EO_COUNT));
- testLoincMap.put(ANALYZER_TEST_EO_PERCENT, testService.getTestsByLoincCode(LOINC_EO_PERCENT));
- testLoincMap.put(ANALYZER_TEST_BASO_COUNT, testService.getTestsByLoincCode(LOINC_BASO_COUNT));
- testLoincMap.put(ANALYZER_TEST_BASO_PERCENT, testService.getTestsByLoincCode(LOINC_BASO_PERCENT));
- testLoincMap.put(ANALYZER_TEST_IG_COUNT, testService.getTestsByLoincCode(LOINC_IG_COUNT));
- testLoincMap.put(ANALYZER_TEST_IG_PERCENT, testService.getTestsByLoincCode(LOINC_IG_PERCENT));
- // testLoincMap.put(ANALYZER_TEST_PDW, testService.getTestsByLoincCode(LOINC_PDW));
- // testLoincMap.put(ANALYZER_TEST_PLCR, testService.getTestsByLoincCode(LOINC_PLCR));
- // testLoincMap.put(ANALYZER_TEST_PCT, testService.getTestsByLoincCode(LOINC_PCT));
- testLoincMap.put(ANALYZER_TEST_RET_COUNT, testService.getTestsByLoincCode(LOINC_RET_COUNT));
- testLoincMap.put(ANALYZER_TEST_RET_PERCENT, testService.getTestsByLoincCode(LOINC_RET_PERCENT));
- testLoincMap.put(ANALYZER_TEST_IRF, testService.getTestsByLoincCode(LOINC_IRF));
- // testLoincMap.put(ANALYZER_TEST_LFR, testService.getTestsByLoincCode(LOINC_LFR));
- // testLoincMap.put(ANALYZER_TEST_MFR, testService.getTestsByLoincCode(LOINC_MFR));
- // testLoincMap.put(ANALYZER_TEST_HFR, testService.getTestsByLoincCode(LOINC_HFR));
- // testLoincMap.put(ANALYZER_TEST_LWBC, testService.getTestsByLoincCode(LOINC_LWBC));
- testLoincMap.put(ANALYZER_TEST_RETHE, testService.getTestsByLoincCode(LOINC_RETHE));
- testLoincMap.put(ANALYZER_TEST_WBCBF, testService.getTestsByLoincCode(LOINC_WBCBF));
- testLoincMap.put(ANALYZER_TEST_RBCBF, testService.getTestsByLoincCode(LOINC_RBCBF));
- testLoincMap.put(ANALYZER_TEST_MN_COUNT, testService.getTestsByLoincCode(LOINC_MN_COUNT));
- testLoincMap.put(ANALYZER_TEST_PMN_COUNT, testService.getTestsByLoincCode(LOINC_PMN_COUNT));
- testLoincMap.put(ANALYZER_TEST_MN_PERCENT, testService.getTestsByLoincCode(LOINC_MN_PERCENT));
- testLoincMap.put(ANALYZER_TEST_TCBF_COUNT, testService.getTestsByLoincCode(LOINC_TCBF_COUNT));
+ testToLoincMap.put(ANALYZER_TEST_WBC, LOINC_WBC);
+ testToLoincMap.put(ANALYZER_TEST_RBC, LOINC_RBC);
+ testToLoincMap.put(ANALYZER_TEST_HGB, LOINC_HGB);
+ testToLoincMap.put(ANALYZER_TEST_HCT, LOINC_HCT);
+ testToLoincMap.put(ANALYZER_TEST_MCV, LOINC_MCV);
+ testToLoincMap.put(ANALYZER_TEST_MCH, LOINC_MCH);
+ testToLoincMap.put(ANALYZER_TEST_MCHC, LOINC_MCHC);
+ testToLoincMap.put(ANALYZER_TEST_RDWSD, LOINC_RDWSD);
+ testToLoincMap.put(ANALYZER_TEST_RDWCV, LOINC_RDWCV);
+ testToLoincMap.put(ANALYZER_TEST_PLT, LOINC_PLT);
+ testToLoincMap.put(ANALYZER_TEST_MPV, LOINC_MPV);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_COUNT, LOINC_NEUT_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_PERCENT, LOINC_NEUT_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_COUNT, LOINC_LYMPH_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_PERCENT, LOINC_LYMPH_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_COUNT, LOINC_MONO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_PERCENT, LOINC_MONO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_EO_COUNT, LOINC_EO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_EO_PERCENT, LOINC_EO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_COUNT, LOINC_BASO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_PERCENT, LOINC_BASO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_IG_COUNT, LOINC_IG_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_IG_PERCENT, LOINC_IG_PERCENT);
+ // testToLoincMap.put(ANALYZER_TEST_PDW, LOINC_PDW);
+ // testToLoincMap.put(ANALYZER_TEST_PLCR, LOINC_PLCR);
+ // testToLoincMap.put(ANALYZER_TEST_PCT, LOINC_PCT);
+ testToLoincMap.put(ANALYZER_TEST_RET_COUNT, LOINC_RET_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_RET_PERCENT, LOINC_RET_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_IRF, LOINC_IRF);
+ // testToLoincMap.put(ANALYZER_TEST_LFR, LOINC_LFR);
+ // testToLoincMap.put(ANALYZER_TEST_MFR, LOINC_MFR);
+ // testToLoincMap.put(ANALYZER_TEST_HFR, LOINC_HFR);
+ // testToLoincMap.put(ANALYZER_TEST_LWBC, LOINC_LWBC);
+ testToLoincMap.put(ANALYZER_TEST_RETHE, LOINC_RETHE);
+ testToLoincMap.put(ANALYZER_TEST_WBCBF, LOINC_WBCBF);
+ testToLoincMap.put(ANALYZER_TEST_RBCBF, LOINC_RBCBF);
+ testToLoincMap.put(ANALYZER_TEST_MN_COUNT, LOINC_MN_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_PMN_COUNT, LOINC_PMN_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MN_PERCENT, LOINC_MN_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_TCBF_COUNT, LOINC_TCBF_COUNT);
+ for (Entry entry : testToLoincMap.entrySet()) {
+ loincToTestCodeMap.put(entry.getValue(), entry.getKey());
+ testCodeToTestsMap.put(entry.getKey(), testService.getTestsByLoincCode(entry.getValue()));
+ }
- Analyzer analyzer = analyzerService.getAnalyzerByName("SysmexXNLAnalyzer");
+ Analyzer analyzer = analyzerService.getAnalyzerByName(SysmexXNLAnalyzer.ANALYZER_NAME);
ANALYZER_ID = analyzer.getId();
}
@@ -249,9 +271,29 @@ public boolean insert(List lines, String currentUserId) {
@Override
public String getError() {
- return "SysmexXNLAnalyzer analyzer unable to write to database";
+ return SysmexXNLAnalyzer.ANALYZER_NAME + " analyzer unable to write to database";
}
+ private Test findMatchingTest(Sample sample, String resultTestCode) {
+ if (sample != null) {
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ List possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // if ((possibleTests == null || possibleTests.size() == 0) && resultTestCode.contains("+")) {
+ // possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // }
+ if (possibleTests != null) {
+ for (Test curTest : possibleTests) {
+ if (curTest.getLoinc() != null && curTest.getLoinc().equals(curAnalysis.getTest().getLoinc())) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "findMatchingTest", "found test in sample for code: " + resultTestCode);
+ return curAnalysis.getTest();
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
//example patient record:
// P|1|||123456|^Jim^Brown||20010820|M|||||^Dr.1||||||||||||^^^WEST
// example order record:
@@ -260,15 +302,16 @@ public String getError() {
// R|1|^^^^WBC^1|7.80|10*3/uL||N||||||20011116101000
private void addRecordsToResults(String patientRecord, String orderRecord, String resultRecord,
List results, String currentUserId) {
- String[] patientRecordFields = patientRecord.split(DEFAULT_FIELD_DELIMITER);
- String[] orderRecordFields = orderRecord.split(DEFAULT_FIELD_DELIMITER);
- String[] orderTestIdFields = orderRecordFields[4].split(DEFAULT_REPEATER_DELIMITER);
- String[] orderIdFields = orderRecordFields[3].split(DEFAULT_SUBFIELD_DELIMITER);
- String[] resultRecordFields = resultRecord.split(DEFAULT_FIELD_DELIMITER);
- String[] resultTestIdField = resultRecordFields[2].split(DEFAULT_SUBFIELD_DELIMITER);
+ String[] patientRecordFields = patientRecord.split(Pattern.quote(FD));
+ String[] orderRecordFields = orderRecord.split(Pattern.quote(FD));
+ String[] orderTestIdFields = orderRecordFields[4].split(Pattern.quote(RD));
+ String[] orderIdFields = orderRecordFields[3].split(Pattern.quote(CD));
+ String[] resultRecordFields = resultRecord.split(Pattern.quote(FD));
+ String[] resultTestIdField = resultRecordFields[2].split(Pattern.quote(CD));
+ String resultRecordAbnormalFlag = resultRecordFields[6];
List orderTestIds = new ArrayList<>();
for (String orderIdField : orderTestIdFields) {
- String[] orderIds = orderIdField.split(DEFAULT_SUBFIELD_DELIMITER);
+ String[] orderIds = orderIdField.split(Pattern.quote(CD));
String orderTestId = orderIds.length >= 5 ? orderIds[4] : "";
if (GenericValidator.isBlankOrNull(orderTestId)) {
LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis parameter name is not present");
@@ -282,30 +325,42 @@ private void addRecordsToResults(String patientRecord, String orderRecord, Strin
String currentAccessionNumber = orderIdFields[2].trim();
Sample sample = sampleService.getSampleByAccessionNumber(currentAccessionNumber);
- Test test = null;
- if (sample != null) {
- for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
- List possibleTests = testLoincMap.get(resultTestId);
- if ((possibleTests == null || possibleTests.size() == 0) && resultTestId.contains("+")) {
- possibleTests = testLoincMap.get(resultTestId);
- }
- if (possibleTests != null) {
- for (Test curTest : possibleTests) {
- if (curTest.getLoinc() != null && curTest.getLoinc().equals(curAnalysis.getTest().getLoinc())) {
- test = curAnalysis.getTest();
- break;
- }
- }
- }
- }
- }
-
+ Test test = findMatchingTest(sample, resultTestId);
+
if (test == null) {
LogEvent.logError(this.getClass().getName(), "addRecordsToResults",
"can't import a result if order does not have that test ordered");
return;
}
-
+
+ switch (resultRecordAbnormalFlag) {
+ case "L": //lower than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "lower than interval result");
+ break;
+ case "H": // higher than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "higher than interval result");
+ break;
+ case ">": //out of assured linearity
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "out of assured linearity result");
+ break;
+ case "N": //normal
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "normal result");
+ break;
+ case "A": //abnormal
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "abnormal result");
+ break;
+ case "W": //low reliability
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "low reliability result");
+ break;
+ case "LL": //less than panic value
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "less than panic value result");
+ break;
+ case "HH": //higher than panic value
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "higher than panic value result");
+ break;
+ default:
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "abnormal flag not understood");
+ }
AnalyzerResults analyzerResults = addResult(results, null, "N", resultRecordFields[3],
DateUtil.convertStringDateToTimestampWithPattern(resultRecordFields[12], "yyyyMMddHHmmss"),
currentAccessionNumber, false, resultRecordFields[4], test);
@@ -366,6 +421,77 @@ private AnalyzerResults createAnalyzerResult(String resultType, String resultVal
public void persistImport(List resultList) {
this.persistImport("1", resultList);
}
+
+ public String buildResponse(List lines) {
+
+ String queryRecord = null;
+
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "buildResponse", "this is a test communication record for " + SysmexXNLAnalyzer.ANALYZER_NAME);
+ }
+ if (line.startsWith(QUERY_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "buildResponse", "request contains query record");
+ String response = generateQueryResponse(line);
+ return response;
+ }
+ }
+ LogEvent.logWarn(this.getClass().getName(), "buildResponse", "no response could be created, no query identifier supplied");
+ return "";
+ }
+
+ private String generateQueryResponse(String queryRecord) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "generating query response");
+ String[] queryRecordFields = queryRecord.split(Pattern.quote(FD));
+
+ String[] startingRangeIdNumber = queryRecordFields[2].split(Pattern.quote(CD));
+ String sampleIdNo = startingRangeIdNumber[2].trim();
+ String sampleNoAttribute = startingRangeIdNumber[3];
+
+ StringBuilder msgBuilder = new StringBuilder();
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "searching for sample with lab Number: " + sampleIdNo);
+
+ Sample sample = sampleService.getSampleByAccessionNumber(sampleIdNo.trim());
+ if (sample == null) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "generateQueryResponse", "no sample found with lab Number: " + sampleIdNo);
+ //return could not find sample messager
+ return msgBuilder.append("H|\\^&|\r\n")
+ .append("P|1|\r\n")
+ .append("O|1||||||||||||||||||||||||Y\r\n") //"Y" is no order exists marker
+ .append("L|1|N\r\n").toString();
+ }
+ Patient patient = sampleHumanService.getPatientForSample(sample);
+ Person person = patient.getPerson();
+ msgBuilder.append("H|\\^&|||||||||||E1394-97\r\n");
+ msgBuilder.append("P|1|||")
+ .append(patient.getNationalId()) //patient identifier
+ .append("|^").append(person.getFirstName()).append("^").append(person.getLastName()) //names
+ .append("||").append(patient.getBirthDate() == null ? "": dateFormat.format(patient.getBirthDate())) //birthdate
+ .append("|").append(patient.getGender()) //gender M F U
+ .append("|||||")
+ .append("")//DR id
+ .append("||||||||||||\r\n");
+
+ msgBuilder.append("O|1|").append(queryRecordFields[2]).append("||");
+
+ boolean first = true;
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ Optional testCode = Optional.ofNullable(loincToTestCodeMap.get(curAnalysis.getTest().getLoinc()));
+ if (testCode.isPresent()) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "found supported test in sample with test code: " + testCode.get());
+ if (!first) {
+ msgBuilder.append("\\");
+ }
+ first = false;
+ msgBuilder.append("^^^^").append(testCode.get());
+ }
+ }
+ msgBuilder.append("||")
+ .append(sample.getEnteredDate() == null ? "" : dateTimeFormat.format(sample.getEnteredDate()))
+ .append("|||||N||||||||||||||Q\r\n");
+ msgBuilder.append("L|1|N\r\n");
+ return msgBuilder.toString();
+ }
}
\ No newline at end of file
diff --git a/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerMenu.java b/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerMenu.java
index 709ba09..2a93a6c 100644
--- a/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerMenu.java
+++ b/analyzers/SysmexXN-L/src/main/java/oe/plugin/analyzer/SysmexXNLAnalyzerMenu.java
@@ -34,22 +34,22 @@ protected void insertMenu() {
// The order this analyzer will show on the menu relative to other analyzers
menu.setPresentationOrder(10);
// The id needs to be unique in the system
- menu.setElementId("httpanalyzer_plugin");
+ menu.setElementId(SysmexXNLAnalyzer.ANALYZER_NAME + "_plugin");
// This will always be "/AnalyzerResults?type=Analyzer->SysmexXNLAnalyzer");
+ SystemModule module = service.getOrCreateSystemModule("AnalyzerResults", SysmexXNLAnalyzer.ANALYZER_NAME,
+ "Results->Analyzer->" + SysmexXNLAnalyzer.ANALYZER_NAME);
Role role = service.getSystemRole( "Results" );
return service.bindRoleToModule( role, module );
}
diff --git a/analyzers/SysmexXP/pom.xml b/analyzers/SysmexXP/pom.xml
index 98bfa07..bad561e 100644
--- a/analyzers/SysmexXP/pom.xml
+++ b/analyzers/SysmexXP/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 0.3
+ 0.5
UTF-8
2.3
diff --git a/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzer.java b/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzer.java
index 3d1591a..46aea54 100644
--- a/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzer.java
+++ b/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzer.java
@@ -20,25 +20,29 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
import org.openelisglobal.common.services.PluginAnalyzerService;
import org.openelisglobal.plugin.AnalyzerImporterPlugin;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
import org.openelisglobal.common.log.LogEvent;
public class SysmexXPAnalyzer implements AnalyzerImporterPlugin {
+ public static final String ANALYZER_NAME = "SysmexXPAnalyzer";
+
@Override
public boolean connect() {
List nameMapping = new ArrayList<>();
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_WBC, "White Blood Cells Count",
+ new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_WBC, "White Blood Cells Count (WBC)",
SysmexXPAnalyzerImplementation.LOINC_WBC));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_RBC, "Red Blood Cells Count",
+ new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_RBC, "Red Blood Cells Count (RBC)",
SysmexXPAnalyzerImplementation.LOINC_RBC));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_HGB, "Hemoglobin",
+ new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_HGB, "Hemoglobin",
SysmexXPAnalyzerImplementation.LOINC_HGB));
nameMapping.add(
new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_HCT, "Hematocrit",
@@ -65,7 +69,7 @@ public boolean connect() {
new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_MPV, "",
SysmexXPAnalyzerImplementation.LOINC_MPV));
nameMapping.add(
- new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_NEUT_COUNT, "Neutrophiles",
+ new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_NEUT_COUNT, "Neutrophiles",
SysmexXPAnalyzerImplementation.LOINC_NEUT_COUNT));
nameMapping.add(
new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_NEUT_PERCENT, "Neutrophiles (%)",
@@ -106,7 +110,7 @@ public boolean connect() {
nameMapping.add(
new PluginAnalyzerService.TestMapping(SysmexXPAnalyzerImplementation.ANALYZER_TEST_MXD_PERCENT, "",
SysmexXPAnalyzerImplementation.LOINC_MXD_PERCENT));
- getInstance().addAnalyzerDatabaseParts("SysmexXPAnalyzer", "SysmexXPAnalyzer", nameMapping, true);
+ getInstance().addAnalyzerDatabaseParts(SysmexXPAnalyzer.ANALYZER_NAME, SysmexXPAnalyzer.ANALYZER_NAME, nameMapping, true);
getInstance().registerAnalyzer(this);
return true;
}
@@ -115,21 +119,22 @@ public boolean connect() {
public boolean isTargetAnalyzer(List lines) {
for (String line : lines) {
if (line.startsWith(SysmexXPAnalyzerImplementation.HEADER_RECORD_IDENTIFIER)) {
- String[] headerRecord = line.split(SysmexXPAnalyzerImplementation.DEFAULT_FIELD_DELIMITER);
+ String[] headerRecord = line.split(Pattern.quote(SysmexXPAnalyzerImplementation.FD));
if (headerRecord.length < 5) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not SysmexXP: header record not long enough");
return false;
}
- String[] senderName = headerRecord[4].split(SysmexXPAnalyzerImplementation.DEFAULT_SUBFIELD_DELIMITER);
- if (senderName.length < 1) {
+ String[] senderNameFields = headerRecord[4].split(Pattern.quote(SysmexXPAnalyzerImplementation.CD));
+ if (senderNameFields.length < 1) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not SysmexXP: sender name field not long enough");
return false;
}
- LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message analyzer name is " + senderName[0]);
- if (senderName[0].equalsIgnoreCase("XP-100")) {
+ String senderName = senderNameFields[0].trim();
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message analyzer name is " + senderName);
+ if (senderName.equalsIgnoreCase("XP-100")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXP (XP-100)");
return true;
- } else if (senderName[0].equalsIgnoreCase("XP-300")) {
+ } else if (senderName.equalsIgnoreCase("XP-300")) {
LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is SysmexXP (XP-300)");
return true;
}
@@ -141,9 +146,25 @@ public boolean isTargetAnalyzer(List lines) {
return false;
}
+ @Override
+ public boolean isAnalyzerResult(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(SysmexXPAnalyzerImplementation.RESULT_RECORD_IDENTIFIER)) {
+ return true;
+ }
+ }
+ LogEvent.logDebug(this.getClass().getSimpleName(), "isAnalyzerResult", "no result recoord identifier located");
+ return false;
+ }
+
@Override
public AnalyzerLineInserter getAnalyzerLineInserter() {
return new SysmexXPAnalyzerImplementation();
}
+ @Override
+ public AnalyzerResponder getAnalyzerResponder() {
+ return new SysmexXPAnalyzerImplementation();
+ }
+
}
diff --git a/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerImplementation.java b/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerImplementation.java
index 395caf1..1dd8743 100644
--- a/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerImplementation.java
+++ b/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerImplementation.java
@@ -17,16 +17,22 @@
package oe.plugin.analyzer;
import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+import java.util.Optional;
import org.apache.commons.validator.GenericValidator;
import org.openelisglobal.analyzer.service.AnalyzerService;
import org.openelisglobal.analyzer.valueholder.Analyzer;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerReaderUtil;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
import org.openelisglobal.analyzerimport.util.AnalyzerTestNameCache;
import org.openelisglobal.analyzerimport.util.MappedTestName;
import org.openelisglobal.analyzerresults.valueholder.AnalyzerResults;
@@ -34,14 +40,17 @@
import org.openelisglobal.spring.util.SpringContext;
import org.openelisglobal.test.service.TestService;
import org.openelisglobal.sample.service.SampleService;
+import org.openelisglobal.samplehuman.service.SampleHumanService;
import org.openelisglobal.analysis.service.AnalysisService;
import org.openelisglobal.test.valueholder.Test;
import org.openelisglobal.analysis.valueholder.Analysis;
+import org.openelisglobal.person.valueholder.Person;
+import org.openelisglobal.patient.valueholder.Patient;
import org.openelisglobal.sample.valueholder.Sample;
import org.openelisglobal.common.util.DateUtil;
import org.openelisglobal.common.log.LogEvent;
-public class SysmexXPAnalyzerImplementation extends AnalyzerLineInserter {
+public class SysmexXPAnalyzerImplementation extends AnalyzerLineInserter implements AnalyzerResponder {
static final String ANALYZER_TEST_WBC = "WBC";
static final String ANALYZER_TEST_RBC = "RBC";
@@ -82,7 +91,7 @@ public class SysmexXPAnalyzerImplementation extends AnalyzerLineInserter {
static final String LOINC_MPV = "32623-1";
static final String LOINC_NEUT_COUNT = "751-8";
static final String LOINC_NEUT_PERCENT = "770-8";
- static final String LOINC_LYMPH_COUNT = "731-0";
+ static final String LOINC_LYMPH_COUNT = "731-0";;
static final String LOINC_LYMPH_PERCENT = "736-9";
static final String LOINC_MONO_COUNT = "742-7";
static final String LOINC_MONO_PERCENT = "5905-5";
@@ -96,54 +105,67 @@ public class SysmexXPAnalyzerImplementation extends AnalyzerLineInserter {
static final String LOINC_MXD_PERCENT = "32155-4";
protected static final String HEADER_RECORD_IDENTIFIER = "H";
+ protected static final String QUERY_RECORD_IDENTIFIER = "Q";
protected static final String PATIENT_RECORD_IDENTIFIER = "P";
protected static final String ORDER_RECORD_IDENTIFIER = "O";
protected static final String RESULT_RECORD_IDENTIFIER = "R";
protected static final String END_RECORD_IDENTIFIER = "L";
- protected static final String DEFAULT_FIELD_DELIMITER = "\\|";
- protected static final String DEFAULT_SUBFIELD_DELIMITER = "\\^";
- protected static final String DEFAULT_REPEATER_DELIMITER = "\\\\";
+ protected static final String FD = "|"; //DEFAULT_FIELD_DELIMITER
+ protected static final String CD = "^"; //DEFAULT_COMPONENT_DELIMITER
+ protected static final String RD = "\\"; //DEFAULT_REPEATER_DELIMITER
+ protected static final String ED = "&"; //DEFAULT_ESCAPE_DELIMITER
protected static final String TEST_COMMUNICATION_IDENTIFIER = "M|1|106";
+ private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+
private TestService testService = SpringContext.getBean(TestService.class);
private SampleService sampleService = SpringContext.getBean(SampleService.class);
+ private SampleHumanService sampleHumanService = SpringContext.getBean(SampleHumanService.class);
private AnalyzerService analyzerService = SpringContext.getBean(AnalyzerService.class);
private AnalysisService analysisService = SpringContext.getBean(AnalysisService.class);
private String ANALYZER_ID;
- private HashMap> testLoincMap = new HashMap<>();
+ private Map testToLoincMap = new HashMap<>();
+ private Map loincToTestCodeMap = new HashMap<>();
+ private Map> testCodeToTestsMap = new HashMap<>();
private AnalyzerReaderUtil readerUtil = new AnalyzerReaderUtil();
public SysmexXPAnalyzerImplementation() {
- testLoincMap.put(ANALYZER_TEST_WBC, testService.getTestsByLoincCode(LOINC_WBC));
- testLoincMap.put(ANALYZER_TEST_RBC, testService.getTestsByLoincCode(LOINC_RBC));
- testLoincMap.put(ANALYZER_TEST_HGB, testService.getTestsByLoincCode(LOINC_HGB));
- testLoincMap.put(ANALYZER_TEST_HCT, testService.getTestsByLoincCode(LOINC_HCT));
- testLoincMap.put(ANALYZER_TEST_MCV, testService.getTestsByLoincCode(LOINC_MCV));
- testLoincMap.put(ANALYZER_TEST_MCH, testService.getTestsByLoincCode(LOINC_MCH));
- testLoincMap.put(ANALYZER_TEST_MCHC, testService.getTestsByLoincCode(LOINC_MCHC));
- testLoincMap.put(ANALYZER_TEST_RDWSD, testService.getTestsByLoincCode(LOINC_RDWSD));
- testLoincMap.put(ANALYZER_TEST_RDWCV, testService.getTestsByLoincCode(LOINC_RDWCV));
- testLoincMap.put(ANALYZER_TEST_PLT, testService.getTestsByLoincCode(LOINC_PLT));
- testLoincMap.put(ANALYZER_TEST_MPV, testService.getTestsByLoincCode(LOINC_MPV));
- testLoincMap.put(ANALYZER_TEST_NEUT_COUNT, testService.getTestsByLoincCode(LOINC_NEUT_COUNT));
- testLoincMap.put(ANALYZER_TEST_NEUT_PERCENT, testService.getTestsByLoincCode(LOINC_NEUT_PERCENT));
- testLoincMap.put(ANALYZER_TEST_LYMPH_COUNT, testService.getTestsByLoincCode(LOINC_LYMPH_COUNT));
- testLoincMap.put(ANALYZER_TEST_LYMPH_PERCENT, testService.getTestsByLoincCode(LOINC_LYMPH_PERCENT));
- testLoincMap.put(ANALYZER_TEST_MONO_COUNT, testService.getTestsByLoincCode(LOINC_MONO_COUNT));
- testLoincMap.put(ANALYZER_TEST_MONO_PERCENT, testService.getTestsByLoincCode(LOINC_MONO_PERCENT));
- testLoincMap.put(ANALYZER_TEST_EO_COUNT, testService.getTestsByLoincCode(LOINC_EO_COUNT));
- testLoincMap.put(ANALYZER_TEST_EO_PERCENT, testService.getTestsByLoincCode(LOINC_EO_PERCENT));
- testLoincMap.put(ANALYZER_TEST_BASO_COUNT, testService.getTestsByLoincCode(LOINC_BASO_COUNT));
- testLoincMap.put(ANALYZER_TEST_BASO_PERCENT, testService.getTestsByLoincCode(LOINC_BASO_PERCENT));
- testLoincMap.put(ANALYZER_TEST_IG_COUNT, testService.getTestsByLoincCode(LOINC_IG_COUNT));
- testLoincMap.put(ANALYZER_TEST_IG_PERCENT, testService.getTestsByLoincCode(LOINC_IG_PERCENT));
- testLoincMap.put(ANALYZER_TEST_MXD_COUNT, testService.getTestsByLoincCode(LOINC_MXD_COUNT));
- testLoincMap.put(ANALYZER_TEST_MXD_PERCENT, testService.getTestsByLoincCode(LOINC_MXD_PERCENT));
-
- Analyzer analyzer = analyzerService.getAnalyzerByName("SysmexXNLAnalyzer");
+ testToLoincMap.put(ANALYZER_TEST_WBC, LOINC_WBC);
+ testToLoincMap.put(ANALYZER_TEST_RBC, LOINC_RBC);
+ testToLoincMap.put(ANALYZER_TEST_HGB, LOINC_HGB);
+ testToLoincMap.put(ANALYZER_TEST_HCT, LOINC_HCT);
+ testToLoincMap.put(ANALYZER_TEST_MCV, LOINC_MCV);
+ testToLoincMap.put(ANALYZER_TEST_MCH, LOINC_MCH);
+ testToLoincMap.put(ANALYZER_TEST_MCHC, LOINC_MCHC);
+ testToLoincMap.put(ANALYZER_TEST_RDWSD, LOINC_RDWSD);
+ testToLoincMap.put(ANALYZER_TEST_RDWCV, LOINC_RDWCV);
+ testToLoincMap.put(ANALYZER_TEST_PLT, LOINC_PLT);
+ testToLoincMap.put(ANALYZER_TEST_MPV, LOINC_MPV);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_COUNT, LOINC_NEUT_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_PERCENT, LOINC_NEUT_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_COUNT, LOINC_LYMPH_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_PERCENT, LOINC_LYMPH_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_COUNT, LOINC_MONO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_PERCENT, LOINC_MONO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_EO_COUNT, LOINC_EO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_EO_PERCENT, LOINC_EO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_COUNT, LOINC_BASO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_PERCENT, LOINC_BASO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_IG_COUNT, LOINC_IG_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_IG_PERCENT, LOINC_IG_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MXD_COUNT, LOINC_MXD_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MXD_PERCENT, LOINC_MXD_PERCENT);
+
+ for (Entry entry : testToLoincMap.entrySet()) {
+ loincToTestCodeMap.put(entry.getValue(), entry.getKey());
+ testCodeToTestsMap.put(entry.getKey(), testService.getTestsByLoincCode(entry.getValue()));
+ }
+
+ Analyzer analyzer = analyzerService.getAnalyzerByName(SysmexXPAnalyzer.ANALYZER_NAME);
ANALYZER_ID = analyzer.getId();
}
@@ -173,7 +195,7 @@ public boolean insert(List lines, String currentUserId) {
List results = new ArrayList<>();
for (String line : lines) {
if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
- LogEvent.logInfo(this.getClass().getName(), "insert", "this is a test communication record for Aquios");
+ LogEvent.logInfo(this.getClass().getName(), "insert", "this is a test communication record for Sysmex XP");
}
if (line.startsWith(PATIENT_RECORD_IDENTIFIER)) {
if (patientRecord != null) {
@@ -200,7 +222,27 @@ public boolean insert(List lines, String currentUserId) {
@Override
public String getError() {
- return "SysmexXNLAnalyzer analyzer unable to write to database";
+ return SysmexXPAnalyzer.ANALYZER_NAME + " analyzer unable to write to database";
+ }
+
+ private Test findMatchingTest(Sample sample, String resultTestCode) {
+ if (sample != null) {
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ List possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // if ((possibleTests == null || possibleTests.size() == 0) && resultTestCode.contains("+")) {
+ // possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // }
+ if (possibleTests != null) {
+ for (Test curTest : possibleTests) {
+ if (curTest.getLoinc() != null && curTest.getLoinc().equals(curAnalysis.getTest().getLoinc())) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "findMatchingTest", "found test in sample for code: " + resultTestCode);
+ return curAnalysis.getTest();
+ }
+ }
+ }
+ }
+ }
+ return null;
}
//example patient record:
@@ -211,15 +253,16 @@ public String getError() {
// R|1|^^^^WBC^26|78|10*2/uL||N||||123456789012345||20011221163530
private void addRecordsToResults(String patientRecord, String orderRecord, String resultRecord,
List results, String currentUserId) {
- String[] patientRecordFields = patientRecord.split(DEFAULT_FIELD_DELIMITER);
- String[] orderRecordFields = orderRecord.split(DEFAULT_FIELD_DELIMITER);
- String[] orderTestIdFields = orderRecordFields[4].split(DEFAULT_REPEATER_DELIMITER);
- String[] orderIdFields = orderRecordFields[3].split(DEFAULT_SUBFIELD_DELIMITER);
- String[] resultRecordFields = resultRecord.split(DEFAULT_FIELD_DELIMITER);
- String[] resultTestIdField = resultRecordFields[2].split(DEFAULT_SUBFIELD_DELIMITER);
+ String[] patientRecordFields = patientRecord.split(Pattern.quote(FD));
+ String[] orderRecordFields = orderRecord.split(Pattern.quote(FD));
+ String[] orderTestIdFields = orderRecordFields[4].split(Pattern.quote(RD));
+ String[] orderIdFields = orderRecordFields[3].split(Pattern.quote(CD));
+ String[] resultRecordFields = resultRecord.split(Pattern.quote(FD));
+ String[] resultTestIdField = resultRecordFields[2].split(Pattern.quote(CD));
+ String resultRecordAbnormalFlag = resultRecordFields[6];
List orderTestIds = new ArrayList<>();
for (String orderIdField : orderTestIdFields) {
- String[] orderIds = orderIdField.split(DEFAULT_SUBFIELD_DELIMITER);
+ String[] orderIds = orderIdField.split(Pattern.quote(CD));
String orderTestId = orderIds.length >= 5 ? orderIds[4] : "";
if (GenericValidator.isBlankOrNull(orderTestId)) {
LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis parameter name is not present");
@@ -233,23 +276,7 @@ private void addRecordsToResults(String patientRecord, String orderRecord, Strin
String currentAccessionNumber = orderIdFields[2].trim();
Sample sample = sampleService.getSampleByAccessionNumber(currentAccessionNumber);
- Test test = null;
- if (sample != null) {
- for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
- List possibleTests = testLoincMap.get(resultTestId);
- if ((possibleTests == null || possibleTests.size() == 0) && resultTestId.contains("+")) {
- possibleTests = testLoincMap.get(resultTestId);
- }
- if (possibleTests != null) {
- for (Test curTest : possibleTests) {
- if (curTest.getLoinc() != null && curTest.getLoinc().equals(curAnalysis.getTest().getLoinc())) {
- test = curAnalysis.getTest();
- break;
- }
- }
- }
- }
- }
+ Test test = findMatchingTest(sample, resultTestId);
if (test == null) {
LogEvent.logError(this.getClass().getName(), "addRecordsToResults",
@@ -257,6 +284,29 @@ private void addRecordsToResults(String patientRecord, String orderRecord, Strin
return;
}
+ switch (resultRecordAbnormalFlag) {
+ case "A": //masked data
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "masked data result");
+ break;
+ case ">": //out of assured linearity
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "out of assured linearity result");
+ break;
+ case "W": //low reliability
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "low reliability result");
+ break;
+ case "H": // higher than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "higher than interval result");
+ break;
+ case "L": //lower than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "lower than interval result");
+ break;
+ case "N": //normal
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "normal result");
+ break;
+ default:
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "abnormal flag not understood");
+ }
+
AnalyzerResults analyzerResults = addResult(results, null, "N", resultRecordFields[3],
DateUtil.convertStringDateToTimestampWithPattern(resultRecordFields[12], "yyyyMMddHHmmss"),
currentAccessionNumber, false, resultRecordFields[4], test);
@@ -316,6 +366,75 @@ private AnalyzerResults createAnalyzerResult(String resultType, String resultVal
public void persistImport(List resultList) {
this.persistImport("1", resultList);
+ }public String buildResponse(List lines) {
+
+ String queryRecord = null;
+
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "buildResponse", "this is a test communication record for " + SysmexXPAnalyzer.ANALYZER_NAME);
+ }
+ if (line.startsWith(QUERY_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "buildResponse", "request contains query record");
+ String response = generateQueryResponse(line);
+ return response;
+ }
+ }
+ LogEvent.logWarn(this.getClass().getName(), "buildResponse", "no response could be created, no query identifier supplied");
+ return "";
+ }
+
+ private String generateQueryResponse(String queryRecord) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "generating query response");
+ String[] queryRecordFields = queryRecord.split(Pattern.quote(FD));
+
+ String[] startingRangeIdNumber = queryRecordFields[2].split(Pattern.quote(CD));
+ String sampleIdNo = startingRangeIdNumber[2].trim();
+ String sampleNoAttribute = startingRangeIdNumber[3];
+
+ StringBuilder msgBuilder = new StringBuilder();
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "searching for sample with lab Number: " + sampleIdNo);
+
+ Sample sample = sampleService.getSampleByAccessionNumber(sampleIdNo.trim());
+ if (sample == null) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "generateQueryResponse", "no sample found with lab Number: " + sampleIdNo);
+ //return could not find sample messager
+ return msgBuilder.append("H|\\^&|\r\n")
+ .append("P|1|\r\n")
+ .append("O|1||||||||||||||||||||||||Y\r\n") //"Y" is no order exists marker
+ .append("L|1|N\r\n").toString();
+ }
+ Patient patient = sampleHumanService.getPatientForSample(sample);
+ Person person = patient.getPerson();
+ msgBuilder.append("H|\\^&|||||||||||E1394-97\r\n");
+ msgBuilder.append("P|1|||")
+ .append(patient.getNationalId()) //patient identifier
+ .append("|^").append(person.getFirstName()).append("^").append(person.getLastName()) //names
+ .append("||").append(patient.getBirthDate() == null ? "": dateFormat.format(patient.getBirthDate())) //birthdate
+ .append("|").append(patient.getGender()) //gender M F U
+ .append("|||||")
+ .append("")//DR id
+ .append("||||||||||||\r\n");
+
+ msgBuilder.append("O|1|").append(queryRecordFields[2]).append("||");
+
+ boolean first = true;
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ Optional testCode = Optional.ofNullable(loincToTestCodeMap.get(curAnalysis.getTest().getLoinc()));
+ if (testCode.isPresent()) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "found supported test in sample with test code: " + testCode.get());
+ if (!first) {
+ msgBuilder.append("\\");
+ }
+ first = false;
+ msgBuilder.append("^^^^").append(testCode.get());
+ }
+ }
+ msgBuilder.append("||")
+ .append(sample.getEnteredDate() == null ? "" : dateTimeFormat.format(sample.getEnteredDate()))
+ .append("|||||N||||||||||||||Q\r\n");
+ msgBuilder.append("L|1|N\r\n");
+ return msgBuilder.toString();
}
}
diff --git a/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerMenu.java b/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerMenu.java
index fc07f0d..161f985 100644
--- a/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerMenu.java
+++ b/analyzers/SysmexXP/src/main/java/oe/plugin/analyzer/SysmexXPAnalyzerMenu.java
@@ -34,22 +34,22 @@ protected void insertMenu() {
// The order this analyzer will show on the menu relative to other analyzers
menu.setPresentationOrder(10);
// The id needs to be unique in the system
- menu.setElementId("httpanalyzer_plugin");
+ menu.setElementId(SysmexXPAnalyzer.ANALYZER_NAME + "_plugin");
// This will always be "/AnalyzerResults?type=Analyzer->SysmexXPAnalyzer");
+ SystemModule module = service.getOrCreateSystemModule("AnalyzerResults", SysmexXPAnalyzer.ANALYZER_NAME,
+ "Results->Analyzer->" + SysmexXPAnalyzer.ANALYZER_NAME);
Role role = service.getSystemRole( "Results" );
return service.bindRoleToModule( role, module );
}
diff --git a/analyzers/pocH-100i/.vscode/settings.json b/analyzers/pocH-100i/.vscode/settings.json
new file mode 100644
index 0000000..890c247
--- /dev/null
+++ b/analyzers/pocH-100i/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "java.project.sourcePaths": [
+ "src/main/java"
+ ]
+}
\ No newline at end of file
diff --git a/analyzers/pocH-100i/pom.xml b/analyzers/pocH-100i/pom.xml
new file mode 100644
index 0000000..af30aac
--- /dev/null
+++ b/analyzers/pocH-100i/pom.xml
@@ -0,0 +1,89 @@
+
+ 4.0.0
+ org.openelisglobal.plugins
+ pocH-100iAnalyzer
+
+ org.openelisglobal
+ openelisglobal-plugins
+ 1.0
+ ../../pom.xml
+
+
+ 0.1
+
+ UTF-8
+ 2.3
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 4.0.1
+ provided
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.4
+
+
+ org.springframework
+ spring-webmvc
+ ${springframework.version}
+
+
+
+
+ src/main/java
+
+
+ src/main/filtered-resources
+ true
+
+
+ src/main/resources
+
+
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+
+ 1.8
+
+
+
+ maven-resources-plugin
+ 2.4.3
+
+
+ copy-resources
+
+ install
+
+ copy-resources
+
+
+ ${project.basedir}/../../plugins
+
+
+
+ target/
+
+ ${project.build.finalName}.jar
+
+
+ false
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzer.java b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzer.java
new file mode 100644
index 0000000..88d1658
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzer.java
@@ -0,0 +1,167 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import static org.openelisglobal.common.services.PluginAnalyzerService.getInstance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
+import org.openelisglobal.common.services.PluginAnalyzerService;
+import org.openelisglobal.plugin.AnalyzerImporterPlugin;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
+import org.openelisglobal.common.log.LogEvent;
+
+public class PocH100iAnalyzer implements AnalyzerImporterPlugin {
+
+ public static final String ANALYZER_NAME = "PocH100iAnalyzer";
+
+ @Override
+ public boolean connect() {
+ List nameMapping = new ArrayList<>();
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_WBC, "White Blood Cells Count (WBC)",
+ PocH100iAnalyzerImplementation.LOINC_WBC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_RBC, "Red Blood Cells Count (RBC)",
+ PocH100iAnalyzerImplementation.LOINC_RBC));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_HGB, "Hemoglobin",
+ PocH100iAnalyzerImplementation.LOINC_HGB));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_HCT, "Hematocrit",
+ PocH100iAnalyzerImplementation.LOINC_HCT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MCV, "Medium corpuscular volum",
+ PocH100iAnalyzerImplementation.LOINC_MCV));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MCH, "",
+ PocH100iAnalyzerImplementation.LOINC_MCH));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MCHC, "",
+ PocH100iAnalyzerImplementation.LOINC_MCHC));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_RDWSD, "",
+ PocH100iAnalyzerImplementation.LOINC_RDWSD));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_RDWCV, "",
+ PocH100iAnalyzerImplementation.LOINC_RDWCV));
+ nameMapping
+ .add(new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_PLT, "Platelets",
+ PocH100iAnalyzerImplementation.LOINC_PLT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MPV, "",
+ PocH100iAnalyzerImplementation.LOINC_MPV));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_NEUT_COUNT, "Neutrophiles",
+ PocH100iAnalyzerImplementation.LOINC_NEUT_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_NEUT_PERCENT, "Neutrophiles (%)",
+ PocH100iAnalyzerImplementation.LOINC_NEUT_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_LYMPH_COUNT, "Lymphocytes (Abs)",
+ PocH100iAnalyzerImplementation.LOINC_LYMPH_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_LYMPH_PERCENT, "Lymphocytes (%)",
+ PocH100iAnalyzerImplementation.LOINC_LYMPH_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MONO_COUNT, "Monocytes (Abs)",
+ PocH100iAnalyzerImplementation.LOINC_MONO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MONO_PERCENT, "Monocytes (%)",
+ PocH100iAnalyzerImplementation.LOINC_MONO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_EO_COUNT, "Eosinophiles",
+ PocH100iAnalyzerImplementation.LOINC_EO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_EO_PERCENT, "Eosinophiles (%)",
+ PocH100iAnalyzerImplementation.LOINC_EO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_BASO_COUNT, "Basophiles",
+ PocH100iAnalyzerImplementation.LOINC_BASO_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_BASO_PERCENT, "Basophiles (%)",
+ PocH100iAnalyzerImplementation.LOINC_BASO_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_IG_COUNT, "",
+ PocH100iAnalyzerImplementation.LOINC_IG_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_IG_PERCENT, "",
+ PocH100iAnalyzerImplementation.LOINC_IG_PERCENT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MXD_COUNT, "",
+ PocH100iAnalyzerImplementation.LOINC_MXD_COUNT));
+ nameMapping.add(
+ new PluginAnalyzerService.TestMapping(PocH100iAnalyzerImplementation.ANALYZER_TEST_MXD_PERCENT, "",
+ PocH100iAnalyzerImplementation.LOINC_MXD_PERCENT));
+ getInstance().addAnalyzerDatabaseParts(ANALYZER_NAME, ANALYZER_NAME, nameMapping, true);
+ getInstance().registerAnalyzer(this);
+ return true;
+ }
+
+ @Override
+ public boolean isTargetAnalyzer(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(PocH100iAnalyzerImplementation.HEADER_RECORD_IDENTIFIER)) {
+ String[] headerRecord = line.split(Pattern.quote(PocH100iAnalyzerImplementation.FD));
+ if (headerRecord.length < 5) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: header record not long enough");
+ return false;
+ }
+ String[] senderNameFields = headerRecord[4].split(Pattern.quote(PocH100iAnalyzerImplementation.CD));
+ if (senderNameFields.length < 1) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: sender name field not long enough");
+ return false;
+ }
+ String senderName = senderNameFields[0].trim();
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message analyzer name is " + senderName);
+ if (senderName.equalsIgnoreCase("pocH-100i")) {
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is PocH100i");
+ return true;
+ }
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: sender name doesn't match");
+ return false;
+ }
+ }
+ LogEvent.logTrace(this.getClass().getSimpleName(), "isTargetAnalyzer", "incoming message is not PocH100i: no header line");
+ return false;
+ }
+
+ @Override
+ public boolean isAnalyzerResult(List lines) {
+ for (String line : lines) {
+ if (line.startsWith(PocH100iAnalyzerImplementation.RESULT_RECORD_IDENTIFIER)) {
+ return true;
+ }
+ }
+ LogEvent.logDebug(this.getClass().getSimpleName(), "isAnalyzerResult", "no result recoord identifier located");
+ return false;
+ }
+
+ @Override
+ public AnalyzerLineInserter getAnalyzerLineInserter() {
+ return new PocH100iAnalyzerImplementation();
+ }
+
+ @Override
+ public AnalyzerResponder getAnalyzerResponder() {
+ return new PocH100iAnalyzerImplementation();
+ }
+
+}
diff --git a/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerImplementation.java b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerImplementation.java
new file mode 100644
index 0000000..f5427af
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerImplementation.java
@@ -0,0 +1,441 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+import java.util.Optional;
+
+import org.apache.commons.validator.GenericValidator;
+import org.openelisglobal.analyzer.service.AnalyzerService;
+import org.openelisglobal.analyzer.valueholder.Analyzer;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerReaderUtil;
+import org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerResponder;
+import org.openelisglobal.analyzerimport.util.AnalyzerTestNameCache;
+import org.openelisglobal.analyzerimport.util.MappedTestName;
+import org.openelisglobal.analyzerresults.valueholder.AnalyzerResults;
+import org.openelisglobal.common.services.PluginAnalyzerService;
+import org.openelisglobal.spring.util.SpringContext;
+import org.openelisglobal.test.service.TestService;
+import org.openelisglobal.sample.service.SampleService;
+import org.openelisglobal.samplehuman.service.SampleHumanService;
+import org.openelisglobal.analysis.service.AnalysisService;
+import org.openelisglobal.test.valueholder.Test;
+import org.openelisglobal.analysis.valueholder.Analysis;
+import org.openelisglobal.person.valueholder.Person;
+import org.openelisglobal.patient.valueholder.Patient;
+import org.openelisglobal.sample.valueholder.Sample;
+import org.openelisglobal.common.util.DateUtil;
+import org.openelisglobal.common.log.LogEvent;
+
+public class PocH100iAnalyzerImplementation extends AnalyzerLineInserter implements AnalyzerResponder {
+
+ static final String ANALYZER_TEST_WBC = "WBC";
+ static final String ANALYZER_TEST_RBC = "RBC";
+ static final String ANALYZER_TEST_HGB = "HGB";
+ static final String ANALYZER_TEST_HCT = "HCT";
+ static final String ANALYZER_TEST_MCV = "MCV";
+ static final String ANALYZER_TEST_MCH = "MCH";
+ static final String ANALYZER_TEST_MCHC = "MCHC";
+ static final String ANALYZER_TEST_RDWSD = "RDW-SD";
+ static final String ANALYZER_TEST_RDWCV = "RDW-CV";
+ static final String ANALYZER_TEST_PLT = "PLT";
+ static final String ANALYZER_TEST_MPV = "MPV";
+ static final String ANALYZER_TEST_NEUT_COUNT = "NEUT#";
+ static final String ANALYZER_TEST_NEUT_PERCENT = "NEUT%";
+ static final String ANALYZER_TEST_LYMPH_COUNT = "LYMPH#";
+ static final String ANALYZER_TEST_LYMPH_PERCENT = "LYMPH%";
+ static final String ANALYZER_TEST_MONO_COUNT = "MONO#";
+ static final String ANALYZER_TEST_MONO_PERCENT = "MONO%";
+ static final String ANALYZER_TEST_EO_COUNT = "EO#";
+ static final String ANALYZER_TEST_EO_PERCENT = "EO%";
+ static final String ANALYZER_TEST_BASO_COUNT = "BASO#";
+ static final String ANALYZER_TEST_BASO_PERCENT = "BASO%";
+ static final String ANALYZER_TEST_IG_COUNT = "IG#";
+ static final String ANALYZER_TEST_IG_PERCENT = "IG%";
+ static final String ANALYZER_TEST_MXD_COUNT = "MXD#";
+ static final String ANALYZER_TEST_MXD_PERCENT = "MXD%";
+
+ static final String LOINC_WBC = "6690-2";
+ static final String LOINC_RBC = "789-8";
+ static final String LOINC_HGB = "718-7";
+ static final String LOINC_HCT = "4544-3";
+ static final String LOINC_MCV = "787-2";
+ static final String LOINC_MCH = "785-6";
+ static final String LOINC_MCHC = "786-4";
+ static final String LOINC_RDWSD = "21000-5";
+ static final String LOINC_RDWCV = "788-0";
+ static final String LOINC_PLT = "777-3";
+ static final String LOINC_MPV = "32623-1";
+ static final String LOINC_NEUT_COUNT = "751-8";
+ static final String LOINC_NEUT_PERCENT = "770-8";
+ static final String LOINC_LYMPH_COUNT = "731-0";;
+ static final String LOINC_LYMPH_PERCENT = "736-9";
+ static final String LOINC_MONO_COUNT = "742-7";
+ static final String LOINC_MONO_PERCENT = "5905-5";
+ static final String LOINC_EO_COUNT = "711-2";
+ static final String LOINC_EO_PERCENT = "713-8";
+ static final String LOINC_BASO_COUNT = "704-7";
+ static final String LOINC_BASO_PERCENT = "706-2";
+ static final String LOINC_IG_COUNT = "53115-2";
+ static final String LOINC_IG_PERCENT = "71695-1";
+ static final String LOINC_MXD_COUNT = "32154-7";
+ static final String LOINC_MXD_PERCENT = "32155-4";
+
+ protected static final String HEADER_RECORD_IDENTIFIER = "H";
+ protected static final String QUERY_RECORD_IDENTIFIER = "Q";
+ protected static final String PATIENT_RECORD_IDENTIFIER = "P";
+ protected static final String ORDER_RECORD_IDENTIFIER = "O";
+ protected static final String RESULT_RECORD_IDENTIFIER = "R";
+ protected static final String END_RECORD_IDENTIFIER = "L";
+ protected static final String FD = "|"; //DEFAULT_FIELD_DELIMITER
+ protected static final String CD = "^"; //DEFAULT_COMPONENT_DELIMITER
+ protected static final String RD = "\\"; //DEFAULT_REPEATER_DELIMITER
+ protected static final String ED = "&"; //DEFAULT_ESCAPE_DELIMITER
+ protected static final String TEST_COMMUNICATION_IDENTIFIER = "M|1|106";
+ private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+
+
+ private TestService testService = SpringContext.getBean(TestService.class);
+ private SampleService sampleService = SpringContext.getBean(SampleService.class);
+ private SampleHumanService sampleHumanService = SpringContext.getBean(SampleHumanService.class);
+ private AnalyzerService analyzerService = SpringContext.getBean(AnalyzerService.class);
+ private AnalysisService analysisService = SpringContext.getBean(AnalysisService.class);
+
+ private String ANALYZER_ID;
+ private Map testToLoincMap = new HashMap<>();
+ private Map loincToTestCodeMap = new HashMap<>();
+ private Map> testCodeToTestsMap = new HashMap<>();
+
+ private AnalyzerReaderUtil readerUtil = new AnalyzerReaderUtil();
+
+ public PocH100iAnalyzerImplementation() {
+
+ testToLoincMap.put(ANALYZER_TEST_WBC, LOINC_WBC);
+ testToLoincMap.put(ANALYZER_TEST_RBC, LOINC_RBC);
+ testToLoincMap.put(ANALYZER_TEST_HGB, LOINC_HGB);
+ testToLoincMap.put(ANALYZER_TEST_HCT, LOINC_HCT);
+ testToLoincMap.put(ANALYZER_TEST_MCV, LOINC_MCV);
+ testToLoincMap.put(ANALYZER_TEST_MCH, LOINC_MCH);
+ testToLoincMap.put(ANALYZER_TEST_MCHC, LOINC_MCHC);
+ testToLoincMap.put(ANALYZER_TEST_RDWSD, LOINC_RDWSD);
+ testToLoincMap.put(ANALYZER_TEST_RDWCV, LOINC_RDWCV);
+ testToLoincMap.put(ANALYZER_TEST_PLT, LOINC_PLT);
+ testToLoincMap.put(ANALYZER_TEST_MPV, LOINC_MPV);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_COUNT, LOINC_NEUT_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_NEUT_PERCENT, LOINC_NEUT_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_COUNT, LOINC_LYMPH_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_LYMPH_PERCENT, LOINC_LYMPH_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_COUNT, LOINC_MONO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MONO_PERCENT, LOINC_MONO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_EO_COUNT, LOINC_EO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_EO_PERCENT, LOINC_EO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_COUNT, LOINC_BASO_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_BASO_PERCENT, LOINC_BASO_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_IG_COUNT, LOINC_IG_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_IG_PERCENT, LOINC_IG_PERCENT);
+ testToLoincMap.put(ANALYZER_TEST_MXD_COUNT, LOINC_MXD_COUNT);
+ testToLoincMap.put(ANALYZER_TEST_MXD_PERCENT, LOINC_MXD_PERCENT);
+
+ for (Entry entry : testToLoincMap.entrySet()) {
+ loincToTestCodeMap.put(entry.getValue(), entry.getKey());
+ testCodeToTestsMap.put(entry.getKey(), testService.getTestsByLoincCode(entry.getValue()));
+ }
+
+ Analyzer analyzer = analyzerService.getAnalyzerByName(PocH100iAnalyzer.ANALYZER_NAME);
+ ANALYZER_ID = analyzer.getId();
+ }
+
+ // example message:
+ // H|\^&|||pocH-100i^01-29^^^^ ^02318732||||||||E1394-97
+ // P|1
+ // O|1||^^ 12345ABCDE^B|^^^^WBC\^^^^RBC\^^^^HGB\^^^^HCT\ ^^^^MCV\^^^^MCH\^^^^MCHC\^^^^PLT\^^^^W-SCR\^^^^W-MCR\^^^^W-LCR\^^^^W-SCC\^^^^W-MCC\^^^^W-LCC\^^^^RDW-SD\^^^^RDW-CV\^^^^PDW\^^^^MPV\^^^^P-LCR|||||||N||||||||||||||F
+ // R|1|^^^^WBC^26|78|10*2/uL||N||||123456789012345||20011221163530
+ // R|2|^^^^RBC^26|350|10*4/uL||L||||123456789012345||20011221163530
+ // R|3|^^^^HGB^26|***.*|g/dL||A||||123456789012345||20011221163530
+ // ……
+ // R|19|^^^^P-LCR^26|50.0|%||H||||123456789012345||20011221163530
+ // L|1|N
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.openelisglobal.analyzerimport.analyzerreaders.AnalyzerLineInserter#insert
+ * (java.util.List, java.lang.String)
+ */
+ @Override
+ public boolean insert(List lines, String currentUserId) {
+
+ String patientRecord = null;
+ String orderRecord = null;
+
+ List results = new ArrayList<>();
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "insert", "this is a test communication record for PocH-100i");
+ }
+ if (line.startsWith(PATIENT_RECORD_IDENTIFIER)) {
+ if (patientRecord != null) {
+ patientRecord = null;
+ orderRecord = null;
+ }
+ patientRecord = line;
+ }
+ if (line.startsWith(ORDER_RECORD_IDENTIFIER)) {
+ orderRecord = line;
+ }
+ if (line.startsWith(RESULT_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "insert", "adding result");
+
+ addRecordsToResults(patientRecord, orderRecord, line, results, currentUserId);
+ }
+ if (line.startsWith(END_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "insert", "end Aquios of record");
+ break;
+ }
+ }
+ return persistImport(currentUserId, results);
+ }
+
+ @Override
+ public String getError() {
+ return PocH100iAnalyzer.ANALYZER_NAME + " analyzer unable to write to database";
+ }
+
+ private Test findMatchingTest(Sample sample, String resultTestCode) {
+ if (sample != null) {
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ List possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // if ((possibleTests == null || possibleTests.size() == 0) && resultTestCode.contains("+")) {
+ // possibleTests = testCodeToTestsMap.get(resultTestCode);
+ // }
+ if (possibleTests != null) {
+ for (Test curTest : possibleTests) {
+ if (curTest.getLoinc() != null && curTest.getLoinc().equals(curAnalysis.getTest().getLoinc())) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "findMatchingTest", "found test in sample for code: " + resultTestCode);
+ return curAnalysis.getTest();
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ //example patient record:
+ // P|1
+ // example order record:
+ // O|1||^^ 12345ABCDE^B|^^^^WBC\^^^^RBC\^^^^HGB\^^^^HCT\ ^^^^MCV\^^^^MCH\^^^^MCHC\^^^^PLT\^^^^W-SCR\^^^^W-MCR\^^^^W-LCR\^^^^W-SCC\^^^^W-MCC\^^^^W-LCC\^^^^RDW-SD\^^^^RDW-CV\^^^^PDW\^^^^MPV\^^^^P-LCR|||||||N||||||||||||||F
+ // example result records:
+ // R|1|^^^^WBC^26|78|10*2/uL||N||||123456789012345||20011221163530
+ private void addRecordsToResults(String patientRecord, String orderRecord, String resultRecord,
+ List results, String currentUserId) {
+ String[] patientRecordFields = patientRecord.split(Pattern.quote(FD));
+ String[] orderRecordFields = orderRecord.split(Pattern.quote(FD));
+ String[] orderTestIdFields = orderRecordFields[4].split(Pattern.quote(RD));
+ String[] orderIdFields = orderRecordFields[3].split(Pattern.quote(CD));
+ String[] resultRecordFields = resultRecord.split(Pattern.quote(FD));
+ String[] resultTestIdField = resultRecordFields[2].split(Pattern.quote(CD));
+ String resultRecordAbnormalFlag = resultRecordFields[6];
+ List orderTestIds = new ArrayList<>();
+ for (String orderIdField : orderTestIdFields) {
+ String[] orderIds = orderIdField.split(Pattern.quote(CD));
+ String orderTestId = orderIds.length >= 5 ? orderIds[4] : "";
+ if (GenericValidator.isBlankOrNull(orderTestId)) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis parameter name is not present");
+ }
+ orderTestIds.add(orderTestId);
+ }
+ if (orderTestIds.size() <= 0) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "order analysis has no tests specified");
+ }
+ String resultTestId = resultTestIdField.length >= 5 ? resultTestIdField[4] : "";
+
+ String currentAccessionNumber = orderIdFields[2].trim();
+ Sample sample = sampleService.getSampleByAccessionNumber(currentAccessionNumber);
+ Test test = findMatchingTest(sample, resultTestId);
+
+ if (test == null) {
+ LogEvent.logError(this.getClass().getName(), "addRecordsToResults",
+ "can't import a result if order does not have that test ordered");
+ LogEvent.logDebug(this.getClass().getSimpleName(), "", "resultTestId: " + resultTestId);
+ return;
+ }
+
+ switch (resultRecordAbnormalFlag) {
+ case "A": //masked data
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "masked data result");
+ break;
+ case ">": //out of assured linearity
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "out of assured linearity result");
+ break;
+ case "W": //low reliability
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "low reliability result");
+ break;
+ case "H": // higher than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "higher than interval result");
+ break;
+ case "L": //lower than reference interval
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "lower than interval result");
+ break;
+ case "N": //normal
+ LogEvent.logDebug(this.getClass().getSimpleName(), "addRecordsToResults", "normal result");
+ break;
+ default:
+ LogEvent.logWarn(this.getClass().getSimpleName(), "addRecordsToResults", "abnormal flag not understood");
+ }
+
+ AnalyzerResults analyzerResults = addResult(results, null, "N", resultRecordFields[3],
+ DateUtil.convertStringDateToTimestampWithPattern(resultRecordFields[12], "yyyyMMddHHmmss"),
+ currentAccessionNumber, false, resultRecordFields[4], test);
+ LogEvent.logDebug(this.getClass().getName(), "addResultLine", "***" + analyzerResults.getAccessionNumber() + " "
+ + analyzerResults.getCompleteDate() + " " + analyzerResults.getResult());
+ }
+
+ public AnalyzerResults addResult(List resultList, List notMatchedResults, String resultType,
+ String resultValue, Date date, String accessionNumber, boolean isControl, String resultUnits,
+ Test test) {
+ LogEvent.logDebug(this.getClass().getName(), "addResult",
+ "adding result for lab Number: " + accessionNumber);
+ AnalyzerResults analyzerResults = createAnalyzerResult(resultType, resultValue, resultUnits, date,
+ accessionNumber, isControl, test);
+ if (analyzerResults.getTestId() != null) {
+ addValueToResults(resultList, analyzerResults);
+ } else {
+ LogEvent.logWarn(this.getClass().getName(), "addResult",
+ "no matching result for " + accessionNumber);
+ notMatchedResults.add(analyzerResults);
+ }
+ return analyzerResults;
+ }
+
+ private void addValueToResults(List resultList, AnalyzerResults result) {
+ resultList.add(result);
+ LogEvent.logDebug(this.getClass().getName(), "addValueToResults",
+ "searching for matching analysis for " + result.getAccessionNumber());
+ AnalyzerResults resultFromDB = readerUtil.createAnalyzerResultFromDB(result);
+ if (resultFromDB != null) {
+ LogEvent.logWarn(this.getClass().getName(), "addValueToResults",
+ "no resultFromDB for " + result.getAccessionNumber());
+ resultList.add(resultFromDB);
+ }
+
+ }
+
+ private AnalyzerResults createAnalyzerResult(String resultType, String resultValue, String resultUnits, Date date,
+ String accessionNumber, boolean isControl, Test test) {
+ LogEvent.logDebug(this.getClass().getName(), "createAnalyzerResult",
+ "creating analyzer result for " + accessionNumber);
+
+ AnalyzerResults analyzerResults = new AnalyzerResults();
+
+ analyzerResults.setAnalyzerId(ANALYZER_ID);
+ analyzerResults.setResult(resultValue);
+ analyzerResults.setUnits(resultUnits);
+ if (date != null) {
+ analyzerResults.setCompleteDate(new Timestamp(date.getTime()));
+ }
+ analyzerResults.setAccessionNumber(accessionNumber);
+ analyzerResults.setTestId(test.getId());
+ analyzerResults.setIsControl(isControl);
+ analyzerResults.setTestName(test.getLocalizedTestName().getLocalizedValue());
+ return analyzerResults;
+ }
+
+ public void persistImport(List resultList) {
+ this.persistImport("1", resultList);
+ }public String buildResponse(List lines) {
+
+ String queryRecord = null;
+
+ for (String line : lines) {
+ if (line.startsWith(TEST_COMMUNICATION_IDENTIFIER)) {
+ LogEvent.logInfo(this.getClass().getName(), "buildResponse", "this is a test communication record for " + PocH100iAnalyzer.ANALYZER_NAME);
+ }
+ if (line.startsWith(QUERY_RECORD_IDENTIFIER)) {
+ LogEvent.logDebug(this.getClass().getName(), "buildResponse", "request contains query record");
+ String response = generateQueryResponse(line);
+ return response;
+ }
+ }
+ LogEvent.logWarn(this.getClass().getName(), "buildResponse", "no response could be created, no query identifier supplied");
+ return "";
+ }
+
+ private String generateQueryResponse(String queryRecord) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "generating query response");
+ String[] queryRecordFields = queryRecord.split(Pattern.quote(FD));
+
+ String[] startingRangeIdNumber = queryRecordFields[2].split(Pattern.quote(CD));
+ String sampleIdNo = startingRangeIdNumber[2].trim();
+ String sampleNoAttribute = startingRangeIdNumber[3];
+
+ StringBuilder msgBuilder = new StringBuilder();
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "searching for sample with lab Number: " + sampleIdNo);
+
+ Sample sample = sampleService.getSampleByAccessionNumber(sampleIdNo.trim());
+ if (sample == null) {
+ LogEvent.logWarn(this.getClass().getSimpleName(), "generateQueryResponse", "no sample found with lab Number: " + sampleIdNo);
+ //return could not find sample messager
+ return msgBuilder.append("H|\\^&|\r\n")
+ .append("P|1|\r\n")
+ .append("O|1||||||||||||||||||||||||Y\r\n") //"Y" is no order exists marker
+ .append("L|1|N\r\n").toString();
+ }
+ Patient patient = sampleHumanService.getPatientForSample(sample);
+ Person person = patient.getPerson();
+ msgBuilder.append("H|\\^&|||||||||||E1394-97\r\n");
+ msgBuilder.append("P|1|||")
+ .append(patient.getNationalId()) //patient identifier
+ .append("|^").append(person.getFirstName()).append("^").append(person.getLastName()) //names
+ .append("||").append(patient.getBirthDate() == null ? "": dateFormat.format(patient.getBirthDate())) //birthdate
+ .append("|").append(patient.getGender()) //gender M F U
+ .append("|||||")
+ .append("")//DR id
+ .append("||||||||||||\r\n");
+
+ msgBuilder.append("O|1|").append(queryRecordFields[2]).append("||");
+
+ boolean first = true;
+ for (Analysis curAnalysis : analysisService.getAnalysesBySampleId(sample.getId())) {
+ Optional testCode = Optional.ofNullable(loincToTestCodeMap.get(curAnalysis.getTest().getLoinc()));
+ if (testCode.isPresent()) {
+ LogEvent.logDebug(this.getClass().getSimpleName(), "generateQueryResponse", "found supported test in sample with test code: " + testCode.get());
+ if (!first) {
+ msgBuilder.append("\\");
+ }
+ first = false;
+ msgBuilder.append("^^^^").append(testCode.get());
+ }
+ }
+ msgBuilder.append("||")
+ .append(sample.getEnteredDate() == null ? "" : dateTimeFormat.format(sample.getEnteredDate()))
+ .append("|||||N||||||||||||||Q\r\n");
+ msgBuilder.append("L|1|N\r\n");
+ return msgBuilder.toString();
+ }
+
+}
diff --git a/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerMenu.java b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerMenu.java
new file mode 100644
index 0000000..1b3aa33
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/java/oe/plugin/analyzer/PocH100iAnalyzerMenu.java
@@ -0,0 +1,57 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations under
+ * the License.
+ *
+ * The Original Code is OpenELIS code.
+ *
+ * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved.
+ */
+
+package oe.plugin.analyzer;
+
+import java.util.Locale;
+
+import org.openelisglobal.common.services.PluginMenuService;
+import org.openelisglobal.common.services.PluginMenuService.KnownMenu;
+import org.openelisglobal.menu.valueholder.Menu;
+import org.openelisglobal.plugin.MenuPlugin;
+
+public class PocH100iAnalyzerMenu extends MenuPlugin {
+
+ @Override
+ protected void insertMenu() {
+ PluginMenuService service = PluginMenuService.getInstance();
+ Menu menu = new Menu();
+
+ menu.setParent(PluginMenuService.getInstance().getKnownMenu(KnownMenu.ANALYZER, "menu_results"));
+ // The order this analyzer will show on the menu relative to other analyzers
+ menu.setPresentationOrder(10);
+ // The id needs to be unique in the system
+ menu.setElementId(PocH100iAnalyzer.ANALYZER_NAME + "_plugin");
+ // This will always be "/AnalyzerResults?type=Analyzer->" + PocH100iAnalyzer.ANALYZER_NAME);
+ Role role = service.getSystemRole( "Results" );
+ return service.bindRoleToModule( role, module );
+ }
+}
diff --git a/analyzers/pocH-100i/src/main/resources/PocH-100iAnalyzer.xml b/analyzers/pocH-100i/src/main/resources/PocH-100iAnalyzer.xml
new file mode 100644
index 0000000..e41e7d5
--- /dev/null
+++ b/analyzers/pocH-100i/src/main/resources/PocH-100iAnalyzer.xml
@@ -0,0 +1,22 @@
+
+
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/openelisglobal-2.5.0.0.jar b/lib/openelisglobal-2.7.3.8.jar
similarity index 95%
rename from lib/openelisglobal-2.5.0.0.jar
rename to lib/openelisglobal-2.7.3.8.jar
index f90db77..0d1ec9c 100644
Binary files a/lib/openelisglobal-2.5.0.0.jar and b/lib/openelisglobal-2.7.3.8.jar differ
diff --git a/pom.xml b/pom.xml
index d942918..5c4dd93 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,19 +25,23 @@
./analyzers/GeneXpertFile
./analyzers/SysmexXN-L
./analyzers/SysmexXP
+ ./analyzers/pocH-100i
-
+
5.3.14
+ 11
+ 11
+ 11
org.openelisglobal
openelisglobal
- 2.5.0.0
+ 2.7.3.8
system
- /home/runner/work/openelisglobal-plugins/openelisglobal-plugins/lib/openelisglobal-2.5.0.0.jar
+ /home/runner/work/openelisglobal-plugins/openelisglobal-plugins/lib/openelisglobal-2.7.3.8.jar
commons-validator