Loinc uploader updates
This commit is contained in:
parent
8c889267e5
commit
488890155c
|
@ -717,10 +717,10 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>${basedir}/src/main/resources</directory>
|
<directory>${project.basedir}/src/main/resources</directory>
|
||||||
</resource>
|
</resource>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>${basedir}/target/generated-resources/tinder</directory>
|
<directory>${project.basedir}/target/generated-resources/tinder</directory>
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</build>
|
</build>
|
||||||
|
|
|
@ -8,7 +8,10 @@ import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.model.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
|
@ -21,9 +24,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -122,7 +125,7 @@ public interface IFhirResourceDaoCodeSystem<T extends IBaseResource, CD, CC> ext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Parameters toParameters() {
|
public Parameters toParameters(List<? extends IPrimitiveType<String>> theProperties) {
|
||||||
Parameters retVal = new Parameters();
|
Parameters retVal = new Parameters();
|
||||||
|
|
||||||
retVal.addParameter().setName("name").setValue(new StringType(getCodeSystemDisplayName()));
|
retVal.addParameter().setName("name").setValue(new StringType(getCodeSystemDisplayName()));
|
||||||
|
@ -133,7 +136,23 @@ public interface IFhirResourceDaoCodeSystem<T extends IBaseResource, CD, CC> ext
|
||||||
retVal.addParameter().setName("abstract").setValue(new BooleanType(isCodeIsAbstract()));
|
retVal.addParameter().setName("abstract").setValue(new BooleanType(isCodeIsAbstract()));
|
||||||
|
|
||||||
if (myProperties != null) {
|
if (myProperties != null) {
|
||||||
|
|
||||||
|
Set<String> properties = Collections.emptySet();
|
||||||
|
if (theProperties != null) {
|
||||||
|
properties = theProperties
|
||||||
|
.stream()
|
||||||
|
.map(IPrimitiveType::getValueAsString)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
for (IContextValidationSupport.BaseConceptProperty next : myProperties) {
|
for (IContextValidationSupport.BaseConceptProperty next : myProperties) {
|
||||||
|
|
||||||
|
if (!properties.isEmpty()) {
|
||||||
|
if (!properties.contains(next.getPropertyName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Parameters.ParametersParameterComponent property = retVal.addParameter().setName("property");
|
Parameters.ParametersParameterComponent property = retVal.addParameter().setName("property");
|
||||||
property
|
property
|
||||||
.addPart()
|
.addPart()
|
||||||
|
|
|
@ -53,6 +53,11 @@ public class TermConceptPropertyFieldBridge implements FieldBridge, StringBridge
|
||||||
for (TermConceptProperty next : properties) {
|
for (TermConceptProperty next : properties) {
|
||||||
String propValue = next.getKey() + "=" + next.getValue();
|
String propValue = next.getKey() + "=" + next.getValue();
|
||||||
theLuceneOptions.addFieldToDocument(theName, propValue, theDocument);
|
theLuceneOptions.addFieldToDocument(theName, propValue, theDocument);
|
||||||
|
|
||||||
|
if (next.getType() == TermConceptPropertyTypeEnum.CODING) {
|
||||||
|
propValue = next.getKey() + "=" + next.getDisplay();
|
||||||
|
theLuceneOptions.addFieldToDocument(theName, propValue, theDocument);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,25 +20,21 @@ package ca.uhn.fhir.jpa.provider.dstu3;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|
||||||
import org.hl7.fhir.convertors.VersionConvertor_30_40;
|
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem.LookupCodeResult;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem.LookupCodeResult;
|
||||||
import ca.uhn.fhir.rest.annotation.Operation;
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import org.hl7.fhir.convertors.VersionConvertor_30_40;
|
||||||
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderDstu3<CodeSystem> {
|
public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderDstu3<CodeSystem> {
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Operation(name = "$lookup", idempotent = true, returnParameters= {
|
@Operation(name = "$lookup", idempotent = true, returnParameters= {
|
||||||
@OperationParam(name="name", type=StringType.class, min=1),
|
@OperationParam(name="name", type=StringType.class, min=1),
|
||||||
|
@ -50,17 +46,17 @@ public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderD
|
||||||
HttpServletRequest theServletRequest,
|
HttpServletRequest theServletRequest,
|
||||||
@OperationParam(name="code", min=0, max=1) CodeType theCode,
|
@OperationParam(name="code", min=0, max=1) CodeType theCode,
|
||||||
@OperationParam(name="system", min=0, max=1) UriType theSystem,
|
@OperationParam(name="system", min=0, max=1) UriType theSystem,
|
||||||
@OperationParam(name="coding", min=0, max=1) Coding theCoding,
|
@OperationParam(name="coding", min=0, max=1) Coding theCoding,
|
||||||
RequestDetails theRequestDetails
|
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties,
|
||||||
|
RequestDetails theRequestDetails
|
||||||
) {
|
) {
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
startRequest(theServletRequest);
|
startRequest(theServletRequest);
|
||||||
try {
|
try {
|
||||||
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
|
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
|
||||||
LookupCodeResult result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails);
|
LookupCodeResult result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails);
|
||||||
result.throwNotFoundIfAppropriate();
|
result.throwNotFoundIfAppropriate();
|
||||||
org.hl7.fhir.r4.model.Parameters parametersR4 = result.toParameters();
|
org.hl7.fhir.r4.model.Parameters parametersR4 = result.toParameters(theProperties);
|
||||||
return VersionConvertor_30_40.convertParameters(parametersR4);
|
return VersionConvertor_30_40.convertParameters(parametersR4);
|
||||||
} catch (FHIRException e) {
|
} catch (FHIRException e) {
|
||||||
throw new InternalErrorException(e);
|
throw new InternalErrorException(e);
|
||||||
|
|
|
@ -20,22 +20,18 @@ package ca.uhn.fhir.jpa.provider.r4;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.hl7.fhir.r4.model.*;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem.LookupCodeResult;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem.LookupCodeResult;
|
||||||
import ca.uhn.fhir.rest.annotation.Operation;
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import org.hl7.fhir.r4.model.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4<CodeSystem> {
|
public class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4<CodeSystem> {
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Operation(name = "$lookup", idempotent = true, returnParameters= {
|
@Operation(name = "$lookup", idempotent = true, returnParameters= {
|
||||||
@OperationParam(name="name", type=StringType.class, min=1),
|
@OperationParam(name="name", type=StringType.class, min=1),
|
||||||
|
@ -47,17 +43,17 @@ public class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4<C
|
||||||
HttpServletRequest theServletRequest,
|
HttpServletRequest theServletRequest,
|
||||||
@OperationParam(name="code", min=0, max=1) CodeType theCode,
|
@OperationParam(name="code", min=0, max=1) CodeType theCode,
|
||||||
@OperationParam(name="system", min=0, max=1) UriType theSystem,
|
@OperationParam(name="system", min=0, max=1) UriType theSystem,
|
||||||
@OperationParam(name="coding", min=0, max=1) Coding theCoding,
|
@OperationParam(name="coding", min=0, max=1) Coding theCoding,
|
||||||
RequestDetails theRequestDetails
|
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties,
|
||||||
|
RequestDetails theRequestDetails
|
||||||
) {
|
) {
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
startRequest(theServletRequest);
|
startRequest(theServletRequest);
|
||||||
try {
|
try {
|
||||||
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
|
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
|
||||||
LookupCodeResult result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails);
|
LookupCodeResult result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails);
|
||||||
result.throwNotFoundIfAppropriate();
|
result.throwNotFoundIfAppropriate();
|
||||||
return result.toParameters();
|
return result.toParameters(theProperties);
|
||||||
} finally {
|
} finally {
|
||||||
endRequest(theServletRequest);
|
endRequest(theServletRequest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,6 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// bool.must(qb.keyword().onField("myProperties").matching(nextFilter.getStringProperty()+"="+nextFilter.getValue()).createQuery());
|
|
||||||
bool.must(qb.phrase().onField("myProperties").sentence(nextFilter.getProperty() + "=" + nextFilter.getValue()).createQuery());
|
bool.must(qb.phrase().onField("myProperties").sentence(nextFilter.getProperty() + "=" + nextFilter.getValue()).createQuery());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ public class TerminologyLoaderSvcImpl implements IHapiTerminologyLoaderSvc {
|
||||||
public static final String LOINC_ANSWERLIST_FILE = "AnswerList_Beta_1.csv";
|
public static final String LOINC_ANSWERLIST_FILE = "AnswerList_Beta_1.csv";
|
||||||
public static final String LOINC_ANSWERLIST_LINK_FILE = "LoincAnswerListLink_Beta_1.csv";
|
public static final String LOINC_ANSWERLIST_LINK_FILE = "LoincAnswerListLink_Beta_1.csv";
|
||||||
public static final String LOINC_DOCUMENT_ONTOLOGY_FILE = "DocumentOntology.csv";
|
public static final String LOINC_DOCUMENT_ONTOLOGY_FILE = "DocumentOntology.csv";
|
||||||
|
public static final String LOINC_UPLOAD_PROPERTIES_FILE = "loincupload.properties";
|
||||||
public static final String LOINC_FILE = "loinc.csv";
|
public static final String LOINC_FILE = "loinc.csv";
|
||||||
public static final String LOINC_HIERARCHY_FILE = "MULTI-AXIAL_HIERARCHY.CSV";
|
public static final String LOINC_HIERARCHY_FILE = "MULTI-AXIAL_HIERARCHY.CSV";
|
||||||
public static final String LOINC_PART_FILE = "Part_Beta_1.csv";
|
public static final String LOINC_PART_FILE = "Part_Beta_1.csv";
|
||||||
|
@ -173,6 +174,7 @@ public class TerminologyLoaderSvcImpl implements IHapiTerminologyLoaderSvc {
|
||||||
descriptors.verifyMandatoryFilesExist(mandatoryFilenameFragments);
|
descriptors.verifyMandatoryFilesExist(mandatoryFilenameFragments);
|
||||||
|
|
||||||
List<String> optionalFilenameFragments = Arrays.asList(
|
List<String> optionalFilenameFragments = Arrays.asList(
|
||||||
|
LOINC_UPLOAD_PROPERTIES_FILE,
|
||||||
LOINC_ANSWERLIST_FILE,
|
LOINC_ANSWERLIST_FILE,
|
||||||
LOINC_ANSWERLIST_LINK_FILE,
|
LOINC_ANSWERLIST_LINK_FILE,
|
||||||
LOINC_PART_FILE,
|
LOINC_PART_FILE,
|
||||||
|
@ -222,17 +224,37 @@ public class TerminologyLoaderSvcImpl implements IHapiTerminologyLoaderSvc {
|
||||||
throw new InternalErrorException("Failed to load loinc.xml", e);
|
throw new InternalErrorException("Failed to load loinc.xml", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> propertyNames = new HashSet<>();
|
Map<String, CodeSystem.PropertyType> propertyNamesToTypes = new HashMap<>();
|
||||||
for (CodeSystem.PropertyComponent nextProperty : loincCs.getProperty()) {
|
for (CodeSystem.PropertyComponent nextProperty : loincCs.getProperty()) {
|
||||||
if (isNotBlank(nextProperty.getCode())) {
|
String nextPropertyCode = nextProperty.getCode();
|
||||||
propertyNames.add(nextProperty.getCode());
|
CodeSystem.PropertyType nextPropertyType = nextProperty.getType();
|
||||||
|
if (isNotBlank(nextPropertyCode)) {
|
||||||
|
propertyNamesToTypes.put(nextPropertyCode, nextPropertyType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IRecordHandler handler;
|
IRecordHandler handler;
|
||||||
|
|
||||||
|
Properties uploadProperties = new Properties();
|
||||||
|
for (FileDescriptor next : theDescriptors.getUncompressedFileDescriptors()) {
|
||||||
|
if (next.getFilename().endsWith("loincupload.properties")) {
|
||||||
|
try {
|
||||||
|
try (InputStream inputStream = next.getInputStream()) {
|
||||||
|
uploadProperties.load(inputStream);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new InternalErrorException("Failed to read loincupload.properties", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Part file
|
||||||
|
handler = new LoincPartHandler(codeSystemVersion, code2concept);
|
||||||
|
iterateOverZipFile(theDescriptors, LOINC_PART_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
Map<PartTypeAndPartName, String> partTypeAndPartNameToPartNumber = ((LoincPartHandler) handler).getPartTypeAndPartNameToPartNumber();
|
||||||
|
|
||||||
// Loinc Codes
|
// Loinc Codes
|
||||||
handler = new LoincHandler(codeSystemVersion, code2concept, propertyNames);
|
handler = new LoincHandler(codeSystemVersion, code2concept, propertyNamesToTypes, partTypeAndPartNameToPartNumber);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Loinc Hierarchy
|
// Loinc Hierarchy
|
||||||
|
@ -240,51 +262,47 @@ public class TerminologyLoaderSvcImpl implements IHapiTerminologyLoaderSvc {
|
||||||
iterateOverZipFile(theDescriptors, LOINC_HIERARCHY_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_HIERARCHY_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Answer lists (ValueSets of potential answers/values for loinc "questions")
|
// Answer lists (ValueSets of potential answers/values for loinc "questions")
|
||||||
handler = new LoincAnswerListHandler(codeSystemVersion, code2concept, propertyNames, valueSets, conceptMaps);
|
handler = new LoincAnswerListHandler(codeSystemVersion, code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_ANSWERLIST_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_ANSWERLIST_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Answer list links (connects loinc observation codes to answerlist codes)
|
// Answer list links (connects loinc observation codes to answerlist codes)
|
||||||
handler = new LoincAnswerListLinkHandler(code2concept, valueSets);
|
handler = new LoincAnswerListLinkHandler(code2concept, valueSets);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_ANSWERLIST_LINK_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_ANSWERLIST_LINK_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Part file
|
|
||||||
handler = new LoincPartHandler(codeSystemVersion, code2concept);
|
|
||||||
iterateOverZipFile(theDescriptors, LOINC_PART_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
|
||||||
|
|
||||||
// Part link file
|
// Part link file
|
||||||
handler = new LoincPartLinkHandler(codeSystemVersion, code2concept);
|
handler = new LoincPartLinkHandler(codeSystemVersion, code2concept);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_PART_LINK_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_PART_LINK_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Part related code mapping
|
// Part related code mapping
|
||||||
handler = new LoincPartRelatedCodeMappingHandler(codeSystemVersion, code2concept, valueSets, conceptMaps);
|
handler = new LoincPartRelatedCodeMappingHandler(codeSystemVersion, code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_PART_RELATED_CODE_MAPPING_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_PART_RELATED_CODE_MAPPING_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Document Ontology File
|
// Document Ontology File
|
||||||
handler = new LoincDocumentOntologyHandler(codeSystemVersion, code2concept, propertyNames, valueSets, conceptMaps);
|
handler = new LoincDocumentOntologyHandler(code2concept, propertyNamesToTypes, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_DOCUMENT_ONTOLOGY_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_DOCUMENT_ONTOLOGY_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// RSNA Playbook file
|
// RSNA Playbook file
|
||||||
handler = new LoincRsnaPlaybookHandler(codeSystemVersion, code2concept, propertyNames, valueSets, conceptMaps);
|
handler = new LoincRsnaPlaybookHandler(code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_RSNA_PLAYBOOK_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_RSNA_PLAYBOOK_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Top 2000 Codes - US
|
// Top 2000 Codes - US
|
||||||
handler = new LoincTop2000LabResultsUsHandler(code2concept, valueSets, conceptMaps);
|
handler = new LoincTop2000LabResultsUsHandler(code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_TOP2000_COMMON_LAB_RESULTS_US_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_TOP2000_COMMON_LAB_RESULTS_US_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Top 2000 Codes - SI
|
// Top 2000 Codes - SI
|
||||||
handler = new LoincTop2000LabResultsSiHandler(code2concept, valueSets, conceptMaps);
|
handler = new LoincTop2000LabResultsSiHandler(code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Universal Lab Order ValueSet
|
// Universal Lab Order ValueSet
|
||||||
handler = new LoincUniversalOrderSetHandler(code2concept, valueSets, conceptMaps);
|
handler = new LoincUniversalOrderSetHandler(code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_UNIVERSAL_LAB_ORDER_VALUESET_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_UNIVERSAL_LAB_ORDER_VALUESET_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// IEEE Medical Device Codes
|
// IEEE Medical Device Codes
|
||||||
handler = new LoincIeeeMedicalDeviceCodeHandler(code2concept, valueSets, conceptMaps);
|
handler = new LoincIeeeMedicalDeviceCodeHandler(code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_CSV, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_CSV, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
// Imaging Document Codes
|
// Imaging Document Codes
|
||||||
handler = new LoincImagingDocumentCodeHandler(code2concept, valueSets, conceptMaps);
|
handler = new LoincImagingDocumentCodeHandler(code2concept, valueSets, conceptMaps, uploadProperties);
|
||||||
iterateOverZipFile(theDescriptors, LOINC_IMAGING_DOCUMENT_CODES_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
iterateOverZipFile(theDescriptors, LOINC_IMAGING_DOCUMENT_CODES_FILE, handler, ',', QuoteMode.NON_NUMERIC);
|
||||||
|
|
||||||
IOUtils.closeQuietly(theDescriptors);
|
IOUtils.closeQuietly(theDescriptors);
|
||||||
|
@ -367,8 +385,8 @@ public class TerminologyLoaderSvcImpl implements IHapiTerminologyLoaderSvc {
|
||||||
private void storeCodeSystem(RequestDetails theRequestDetails, final TermCodeSystemVersion theCodeSystemVersion, CodeSystem theCodeSystem, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
private void storeCodeSystem(RequestDetails theRequestDetails, final TermCodeSystemVersion theCodeSystemVersion, CodeSystem theCodeSystem, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
||||||
Validate.isTrue(theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.NOTPRESENT);
|
Validate.isTrue(theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.NOTPRESENT);
|
||||||
|
|
||||||
List<ValueSet> valueSets = ObjectUtils.defaultIfNull(theValueSets, Collections.<ValueSet>emptyList());
|
List<ValueSet> valueSets = ObjectUtils.defaultIfNull(theValueSets, Collections.emptyList());
|
||||||
List<ConceptMap> conceptMaps = ObjectUtils.defaultIfNull(theConceptMaps, Collections.<ConceptMap>emptyList());
|
List<ConceptMap> conceptMaps = ObjectUtils.defaultIfNull(theConceptMaps, Collections.emptyList());
|
||||||
|
|
||||||
myTermSvc.setProcessDeferred(false);
|
myTermSvc.setProcessDeferred(false);
|
||||||
if (myTermSvcDstu3 != null) {
|
if (myTermSvcDstu3 != null) {
|
||||||
|
|
|
@ -30,21 +30,31 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
abstract class BaseHandler implements IRecordHandler {
|
public abstract class BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
|
public static final String LOINC_COPYRIGHT_STATEMENT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/";
|
||||||
|
/**
|
||||||
|
* This is <b>NOT</b> the LOINC CodeSystem URI! It is just
|
||||||
|
* the website URL to LOINC.
|
||||||
|
*/
|
||||||
|
public static final String LOINC_WEBSITE_URL = "https://loinc.org";
|
||||||
|
public static final String REGENSTRIEF_INSTITUTE_INC = "Regenstrief Institute, Inc.";
|
||||||
private final List<ConceptMap> myConceptMaps;
|
private final List<ConceptMap> myConceptMaps;
|
||||||
private final Map<String, ConceptMap> myIdToConceptMaps = new HashMap<>();
|
private final Map<String, ConceptMap> myIdToConceptMaps = new HashMap<>();
|
||||||
private final List<ValueSet> myValueSets;
|
private final List<ValueSet> myValueSets;
|
||||||
private final Map<String, ValueSet> myIdToValueSet = new HashMap<>();
|
private final Map<String, ValueSet> myIdToValueSet = new HashMap<>();
|
||||||
private final Map<String, TermConcept> myCode2Concept;
|
private final Map<String, TermConcept> myCode2Concept;
|
||||||
|
private final Properties myUploadProperties;
|
||||||
|
|
||||||
BaseHandler(Map<String, TermConcept> theCode2Concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
BaseLoincHandler(Map<String, TermConcept> theCode2Concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
myValueSets = theValueSets;
|
myValueSets = theValueSets;
|
||||||
myCode2Concept = theCode2Concept;
|
myCode2Concept = theCode2Concept;
|
||||||
myConceptMaps = theConceptMaps;
|
myConceptMaps = theConceptMaps;
|
||||||
|
myUploadProperties = theUploadProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addCodeAsIncludeToValueSet(ValueSet theVs, String theCodeSystemUrl, String theCode, String theDisplayName) {
|
void addCodeAsIncludeToValueSet(ValueSet theVs, String theCodeSystemUrl, String theCode, String theDisplayName) {
|
||||||
|
@ -100,20 +110,25 @@ abstract class BaseHandler implements IRecordHandler {
|
||||||
conceptMap.setId(theMapping.getConceptMapId());
|
conceptMap.setId(theMapping.getConceptMapId());
|
||||||
conceptMap.setUrl(theMapping.getConceptMapUri());
|
conceptMap.setUrl(theMapping.getConceptMapUri());
|
||||||
conceptMap.setName(theMapping.getConceptMapName());
|
conceptMap.setName(theMapping.getConceptMapName());
|
||||||
conceptMap.setPublisher("Regentrief Institute, Inc.");
|
conceptMap.setVersion(myUploadProperties.getProperty("conceptmap.version"));
|
||||||
|
conceptMap.setPublisher(REGENSTRIEF_INSTITUTE_INC);
|
||||||
conceptMap.addContact()
|
conceptMap.addContact()
|
||||||
.setName("Regentrief Institute, Inc.")
|
.setName(REGENSTRIEF_INSTITUTE_INC)
|
||||||
.addTelecom()
|
.addTelecom()
|
||||||
.setSystem(ContactPoint.ContactPointSystem.URL)
|
.setSystem(ContactPoint.ContactPointSystem.URL)
|
||||||
.setValue("https://loinc.org");
|
.setValue(LOINC_WEBSITE_URL);
|
||||||
conceptMap.setCopyright(theCopyright);
|
String copyright = theCopyright;
|
||||||
|
if (!copyright.contains("LOINC")) {
|
||||||
|
copyright = LOINC_COPYRIGHT_STATEMENT + ". " + copyright;
|
||||||
|
}
|
||||||
|
conceptMap.setCopyright(copyright);
|
||||||
myIdToConceptMaps.put(theMapping.getConceptMapId(), conceptMap);
|
myIdToConceptMaps.put(theMapping.getConceptMapId(), conceptMap);
|
||||||
myConceptMaps.add(conceptMap);
|
myConceptMaps.add(conceptMap);
|
||||||
} else {
|
} else {
|
||||||
conceptMap = myIdToConceptMaps.get(theMapping.getConceptMapId());
|
conceptMap = myIdToConceptMaps.get(theMapping.getConceptMapId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNotBlank(theMapping.getCopyright())) {
|
if (isBlank(theMapping.getCopyright())) {
|
||||||
conceptMap.setCopyright(theMapping.getCopyright());
|
conceptMap.setCopyright(theMapping.getCopyright());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,21 +179,28 @@ abstract class BaseHandler implements IRecordHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueSet getValueSet(String theValueSetId, String theValueSetUri, String theValueSetName) {
|
ValueSet getValueSet(String theValueSetId, String theValueSetUri, String theValueSetName, String theVersionPropertyName) {
|
||||||
|
|
||||||
|
String version = null;
|
||||||
|
if (isNotBlank(theVersionPropertyName)) {
|
||||||
|
version = myUploadProperties.getProperty(theVersionPropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
ValueSet vs;
|
ValueSet vs;
|
||||||
if (!myIdToValueSet.containsKey(theValueSetId)) {
|
if (!myIdToValueSet.containsKey(theValueSetId)) {
|
||||||
vs = new ValueSet();
|
vs = new ValueSet();
|
||||||
vs.setUrl(theValueSetUri);
|
vs.setUrl(theValueSetUri);
|
||||||
vs.setId(theValueSetId);
|
vs.setId(theValueSetId);
|
||||||
|
vs.setVersion(version);
|
||||||
vs.setName(theValueSetName);
|
vs.setName(theValueSetName);
|
||||||
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
vs.setPublisher("Regenstrief Institute, Inc.");
|
vs.setPublisher(REGENSTRIEF_INSTITUTE_INC);
|
||||||
vs.addContact()
|
vs.addContact()
|
||||||
.setName("Regenstrief Institute, Inc.")
|
.setName(REGENSTRIEF_INSTITUTE_INC)
|
||||||
.addTelecom()
|
.addTelecom()
|
||||||
.setSystem(ContactPoint.ContactPointSystem.URL)
|
.setSystem(ContactPoint.ContactPointSystem.URL)
|
||||||
.setValue("https://loinc.org");
|
.setValue(LOINC_WEBSITE_URL);
|
||||||
vs.setCopyright("This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/");
|
vs.setCopyright(LOINC_COPYRIGHT_STATEMENT);
|
||||||
myIdToValueSet.put(theValueSetId, vs);
|
myIdToValueSet.put(theValueSetId, vs);
|
||||||
myValueSets.add(vs);
|
myValueSets.add(vs);
|
||||||
} else {
|
} else {
|
|
@ -29,17 +29,18 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class BaseLoincTop2000LabResultsHandler extends BaseHandler implements IRecordHandler {
|
public class BaseLoincTop2000LabResultsHandler extends BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
private String myValueSetId;
|
private String myValueSetId;
|
||||||
private String myValueSetUri;
|
private String myValueSetUri;
|
||||||
private String myValueSetName;
|
private String myValueSetName;
|
||||||
|
|
||||||
public BaseLoincTop2000LabResultsHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, String theValueSetId, String theValueSetUri, String theValueSetName, List<ConceptMap> theConceptMaps) {
|
public BaseLoincTop2000LabResultsHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, String theValueSetId, String theValueSetUri, String theValueSetName, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
myValueSetId = theValueSetId;
|
myValueSetId = theValueSetId;
|
||||||
myValueSetUri = theValueSetUri;
|
myValueSetUri = theValueSetUri;
|
||||||
myValueSetName = theValueSetName;
|
myValueSetName = theValueSetName;
|
||||||
|
@ -50,7 +51,7 @@ public class BaseLoincTop2000LabResultsHandler extends BaseHandler implements IR
|
||||||
String loincNumber = trim(theRecord.get("LOINC #"));
|
String loincNumber = trim(theRecord.get("LOINC #"));
|
||||||
String displayName = trim(theRecord.get("Long Common Name"));
|
String displayName = trim(theRecord.get("Long Common Name"));
|
||||||
|
|
||||||
ValueSet valueSet = getValueSet(myValueSetId, myValueSetUri, myValueSetName);
|
ValueSet valueSet = getValueSet(myValueSetId, myValueSetUri, myValueSetName, null);
|
||||||
addCodeAsIncludeToValueSet(valueSet, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, displayName);
|
addCodeAsIncludeToValueSet(valueSet, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -27,27 +27,21 @@ import org.apache.commons.csv.CSVRecord;
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
public class LoincAnswerListHandler extends BaseHandler {
|
public class LoincAnswerListHandler extends BaseLoincHandler {
|
||||||
|
|
||||||
private final Map<String, TermConcept> myCode2Concept;
|
private final Map<String, TermConcept> myCode2Concept;
|
||||||
private final TermCodeSystemVersion myCodeSystemVersion;
|
private final TermCodeSystemVersion myCodeSystemVersion;
|
||||||
private final Set<String> myPropertyNames;
|
|
||||||
private final List<ValueSet> myValueSets;
|
|
||||||
private final Map<String, ValueSet> myIdToValueSet = new HashMap<>();
|
|
||||||
|
|
||||||
public LoincAnswerListHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, Set<String> thePropertyNames, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincAnswerListHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
myCodeSystemVersion = theCodeSystemVersion;
|
myCodeSystemVersion = theCodeSystemVersion;
|
||||||
myCode2Concept = theCode2concept;
|
myCode2Concept = theCode2concept;
|
||||||
myPropertyNames = thePropertyNames;
|
|
||||||
myValueSets = theValueSets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -91,11 +85,11 @@ public class LoincAnswerListHandler extends BaseHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Answer list ValueSet
|
// Answer list ValueSet
|
||||||
ValueSet vs = getValueSet(answerListId, "urn:oid:" + answerListOid, answerListName);
|
ValueSet vs = getValueSet(answerListId, "http://loinc.org/vs/" + answerListId, answerListName, "answerlist.version");
|
||||||
if (vs.getIdentifier().isEmpty()) {
|
if (vs.getIdentifier().isEmpty()) {
|
||||||
vs.addIdentifier()
|
vs.addIdentifier()
|
||||||
.setSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
.setSystem("urn:ietf:rfc:3986")
|
||||||
.setValue(answerListId);
|
.setValue("urn:oid:" + answerListOid);
|
||||||
}
|
}
|
||||||
|
|
||||||
vs
|
vs
|
||||||
|
|
|
@ -20,33 +20,31 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
|
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
|
||||||
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import org.apache.commons.csv.CSVRecord;
|
import org.apache.commons.csv.CSVRecord;
|
||||||
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class LoincDocumentOntologyHandler extends BaseHandler implements IRecordHandler {
|
public class LoincDocumentOntologyHandler extends BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
public static final String DOCUMENT_ONTOLOGY_CODES_VS_ID = "loinc-document-ontology";
|
public static final String DOCUMENT_ONTOLOGY_CODES_VS_ID = "loinc-document-ontology";
|
||||||
public static final String DOCUMENT_ONTOLOGY_CODES_VS_URI = "http://loinc.org/vs/loinc-document-ontology";
|
public static final String DOCUMENT_ONTOLOGY_CODES_VS_URI = "http://loinc.org/vs/loinc-document-ontology";
|
||||||
public static final String DOCUMENT_ONTOLOGY_CODES_VS_NAME = "LOINC Document Ontology Codes";
|
public static final String DOCUMENT_ONTOLOGY_CODES_VS_NAME = "LOINC Document Ontology Codes";
|
||||||
private final Map<String, TermConcept> myCode2Concept;
|
private final Map<String, TermConcept> myCode2Concept;
|
||||||
private final TermCodeSystemVersion myCodeSystemVersion;
|
|
||||||
private final Set<String> myPropertyNames;
|
|
||||||
|
|
||||||
public LoincDocumentOntologyHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, Set<String> thePropertyNames, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincDocumentOntologyHandler(Map<String, TermConcept> theCode2concept, Map<String, CodeSystem.PropertyType> thePropertyNames, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
myCodeSystemVersion = theCodeSystemVersion;
|
|
||||||
myCode2Concept = theCode2concept;
|
myCode2Concept = theCode2concept;
|
||||||
myPropertyNames = thePropertyNames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,7 +57,7 @@ public class LoincDocumentOntologyHandler extends BaseHandler implements IRecord
|
||||||
String partName = trim(theRecord.get("PartName"));
|
String partName = trim(theRecord.get("PartName"));
|
||||||
|
|
||||||
// RSNA Codes VS
|
// RSNA Codes VS
|
||||||
ValueSet vs = getValueSet(DOCUMENT_ONTOLOGY_CODES_VS_ID, DOCUMENT_ONTOLOGY_CODES_VS_URI, DOCUMENT_ONTOLOGY_CODES_VS_NAME);
|
ValueSet vs = getValueSet(DOCUMENT_ONTOLOGY_CODES_VS_ID, DOCUMENT_ONTOLOGY_CODES_VS_URI, DOCUMENT_ONTOLOGY_CODES_VS_NAME, null);
|
||||||
addCodeAsIncludeToValueSet(vs, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, null);
|
addCodeAsIncludeToValueSet(vs, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, null);
|
||||||
|
|
||||||
// Part Properties
|
// Part Properties
|
||||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -22,13 +22,17 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
|
||||||
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
||||||
import ca.uhn.fhir.jpa.term.TerminologyLoaderSvcImpl;
|
import ca.uhn.fhir.jpa.term.TerminologyLoaderSvcImpl;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import org.apache.commons.csv.CSVRecord;
|
import org.apache.commons.csv.CSVRecord;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
@ -37,12 +41,14 @@ public class LoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
private final Map<String, TermConcept> myCode2Concept;
|
private final Map<String, TermConcept> myCode2Concept;
|
||||||
private final TermCodeSystemVersion myCodeSystemVersion;
|
private final TermCodeSystemVersion myCodeSystemVersion;
|
||||||
private final Set<String> myPropertyNames;
|
private final Map<String, CodeSystem.PropertyType> myPropertyNames;
|
||||||
|
private final Map<PartTypeAndPartName, String> myPartTypeAndPartNameToPartNumber;
|
||||||
|
|
||||||
public LoincHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, Set<String> thePropertyNames) {
|
public LoincHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, Map<String, CodeSystem.PropertyType> thePropertyNames, Map<PartTypeAndPartName, String> thePartTypeAndPartNameToPartNumber) {
|
||||||
myCodeSystemVersion = theCodeSystemVersion;
|
myCodeSystemVersion = theCodeSystemVersion;
|
||||||
myCode2Concept = theCode2concept;
|
myCode2Concept = theCode2concept;
|
||||||
myPropertyNames = thePropertyNames;
|
myPropertyNames = thePropertyNames;
|
||||||
|
myPartTypeAndPartNameToPartNumber = thePartTypeAndPartNameToPartNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,13 +70,57 @@ public class LoincHandler implements IRecordHandler {
|
||||||
.setValue(shortName);
|
.setValue(shortName);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String nextPropertyName : myPropertyNames) {
|
for (String nextPropertyName : myPropertyNames.keySet()) {
|
||||||
if (!theRecord.toMap().containsKey(nextPropertyName)) {
|
if (!theRecord.toMap().containsKey(nextPropertyName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeSystem.PropertyType nextPropertyType = myPropertyNames.get(nextPropertyName);
|
||||||
|
|
||||||
String nextPropertyValue = theRecord.get(nextPropertyName);
|
String nextPropertyValue = theRecord.get(nextPropertyName);
|
||||||
if (isNotBlank(nextPropertyValue)) {
|
if (isNotBlank(nextPropertyValue)) {
|
||||||
concept.addPropertyString(nextPropertyName, nextPropertyValue);
|
nextPropertyValue = trim(nextPropertyValue);
|
||||||
|
|
||||||
|
switch (nextPropertyType) {
|
||||||
|
case STRING:
|
||||||
|
concept.addPropertyString(nextPropertyName, nextPropertyValue);
|
||||||
|
break;
|
||||||
|
case CODING:
|
||||||
|
PartTypeAndPartName key = new PartTypeAndPartName(nextPropertyName, nextPropertyValue);
|
||||||
|
String partNumber = myPartTypeAndPartNameToPartNumber.get(key);
|
||||||
|
|
||||||
|
if (partNumber == null && nextPropertyName.equals("TIME_ASPCT")) {
|
||||||
|
key = new PartTypeAndPartName("TIME", nextPropertyValue);
|
||||||
|
partNumber = myPartTypeAndPartNameToPartNumber.get(key);
|
||||||
|
}
|
||||||
|
if (partNumber == null && nextPropertyName.equals("METHOD_TYP")) {
|
||||||
|
key = new PartTypeAndPartName("METHOD", nextPropertyValue);
|
||||||
|
partNumber = myPartTypeAndPartNameToPartNumber.get(key);
|
||||||
|
}
|
||||||
|
if (partNumber == null && nextPropertyName.equals("SCALE_TYP")) {
|
||||||
|
key = new PartTypeAndPartName("SCALE", nextPropertyValue);
|
||||||
|
partNumber = myPartTypeAndPartNameToPartNumber.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partNumber == null && nextPropertyName.equals("SYSTEM") && nextPropertyValue.startsWith("^")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate.notBlank(partNumber, "Unknown part: " + key);
|
||||||
|
if (isNotBlank(partNumber)) {
|
||||||
|
concept.addPropertyCoding(nextPropertyName, IHapiTerminologyLoaderSvc.LOINC_URI, partNumber, nextPropertyValue);
|
||||||
|
} else {
|
||||||
|
ourLog.warn("Unable to find part code with TYPE[{}] and NAME[{}]", key.getPartType(), key.getPartName());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CODE:
|
||||||
|
case INTEGER:
|
||||||
|
case BOOLEAN:
|
||||||
|
case DATETIME:
|
||||||
|
case NULL:
|
||||||
|
throw new InternalErrorException("Don't know how to handle LOINC property of type: " + nextPropertyType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,5 +128,5 @@ public class LoincHandler implements IRecordHandler {
|
||||||
myCode2Concept.put(code, concept);
|
myCode2Concept.put(code, concept);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(LoincHandler.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,11 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class LoincIeeeMedicalDeviceCodeHandler extends BaseHandler implements IRecordHandler {
|
public class LoincIeeeMedicalDeviceCodeHandler extends BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
public static final String LOINC_IEEE_CM_ID = "LOINC-IEEE-MEDICAL-DEVICE-CM";
|
public static final String LOINC_IEEE_CM_ID = "LOINC-IEEE-MEDICAL-DEVICE-CM";
|
||||||
public static final String LOINC_IEEE_CM_URI = "http://loinc.org/fhir/loinc-ieee-device-code-mappings";
|
public static final String LOINC_IEEE_CM_URI = "http://loinc.org/fhir/loinc-ieee-device-code-mappings";
|
||||||
|
@ -43,8 +44,8 @@ public class LoincIeeeMedicalDeviceCodeHandler extends BaseHandler implements IR
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public LoincIeeeMedicalDeviceCodeHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincIeeeMedicalDeviceCodeHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -29,17 +29,18 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class LoincImagingDocumentCodeHandler extends BaseHandler implements IRecordHandler {
|
public class LoincImagingDocumentCodeHandler extends BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
public static final String VS_ID = "loinc-imaging-document-codes";
|
public static final String VS_ID = "loinc-imaging-document-codes";
|
||||||
public static final String VS_URI = "http://loinc.org/fhir/loinc-imaging-document-codes";
|
public static final String VS_URI = "http://loinc.org/fhir/loinc-imaging-document-codes";
|
||||||
public static final String VS_NAME = "LOINC Imaging Document Codes";
|
public static final String VS_NAME = "LOINC Imaging Document Codes";
|
||||||
|
|
||||||
public LoincImagingDocumentCodeHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincImagingDocumentCodeHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +48,7 @@ public class LoincImagingDocumentCodeHandler extends BaseHandler implements IRec
|
||||||
String loincNumber = trim(theRecord.get("LOINC_NUM"));
|
String loincNumber = trim(theRecord.get("LOINC_NUM"));
|
||||||
String displayName = trim(theRecord.get("LONG_COMMON_NAME"));
|
String displayName = trim(theRecord.get("LONG_COMMON_NAME"));
|
||||||
|
|
||||||
ValueSet valueSet = getValueSet(VS_ID, VS_URI, VS_NAME);
|
ValueSet valueSet = getValueSet(VS_ID, VS_URI, VS_NAME,null);
|
||||||
addCodeAsIncludeToValueSet(valueSet, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, displayName);
|
addCodeAsIncludeToValueSet(valueSet, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
||||||
import org.apache.commons.csv.CSVRecord;
|
import org.apache.commons.csv.CSVRecord;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -37,6 +38,7 @@ public class LoincPartHandler implements IRecordHandler {
|
||||||
private final Map<String, TermConcept> myCode2Concept;
|
private final Map<String, TermConcept> myCode2Concept;
|
||||||
private final TermCodeSystemVersion myCodeSystemVersion;
|
private final TermCodeSystemVersion myCodeSystemVersion;
|
||||||
private final Map<String, ValueSet> myIdToValueSet = new HashMap<>();
|
private final Map<String, ValueSet> myIdToValueSet = new HashMap<>();
|
||||||
|
private final Map<PartTypeAndPartName, String> myPartTypeAndPartNameToPartNumber = new HashMap<>();
|
||||||
|
|
||||||
public LoincPartHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept) {
|
public LoincPartHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept) {
|
||||||
myCodeSystemVersion = theCodeSystemVersion;
|
myCodeSystemVersion = theCodeSystemVersion;
|
||||||
|
@ -58,13 +60,17 @@ public class LoincPartHandler implements IRecordHandler {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
PartTypeAndPartName partTypeAndPartName = new PartTypeAndPartName(partTypeName, partName);
|
||||||
|
String previousValue = myPartTypeAndPartNameToPartNumber.put(partTypeAndPartName, partNumber);
|
||||||
|
Validate.isTrue(previousValue == null, "Already had part: " + partTypeAndPartName);
|
||||||
|
|
||||||
TermConcept concept = myCode2Concept.get(partNumber);
|
TermConcept concept = myCode2Concept.get(partNumber);
|
||||||
if (concept == null) {
|
if (concept == null) {
|
||||||
concept = new TermConcept(myCodeSystemVersion, partNumber);
|
concept = new TermConcept(myCodeSystemVersion, partNumber);
|
||||||
concept.setDisplay(partName);
|
concept.setDisplay(partName);
|
||||||
myCode2Concept.put(partNumber, concept);
|
myCode2Concept.put(partNumber, concept);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNotBlank(partDisplayName)) {
|
if (isNotBlank(partDisplayName)) {
|
||||||
concept.addDesignation()
|
concept.addDesignation()
|
||||||
.setConcept(concept)
|
.setConcept(concept)
|
||||||
|
@ -74,4 +80,9 @@ public class LoincPartHandler implements IRecordHandler {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<PartTypeAndPartName, String> getPartTypeAndPartNameToPartNumber() {
|
||||||
|
return myPartTypeAndPartNameToPartNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -32,22 +32,23 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class LoincPartRelatedCodeMappingHandler extends BaseHandler implements IRecordHandler {
|
public class LoincPartRelatedCodeMappingHandler extends BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
public static final String LOINC_PART_MAP_ID = "LOINC-PART-MAP";
|
public static final String LOINC_SCT_PART_MAP_ID = "loinc-parts-to-snomed-ct";
|
||||||
public static final String LOINC_PART_MAP_URI = "http://loinc.org/cm/loinc-parts-to-snomed-ct";
|
public static final String LOINC_SCT_PART_MAP_URI = "http://loinc.org/cm/loinc-parts-to-snomed-ct";
|
||||||
public static final String LOINC_PART_MAP_NAME = "LOINC Part Map";
|
public static final String LOINC_SCT_PART_MAP_NAME = "LOINC Part Map to SNOMED CT";
|
||||||
private static final String CM_COPYRIGHT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC Part File, LOINC/SNOMED CT Expression Association and Map Sets File, RELMA database and associated search index files include SNOMED Clinical Terms (SNOMED CT®) which is used by permission of the International Health Terminology Standards Development Organisation (IHTSDO) under license. All rights are reserved. SNOMED CT® was originally created by The College of American Pathologists. “SNOMED” and “SNOMED CT” are registered trademarks of the IHTSDO. Use of SNOMED CT content is subject to the terms and conditions set forth in the SNOMED CT Affiliate License Agreement. It is the responsibility of those implementing this product to ensure they are appropriately licensed and for more information on the license, including how to register as an Affiliate Licensee, please refer to http://www.snomed.org/snomed-ct/get-snomed-ct or info@snomed.org. Under the terms of the Affiliate License, use of SNOMED CT in countries that are not IHTSDO Members is subject to reporting and fee payment obligations. However, IHTSDO agrees to waive the requirements to report and pay fees for use of SNOMED CT content included in the LOINC Part Mapping and LOINC Term Associations for purposes that support or enable more effective use of LOINC. This material includes content from the US Edition to SNOMED CT, which is developed and maintained by the U.S. National Library of Medicine and is available to authorized UMLS Metathesaurus Licensees from the UTS Downloads site at https://uts.nlm.nih.gov.";
|
private static final String CM_COPYRIGHT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC Part File, LOINC/SNOMED CT Expression Association and Map Sets File, RELMA database and associated search index files include SNOMED Clinical Terms (SNOMED CT®) which is used by permission of the International Health Terminology Standards Development Organisation (IHTSDO) under license. All rights are reserved. SNOMED CT® was originally created by The College of American Pathologists. “SNOMED” and “SNOMED CT” are registered trademarks of the IHTSDO. Use of SNOMED CT content is subject to the terms and conditions set forth in the SNOMED CT Affiliate License Agreement. It is the responsibility of those implementing this product to ensure they are appropriately licensed and for more information on the license, including how to register as an Affiliate Licensee, please refer to http://www.snomed.org/snomed-ct/get-snomed-ct or info@snomed.org. Under the terms of the Affiliate License, use of SNOMED CT in countries that are not IHTSDO Members is subject to reporting and fee payment obligations. However, IHTSDO agrees to waive the requirements to report and pay fees for use of SNOMED CT content included in the LOINC Part Mapping and LOINC Term Associations for purposes that support or enable more effective use of LOINC. This material includes content from the US Edition to SNOMED CT, which is developed and maintained by the U.S. National Library of Medicine and is available to authorized UMLS Metathesaurus Licensees from the UTS Downloads site at https://uts.nlm.nih.gov.";
|
||||||
private final Map<String, TermConcept> myCode2Concept;
|
private final Map<String, TermConcept> myCode2Concept;
|
||||||
private final TermCodeSystemVersion myCodeSystemVersion;
|
private final TermCodeSystemVersion myCodeSystemVersion;
|
||||||
private final List<ConceptMap> myConceptMaps;
|
private final List<ConceptMap> myConceptMaps;
|
||||||
|
|
||||||
public LoincPartRelatedCodeMappingHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincPartRelatedCodeMappingHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
myCodeSystemVersion = theCodeSystemVersion;
|
myCodeSystemVersion = theCodeSystemVersion;
|
||||||
myCode2Concept = theCode2concept;
|
myCode2Concept = theCode2concept;
|
||||||
myConceptMaps = theConceptMaps;
|
myConceptMaps = theConceptMaps;
|
||||||
|
@ -86,11 +87,24 @@ public class LoincPartRelatedCodeMappingHandler extends BaseHandler implements I
|
||||||
throw new InternalErrorException("Unknown MapType '" + mapType + "' for PartNumber: " + partNumber);
|
throw new InternalErrorException("Unknown MapType '" + mapType + "' for PartNumber: " + partNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String loincPartMapId;
|
||||||
|
String loincPartMapUri;
|
||||||
|
String loincPartMapName;
|
||||||
|
switch (extCodeSystem) {
|
||||||
|
case IHapiTerminologyLoaderSvc.SCT_URI:
|
||||||
|
loincPartMapId = LOINC_SCT_PART_MAP_ID;
|
||||||
|
loincPartMapUri = LOINC_SCT_PART_MAP_URI;
|
||||||
|
loincPartMapName = LOINC_SCT_PART_MAP_NAME;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InternalErrorException("Don't know how to handle mapping to system: " + extCodeSystem);
|
||||||
|
}
|
||||||
|
|
||||||
addConceptMapEntry(
|
addConceptMapEntry(
|
||||||
new ConceptMapping()
|
new ConceptMapping()
|
||||||
.setConceptMapId(LOINC_PART_MAP_ID)
|
.setConceptMapId(loincPartMapId)
|
||||||
.setConceptMapUri(LOINC_PART_MAP_URI)
|
.setConceptMapUri(loincPartMapUri)
|
||||||
.setConceptMapName(LOINC_PART_MAP_NAME)
|
.setConceptMapName(loincPartMapName)
|
||||||
.setSourceCodeSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
.setSourceCodeSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
||||||
.setSourceCode(partNumber)
|
.setSourceCode(partNumber)
|
||||||
.setSourceDisplay(partName)
|
.setSourceDisplay(partName)
|
||||||
|
|
|
@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
|
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
|
||||||
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
import ca.uhn.fhir.jpa.term.IRecordHandler;
|
||||||
|
@ -35,7 +34,7 @@ import java.util.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class LoincRsnaPlaybookHandler extends BaseHandler implements IRecordHandler {
|
public class LoincRsnaPlaybookHandler extends BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
public static final String RSNA_CODES_VS_ID = "loinc-rsna-radiology-playbook";
|
public static final String RSNA_CODES_VS_ID = "loinc-rsna-radiology-playbook";
|
||||||
public static final String RSNA_CODES_VS_URI = "http://loinc.org/vs/loinc-rsna-radiology-playbook";
|
public static final String RSNA_CODES_VS_URI = "http://loinc.org/vs/loinc-rsna-radiology-playbook";
|
||||||
|
@ -59,8 +58,6 @@ public class LoincRsnaPlaybookHandler extends BaseHandler implements IRecordHand
|
||||||
public static final String RPID_CS_URI = RID_CS_URI;
|
public static final String RPID_CS_URI = RID_CS_URI;
|
||||||
private static final String CM_COPYRIGHT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC/RSNA Radiology Playbook and the LOINC Part File contain content from RadLex® (http://rsna.org/RadLex.aspx), copyright © 2005-2017, The Radiological Society of North America, Inc., available at no cost under the license at http://www.rsna.org/uploadedFiles/RSNA/Content/Informatics/RadLex_License_Agreement_and_Terms_of_Use_V2_Final.pdf.";
|
private static final String CM_COPYRIGHT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC/RSNA Radiology Playbook and the LOINC Part File contain content from RadLex® (http://rsna.org/RadLex.aspx), copyright © 2005-2017, The Radiological Society of North America, Inc., available at no cost under the license at http://www.rsna.org/uploadedFiles/RSNA/Content/Informatics/RadLex_License_Agreement_and_Terms_of_Use_V2_Final.pdf.";
|
||||||
private final Map<String, TermConcept> myCode2Concept;
|
private final Map<String, TermConcept> myCode2Concept;
|
||||||
private final TermCodeSystemVersion myCodeSystemVersion;
|
|
||||||
private final Set<String> myPropertyNames;
|
|
||||||
private final List<ValueSet> myValueSets;
|
private final List<ValueSet> myValueSets;
|
||||||
private final Map<String, ValueSet> myIdToValueSet = new HashMap<>();
|
private final Map<String, ValueSet> myIdToValueSet = new HashMap<>();
|
||||||
private final Set<String> myCodesInRsnaPlaybookValueSet = new HashSet<>();
|
private final Set<String> myCodesInRsnaPlaybookValueSet = new HashSet<>();
|
||||||
|
@ -68,11 +65,9 @@ public class LoincRsnaPlaybookHandler extends BaseHandler implements IRecordHand
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public LoincRsnaPlaybookHandler(TermCodeSystemVersion theCodeSystemVersion, Map<String, TermConcept> theCode2concept, Set<String> thePropertyNames, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincRsnaPlaybookHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
myCodeSystemVersion = theCodeSystemVersion;
|
|
||||||
myCode2Concept = theCode2concept;
|
myCode2Concept = theCode2concept;
|
||||||
myPropertyNames = thePropertyNames;
|
|
||||||
myValueSets = theValueSets;
|
myValueSets = theValueSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
public class LoincTop2000LabResultsSiHandler extends BaseLoincTop2000LabResultsHandler {
|
public class LoincTop2000LabResultsSiHandler extends BaseLoincTop2000LabResultsHandler {
|
||||||
|
|
||||||
|
@ -33,8 +34,8 @@ public class LoincTop2000LabResultsSiHandler extends BaseLoincTop2000LabResultsH
|
||||||
public static final String TOP_2000_SI_VS_URI = "http://loinc.org/vs/top-2000-lab-observations-si";
|
public static final String TOP_2000_SI_VS_URI = "http://loinc.org/vs/top-2000-lab-observations-si";
|
||||||
public static final String TOP_2000_SI_VS_NAME = "Top 2000 Lab Results SI";
|
public static final String TOP_2000_SI_VS_NAME = "Top 2000 Lab Results SI";
|
||||||
|
|
||||||
public LoincTop2000LabResultsSiHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincTop2000LabResultsSiHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, TOP_2000_SI_VS_ID, TOP_2000_SI_VS_URI, TOP_2000_SI_VS_NAME, theConceptMaps);
|
super(theCode2concept, theValueSets, TOP_2000_SI_VS_ID, TOP_2000_SI_VS_URI, TOP_2000_SI_VS_NAME, theConceptMaps, theUploadProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
public class LoincTop2000LabResultsUsHandler extends BaseLoincTop2000LabResultsHandler {
|
public class LoincTop2000LabResultsUsHandler extends BaseLoincTop2000LabResultsHandler {
|
||||||
|
|
||||||
|
@ -33,8 +34,8 @@ public class LoincTop2000LabResultsUsHandler extends BaseLoincTop2000LabResultsH
|
||||||
public static final String TOP_2000_US_VS_URI = "http://loinc.org/vs/top-2000-lab-observations-us";
|
public static final String TOP_2000_US_VS_URI = "http://loinc.org/vs/top-2000-lab-observations-us";
|
||||||
public static final String TOP_2000_US_VS_NAME = "Top 2000 Lab Results US";
|
public static final String TOP_2000_US_VS_NAME = "Top 2000 Lab Results US";
|
||||||
|
|
||||||
public LoincTop2000LabResultsUsHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincTop2000LabResultsUsHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, TOP_2000_US_VS_ID, TOP_2000_US_VS_URI, TOP_2000_US_VS_NAME, theConceptMaps);
|
super(theCode2concept, theValueSets, TOP_2000_US_VS_ID, TOP_2000_US_VS_URI, TOP_2000_US_VS_NAME, theConceptMaps, theUploadProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,14 @@ import java.util.*;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class LoincUniversalOrderSetHandler extends BaseHandler implements IRecordHandler {
|
public class LoincUniversalOrderSetHandler extends BaseLoincHandler implements IRecordHandler {
|
||||||
|
|
||||||
public static final String VS_ID = "loinc-universal-order-set-vs";
|
public static final String VS_ID = "loinc-universal-order-set-vs";
|
||||||
public static final String VS_URI = "http://loinc.org/fhir/loinc-universal-order-set";
|
public static final String VS_URI = "http://loinc.org/fhir/loinc-universal-order-set";
|
||||||
public static final String VS_NAME = "LOINC Universal Order Set";
|
public static final String VS_NAME = "LOINC Universal Order Set";
|
||||||
|
|
||||||
public LoincUniversalOrderSetHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public LoincUniversalOrderSetHandler(Map<String, TermConcept> theCode2concept, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps, Properties theUploadProperties) {
|
||||||
super(theCode2concept, theValueSets, theConceptMaps);
|
super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +47,7 @@ public class LoincUniversalOrderSetHandler extends BaseHandler implements IRecor
|
||||||
String displayName = trim(theRecord.get("LONG_COMMON_NAME"));
|
String displayName = trim(theRecord.get("LONG_COMMON_NAME"));
|
||||||
String orderObs = trim(theRecord.get("ORDER_OBS"));
|
String orderObs = trim(theRecord.get("ORDER_OBS"));
|
||||||
|
|
||||||
ValueSet valueSet = getValueSet(VS_ID, VS_URI, VS_NAME);
|
ValueSet valueSet = getValueSet(VS_ID, VS_URI, VS_NAME, null);
|
||||||
addCodeAsIncludeToValueSet(valueSet, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, displayName);
|
addCodeAsIncludeToValueSet(valueSet, IHapiTerminologyLoaderSvc.LOINC_URI, loincNumber, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package ca.uhn.fhir.jpa.term.loinc;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
|
||||||
|
public class PartTypeAndPartName {
|
||||||
|
private final String myPartType;
|
||||||
|
private final String myPartName;
|
||||||
|
|
||||||
|
public PartTypeAndPartName(String thePartType, String thePartName) {
|
||||||
|
myPartType = thePartType;
|
||||||
|
myPartName = thePartName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object theO) {
|
||||||
|
if (this == theO) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theO == null || getClass() != theO.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PartTypeAndPartName that = (PartTypeAndPartName) theO;
|
||||||
|
|
||||||
|
return new EqualsBuilder()
|
||||||
|
.append(myPartType, that.myPartType)
|
||||||
|
.append(myPartName, that.myPartName)
|
||||||
|
.isEquals();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPartName() {
|
||||||
|
return myPartName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPartType() {
|
||||||
|
return myPartType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return new HashCodeBuilder(17, 37)
|
||||||
|
.append(myPartType)
|
||||||
|
.append(myPartName)
|
||||||
|
.toHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this)
|
||||||
|
.append("partType", myPartType)
|
||||||
|
.append("partName", myPartName)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,8 +4,10 @@ import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.dao.dstu3.BaseJpaDstu3Test;
|
import ca.uhn.fhir.jpa.dao.dstu3.BaseJpaDstu3Test;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.hl7.fhir.convertors.VersionConvertor_30_40;
|
import org.hl7.fhir.convertors.VersionConvertor_30_40;
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -14,13 +16,14 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test {
|
public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
|
@ -39,8 +42,83 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test {
|
||||||
myDaoConfig.setDeferIndexingForCodesystemsOfSize(20000);
|
myDaoConfig.setDeferIndexingForCodesystemsOfSize(20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T extends Type> Optional<T> findProperty(Parameters theParameters, String thePropertyName) {
|
||||||
|
return theParameters
|
||||||
|
.getParameter()
|
||||||
|
.stream()
|
||||||
|
.filter(t -> t.getName().equals("property"))
|
||||||
|
.filter(t -> ((PrimitiveType<?>) t.getPart().get(0).getValue()).getValueAsString().equals(thePropertyName))
|
||||||
|
.map(t -> (T) t.getPart().get(1).getValue())
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Type> Optional<T> getPropertyPart(Parameters theParameters, String thePropName, String thePart) {
|
||||||
|
return theParameters
|
||||||
|
.getParameter()
|
||||||
|
.stream()
|
||||||
|
.filter(t -> t.getName().equals(thePropName))
|
||||||
|
.flatMap(t -> t.getPart().stream())
|
||||||
|
.filter(t -> t.getName().equals(thePart))
|
||||||
|
.map(t -> (T) t.getValue())
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExpandWithProperty() throws Exception {
|
public void testExpandWithPropertyCoding() throws Exception {
|
||||||
|
ZipCollectionBuilder files = new ZipCollectionBuilder();
|
||||||
|
TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesToZip(files);
|
||||||
|
TerminologyLoaderSvcLoincTest.addLoincOptionalFilesToZip(files);
|
||||||
|
myLoader.loadLoinc(files.getFiles(), mySrd);
|
||||||
|
|
||||||
|
// Search by code
|
||||||
|
ValueSet input = new ValueSet();
|
||||||
|
input
|
||||||
|
.getCompose()
|
||||||
|
.addInclude()
|
||||||
|
.setSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
||||||
|
.addFilter()
|
||||||
|
.setProperty("SCALE_TYP")
|
||||||
|
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||||
|
.setValue("LP7753-9");
|
||||||
|
ValueSet expanded = myValueSetDao.expand(input, null);
|
||||||
|
Set<String> codes = toExpandedCodes(expanded);
|
||||||
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded));
|
||||||
|
ourLog.info("Codes: {}", codes);
|
||||||
|
assertThat(codes, containsInAnyOrder("10019-8", "10013-1", "10014-9", "10016-4", "17788-1", "10000-8", "10017-2", "10015-6", "10020-6", "10018-0"));
|
||||||
|
|
||||||
|
// Search by display name
|
||||||
|
input = new ValueSet();
|
||||||
|
input
|
||||||
|
.getCompose()
|
||||||
|
.addInclude()
|
||||||
|
.setSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
||||||
|
.addFilter()
|
||||||
|
.setProperty("SCALE_TYP")
|
||||||
|
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||||
|
.setValue("Qn");
|
||||||
|
expanded = myValueSetDao.expand(input, null);
|
||||||
|
codes = toExpandedCodes(expanded);
|
||||||
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded));
|
||||||
|
assertThat(codes, containsInAnyOrder("10019-8", "10013-1", "10014-9", "10016-4", "17788-1", "10000-8", "10017-2", "10015-6", "10020-6", "10018-0"));
|
||||||
|
|
||||||
|
// Search by something that doesn't match
|
||||||
|
input = new ValueSet();
|
||||||
|
input
|
||||||
|
.getCompose()
|
||||||
|
.addInclude()
|
||||||
|
.setSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
||||||
|
.addFilter()
|
||||||
|
.setProperty("SCALE_TYP")
|
||||||
|
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||||
|
.setValue("Qn999");
|
||||||
|
expanded = myValueSetDao.expand(input, null);
|
||||||
|
codes = toExpandedCodes(expanded);
|
||||||
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded));
|
||||||
|
assertThat(codes, empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandWithPropertyString() throws Exception {
|
||||||
ZipCollectionBuilder files = new ZipCollectionBuilder();
|
ZipCollectionBuilder files = new ZipCollectionBuilder();
|
||||||
TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesToZip(files);
|
TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesToZip(files);
|
||||||
TerminologyLoaderSvcLoincTest.addLoincOptionalFilesToZip(files);
|
TerminologyLoaderSvcLoincTest.addLoincOptionalFilesToZip(files);
|
||||||
|
@ -52,13 +130,14 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test {
|
||||||
.addInclude()
|
.addInclude()
|
||||||
.setSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
.setSystem(IHapiTerminologyLoaderSvc.LOINC_URI)
|
||||||
.addFilter()
|
.addFilter()
|
||||||
.setProperty("SCALE_TYP")
|
.setProperty("CLASS")
|
||||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||||
.setValue("Ord");
|
.setValue("EKG.MEAS");
|
||||||
ValueSet expanded = myValueSetDao.expand(input, null);
|
ValueSet expanded = myValueSetDao.expand(input, null);
|
||||||
Set<String> codes = toExpandedCodes(expanded);
|
Set<String> codes = toExpandedCodes(expanded);
|
||||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded));
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded));
|
||||||
assertThat(codes, containsInAnyOrder("1001-7", "61438-8"));
|
ourLog.info("Codes: {}", codes);
|
||||||
|
assertThat(codes, containsInAnyOrder("10019-8", "10013-1", "10014-9", "10000-8", "10016-4", "10017-2", "10015-6", "10020-6", "10018-0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -69,25 +148,53 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test {
|
||||||
myLoader.loadLoinc(files.getFiles(), mySrd);
|
myLoader.loadLoinc(files.getFiles(), mySrd);
|
||||||
|
|
||||||
IFhirResourceDaoCodeSystem.LookupCodeResult result = myCodeSystemDao.lookupCode(new StringType("10013-1"), new StringType(IHapiTerminologyLoaderSvc.LOINC_URI), null, mySrd);
|
IFhirResourceDaoCodeSystem.LookupCodeResult result = myCodeSystemDao.lookupCode(new StringType("10013-1"), new StringType(IHapiTerminologyLoaderSvc.LOINC_URI), null, mySrd);
|
||||||
org.hl7.fhir.r4.model.Parameters parametersR4 = result.toParameters();
|
org.hl7.fhir.r4.model.Parameters parametersR4 = result.toParameters(null);
|
||||||
Parameters parameters = VersionConvertor_30_40.convertParameters(parametersR4);
|
Parameters parameters = VersionConvertor_30_40.convertParameters(parametersR4);
|
||||||
|
|
||||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(parameters));
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(parameters));
|
||||||
|
|
||||||
assertEquals("SYSTEM", this.<CodeType>getPropertyPart(parameters, "property", "code").get().getValueAsString());
|
Optional<Coding> propertyValue = findProperty(parameters, "SCALE_TYP");
|
||||||
assertEquals("Heart", this.<StringType>getPropertyPart(parameters, "property", "value").get().getValueAsString());
|
assertTrue(propertyValue.isPresent());
|
||||||
|
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, propertyValue.get().getSystem());
|
||||||
|
assertEquals("LP7753-9", propertyValue.get().getCode());
|
||||||
|
assertEquals("Qn", propertyValue.get().getDisplay());
|
||||||
|
|
||||||
|
propertyValue = findProperty(parameters, "COMPONENT");
|
||||||
|
assertTrue(propertyValue.isPresent());
|
||||||
|
|
||||||
|
Optional<StringType> propertyValueString = findProperty(parameters, "ORDER_OBS");
|
||||||
|
assertTrue(propertyValueString.isPresent());
|
||||||
|
assertEquals("Observation", propertyValueString.get().getValue());
|
||||||
|
|
||||||
|
propertyValueString = findProperty(parameters, "CLASSTYPE");
|
||||||
|
assertTrue(propertyValueString.isPresent());
|
||||||
|
assertEquals("2", propertyValueString.get().getValue());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Type> Optional<T> getPropertyPart(Parameters theParameters, String thePropName, String thePart) {
|
@Test
|
||||||
return theParameters
|
public void testLookupWithPropertiesExplicit() throws Exception {
|
||||||
.getParameter()
|
ZipCollectionBuilder files = new ZipCollectionBuilder();
|
||||||
.stream()
|
TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesToZip(files);
|
||||||
.filter(t -> t.getName().equals(thePropName))
|
TerminologyLoaderSvcLoincTest.addLoincOptionalFilesToZip(files);
|
||||||
.flatMap(t -> t.getPart().stream())
|
myLoader.loadLoinc(files.getFiles(), mySrd);
|
||||||
.filter(t -> t.getName().equals(thePart))
|
|
||||||
.map(t -> (T)t.getValue())
|
IFhirResourceDaoCodeSystem.LookupCodeResult result = myCodeSystemDao.lookupCode(new StringType("10013-1"), new StringType(IHapiTerminologyLoaderSvc.LOINC_URI), null, mySrd);
|
||||||
.findFirst();
|
List<? extends IPrimitiveType<String>> properties = Lists.newArrayList(new CodeType("SCALE_TYP"));
|
||||||
|
org.hl7.fhir.r4.model.Parameters parametersR4 = result.toParameters(properties);
|
||||||
|
Parameters parameters = VersionConvertor_30_40.convertParameters(parametersR4);
|
||||||
|
|
||||||
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(parameters));
|
||||||
|
|
||||||
|
Optional<Coding> propertyValueCoding = findProperty(parameters, "SCALE_TYP");
|
||||||
|
assertTrue(propertyValueCoding.isPresent());
|
||||||
|
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, propertyValueCoding.get().getSystem());
|
||||||
|
assertEquals("LP7753-9", propertyValueCoding.get().getCode());
|
||||||
|
assertEquals("Qn", propertyValueCoding.get().getDisplay());
|
||||||
|
|
||||||
|
propertyValueCoding = findProperty(parameters, "COMPONENT");
|
||||||
|
assertFalse(propertyValueCoding.isPresent());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> toExpandedCodes(ValueSet theExpanded) {
|
private Set<String> toExpandedCodes(ValueSet theExpanded) {
|
||||||
|
|
|
@ -110,8 +110,10 @@ public class TerminologyLoaderSvcLoincTest {
|
||||||
// Normal loinc code
|
// Normal loinc code
|
||||||
code = concepts.get("10013-1");
|
code = concepts.get("10013-1");
|
||||||
assertEquals("10013-1", code.getCode());
|
assertEquals("10013-1", code.getCode());
|
||||||
assertEquals("Elpot", code.getStringProperty("PROPERTY"));
|
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, code.getCodingProperties("PROPERTY").get(0).getSystem());
|
||||||
assertEquals("Pt", code.getStringProperty("TIME_ASPCT"));
|
assertEquals("LP6802-5", code.getCodingProperties("PROPERTY").get(0).getCode());
|
||||||
|
assertEquals("Elpot", code.getCodingProperties("PROPERTY").get(0).getDisplay());
|
||||||
|
assertEquals("EKG.MEAS", code.getStringProperty("CLASS"));
|
||||||
assertEquals("R' wave amplitude in lead I", code.getDisplay());
|
assertEquals("R' wave amplitude in lead I", code.getDisplay());
|
||||||
|
|
||||||
// Loinc code with answer
|
// Loinc code with answer
|
||||||
|
@ -135,10 +137,11 @@ public class TerminologyLoaderSvcLoincTest {
|
||||||
|
|
||||||
// AnswerList valueSet
|
// AnswerList valueSet
|
||||||
vs = valueSets.get("LL1001-8");
|
vs = valueSets.get("LL1001-8");
|
||||||
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, vs.getIdentifier().get(0).getSystem());
|
assertEquals("Beta.1", vs.getVersion());
|
||||||
assertEquals("LL1001-8", vs.getIdentifier().get(0).getValue());
|
assertEquals("urn:ietf:rfc:3986", vs.getIdentifier().get(0).getSystem());
|
||||||
|
assertEquals("urn:oid:1.3.6.1.4.1.12009.10.1.166", vs.getIdentifier().get(0).getValue());
|
||||||
assertEquals("PhenX05_14_30D freq amts", vs.getName());
|
assertEquals("PhenX05_14_30D freq amts", vs.getName());
|
||||||
assertEquals("urn:oid:1.3.6.1.4.1.12009.10.1.166", vs.getUrl());
|
assertEquals("http://loinc.org/vs/LL1001-8", vs.getUrl());
|
||||||
assertEquals(1, vs.getCompose().getInclude().size());
|
assertEquals(1, vs.getCompose().getInclude().size());
|
||||||
assertEquals(7, vs.getCompose().getInclude().get(0).getConcept().size());
|
assertEquals(7, vs.getCompose().getInclude().get(0).getConcept().size());
|
||||||
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem());
|
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem());
|
||||||
|
@ -151,10 +154,12 @@ public class TerminologyLoaderSvcLoincTest {
|
||||||
assertEquals("adjusted for maternal weight", code.getDisplay());
|
assertEquals("adjusted for maternal weight", code.getDisplay());
|
||||||
|
|
||||||
// Part Mappings
|
// Part Mappings
|
||||||
conceptMap = conceptMaps.get(LoincPartRelatedCodeMappingHandler.LOINC_PART_MAP_ID);
|
conceptMap = conceptMaps.get(LoincPartRelatedCodeMappingHandler.LOINC_SCT_PART_MAP_ID);
|
||||||
assertEquals(null, conceptMap.getSource());
|
assertEquals(null, conceptMap.getSource());
|
||||||
assertEquals(null, conceptMap.getTarget());
|
assertEquals(null, conceptMap.getTarget());
|
||||||
assertEquals("This material includes SNOMED Clinical Terms® (SNOMED CT®) which is used by permission of the International Health Terminology Standards Development Organisation (IHTSDO) under license. All rights reserved. SNOMED CT® was originally created by The College of American Pathologists. “SNOMED” and “SNOMED CT” are registered trademarks of the IHTSDO.This material includes content from the US Edition to SNOMED CT, which is developed and maintained by the U.S. National Library of Medicine and is available to authorized UMLS Metathesaurus Licensees from the UTS Downloads site at https://uts.nlm.nih.gov.Use of SNOMED CT content is subject to the terms and conditions set forth in the SNOMED CT Affiliate License Agreement. It is the responsibility of those implementing this product to ensure they are appropriately licensed and for more information on the license, including how to register as an Affiliate Licensee, please refer to http://www.snomed.org/snomed-ct/get-snomed-ct or info@snomed.org<mailto:info@snomed.org>. This may incur a fee in SNOMED International non-Member countries.", conceptMap.getCopyright());
|
assertEquals(LoincPartRelatedCodeMappingHandler.LOINC_SCT_PART_MAP_URI, conceptMap.getUrl());
|
||||||
|
assertEquals("This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC Part File, LOINC/SNOMED CT Expression Association and Map Sets File, RELMA database and associated search index files include SNOMED Clinical Terms (SNOMED CT®) which is used by permission of the International Health Terminology Standards Development Organisation (IHTSDO) under license. All rights are reserved. SNOMED CT® was originally created by The College of American Pathologists. “SNOMED” and “SNOMED CT” are registered trademarks of the IHTSDO. Use of SNOMED CT content is subject to the terms and conditions set forth in the SNOMED CT Affiliate License Agreement. It is the responsibility of those implementing this product to ensure they are appropriately licensed and for more information on the license, including how to register as an Affiliate Licensee, please refer to http://www.snomed.org/snomed-ct/get-snomed-ct or info@snomed.org. Under the terms of the Affiliate License, use of SNOMED CT in countries that are not IHTSDO Members is subject to reporting and fee payment obligations. However, IHTSDO agrees to waive the requirements to report and pay fees for use of SNOMED CT content included in the LOINC Part Mapping and LOINC Term Associations for purposes that support or enable more effective use of LOINC. This material includes content from the US Edition to SNOMED CT, which is developed and maintained by the U.S. National Library of Medicine and is available to authorized UMLS Metathesaurus Licensees from the UTS Downloads site at https://uts.nlm.nih.gov.", conceptMap.getCopyright());
|
||||||
|
assertEquals("Beta.1", conceptMap.getVersion());
|
||||||
assertEquals(1, conceptMap.getGroup().size());
|
assertEquals(1, conceptMap.getGroup().size());
|
||||||
group = conceptMap.getGroup().get(0);
|
group = conceptMap.getGroup().get(0);
|
||||||
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, group.getSource());
|
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, group.getSource());
|
||||||
|
@ -320,9 +325,6 @@ public class TerminologyLoaderSvcLoincTest {
|
||||||
// Normal loinc code
|
// Normal loinc code
|
||||||
TermConcept code = concepts.get("10013-1");
|
TermConcept code = concepts.get("10013-1");
|
||||||
assertEquals("10013-1", code.getCode());
|
assertEquals("10013-1", code.getCode());
|
||||||
assertEquals("Elpot", code.getStringProperty("PROPERTY"));
|
|
||||||
assertEquals("Pt", code.getStringProperty("TIME_ASPCT"));
|
|
||||||
assertEquals("R' wave amplitude in lead I", code.getDisplay());
|
|
||||||
|
|
||||||
// No valuesets or conceptmaps get created
|
// No valuesets or conceptmaps get created
|
||||||
assertThat(valueSets.keySet(), empty());
|
assertThat(valueSets.keySet(), empty());
|
||||||
|
@ -350,6 +352,7 @@ public class TerminologyLoaderSvcLoincTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addLoincOptionalFilesToZip(ZipCollectionBuilder theFiles) throws IOException {
|
static void addLoincOptionalFilesToZip(ZipCollectionBuilder theFiles) throws IOException {
|
||||||
|
theFiles.addFileZip("/loinc/", "loincupload.properties");
|
||||||
theFiles.addFileZip("/loinc/", "AnswerList_Beta_1.csv", TerminologyLoaderSvcImpl.LOINC_ANSWERLIST_FILE);
|
theFiles.addFileZip("/loinc/", "AnswerList_Beta_1.csv", TerminologyLoaderSvcImpl.LOINC_ANSWERLIST_FILE);
|
||||||
theFiles.addFileZip("/loinc/", TerminologyLoaderSvcImpl.LOINC_ANSWERLIST_LINK_FILE, TerminologyLoaderSvcImpl.LOINC_ANSWERLIST_LINK_FILE);
|
theFiles.addFileZip("/loinc/", TerminologyLoaderSvcImpl.LOINC_ANSWERLIST_LINK_FILE, TerminologyLoaderSvcImpl.LOINC_ANSWERLIST_LINK_FILE);
|
||||||
theFiles.addFileZip("/loinc/", TerminologyLoaderSvcImpl.LOINC_PART_FILE, TerminologyLoaderSvcImpl.LOINC_PART_FILE);
|
theFiles.addFileZip("/loinc/", TerminologyLoaderSvcImpl.LOINC_PART_FILE, TerminologyLoaderSvcImpl.LOINC_PART_FILE);
|
||||||
|
|
|
@ -8,3 +8,33 @@
|
||||||
"LP173484-9","ADJUSTMENT","W hyperextension)",,"ACTIVE"
|
"LP173484-9","ADJUSTMENT","W hyperextension)",,"ACTIVE"
|
||||||
"LP6244-0","METHOD","EKG","Electrocardiogram (EKG)","ACTIVE"
|
"LP6244-0","METHOD","EKG","Electrocardiogram (EKG)","ACTIVE"
|
||||||
"LP18172-4","COMPONENT","Interferon.beta","Interferon beta","ACTIVE"
|
"LP18172-4","COMPONENT","Interferon.beta","Interferon beta","ACTIVE"
|
||||||
|
"LP7289-4","SYSTEM","Heart","Heart","ACTIVE"
|
||||||
|
"LP6960-1","TIME","Pt","Point in time (spot)","ACTIVE"
|
||||||
|
"LP6802-5","PROPERTY","Elpot","Electrical Potential (Voltage)","ACTIVE"
|
||||||
|
"LP7753-9","SCALE","Qn","Qn","ACTIVE"
|
||||||
|
"LP31101-6","COMPONENT","R' wave amplitude.lead I","R' wave amplitude.lead I","ACTIVE"
|
||||||
|
"LP31102-4","COMPONENT","R' wave amplitude.lead II","R' wave amplitude.lead II","ACTIVE"
|
||||||
|
"LP31103-2","COMPONENT","R' wave amplitude.lead III","R' wave amplitude.lead III","ACTIVE"
|
||||||
|
"LP31104-0","COMPONENT","R' wave amplitude.lead V1","R' wave amplitude.lead V1","ACTIVE"
|
||||||
|
"LP31105-7","COMPONENT","R' wave amplitude.lead V2","R' wave amplitude.lead V2","ACTIVE"
|
||||||
|
"LP31106-5","COMPONENT","R' wave amplitude.lead V3","R' wave amplitude.lead V3","ACTIVE"
|
||||||
|
"LP31107-3","COMPONENT","R' wave amplitude.lead V4","R' wave amplitude.lead V4","ACTIVE"
|
||||||
|
"LP31108-1","COMPONENT","R' wave amplitude.lead V5","R' wave amplitude.lead V5","ACTIVE"
|
||||||
|
"LP31109-9","COMPONENT","R' wave amplitude.lead V6","R' wave amplitude.lead V6","ACTIVE"
|
||||||
|
"LP31110-7","COMPONENT","R' wave duration.lead AVF","R' wave duration.lead AVF","ACTIVE"
|
||||||
|
"LP30269-2","SYSTEM","Ser/Plas^donor",,"ACTIVE"
|
||||||
|
"LP149220-8","PROPERTY","Pr","Presence","ACTIVE"
|
||||||
|
"LP7751-3","SCALE","Ord","Ord","ACTIVE"
|
||||||
|
"LP37904-7","COMPONENT","DBG Ab","DBG Ab","ACTIVE"
|
||||||
|
"LP6813-2","PROPERTY","Find","Finding","ACTIVE"
|
||||||
|
"LP95333-8","METHOD","PhenX","PhenX","ACTIVE"
|
||||||
|
"LP102627-9","COMPONENT","Each time you ate bread, toast or dinner rolls, how much did you usually eat in the past 30D","Each time you ate bread, toast or dinner rolls, how much did you usually eat in the past 30 days","ACTIVE"
|
||||||
|
"LP6879-3","PROPERTY","Time","Time (e.g. seconds)","ACTIVE"
|
||||||
|
"LP31088-5","COMPONENT","R wave duration.lead AVR","R wave duration.lead AVR","ACTIVE"
|
||||||
|
"LP206647-2","SYSTEM","Neck>Thyroid gland","Thyroid gland","ACTIVE"
|
||||||
|
"LP208655-3","METHOD","NM","NM","ACTIVE"
|
||||||
|
"LP32888-7","SCALE","Doc","Doc","ACTIVE"
|
||||||
|
"LP31534-8","COMPONENT","Study report","Study report","ACTIVE"
|
||||||
|
"LP7057-5","SYSTEM","Bld","Blood","ACTIVE"
|
||||||
|
"LP6838-9","PROPERTY","NFr","Number Fraction","ACTIVE"
|
||||||
|
"LP6141-8","METHOD","Automated count","Automated count","ACTIVE"
|
||||||
|
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
# This is the version identifier for the AnswerList file
|
||||||
|
answerlist.version=Beta.1
|
||||||
|
|
||||||
|
# This is the version identifier for uploaded ConceptMap resources
|
||||||
|
conceptmap.version=Beta.1
|
||||||
|
|
Loading…
Reference in New Issue