diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/CommonConfig.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/CommonConfig.java index 859a73641e3..86e03ec3d15 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/CommonConfig.java +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/CommonConfig.java @@ -20,28 +20,18 @@ package ca.uhn.fhir.jpa.demo; * #L% */ -import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; -import ca.uhn.fhir.jpa.search.elastic.ElasticsearchHibernatePropertiesBuilder; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.lang3.time.DateUtils; import org.hibernate.dialect.H2Dialect; -import org.hibernate.search.elasticsearch.cfg.ElasticsearchIndexStatus; -import org.hibernate.search.elasticsearch.cfg.IndexSchemaManagementStrategy; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import pl.allegro.tech.embeddedelasticsearch.EmbeddedElastic; -import pl.allegro.tech.embeddedelasticsearch.PopularProperties; -import javax.annotation.PreDestroy; import javax.sql.DataSource; -import java.io.IOException; import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.TimeUnit; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -110,55 +100,7 @@ public class CommonConfig { extraProperties.put("hibernate.search.autoregister_listeners", "false"); } - return configureElasticearch(extraProperties); - } - - private Properties configureElasticearch(Properties theExtraProperties) { - - String elasticsearchHost = "localhost"; - String elasticsearchUserId = ""; - String elasticsearchPassword = ""; - int elasticsearchPort = embeddedElasticSearch().getHttpPort(); - - new ElasticsearchHibernatePropertiesBuilder() - .setDebugRefreshAfterWrite(true) - .setDebugPrettyPrintJsonLog(true) - .setIndexSchemaManagementStrategy(IndexSchemaManagementStrategy.CREATE) - .setIndexManagementWaitTimeoutMillis(10000) - .setRequiredIndexStatus(ElasticsearchIndexStatus.YELLOW) - .setRestUrl("http://" + elasticsearchHost + ":" + elasticsearchPort) - .setUsername(elasticsearchUserId) - .setPassword(elasticsearchPassword) - .apply(theExtraProperties); - - return theExtraProperties; - - } - - @Bean - public EmbeddedElastic embeddedElasticSearch() { - String ELASTIC_VERSION = "6.5.4"; - - EmbeddedElastic embeddedElastic = null; - try { - embeddedElastic = EmbeddedElastic.builder() - .withElasticVersion(ELASTIC_VERSION) - .withSetting(PopularProperties.TRANSPORT_TCP_PORT, 0) - .withSetting(PopularProperties.HTTP_PORT, 0) - .withSetting(PopularProperties.CLUSTER_NAME, UUID.randomUUID()) - .withStartTimeout(60, TimeUnit.SECONDS) - .build() - .start(); - } catch (IOException | InterruptedException e) { - throw new ConfigurationException(e); - } - - return embeddedElastic; - } - - @PreDestroy - public void stop() { - embeddedElasticSearch().stop(); + return extraProperties; } @Bean diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_1_0/1917-account-for-loinc268.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_1_0/1917-account-for-loinc268.yaml new file mode 100644 index 00000000000..199e3832485 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_1_0/1917-account-for-loinc268.yaml @@ -0,0 +1,4 @@ +--- +type: add +issue: 1917 +title: "The LOINC importer has been updated to support the file format used by the LOINC 2.68 release." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java index a936c87792f..f2c7f221e30 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java @@ -105,11 +105,11 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao theFiles, RequestDetails theRequestDetails) { try (LoadedFileDescriptors descriptors = new LoadedFileDescriptors(theFiles)) { - List loincUploadPropertiesFragment = Collections.singletonList( - LOINC_UPLOAD_PROPERTIES_FILE.getCode() - ); - descriptors.verifyMandatoryFilesExist(loincUploadPropertiesFragment); - Properties uploadProperties = getProperties(descriptors, LOINC_UPLOAD_PROPERTIES_FILE.getCode()); List mandatoryFilenameFragments = Arrays.asList( @@ -119,7 +114,8 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc { uploadProperties.getProperty(LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_FILE.getCode(), LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_IMAGING_DOCUMENT_CODES_FILE.getCode(), LOINC_IMAGING_DOCUMENT_CODES_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_PART_FILE.getCode(), LOINC_PART_FILE_DEFAULT.getCode()), - uploadProperties.getProperty(LOINC_PART_LINK_FILE.getCode(), LOINC_PART_LINK_FILE_DEFAULT.getCode()), + uploadProperties.getProperty(LOINC_PART_LINK_FILE_PRIMARY.getCode(), LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()), + uploadProperties.getProperty(LOINC_PART_LINK_FILE_SUPPLEMENTARY.getCode(), LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_PART_RELATED_CODE_MAPPING_FILE.getCode(), LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_RSNA_PLAYBOOK_FILE.getCode(), LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE.getCode(), LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE_DEFAULT.getCode()), @@ -238,6 +234,13 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc { @NotNull private Properties getProperties(LoadedFileDescriptors theDescriptors, String thePropertiesFile) { Properties retVal = new Properties(); + + try (InputStream propertyStream = TermLoaderSvcImpl.class.getResourceAsStream("/ca/uhn/fhir/jpa/term/loinc/loincupload.properties")) { + retVal.load(propertyStream); + } catch (IOException e) { + throw new InternalErrorException("Failed to process loinc.properties", e); + } + for (FileDescriptor next : theDescriptors.getUncompressedFileDescriptors()) { if (next.getFilename().endsWith(thePropertiesFile)) { try { @@ -425,10 +428,6 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc { handler = new LoincRsnaPlaybookHandler(code2concept, valueSets, conceptMaps, theUploadProperties); iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_RSNA_PLAYBOOK_FILE.getCode(), LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); - // Part link - handler = new LoincPartLinkHandler(codeSystemVersion, code2concept); - iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE.getCode(), LOINC_PART_LINK_FILE_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); - // Part related code mapping handler = new LoincPartRelatedCodeMappingHandler(code2concept, valueSets, conceptMaps, theUploadProperties); iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_PART_RELATED_CODE_MAPPING_FILE.getCode(), LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); @@ -469,6 +468,11 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc { handler = new LoincParentGroupFileHandler(code2concept, valueSets, conceptMaps, theUploadProperties); iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_PARENT_GROUP_FILE.getCode(), LOINC_PARENT_GROUP_FILE_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); + // Part link + handler = new LoincPartLinkHandler(codeSystemVersion, code2concept, propertyNamesToTypes); + iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE_PRIMARY.getCode(), LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); + iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE_SUPPLEMENTARY.getCode(), LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); + IOUtils.closeQuietly(theDescriptors); valueSets.add(getValueSetLoincAll()); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java index ecf3dce5c73..8f9fad210bc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java @@ -86,44 +86,9 @@ public class LoincHandler implements IRecordHandler { concept.addPropertyString(nextPropertyName, nextPropertyValue); break; case CODING: - // TODO: handle "Ser/Plas^Donor" - String propertyValue = nextPropertyValue; - if (nextPropertyName.equals("COMPONENT")) { - if (propertyValue.contains("^")) { - propertyValue = propertyValue.substring(0, propertyValue.indexOf("^")); - } else if (propertyValue.contains("/")) { - propertyValue = propertyValue.substring(0, propertyValue.indexOf("/")); - } - } - - PartTypeAndPartName key = new PartTypeAndPartName(nextPropertyName, propertyValue); - 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; - } - - if (isNotBlank(partNumber)) { - concept.addPropertyCoding(nextPropertyName, ITermLoaderSvc.LOINC_URI, partNumber, nextPropertyValue); - } else { - String msg = "Unable to find part code with TYPE[" + key.getPartType() + "] and NAME[" + nextPropertyValue + "] (using name " + propertyValue + ")"; - ourLog.warn(msg); -// throw new InternalErrorException(msg); - } + // These are handles by the LOINC PartLink file break; + case DECIMAL: case CODE: case INTEGER: diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartLinkHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartLinkHandler.java index e9e1bae1031..ccce7446de9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartLinkHandler.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartLinkHandler.java @@ -22,12 +22,17 @@ package ca.uhn.fhir.jpa.term.loinc; import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermConcept; +import ca.uhn.fhir.jpa.entity.TermConceptProperty; import ca.uhn.fhir.jpa.term.IRecordHandler; +import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import org.apache.commons.csv.CSVRecord; +import org.hl7.fhir.r4.model.CodeSystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; +import java.util.Optional; import static org.apache.commons.lang3.StringUtils.trim; @@ -36,40 +41,65 @@ public class LoincPartLinkHandler implements IRecordHandler { private static final Logger ourLog = LoggerFactory.getLogger(LoincPartLinkHandler.class); private final Map myCode2Concept; private final TermCodeSystemVersion myCodeSystemVersion; + private final Map myPropertyNames; private Long myPartCount; - public LoincPartLinkHandler(TermCodeSystemVersion theCodeSystemVersion, Map theCode2concept) { + public LoincPartLinkHandler(TermCodeSystemVersion theCodeSystemVersion, Map theCode2concept, Map thePropertyNames) { myCodeSystemVersion = theCodeSystemVersion; myCode2Concept = theCode2concept; + myPropertyNames = thePropertyNames; } @Override public void accept(CSVRecord theRecord) { String loincNumber = trim(theRecord.get("LoincNumber")); - String longCommonName = trim(theRecord.get("LongCommonName")); + String property = trim(theRecord.get("Property")); + String partName = trim(theRecord.get("PartName")); String partNumber = trim(theRecord.get("PartNumber")); + /* + * Property has the form http://loinc.org/property/COMPONENT + * but we want just the COMPONENT part + */ + int lastSlashIdx = property.lastIndexOf("/"); + String propertyPart = property.substring(lastSlashIdx + 1); + TermConcept loincConcept = myCode2Concept.get(loincNumber); - TermConcept partConcept = myCode2Concept.get(partNumber); - if (loincConcept == null) { - ourLog.warn("No loinc code: {}", loincNumber); - return; + throw new InternalErrorException("Unknown loinc code: " + loincNumber); } - if (partConcept == null) { - if (myPartCount == null) { - myPartCount = myCode2Concept - .keySet() - .stream() - .filter(t->t.startsWith("LP")) - .count(); - } - ourLog.debug("No part code: {} - Have {} part codes", partNumber, myPartCount); + + CodeSystem.PropertyType propertyType = myPropertyNames.get(propertyPart); + if (propertyType == null) { return; } - // For now we're ignoring these + String expectedValue; + if (propertyType == CodeSystem.PropertyType.STRING) { + expectedValue = partName; + } else if (propertyType == CodeSystem.PropertyType.CODING) { + expectedValue = partNumber; + } else { + throw new InternalErrorException("Don't know how to handle property of type: " + propertyType); + } + + Optional existingProprty = loincConcept + .getProperties() + .stream() + .filter(t -> t.getKey().equals(propertyPart)) + .filter(t -> t.getValue().equals(expectedValue)) + .findFirst(); + if (existingProprty.isPresent()) { + return; + } + + ourLog.info("Adding new property {} = {}", propertyPart, partNumber); + if (propertyType == CodeSystem.PropertyType.STRING) { + loincConcept.addPropertyString(propertyPart, partName); + } else { + loincConcept.addPropertyCoding(propertyPart, ITermLoaderSvc.LOINC_URI, partNumber, partName); + } } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartRelatedCodeMappingHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartRelatedCodeMappingHandler.java index 02e08bc533e..5fefd31a549 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartRelatedCodeMappingHandler.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincPartRelatedCodeMappingHandler.java @@ -88,6 +88,9 @@ public class LoincPartRelatedCodeMappingHandler extends BaseLoincHandler impleme case "wider": equivalence = Enumerations.ConceptMapEquivalence.WIDER; break; + case "relatedto": + equivalence = Enumerations.ConceptMapEquivalence.RELATEDTO; + break; default: throw new InternalErrorException("Unknown equivalence '" + mapType + "' for PartNumber: " + partNumber); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincUploadPropertiesEnum.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincUploadPropertiesEnum.java index 40c36d6eb3e..d1d1295c9e2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincUploadPropertiesEnum.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincUploadPropertiesEnum.java @@ -67,9 +67,13 @@ public enum LoincUploadPropertiesEnum { // Part LOINC_PART_FILE("loinc.part.file"), LOINC_PART_FILE_DEFAULT("AccessoryFiles/PartFile/Part.csv"), + // Part link - LOINC_PART_LINK_FILE("loinc.part.link.file"), - LOINC_PART_LINK_FILE_DEFAULT("AccessoryFiles/PartFile/LoincPartLink.csv"), + LOINC_PART_LINK_FILE_PRIMARY("loinc.part.link.primary.file"), + LOINC_PART_LINK_FILE_PRIMARY_DEFAULT("AccessoryFiles/PartFile/LoincPartLink_Primary.csv"), + LOINC_PART_LINK_FILE_SUPPLEMENTARY("loinc.part.link.supplementary.file"), + LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT("AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv"), + // Part related code mapping LOINC_PART_RELATED_CODE_MAPPING_FILE("loinc.part.related.code.mapping.file"), LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT("AccessoryFiles/PartFile/PartRelatedCodeMapping.csv"), diff --git a/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/term/loinc/loinc.xml b/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/term/loinc/loinc.xml index 7fc6b37e371..efe4184e99b 100644 --- a/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/term/loinc/loinc.xml +++ b/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/term/loinc/loinc.xml @@ -1,442 +1,548 @@ - + - - - - - - - - - - - - + + + + + + + + + + + + + + <status value="active"/> + <experimental value="false"/> + + <publisher value="Regenstrief Institute, Inc."/> + <contact> + <telecom> + <value value="http://loinc.org"/> + </telecom> + </contact> + + <!-- + <date value=2020-06/> + --> + <description value="LOINC is a freely available international standard for tests, measurements, and observations"/> + <copyright value="This material contains content from LOINC (http://loinc.org). LOINC is copyright ©1995-2020, Regenstrief Institute, Inc. and the Logical Observation Identifiers Names and Codes (LOINC) Committee and is available at no cost under the license at http://loinc.org/license. LOINC® is a registered United States trademark of Regenstrief Institute, Inc."/> + <caseSensitive value="false"/> + + <valueSet value=" http://loinc.org/vs"/> + <!-- + For a version specific reference: + <valueSet value="http://loinc.org/2.68/vs"/> --> - <!-- if a specific version is specified, the name should carry this information should be in the name (e.g. LOINC_259) and title --> - <name value="LOINC"/> - <title value="LOINC Code System"/> - <status value="active"/> - <experimental value="false"/> - - <publisher value="Regenstrief Institute, Inc."/> - <contact> - <telecom> - <value value="http://loinc.org"/> - </telecom> - </contact> - - <!-- - <date value=[date for this version]"/> - --> - <description value="LOINC is a freely available international standard for tests, measurements, and observations"/> - <copyright value="This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at http://loinc.org/terms-of-use"/> - <caseSensitive value="false"/> - - <valueSet value=" http://loinc.org/vs"/> - <!-- - for a version specific reference: - <valueSet value="http://loinc.org/2.56/vs"/> - --> - - <!-- - It's at the discretion of servers whether to present fragments of LOINC heirarchically or not, when - using the code system resource. But, if they are heirarchical, the Hierarchy SHALL be based on the is-a relationship that is derived from the LOINC Multiaxial Hierarchy. - --> - <HierarchyMeaning value="is-a"/> - <compositional value="false"/> <!-- no compositional grammar in LOINC --> - <versionNeeded value="false"/> - - <!-- this canonical definition of LOINC does not include the content. - Servers may choose to include fragments (but not, due to size constraints, all of LOINC) --> - <content value="not-present"/> - -<!-- <count value="65000"/>... if working with a specific version, you could nominate a count of the total number of concepts (including the answers, Hierarchy, etc.) --> + <!-- + It's at the discretion of servers whether to present fragments of LOINC hierarchically or not, when using the code system resource. But, if they are hierarchical, the Hierarchy SHALL be based on the is-a relationship that is derived from the LOINC Multiaxial Hierarchy. + --> + <hierarchyMeaning value="is-a"/> + <compositional value="false"/> <!-- no compositional grammar in LOINC --> + <versionNeeded value="false"/> - <!-- - Generally defined filters for specifying value sets - In LOINC, all the properties can be used as filters too, but they are not defined explicitly as filters as well. - Note that parent/child/ancestor/descendant are defined by FHIR, but repeated here to document them clearly. - - For illustration purposes, consider this slice of the LOINC Multiaxial Hierarchy when reading the descriptions: - - Microbiology [LP31755-9] - Microorganism [LP14559-6] - Virus [LP14855-8] - Zika virus [LP200137-0] - Zika virus RNA | XXX [LP203413-2] - Zika virus RNA [Presence] in Unspecified specimen by Probe and target amplification method [79190-5] + <!-- + This canonical definition of LOINC does not include the LOINC content, which is distributed separately for portability. - Language Note: The filters defined here are specified using the default LOINC language - English (US). Requests are meant to be specified and interpreted on the English version. The return can be in a specified language (if supported by the server). But note that not all filters/properties have language translations available. - --> - <filter> - <code value="parent"/> - <description value="Allows for the selection of a set of codes based on their appearance in the LOINC Multiaxial Hierarchy. parent selects immediate children only. For example, the code '79190-5' has the parent 'LP203413-2'"/> - <operator value="="/> - <value value="A Part code"/> - </filter> - <filter> - <code value="child"/> - <description value="Allows for the selection of a set of codes based on their appearance in the LOINC Multiaxial Hierarchy. child selects immediate children only. For example, the code 'LP203413-2' has the child '79190-5'"/> - <operator value="in"/> - <value value="A comma separated list of Part codes"/> - </filter> - <filter> - <code value="ancestor"/> - <description value="Allows for the selection of a set of codes based on their appearance in the LOINC Multiaxial Hierarchy. ancestor includes parents transitively, e.g. 'LP203413-2' eventually has an ancestor 'LP14559-6', so the code '79190-5' is in the set of codes that have ancestor=LP14559-6"/> - <operator value="="/> - <value value="A Part code"/> - </filter> - <filter> - <code value="descendant"/> - <description value="Allows for the selection of a set of codes based on their appearance in the LOINC Multiaxial Hierarchy. descendant includes children transitively, e.g. 'LP14559-6' eventually has a descendant 'LP203413-2', so the code '79190-5' is in the set of codes that have descendant=LP14559-6"/> - <operator value="in"/> - <value value="A comma separated list of Part codes"/> - </filter> - <filter> - <code value="copyright"/> - <description value="Allows for the inclusion or exclusion of LOINC codes that include 3rd party copyright notices. LOINC = only codes with a sole copyright by Regenstrief. 3rdParty = only codes with a 3rd party copyright in addition to the one from Regenstrief"/> - <operator value="="/> - <value value="LOINC | 3rdParty"/> - </filter> - <!-- properties. There are 3 kinds of properties: - fhir: display, designation; these are not described here since they are inherent in the specification - infrastructural: defined by FHIR, but documented here for LOINC - LOINC properties: defined by the main LOINC table - concept model: defined by the LOINC Multiaxial Hierarchy - --> - <!-- first, the infrastructural properties - inherited from FHIR, but documented here --> - <property> - <code value="parent"/> - <uri value="http://hl7.org/fhir/concept-properties#parent"/> - <description value="A parent code in the Multiaxial Hierarchy"/> - <type value=""/> - </property> - <property> - <code value="child"/> - <uri value="http://hl7.org/fhir/concept-properties#child"/> - <description value="A child code in the Multiaxial Hierarchy"/> - <type value=""/> - </property> - <!-- - LOINC properties. - These apply to the main LOINC codes, but not the Multiaxial Hierarchy, the answer lists, or the part codes. - - Notes: - SHORTNAME = display & LONG_COMMON_NAME = definition - Properties are specified as type "code", which are LOINC Part codes (LP-). - It is anticipated that the LOINC Part codes to be used in these properties will be published in the June 2017 LOINC release. - --> - <property> - <code value="STATUS"/> - <uri value="http://loinc.org/property/STATUS"/> - <description value="Status of the term. Within LOINC, codes with STATUS=DEPRECATED are considered inactive. Current values: ACTIVE, TRIAL, DISCOURAGED, and DEPRECATED"/> - <!-- DV NOTE: changed this from boolean to string --> - <type value="string"/> - </property> - <property> - <code value="COMPONENT"/> - <uri value="http://loinc.org/property/COMPONENT"/> - <description value="First major axis-component or analyte: Analyte Name, Analyte sub-class, Challenge"/> - <type value="Coding"/> - </property> - <property> - <code value="PROPERTY"/> - <uri value="http://loinc.org/property/PROPERTY"/> - <description value="Second major axis-property observed: Kind of Property (also called kind of quantity)"/> - <type value="Coding"/> - </property> - <property> - <code value="TIME_ASPCT"/> - <uri value="http://loinc.org/property/TIME_ASPCT"/> - <description value="Third major axis-timing of the measurement: Time Aspect (Point or moment in time vs. time interval)"/> - <type value="Coding"/> - </property> - <property> - <code value="SYSTEM"/> - <uri value="http://loinc.org/property/SYSTEM"/> - <description value="Fourth major axis-type of specimen or system: System (Sample) Type"/> - <type value="Coding"/> - </property> - <property> - <code value="SCALE_TYP"/> - <uri value="http://loinc.org/property/SCALE_TYP"/> - <description value="Fifth major axis-scale of measurement: Type of Scale"/> - <type value="Coding"/> - </property> - <property> - <code value="METHOD_TYP"/> - <uri value="http://loinc.org/property/METHOD_TYP"/> - <description value="Sixth major axis-method of measurement: Type of Method"/> - <type value="Coding"/> - </property> - <property> - <code value="CLASS"/> - <uri value="http://loinc.org/property/CLASS"/> - <description value="An arbitrary classification of the terms for grouping related observations together"/> - <type value="string"/> - </property> - <!-- Note: removed in 0.3 - <property> - <code value="CHNG_TYPE"/> - <uri value="http://loinc.org/property/CHNG_TYPE"/> - <description value="A classification of the type of change made to a LOINC term, e.g. DEL=deprecated, ADD=add"/> - <type value="string"/> - </property> - --> - <property> - <code value="VersionLastChanged"/> - <uri value="http://loinc.org/property/VersionLastChanged"/> - <description value="The LOINC version number in which the record has last changed. For new records, this field contains the same value as the FirstPublishedRelease property."/> - <type value="string"/> - </property> - <property> - <code value="CONSUMER_NAME"/> - <uri value="http://loinc.org/property/CONSUMER_NAME"/> - <description value="An experimental (beta) consumer friendly name for this item. The intent is to provide a test name that health care consumers will recognize; it will be similar to the names that might appear on a lab report"/> - <type value="string"/> - </property> - <property> - <code value="CLASSTYPE"/> - <uri value="http://loinc.org/property/CLASSTYPE"/> - <description value="1=Laboratory class; 2=Clinical class; 3=Claims attachments; 4=Surveys"/> - <type value="string"/> - </property> - <property> - <code value="ORDER_OBS"/> - <uri value="http://loinc.org/property/ORDER_OBS"/> - <description value="Provides users with an idea of the intended use of the term by categorizing it as an order only, observation only, or both"/> - <type value="string"/> - </property> - <property> - <code value="HL7_ATTACHMENT_STRUCTURE"/> - <uri value="http://loinc.org/property/HL7_ATTACHMENT_STRUCTURE"/> - <description value="This property is populated in collaboration with the HL7 Attachments Work Group as described in the HL7 Attachment Specification: Supplement to Consolidated CDA Templated Guide."/> - <type value="string"/> - </property> - <property> - <code value="VersionFirstReleased"/> - <uri value="http://loinc.org/property/VersionFirstReleased"/> - <description value="This is the LOINC version number in which this LOINC term was first published."/> - <type value="string"/> - </property> - <property> - <code value="PanelType"/> - <uri value="http://loinc.org/property/PanelType"/> - <description value="For LOINC terms that are panels, this attribute classifies them as a 'Convenience group', 'Organizer', or 'Panel'"/> - <type value="string"/> - </property> - <property> - <code value="ValidHL7AttachmentRequest"/> - <uri value="http://loinc.org/property/ValidHL7AttachmentRequest"/> - <description value="A value of Y in this field indicates that this LOINC code can be sent by a payer as part of an HL7 Attachment request for additional information."/> - <type value="string"/> - </property> + Servers may choose to include fragments of LOINC for illustration purposes. + --> + <content value="not-present"/> - <!-- LOINC/RSNA Radiology Playbook properties. These apply only to terms in the LOINC/RSNA Radiology Playbook File. - Notes: - Properties are specified as type "code", which are LOINC Part codes (LP-) - Converted the attribute names from LOINC style to FHIR style b/c they contained periods - Maneuver sub-attributes are being released in 2016 12. - --> - <property> - <code value="rad-modality-modality-type"/> - <uri value="http://loinc.org/property/rad-modality-type"/> - <description value="Modality is used to represent the device used to acquire imaging information."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-modality-modality-subtype"/> - <uri value="http://loinc.org/property/rad-modality-subtype"/> - <description value="Modality subtype may be optionally included to signify a particularly common or evocative configuration of the modality."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-anatomic-location-region-imaged"/> - <uri value="http://loinc.org/property/rad-anatomic-location-region-imaged"/> - <description value="The Anatomic Location Region Imaged attribute is used in two ways: as a coarse-grained descriptor of the area imaged and a grouper for finding related imaging exams; or, it is used just as a grouper."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-anatomic-location-imaging-focus"/> - <uri value="http://loinc.org/property/rad-anatomic-location-imaging-focus"/> - <description value="The Anatomic Location Imaging Focus is a more fine-grained descriptor of the specific target structure of an imaging exam. In many areas, the focus should be a specific organ."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-anatomic-location-laterality-presence"/> - <uri value="http://loinc.org/property/rad-anatomic-location-laterality-presence"/> - <description value="Radiology Exams that require laterality to be specified in order to be performed are signified with an Anatomic Location Laterality Presence attribute set to 'True'"/> - <type value="Coding"/> - </property> - <property> - <code value="rad-anatomic-location-laterality"/> - <uri value="http://loinc.org/property/rad-anatomic-location-laterality"/> - <description value="Radiology exam Laterality is specified as one of: Left, Right, Bilateral, Unilateral, Unspecified"/> - <type value="Coding"/> - </property> - <property> - <code value="rad-view-view-aggregation"/> - <uri value="http://loinc.org/property/rad-view-aggregation"/> - <description value="Aggregation describes the extent of the imaging performed, whether in quantitative terms (e.g., '3 or more views') or subjective terms (e.g., 'complete')."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-view-view-type"/> - <uri value="http://loinc.org/property/rad-view-view-type"/> - <description value="View type names specific views, such as 'lateral' or 'AP'."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-maneuver-maneuver-type"/> - <uri value="http://loinc.org/property/rad-maneuver-maneuver-type"/> - <description value="Maneuver type indicates an action taken with the goal of elucidating or testing a dynamic aspect of the anatomy."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-timing"/> - <uri value="http://loinc.org/property/rad-timing"/> - <description value="The Timing/Existence property used in conjunction with pharmaceutical and manueuver properties. It specifies whether or not the imaging occurs in the presence of the administered pharmaceutical or a manuever designed to test some dynamic aspect of anatomy or physiology ."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-pharmaceutical-substance-given"/> - <uri value="http://loinc.org/property/rad-pharmaceutical-substance-given"/> - <description value="The Pharmaceutical Substance Given specifies administered contrast agents, radiopharmaceuticals, medications, or other clinically important agents and challenges during the imaging procedure."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-pharmaceutical-route"/> - <uri value="http://loinc.org/property/rad-pharmaceutical-route"/> - <description value="Route specifies the route of administration of the pharmeceutical."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-reason-for-exam"/> - <uri value="http://loinc.org/property/rad-reason-for-exam"/> - <description value="Reason for exam is used to describe a clinical indication or a purpose for the study."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-guidance-for-presence"/> - <uri value="http://loinc.org/property/rad-guidance-for-presence"/> - <description value="Guidance for.Presence indicates when a procedure is guided by imaging."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-guidance-for-approach"/> - <uri value="http://loinc.org/property/rad-guidance-for-approach"/> - <description value="Guidance for.Approach refers to the primary route of access used, such as percutaneous, transcatheter, or transhepatic."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-guidance-for-action"/> - <uri value="http://loinc.org/property/rad-guidance-for-action"/> - <description value="Guidance for.Action indicates the intervention performed, such as biopsy, aspiration, or ablation."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-guidance-for-object"/> - <uri value="http://loinc.org/property/rad-guidance-for-object"/> - <description value="Guidance for.Object specifies the target of the action, such as mass, abscess or cyst."/> - <type value="Coding"/> - </property> - <property> - <code value="rad-subject"/> - <uri value="http://loinc.org/property/rad-subject"/> - <description value="Subject is intended for use when there is a need to distinguish between the patient associated with an imaging study, and the target of the study."/> - <type value="Coding"/> - </property> - <!-- Document Ontology properties. These apply only to terms in the LOINC Document Ontology File - Notes: - Properties are specified as type "code", which are LOINC Part codes (LP-) - Converted the attribute names from LOINC style to FHIR style b/c they contained periods - --> - <property> - <code value="document-kind"/> - <uri value="http://loinc.org/property/document-kind"/> - <description value="Characterizes the general structure of the document at a macro level."/> - <type value="Coding"/> - </property> - <property> - <code value="document-role"/> - <uri value="http://loinc.org/property/document-role"/> - <description value="Characterizes the training or professional level of the author of the document, but does not break down to specialty or subspecialty.."/> - <type value="Coding"/> - </property> - <property> - <code value="document-setting"/> - <uri value="http://loinc.org/property/document-setting"/> - <description value="Setting is a modest extension of CMS’s coarse definition of care settings, such as outpatient, hospital, etc. Setting is not equivalent to location, which typically has more locally defined meanings."/> - <type value="Coding"/> - </property> - <property> - <code value="document-subject-matter-domain"/> - <uri value="http://loinc.org/property/document-subject-matter-domain"/> - <description value="Characterizes the clinical domain that is the subject of the document. For example, Internal Medicine, Neurology, Physical Therapy, etc."/> - <type value="Coding"/> - </property> - <property> - <code value="document-type-of-service"/> - <uri value="http://loinc.org/property/document-type-of-service"/> - <description value="Characterizes the kind of service or activity provided to/for the patient (or other subject of the service) that is described in the document."/> - <type value="Coding"/> - </property> - <!-- Answer list related properties --> - <property> - <code value="answer-list"/> - <uri value="http://loinc.org/property/answer-list"/> - <description value="An answer list associated with this LOINC code (if there are matching answer lists defined). Only on normal LOINC Codes"/> - <type value="Coding"/> - </property> - <!-- Note: We expect to add an AnswerListType property when LOINC publishes new answer list file format in June 2017 --> - <property> - <code value="answers-for"/> - <uri value="http://loinc.org/property/answers-for"/> - <description value="A LOINC Code for which this answer list is used. Only on normal LL- Codes"/> - <type value="Coding"/> - </property> - <!-- Note for future consideration. These are properties of LA codes in the context of a particular list. Not global properties - <property> - <code value="sequence"/> - <uri value="http://loinc.org/property/sequence"/> - <description value="Sequence Number of a answer in a set of answers (LA- codes only)"/> - <type value="integer"/> - </property> - <property> - <code value="score"/> - <uri value="http://loinc.org/property/score"/> - <description value="Score assigned to an answer (LA- codes only)"/> - <type value="integer"/> - </property> - --> + <!-- + <count value="65000"/> + If working with a specific version, you could nominate a count of the total number of concepts (including the answers, Hierarchy, etc.). In this canonical definition we do not. + --> + + <!-- + FILTERS + Generally defined filters for specifying value sets + In LOINC, all the properties can also be used as filters, but they are not defined explicitly as filters. + Parent/child properties are as defined by FHIR. Note that at this time the LOINC code system resource does not support ancestor/descendant relationships. + + For illustration purposes, consider this slice of the LOINC Multiaxial Hierarchy when reading the descriptions below: + + Microbiology [LP7819-8] + Microorganism [LP14559-6] + Virus [LP14855-8] + Zika virus [LP200137-0] + Zika virus RNA | XXX [LP203271-4] + Zika virus RNA | XXX | Microbiology [LP379670-5] + Zika virus RNA [Presence] in Unspecified specimen by Probe and target amplification method [79190-5] + + Language Note: The filters defined here are specified using the default LOINC language - English (US). Requests are meant to be specified and interpreted on the English version. The return can be in a specified language (if supported by the server). But note that not all filters/properties have language translations available. + --> + <filter> + <code value="parent"/> + <description value="Allows for the selection of a set of codes based on their appearance in the LOINC Multiaxial Hierarchy. Parent selects immediate parent only. For example, the code '79190-5' has the parent 'LP379670-5'"/> + <operator value="="/> + <value value="A Part code"/> + </filter> + <filter> + <code value="child"/> + <description value="Allows for the selection of a set of codes based on their appearance in the LOINC Multiaxial Hierarchy. Child selects immediate children only. For example, the code 'LP379670-5' has the child '79190-5'. Only LOINC Parts have children; LOINC codes do not have any children because they are leaf nodes."/> + <operator value="="/> + <value value="A comma separated list of Part or LOINC codes"/> + </filter> + <filter> + <code value="copyright"/> + <description value="Allows for the inclusion or exclusion of LOINC codes that include 3rd party copyright notices. LOINC = only codes with a sole copyright by Regenstrief. 3rdParty = only codes with a 3rd party copyright in addition to the one from Regenstrief"/> + <operator value="="/> + <value value="LOINC | 3rdParty"/> + </filter> + + <!-- + PROPERTIES + There are 4 kinds of properties that apply to all LOINC codes: + 1. FHIR: display, designation; these are not described here since they are inherent in the specification + 2. Infrastructural: defined by FHIR, but documented here for the LOINC Multiaxial Hierarchy + 3. Primary LOINC properties: defined by the main LOINC table + 4. Secondary LOINC properties: defined by the LoincPartLink table + Additionally, there are 2 kinds of properties specific to Document ontology and Radiology codes, respectively: + 1. LOINC/RSNA Radiology Playbook properties + 2. Document Ontology properties + --> + <!-- + Infrastructural properties - inherited from FHIR, but documented here for the LOINC Multiaxial Hierarchy. + --> + + <property> + <code value="parent"/> + <uri value="http://hl7.org/fhir/concept-properties#parent"/> + <description value="A parent code in the Multiaxial Hierarchy"/> + <type value=""/> + </property> + <property> + <code value="child"/> + <uri value="http://hl7.org/fhir/concept-properties#child"/> + <description value="A child code in the Multiaxial Hierarchy"/> + <type value=""/> + </property> + + <!-- + Primary LOINC properties. + These apply to the main LOINC codes, but not the Multiaxial Hierarchy, Answer lists, or the Part codes. + Notes: + In the LOINC code system resource, the display element = LONG_COMMON_NAME + Many properties are specified as type "coding", which allows use of LOINC Part codes (LP-) and the display text. LOINC Parts and their associations to LOINC terms are published in the LOINC Part File. + The properties defined here follow the guidance of the LOINC Users' Manual, which states that they should be expressed with the LOINC attributes contained in the LOINC Table. Properties that are not defined in the LOINC Table use FHIR-styled names. + --> + + <property> + <code value="STATUS"/> + <uri value="http://loinc.org/property/STATUS"/> + <description value="Status of the term. Within LOINC, codes with STATUS=DEPRECATED are considered inactive. Current values: ACTIVE, TRIAL, DISCOURAGED, and DEPRECATED"/> + <type value="string"/> + </property> + <property> + <code value="COMPONENT"/> + <uri value="http://loinc.org/property/COMPONENT"/> + <description value="First major axis-component or analyte: Analyte Name, Analyte sub-class, Challenge"/> + <type value="Coding"/> + </property> + <property> + <code value="PROPERTY"/> + <uri value="http://loinc.org/property/PROPERTY"/> + <description value="Second major axis-property observed: Kind of Property (also called kind of quantity)"/> + <type value="Coding"/> + </property> + <property> + <code value="TIME_ASPCT"/> + <uri value="http://loinc.org/property/TIME_ASPCT"/> + <description value="Third major axis-timing of the measurement: Time Aspect (Point or moment in time vs. time interval)"/> + <type value="Coding"/> + </property> + <property> + <code value="SYSTEM"/> + <uri value="http://loinc.org/property/SYSTEM"/> + <description value="Fourth major axis-type of specimen or system: System (Sample) Type"/> + <type value="Coding"/> + </property> + <property> + <code value="SCALE_TYP"/> + <uri value="http://loinc.org/property/SCALE_TYP"/> + <description value="Fifth major axis-scale of measurement: Type of Scale"/> + <type value="Coding"/> + </property> + <property> + <code value="METHOD_TYP"/> + <uri value="http://loinc.org/property/METHOD_TYP"/> + <description value="Sixth major axis-method of measurement: Type of Method"/> + <type value="Coding"/> + </property> + <property> + <code value="CLASS"/> + <uri value="http://loinc.org/property/CLASS"/> + <description value="An arbitrary classification of the terms for grouping related observations together"/> + <type value="Coding"/> + </property> + <property> + <code value="VersionLastChanged"/> + <uri value="http://loinc.org/property/VersionLastChanged"/> + <description value="The LOINC version number in which the record has last changed. For new records, this field contains the same value as the VersionFirstReleased property."/> + <type value="string"/> + </property> + <property> + <code value="CLASSTYPE"/> + <uri value="http://loinc.org/property/CLASSTYPE"/> + <description value="1=Laboratory class; 2=Clinical class; 3=Claims attachments; 4=Surveys"/> + <type value="string"/> + </property> + <property> + <code value="ORDER_OBS"/> + <uri value="http://loinc.org/property/ORDER_OBS"/> + <description value="Provides users with an idea of the intended use of the term by categorizing it as an order only, observation only, or both"/> + <type value="string"/> + </property> + <property> + <code value="HL7_ATTACHMENT_STRUCTURE"/> + <uri value="http://loinc.org/property/HL7_ATTACHMENT_STRUCTURE"/> + <description value="This property is populated in collaboration with the HL7 Attachments Work Group as described in the HL7 Attachment Specification: Supplement to Consolidated CDA Templated Guide."/> + <type value="string"/> + </property> + <property> + <code value="VersionFirstReleased"/> + <uri value="http://loinc.org/property/VersionFirstReleased"/> + <description value="This is the LOINC version number in which this LOINC term was first published."/> + <type value="string"/> + </property> + <property> + <code value="PanelType"/> + <uri value="http://loinc.org/property/PanelType"/> + <description value="For LOINC terms that are panels, this attribute classifies them as a 'Convenience group', 'Organizer', or 'Panel'"/> + <type value="string"/> + </property> + <property> + <code value="ValidHL7AttachmentRequest"/> + <uri value="http://loinc.org/property/ValidHL7AttachmentRequest"/> + <description value="A value of Y in this field indicates that this LOINC code can be sent by a payer as part of an HL7 Attachment request for additional information."/> + <type value="string"/> + </property> + <property> + <code value="DisplayName"/> + <uri value="http://loinc.org/property/DisplayName"/> + <description value="A name that is more 'clinician-friendly' compared to the current LOINC Short Name, Long Common Name, and Fully Specified Name. It is created algorithmically from the manually crafted display text for each Part and is generally more concise than the Long Common Name."/> + <type value="string"/> + </property> + <property> + <code value="answer-list"/> + <uri value="http://loinc.org/property/answer-list"/> + <description value="An answer list associated with this LOINC code (if there are matching answer lists defined)."/> + <type value="Coding"/> + </property> + + <!-- + Secondary LOINC properties. + These properties also apply to the main LOINC codes, but not the Multiaxial Hierarchy, Answer lists, or the Part codes. + Notes: + These properties are defined in the LoincPartLink table. + --> + + <property> + <code value="analyte"/> + <uri value="http://loinc.org/property/analyte"/> + <description value="First sub-part of the Component, i.e., the part of the Component before the first carat"/> + <type value="Coding"/> + </property> + <property> + <code value="analyte-core"/> + <uri value="http://loinc.org/property/analyte-core"/> + <description value="The primary part of the analyte without the suffix"/> + <type value="Coding"/> + </property> + <property> + <code value="analyte-suffix"/> + <uri value="http://loinc.org/property/analyte-suffix"/> + <description value="The suffix part of the analyte, if present, e.g., Ab or DNA"/> + <type value="Coding"/> + </property> + <property> + <code value="analyte-numerator"/> + <uri value="http://loinc.org/property/analyte-numerator"/> + <description value="The numerator part of the analyte, i.e., everything before the slash in analytes that contain a divisor"/> + <type value="Coding"/> + </property> + <property> + <code value="analyte-divisor"/> + <uri value="http://loinc.org/property/analyte-divisor"/> + <description value="The divisor part of the analyte, if present, i.e., after the slash and before the first carat"/> + <type value="Coding"/> + </property> + <property> + <code value="analyte-divisor-suffix"/> + <uri value="http://loinc.org/property/analyte-divisor-suffix"/> + <description value="The suffix part of the divisor, if present"/> + <type value="Coding"/> + </property> + <property> + <code value="challenge"/> + <uri value="http://loinc.org/property/challenge"/> + <description value="Second sub-part of the Component, i.e., after the first carat"/> + <type value="Coding"/> + </property> + <property> + <code value="adjustment"/> + <uri value="http://loinc.org/property/adjustment"/> + <description value="Third sub-part of the Component, i.e., after the second carat"/> + <type value="Coding"/> + </property> + <property> + <code value="count"/> + <uri value="http://loinc.org/property/count"/> + <description value="Fourth sub-part of the Component, i.e., after the third carat"/> + <type value="Coding"/> + </property> + <property> + <code value="time-core"/> + <uri value="http://loinc.org/property/time-core"/> + <description value="The primary part of the Time"/> + <type value="Coding"/> + </property> + <property> + <code value="time-modifier"/> + <uri value="http://loinc.org/property/time-modifier"/> + <description value="The modifier of the Time value, such as mean or max"/> + <type value="Coding"/> + </property> + <property> + <code value="system-core"/> + <uri value="http://loinc.org/property/system-core"/> + <description value="The primary part of the System, i.e., without the super system"/> + <type value="Coding"/> + </property> + <property> + <code value="super-system"/> + <uri value="http://loinc.org/property/super-system"/> + <description value="The super system part of the System, if present. The super system represents the source of the specimen when the source is someone or something other than the patient whose chart the result will be stored in. For example, fetus is the super system for measurements done on obstetric ultrasounds, because the fetus is being measured and that measurement is being recorded in the patient's (mother's) chart."/> + <type value="Coding"/> + </property> + <property> + <code value="analyte-gene"/> + <uri value="http://loinc.org/property/analyte-gene"/> + <description value="The specific gene represented in the analyte"/> + <type value="Coding"/> + </property> + <property> + <code value="category"/> + <uri value="http://loinc.org/property/category"/> + <description value="A single LOINC term can be assigned one or more categories based on both programmatic and manual tagging. Category properties also utilize LOINC Class Parts."/> + <type value="Coding"/> + </property> + <property> + <code value="search"/> + <uri value="http://loinc.org/property/search"/> + <description value="Synonyms, fragments, and other Parts that are linked to a term to enable more encompassing search results."/> + <type value="Coding"/> + </property> + + <!-- + LOINC/RSNA Radiology Playbook properties. These apply only to terms in the LOINC/RSNA Radiology Playbook File. + Notes: + Properties are specified as type "coding", which are represented by LOINC Part codes (LP-) and their display names. + The attribute names here use FHIR styled names rather than their original LOINC style names because the original names contain periods. + --> + + <property> + <code value="rad-modality-modality-type"/> + <uri value="http://loinc.org/property/rad-modality-modality-type"/> + <description value="Modality is used to represent the device used to acquire imaging information."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-modality-modality-subtype"/> + <uri value="http://loinc.org/property/rad-modality-modality-subtype"/> + <description value="Modality subtype may be optionally included to signify a particularly common or evocative configuration of the modality."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-anatomic-location-region-imaged"/> + <uri value="http://loinc.org/property/rad-anatomic-location-region-imaged"/> + <description value="The Anatomic Location Region Imaged attribute is used in two ways: as a coarse-grained descriptor of the area imaged and a grouper for finding related imaging exams; or, it is used just as a grouper."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-anatomic-location-imaging-focus"/> + <uri value="http://loinc.org/property/rad-anatomic-location-imaging-focus"/> + <description value="The Anatomic Location Imaging Focus is a more fine-grained descriptor of the specific target structure of an imaging exam. In many areas, the focus should be a specific organ."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-anatomic-location-laterality-presence"/> + <uri value="http://loinc.org/property/rad-anatomic-location-laterality-presence"/> + <description value="Radiology Exams that require laterality to be specified in order to be performed are signified with an Anatomic Location Laterality Presence attribute set to 'True'"/> + <type value="Coding"/> + </property> + <property> + <code value="rad-anatomic-location-laterality"/> + <uri value="http://loinc.org/property/rad-anatomic-location-laterality"/> + <description value="Radiology exam Laterality is specified as one of: Left, Right, Bilateral, Unilateral, Unspecified"/> + <type value="Coding"/> + </property> + <property> + <code value="rad-view-aggregation"/> + <uri value="http://loinc.org/property/rad-view-aggregation"/> + <description value="Aggregation describes the extent of the imaging performed, whether in quantitative terms (e.g., '3 or more views') or subjective terms (e.g., 'complete')."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-view-view-type"/> + <uri value="http://loinc.org/property/rad-view-view-type"/> + <description value="View type names specific views, such as 'lateral' or 'AP'."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-maneuver-maneuver-type"/> + <uri value="http://loinc.org/property/rad-maneuver-maneuver-type"/> + <description value="Maneuver type indicates an action taken with the goal of elucidating or testing a dynamic aspect of the anatomy."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-timing"/> + <uri value="http://loinc.org/property/rad-timing"/> + <description value="The Timing/Existence property used in conjunction with pharmaceutical and maneuver properties. It specifies whether or not the imaging occurs in the presence of the administered pharmaceutical or a maneuver designed to test some dynamic aspect of anatomy or physiology ."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-pharmaceutical-substance-given"/> + <uri value="http://loinc.org/property/rad-pharmaceutical-substance-given"/> + <description value="The Pharmaceutical Substance Given specifies administered contrast agents, radiopharmaceuticals, medications, or other clinically important agents and challenges during the imaging procedure."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-pharmaceutical-route"/> + <uri value="http://loinc.org/property/rad-pharmaceutical-route"/> + <description value="Route specifies the route of administration of the pharmaceutical."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-reason-for-exam"/> + <uri value="http://loinc.org/property/rad-reason-for-exam"/> + <description value="Reason for exam is used to describe a clinical indication or a purpose for the study."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-guidance-for-presence"/> + <uri value="http://loinc.org/property/rad-guidance-for-presence"/> + <description value="Guidance for.Presence indicates when a procedure is guided by imaging."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-guidance-for-approach"/> + <uri value="http://loinc.org/property/rad-guidance-for-approach"/> + <description value="Guidance for.Approach refers to the primary route of access used, such as percutaneous, transcatheter, or transhepatic."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-guidance-for-action"/> + <uri value="http://loinc.org/property/rad-guidance-for-action"/> + <description value="Guidance for.Action indicates the intervention performed, such as biopsy, aspiration, or ablation."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-guidance-for-object"/> + <uri value="http://loinc.org/property/rad-guidance-for-object"/> + <description value="Guidance for.Object specifies the target of the action, such as mass, abscess or cyst."/> + <type value="Coding"/> + </property> + <property> + <code value="rad-subject"/> + <uri value="http://loinc.org/property/rad-subject"/> + <description value="Subject is intended for use when there is a need to distinguish between the patient associated with an imaging study, and the target of the study."/> + <type value="Coding"/> + </property> + + <!-- + Document Ontology properties. + These apply only to terms in the LOINC Document Ontology File + Notes + Properties are specified as type "coding", which are represented by LOINC Part codes (LP-) and their display names. + The attribute names here use FHIR styled names rather than their original LOINC style names because those contain periods. + --> + + <property> + <code value="document-kind"/> + <uri value="http://loinc.org/property/document-kind"/> + <description value="Characterizes the general structure of the document at a macro level."/> + <type value="Coding"/> + </property> + <property> + <code value="document-role"/> + <uri value="http://loinc.org/property/document-role"/> + <description value="Characterizes the training or professional level of the author of the document, but does not break down to specialty or subspecialty."/> + <type value="Coding"/> + </property> + <property> + <code value="document-setting"/> + <uri value="http://loinc.org/property/document-setting"/> + <description value="Setting is a modest extension of CMS’s coarse definition of care settings, such as outpatient, hospital, etc. Setting is not equivalent to location, which typically has more locally defined meanings."/> + <type value="Coding"/> + </property> + <property> + <code value="document-subject-matter-domain"/> + <uri value="http://loinc.org/property/document-subject-matter-domain"/> + <description value="Characterizes the clinical domain that is the subject of the document. For example, Internal Medicine, Neurology, Physical Therapy, etc."/> + <type value="Coding"/> + </property> + <property> + <code value="document-type-of-service"/> + <uri value="http://loinc.org/property/document-type-of-service"/> + <description value="Characterizes the kind of service or activity provided to/for the patient (or other subject of the service) that is described in the document."/> + <type value="Coding"/> + </property> + + <!-- Answer list related properties --> + <property> + <code value="answers-for"/> + <uri value="http://loinc.org/property/answers-for"/> + <description value="A LOINC Code for which this answer list is used."/> + <type value="Coding"/> + </property> + + <!-- Note for future consideration. These are properties of LA codes in the context of a particular list. Not global properties. + <property> + <code value="sequence"/> + <uri value="http://loinc.org/property/sequence"/> + <description value="Sequence Number of a answer in a set of answers (LA- codes only)"/> + <type value="integer"/> + </property> + <property> + <code value="score"/> + <uri value="http://loinc.org/property/score"/> + <description value="Score assigned to an answer (LA- codes only)"/> + <type value="integer"/> + </property> + --> </CodeSystem> + diff --git a/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/term/loinc/loincupload.properties b/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/term/loinc/loincupload.properties new file mode 100644 index 00000000000..986d2afdaa0 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/main/resources/ca/uhn/fhir/jpa/term/loinc/loincupload.properties @@ -0,0 +1,83 @@ +################# +### MANDATORY ### +################# + +# Answer lists (ValueSets of potential answers/values for LOINC "questions") +## File must be present +loinc.answerlist.file=AccessoryFiles/AnswerFile/AnswerList.csv +# Answer list links (connects LOINC observation codes to answer list codes) +## File must be present +loinc.answerlist.link.file=AccessoryFiles/AnswerFile/LoincAnswerListLink.csv + +# Document ontology +## File must be present +loinc.document.ontology.file=AccessoryFiles/DocumentOntology/DocumentOntology.csv + +# LOINC codes +## File must be present +loinc.file=LoincTable/Loinc.csv + +# LOINC hierarchy +## File must be present +loinc.hierarchy.file=AccessoryFiles/MultiAxialHierarchy/MultiAxialHierarchy.csv + +# IEEE medical device codes +## File must be present +loinc.ieee.medical.device.code.mapping.table.file=AccessoryFiles/LoincIeeeMedicalDeviceCodeMappingTable/LoincIeeeMedicalDeviceCodeMappingTable.csv + +# Imaging document codes +## File must be present +loinc.imaging.document.codes.file=AccessoryFiles/ImagingDocuments/ImagingDocumentCodes.csv + +# Part +## File must be present +loinc.part.file=AccessoryFiles/PartFile/Part.csv + +# Part link +## File must be present +loinc.part.link.primary.file=AccessoryFiles/PartFile/LoincPartLink_Primary.csv +loinc.part.link.supplementary.file=AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv + +# Part related code mapping +## File must be present +loinc.part.related.code.mapping.file=AccessoryFiles/PartFile/PartRelatedCodeMapping.csv + +# RSNA playbook +## File must be present +loinc.rsna.playbook.file=AccessoryFiles/LoincRsnaRadiologyPlaybook/LoincRsnaRadiologyPlaybook.csv + +# Top 2000 codes - SI +## File must be present +loinc.top2000.common.lab.results.si.file=AccessoryFiles/Top2000Results/SI/Top2000CommonLabResultsSi.csv +# Top 2000 codes - US +## File must be present +loinc.top2000.common.lab.results.us.file=AccessoryFiles/Top2000Results/US/Top2000CommonLabResultsUs.csv + +# Universal lab order ValueSet +## File must be present +loinc.universal.lab.order.valueset.file=AccessoryFiles/LoincUniversalLabOrdersValueSet/LoincUniversalLabOrdersValueSet.csv + +################ +### OPTIONAL ### +################ + +# This is the version identifier for the answer list file +## Key may be omitted +loinc.answerlist.version=Beta.1 + +# This is the version identifier for uploaded ConceptMap resources +## Key may be omitted +loinc.conceptmap.version=Beta.1 + +# Group +## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv +## File may be omitted +loinc.group.file=AccessoryFiles/GroupFile/Group.csv +# Group terms +## Default value if key not provided: AccessoryFiles/GroupFile/GroupLoincTerms.csv +## File may be omitted +loinc.group.terms.file=AccessoryFiles/GroupFile/GroupLoincTerms.csv +# Parent group +## Default value if key not provided: AccessoryFiles/GroupFile/ParentGroup.csv +## File may be omitted +loinc.parent.group.file=AccessoryFiles/GroupFile/ParentGroup.csv diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java index cfb73e25a0b..e53eeb26014 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java @@ -492,7 +492,8 @@ public class TerminologyUploaderProviderR4Test extends BaseResourceProviderR4Tes addFile(zos, LOINC_GROUP_FILE_DEFAULT.getCode()); addFile(zos, LOINC_GROUP_TERMS_FILE_DEFAULT.getCode()); addFile(zos, LOINC_PARENT_GROUP_FILE_DEFAULT.getCode()); - addFile(zos, LOINC_PART_LINK_FILE_DEFAULT.getCode()); + addFile(zos, LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()); + addFile(zos, LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode()); addFile(zos, LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode()); addFile(zos, LOINC_DOCUMENT_ONTOLOGY_FILE_DEFAULT.getCode()); addFile(zos, LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode()); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcIntegrationDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcIntegrationDstu3Test.java index dd4abe50c7f..6a06243fde9 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcIntegrationDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcIntegrationDstu3Test.java @@ -86,7 +86,7 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test { 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")); + assertThat(codes, containsInAnyOrder("10013-1")); // Search by display name input = new ValueSet(); @@ -101,7 +101,7 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test { 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")); + assertThat(codes, containsInAnyOrder("10013-1")); // Search by something that doesn't match input = new ValueSet(); @@ -149,7 +149,7 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test { 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", "10000-8", "10016-4", "10017-2", "10015-6", "10020-6", "10018-0")); + assertThat(codes, containsInAnyOrder("10013-1")); } @Test @@ -188,7 +188,7 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test { TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesToZip(files); myLoader.loadLoinc(files.getFiles(), mySrd); - IValidationSupport.LookupCodeResult result = myCodeSystemDao.lookupCode(new StringType("17788-1"), new StringType(ITermLoaderSvc.LOINC_URI), null, mySrd); + IValidationSupport.LookupCodeResult result = myCodeSystemDao.lookupCode(new StringType("10013-1"), new StringType(ITermLoaderSvc.LOINC_URI), null, mySrd); Parameters parameters = (Parameters) result.toParameters(myFhirCtx, null); ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(parameters)); @@ -196,8 +196,8 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test { Optional<Coding> propertyValue = findProperty(parameters, "COMPONENT"); assertTrue(propertyValue.isPresent()); assertEquals(ITermLoaderSvc.LOINC_URI, propertyValue.get().getSystem()); - assertEquals("LP19258-0", propertyValue.get().getCode()); - assertEquals("Large unstained cells/100 leukocytes", propertyValue.get().getDisplay()); + assertEquals("LP31101-6", propertyValue.get().getCode()); + assertEquals("R' wave amplitude.lead I", propertyValue.get().getDisplay()); } @Test diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincTest.java index 1cef209f864..342c82421eb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologyLoaderSvcLoincTest.java @@ -76,18 +76,20 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest { // Normal LOINC code code = concepts.get("10013-1"); assertEquals("10013-1", code.getCode()); + // Coding Property assertEquals(ITermLoaderSvc.LOINC_URI, code.getCodingProperties("PROPERTY").get(0).getSystem()); assertEquals("LP6802-5", code.getCodingProperties("PROPERTY").get(0).getCode()); assertEquals("Elpot", code.getCodingProperties("PROPERTY").get(0).getDisplay()); - assertEquals("EKG.MEAS", code.getStringProperty("CLASS")); + // String Property + assertEquals("2", code.getStringProperty("CLASSTYPE")); assertEquals("R' wave amplitude in lead I", code.getDisplay()); - + // Coding Property from Part File + assertEquals(ITermLoaderSvc.LOINC_URI, code.getCodingProperties("TIME_ASPCT").get(0).getSystem()); + assertEquals("LP6960-1", code.getCodingProperties("TIME_ASPCT").get(0).getCode()); + assertEquals("Pt", code.getCodingProperties("TIME_ASPCT").get(0).getDisplay()); // Code with component that has a divisor code = concepts.get("17788-1"); assertEquals("17788-1", code.getCode()); - assertEquals(1, code.getCodingProperties("COMPONENT").size()); - assertEquals("http://loinc.org", code.getCodingProperties("COMPONENT").get(0).getSystem()); - assertEquals("LP19258-0", code.getCodingProperties("COMPONENT").get(0).getCode()); // LOINC code with answer code = concepts.get("61438-8"); @@ -379,7 +381,8 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest { theFiles.addFileZip("/loinc/", LOINC_ANSWERLIST_LINK_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_ANSWERLIST_LINK_DUPLICATE_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_PART_FILE_DEFAULT.getCode()); - theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_DEFAULT.getCode()); + theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()); + theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_DOCUMENT_ONTOLOGY_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode()); @@ -413,7 +416,10 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest { assertEquals(ITermLoaderSvc.LOINC_URI, code.getCodingProperties("PROPERTY").get(0).getSystem()); assertEquals("LP6802-5", code.getCodingProperties("PROPERTY").get(0).getCode()); assertEquals("Elpot", code.getCodingProperties("PROPERTY").get(0).getDisplay()); - assertEquals("EKG.MEAS", code.getStringProperty("CLASS")); + assertEquals(ITermLoaderSvc.LOINC_URI, code.getCodingProperties("PROPERTY").get(0).getSystem()); + assertEquals("LP6802-5", code.getCodingProperties("PROPERTY").get(0).getCode()); + assertEquals("Elpot", code.getCodingProperties("PROPERTY").get(0).getDisplay()); + assertEquals("2", code.getStringProperty("CLASSTYPE")); assertEquals("R' wave amplitude in lead I", code.getDisplay()); // Codes with parent and child properties diff --git a/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink.csv b/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink.csv deleted file mode 100644 index 07277640bd7..00000000000 --- a/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink.csv +++ /dev/null @@ -1,10 +0,0 @@ -"LoincNumber","LongCommonName","PartNumber","PartName","PartTypeName","LinkTypeName" -"10000-8","R wave duration in lead AVR","LP31088-5","R wave duration.lead AVR","COMPONENT","Primary" -"10000-8","R wave duration in lead AVR","LP6244-0","EKG","METHOD","Primary" -"10000-8","R wave duration in lead AVR","LP6879-3","Time","PROPERTY","Primary" -"10000-8","R wave duration in lead AVR","LP6960-1","Pt","TIME","Primary" -"10000-8","R wave duration in lead AVR","LP7289-4","Heart","SYSTEM","Primary" -"10000-8","R wave duration in lead AVR","LP7753-9","Qn","SCALE","Primary" -"10000-8","R wave duration in lead AVR","LP7795-0","EKG.MEAS","CLASS","Primary" -"10000-8","R wave duration in lead AVR","LP14259-3","Lead","COMPONENT","Search" -"10000-8","R wave duration in lead AVR","LP14744-4","Duration","COMPONENT","Search" diff --git a/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink_Primary.csv b/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink_Primary.csv new file mode 100644 index 00000000000..8dbe575ffd2 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink_Primary.csv @@ -0,0 +1,7 @@ +"LoincNumber","LongCommonName" ,"PartNumber","PartName" ,"PartCodeSystem" ,"PartTypeName","LinkTypeName","Property" +"10013-1" ,"R' wave amplitude in lead I","LP31101-6" ,"R' wave amplitude.lead I","http://loinc.org","COMPONENT" ,"Primary" ,"http://loinc.org/property/COMPONENT" +"10013-1" ,"R' wave amplitude in lead I","LP6802-5" ,"Elpot" ,"http://loinc.org","PROPERTY" ,"Primary" ,"http://loinc.org/property/PROPERTY" +"10013-1" ,"R' wave amplitude in lead I","LP6960-1" ,"Pt" ,"http://loinc.org","TIME" ,"Primary" ,"http://loinc.org/property/TIME_ASPCT" +"10013-1" ,"R' wave amplitude in lead I","LP7289-4" ,"Heart" ,"http://loinc.org","SYSTEM" ,"Primary" ,"http://loinc.org/property/SYSTEM" +"10013-1" ,"R' wave amplitude in lead I","LP7753-9" ,"Qn" ,"http://loinc.org","SCALE" ,"Primary" ,"http://loinc.org/property/SCALE_TYP" +"10013-1" ,"R' wave amplitude in lead I","LP6244-0" ,"EKG" ,"http://loinc.org","METHOD" ,"Primary" ,"http://loinc.org/property/METHOD_TYP" diff --git a/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv b/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv new file mode 100644 index 00000000000..869c2c1651d --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/loinc/AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv @@ -0,0 +1,13 @@ +"LoincNumber","LongCommonName" ,"PartNumber","PartName" ,"PartCodeSystem" ,"PartTypeName","LinkTypeName" ,"Property" +"10013-1" ,"R' wave amplitude in lead I","LP31101-6" ,"R' wave amplitude.lead I","http://loinc.org","COMPONENT" ,"DetailedModel" ,"http://loinc.org/property/analyte" +"10013-1" ,"R' wave amplitude in lead I","LP6802-5" ,"Elpot" ,"http://loinc.org","PROPERTY" ,"DetailedModel" ,"http://loinc.org/property/PROPERTY" +"10013-1" ,"R' wave amplitude in lead I","LP6960-1" ,"Pt" ,"http://loinc.org","TIME" ,"DetailedModel" ,"http://loinc.org/property/time-core" +"10013-1" ,"R' wave amplitude in lead I","LP7289-4" ,"Heart" ,"http://loinc.org","SYSTEM" ,"DetailedModel" ,"http://loinc.org/property/system-core" +"10013-1" ,"R' wave amplitude in lead I","LP7753-9" ,"Qn" ,"http://loinc.org","SCALE" ,"DetailedModel" ,"http://loinc.org/property/SCALE_TYP" +"10013-1" ,"R' wave amplitude in lead I","LP6244-0" ,"EKG" ,"http://loinc.org","METHOD" ,"DetailedModel" ,"http://loinc.org/property/METHOD_TYP" +"10013-1" ,"R' wave amplitude in lead I","LP31101-6" ,"R' wave amplitude.lead I","http://loinc.org","COMPONENT" ,"SyntaxEnhancement","http://loinc.org/property/analyte-core" +"10013-1" ,"R' wave amplitude in lead I","LP190563-9","Cardiology" ,"http://loinc.org","CLASS" ,"Metadata" ,"http://loinc.org/property/category" +"10013-1" ,"R' wave amplitude in lead I","LP29708-2" ,"Cardiology" ,"http://loinc.org","CLASS" ,"Metadata" ,"http://loinc.org/property/category" +"10013-1" ,"R' wave amplitude in lead I","LP7787-7" ,"Clinical" ,"http://loinc.org","CLASS" ,"Metadata" ,"http://loinc.org/property/category" +"10013-1" ,"R' wave amplitude in lead I","LP7795-0" ,"EKG measurements" ,"http://loinc.org","CLASS" ,"Metadata" ,"http://loinc.org/property/category" +"10013-1" ,"R' wave amplitude in lead I","LP7795-0" ,"EKG.MEAS" ,"http://loinc.org","CLASS" ,"Metadata" ,"http://loinc.org/property/CLASS" diff --git a/hapi-fhir-jpaserver-base/src/test/resources/loinc/loincupload.properties b/hapi-fhir-jpaserver-base/src/test/resources/loinc/loincupload.properties index 3c01c55a2a9..986d2afdaa0 100644 --- a/hapi-fhir-jpaserver-base/src/test/resources/loinc/loincupload.properties +++ b/hapi-fhir-jpaserver-base/src/test/resources/loinc/loincupload.properties @@ -3,68 +3,57 @@ ################# # Answer lists (ValueSets of potential answers/values for LOINC "questions") -## Default value if key not provided: AccessoryFiles/AnswerFile/AnswerList.csv ## File must be present loinc.answerlist.file=AccessoryFiles/AnswerFile/AnswerList.csv # Answer list links (connects LOINC observation codes to answer list codes) -## Default value if key not provided: AccessoryFiles/AnswerFile/LoincAnswerListLink.csv ## File must be present loinc.answerlist.link.file=AccessoryFiles/AnswerFile/LoincAnswerListLink.csv # Document ontology -## Default value if key not provided: AccessoryFiles/DocumentOntology/DocumentOntology.csv ## File must be present loinc.document.ontology.file=AccessoryFiles/DocumentOntology/DocumentOntology.csv # LOINC codes -## Default value if key not provided: LoincTable/Loinc.csv ## File must be present loinc.file=LoincTable/Loinc.csv # LOINC hierarchy -## Default value if key not provided: AccessoryFiles/MultiAxialHierarchy/MultiAxialHierarchy.csv ## File must be present loinc.hierarchy.file=AccessoryFiles/MultiAxialHierarchy/MultiAxialHierarchy.csv # IEEE medical device codes -## Default value if key not provided: AccessoryFiles/LoincIeeeMedicalDeviceCodeMappingTable/LoincIeeeMedicalDeviceCodeMappingTable.csv ## File must be present loinc.ieee.medical.device.code.mapping.table.file=AccessoryFiles/LoincIeeeMedicalDeviceCodeMappingTable/LoincIeeeMedicalDeviceCodeMappingTable.csv # Imaging document codes -## Default value if key not provided: AccessoryFiles/ImagingDocuments/ImagingDocumentCodes.csv ## File must be present loinc.imaging.document.codes.file=AccessoryFiles/ImagingDocuments/ImagingDocumentCodes.csv # Part -## Default value if key not provided: AccessoryFiles/PartFile/Part.csv ## File must be present loinc.part.file=AccessoryFiles/PartFile/Part.csv + # Part link -## Default value if key not provided: AccessoryFiles/PartFile/LoincPartLink.csv ## File must be present -loinc.part.link.file=AccessoryFiles/PartFile/LoincPartLink.csv +loinc.part.link.primary.file=AccessoryFiles/PartFile/LoincPartLink_Primary.csv +loinc.part.link.supplementary.file=AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv + # Part related code mapping -## Default value if key not provided: AccessoryFiles/PartFile/PartRelatedCodeMapping.csv ## File must be present loinc.part.related.code.mapping.file=AccessoryFiles/PartFile/PartRelatedCodeMapping.csv # RSNA playbook -## Default value if key not provided: AccessoryFiles/LoincRsnaRadiologyPlaybook/LoincRsnaRadiologyPlaybook.csv ## File must be present loinc.rsna.playbook.file=AccessoryFiles/LoincRsnaRadiologyPlaybook/LoincRsnaRadiologyPlaybook.csv # Top 2000 codes - SI -## Default value if key not provided: AccessoryFiles/Top2000Results/SI/Top2000CommonLabResultsSi.csv ## File must be present loinc.top2000.common.lab.results.si.file=AccessoryFiles/Top2000Results/SI/Top2000CommonLabResultsSi.csv # Top 2000 codes - US -## Default value if key not provided: AccessoryFiles/Top2000Results/US/Top2000CommonLabResultsUs.csv ## File must be present loinc.top2000.common.lab.results.us.file=AccessoryFiles/Top2000Results/US/Top2000CommonLabResultsUs.csv # Universal lab order ValueSet -## Default value if key not provided: AccessoryFiles/LoincUniversalLabOrdersValueSet/LoincUniversalLabOrdersValueSet.csv ## File must be present loinc.universal.lab.order.valueset.file=AccessoryFiles/LoincUniversalLabOrdersValueSet/LoincUniversalLabOrdersValueSet.csv diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/FhirTerserR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/FhirTerserR4Test.java index c06e09405c0..b695d947ed7 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/FhirTerserR4Test.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/FhirTerserR4Test.java @@ -6,10 +6,30 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.annotation.Block; import ca.uhn.fhir.parser.DataFormatException; import org.hamcrest.Matchers; -import org.hl7.fhir.instance.model.api.*; -import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.instance.model.api.IBase; +import org.hl7.fhir.instance.model.api.IBaseExtension; +import org.hl7.fhir.instance.model.api.IBaseReference; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IPrimitiveType; +import org.hl7.fhir.r4.model.BooleanType; +import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Enumeration; +import org.hl7.fhir.r4.model.Enumerations; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.MarkdownType; +import org.hl7.fhir.r4.model.Money; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.Organization; +import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient.LinkType; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.PrimitiveType; +import org.hl7.fhir.r4.model.Quantity; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.SimpleQuantity; +import org.hl7.fhir.r4.model.StringType; +import org.hl7.fhir.r4.model.ValueSet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; @@ -19,11 +39,22 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when;