001/*- 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.term.loinc; 021 022import ca.uhn.fhir.i18n.Msg; 023import ca.uhn.fhir.jpa.entity.TermConcept; 024import ca.uhn.fhir.jpa.term.IZipContentsHandlerCsv; 025import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; 026import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 027import org.apache.commons.csv.CSVRecord; 028import org.hl7.fhir.r4.model.ConceptMap; 029import org.hl7.fhir.r4.model.Enumerations; 030import org.hl7.fhir.r4.model.ValueSet; 031 032import java.util.List; 033import java.util.Map; 034import java.util.Properties; 035 036import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_VERSION; 037import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CONCEPTMAP_VERSION; 038import static org.apache.commons.lang3.StringUtils.defaultString; 039import static org.apache.commons.lang3.StringUtils.trim; 040 041public class LoincPartRelatedCodeMappingHandler extends BaseLoincHandler implements IZipContentsHandlerCsv { 042 043 public static final String LOINC_SCT_PART_MAP_ID = "loinc-parts-to-snomed-ct"; 044 public static final String LOINC_SCT_PART_MAP_URI = "http://loinc.org/cm/loinc-parts-to-snomed-ct"; 045 public static final String LOINC_TERM_TO_RPID_PART_MAP_ID = "loinc-to-radlex"; 046 public static final String LOINC_TERM_TO_RPID_PART_MAP_URI = "http://loinc.org/cm/loinc-to-radlex"; 047 public static final String LOINC_TERM_TO_RPID_PART_MAP_NAME = "LOINC Terms to RadLex RPIDs"; 048 public static final String LOINC_PART_TO_RID_PART_MAP_ID = "loinc-parts-to-radlex"; 049 public static final String LOINC_PART_TO_RID_PART_MAP_URI = "http://loinc.org/cm/loinc-parts-to-radlex"; 050 public static final String LOINC_PART_TO_RID_PART_MAP_NAME = "LOINC Parts to RadLex RIDs"; 051 private static final String LOINC_SCT_PART_MAP_NAME = "LOINC Part Map to SNOMED CT"; 052 private static final String LOINC_RXNORM_PART_MAP_ID = "loinc-parts-to-rxnorm"; 053 private static final String LOINC_RXNORM_PART_MAP_URI = "http://loinc.org/cm/loinc-parts-to-rxnorm"; 054 private static final String LOINC_RXNORM_PART_MAP_NAME = "LOINC Part Map to RxNORM"; 055 056 private static final String LOINC_PUBCHEM_PART_MAP_ID = "loinc-parts-to-pubchem"; 057 private static final String LOINC_PUBCHEM_PART_MAP_URI = "http://loinc.org/cm/loinc-parts-to-pubchem"; 058 private static final String LOINC_PUBCHEM_PART_MAP_NAME = "LOINC Part Map to PubChem"; 059 060 private static final String CM_COPYRIGHT = 061 "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."; 062 063 public LoincPartRelatedCodeMappingHandler( 064 Map<String, TermConcept> theCode2concept, 065 List<ValueSet> theValueSets, 066 List<ConceptMap> theConceptMaps, 067 Properties theUploadProperties, 068 String theCopyrightStatement) { 069 super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties, theCopyrightStatement); 070 } 071 072 @Override 073 public void accept(CSVRecord theRecord) { 074 075 String partNumber = trim(theRecord.get("PartNumber")); 076 String partName = trim(theRecord.get("PartName")); 077 String extCodeId = trim(theRecord.get("ExtCodeId")); 078 // TODO: use hex code for ascii 160 079 extCodeId = extCodeId.replace(" ", ""); 080 String extCodeDisplayName = trim(theRecord.get("ExtCodeDisplayName")); 081 String extCodeSystem = trim(theRecord.get("ExtCodeSystem")); 082 String mapType = trim(theRecord.get("Equivalence")); 083 String extCodeSystemVersion = trim(theRecord.get("ExtCodeSystemVersion")); 084 String extCodeSystemCopyrightNotice = trim(theRecord.get("ExtCodeSystemCopyrightNotice")); 085 086 // CodeSystem version from properties file 087 String codeSystemVersionId = myUploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode()); 088 089 // ConceptMap version from properties files 090 String loincPartMapVersion; 091 if (codeSystemVersionId != null) { 092 loincPartMapVersion = 093 myUploadProperties.getProperty(LOINC_CONCEPTMAP_VERSION.getCode()) + "-" + codeSystemVersionId; 094 } else { 095 loincPartMapVersion = myUploadProperties.getProperty(LOINC_CONCEPTMAP_VERSION.getCode()); 096 } 097 098 Enumerations.ConceptMapEquivalence equivalence; 099 switch (trim(defaultString(mapType))) { 100 case "": 101 case "equivalent": 102 // 'equal' is more exact than 'equivalent' in the equivalence codes 103 equivalence = Enumerations.ConceptMapEquivalence.EQUAL; 104 break; 105 case "narrower": 106 equivalence = Enumerations.ConceptMapEquivalence.NARROWER; 107 break; 108 case "wider": 109 equivalence = Enumerations.ConceptMapEquivalence.WIDER; 110 break; 111 case "relatedto": 112 equivalence = Enumerations.ConceptMapEquivalence.RELATEDTO; 113 break; 114 default: 115 throw new InternalErrorException( 116 Msg.code(916) + "Unknown equivalence '" + mapType + "' for PartNumber: " + partNumber); 117 } 118 119 String loincPartMapId; 120 String loincPartMapUri; 121 String loincPartMapName; 122 switch (extCodeSystem) { 123 case ITermLoaderSvc.SCT_URI: 124 loincPartMapId = LOINC_SCT_PART_MAP_ID; 125 loincPartMapUri = LOINC_SCT_PART_MAP_URI; 126 loincPartMapName = LOINC_SCT_PART_MAP_NAME; 127 break; 128 case "http://www.nlm.nih.gov/research/umls/rxnorm": 129 loincPartMapId = LOINC_RXNORM_PART_MAP_ID; 130 loincPartMapUri = LOINC_RXNORM_PART_MAP_URI; 131 loincPartMapName = LOINC_RXNORM_PART_MAP_NAME; 132 break; 133 case "http://www.radlex.org": 134 loincPartMapId = LOINC_PART_TO_RID_PART_MAP_ID; 135 loincPartMapUri = LOINC_PART_TO_RID_PART_MAP_URI; 136 loincPartMapName = LOINC_PART_TO_RID_PART_MAP_NAME; 137 break; 138 case "http://pubchem.ncbi.nlm.nih.gov": 139 loincPartMapId = LOINC_PUBCHEM_PART_MAP_ID; 140 loincPartMapUri = LOINC_PUBCHEM_PART_MAP_URI; 141 loincPartMapName = LOINC_PUBCHEM_PART_MAP_NAME; 142 break; 143 default: 144 loincPartMapId = extCodeSystem.replaceAll("[^a-zA-Z]", ""); 145 loincPartMapUri = extCodeSystem; 146 loincPartMapName = "Unknown Mapping"; 147 break; 148 } 149 String conceptMapId; 150 if (codeSystemVersionId != null) { 151 conceptMapId = loincPartMapId + "-" + codeSystemVersionId; 152 } else { 153 conceptMapId = loincPartMapId; 154 } 155 156 addConceptMapEntry( 157 new ConceptMapping() 158 .setConceptMapId(conceptMapId) 159 .setConceptMapUri(loincPartMapUri) 160 .setConceptMapVersion(loincPartMapVersion) 161 .setConceptMapName(loincPartMapName) 162 .setSourceCodeSystem(ITermLoaderSvc.LOINC_URI) 163 .setSourceCodeSystemVersion(codeSystemVersionId) 164 .setSourceCode(partNumber) 165 .setSourceDisplay(partName) 166 .setTargetCodeSystem(extCodeSystem) 167 .setTargetCode(extCodeId) 168 .setTargetDisplay(extCodeDisplayName) 169 .setTargetCodeSystemVersion(extCodeSystemVersion) 170 .setEquivalence(equivalence) 171 .setCopyright(extCodeSystemCopyrightNotice), 172 myLoincCopyrightStatement + " " + CM_COPYRIGHT); 173 } 174}