Search in sources :

Example 11 with ConceptMap

use of org.hl7.fhir.r4b.model.ConceptMap in project health-patterns by LinuxForHealth.

the class TerminologyService method translateResource.

/**
 * Translates the given single FHIR resource represented as a {@link JsonNode}.
 *
 * @param resource the FHIR resource to translate
 * @returns true if there was something to translate, false otherwise
 * @throws DeIdentifierException if there is an error in the de-identification REST API or parsing the JSON
 * @throws IllegalArgumentException if the given JSON does not have a 'resource' object
 */
private boolean translateResource(JsonNode resource) {
    boolean translatedSomething = false;
    String resourceType = getResourceType(resource);
    boolean isTranslatable = StringUtils.equalsAny(resourceType, TRANSLATABLE_FHIR_TYPES);
    if (!isTranslatable) {
        return translatedSomething;
    }
    ArrayNode extensions = (ArrayNode) resource.get(EXTENSION_OBJECT);
    if (extensions == null) {
        return translatedSomething;
    }
    for (int i = 0; i < extensions.size(); i++) {
        JsonNode extension = extensions.get(i);
        JsonNode urlJson = extension.get(URL_OBJECT);
        JsonNode valueCodeJson = extension.get(VALUE_CODE_OBJECT);
        if (urlJson == null || valueCodeJson == null) {
            // In order to do a translation we need both the url and the valueCode
            continue;
        }
        // The resource's extension URL is the URL for the StructureDefinition, so we resolve a ValueSet if known
        String structureDefinitionURL = urlJson.asText();
        String valueSetURL = valueSetForStructureDefinition.get(structureDefinitionURL);
        // and if known we check the FHIR Server's known ConceptMaps to see if there is a corresponding one
        // http://4603f72b-us-south.lb.appdomain.cloud/fhir-server/api/v4/ConceptMap?_format=json&source-uri=http://hl7.org/fhir/us/core/ValueSet/birthsex
        Bundle bundle = fhirClient.search().forResource(ConceptMap.class).where(ConceptMap.SOURCE_URI.hasId(valueSetURL)).returnBundle(Bundle.class).execute();
        String conceptMapId;
        if (!bundle.getEntry().isEmpty()) {
            Resource conceptMap = bundle.getEntry().get(0).getResource();
            if (bundle.getEntry().size() > 1) {
                System.err.println("Found multiple ConceptMaps that will map " + valueSetURL + " for this StructureDefinition, will use the first one " + conceptMap.getId());
            } else {
                System.out.println("Found ConceptMap for " + valueSetURL + ": " + conceptMap.getId() + " !!");
            }
            conceptMapId = conceptMap.getIdElement().getIdPart();
        } else {
            System.out.println("Did not find ConceptMap for " + valueSetURL + "!!");
            continue;
        }
        // "POST ${FHIR_URL}/${conceptMapID}/$translate?code=${code}&system=${valueSet}&_format=json
        String valueCode = valueCodeJson.asText();
        String url = String.format("%s/ConceptMap/%s/$translate?code=%s&system=%s&_format=json", fhirClient.getServerBase(), conceptMapId, valueCode, valueSetURL);
        Parameters translationResponse = fhirClient.fetchResourceFromUrl(Parameters.class, url);
        // This is what comes back from the server
        // {
        // "resourceType": "Parameters",
        // "parameter": [
        // {
        // "name": "result",
        // "valueBoolean": true
        // },
        // {
        // "name": "match",
        // "part": [
        // {
        // "name": "equivalence",
        // "valueCode": "equivalent"
        // },
        // {
        // "name": "concept",
        // "valueCoding": {
        // "system": "http://ibm.com/fhir/cdm/ValueSet/sex-assigned-at-birth",
        // "code": "male",
        // "display": "Male"
        // }
        // }
        // ]
        // }
        // ]
        // }
        Coding translatedCode = null;
        List<ParametersParameterComponent> parameters = translationResponse.getParameter();
        for (ParametersParameterComponent parameter : parameters) {
            if (parameter.getName().equals(MATCH_VALUE)) {
                List<ParametersParameterComponent> parts = parameter.getPart();
                for (ParametersParameterComponent part : parts) {
                    if (part.getName().equals(CONCEPT_VALUE)) {
                        try {
                            translatedCode = (Coding) part.getValue();
                        } catch (ClassCastException e) {
                            String jsonResponse = fhirClient.getFhirContext().newJsonParser().encodeResourceToString(translationResponse);
                            System.err.println("Found a ConceptMap that will map " + valueSetURL + " for this StructureDefinition, but the FHIR server returned an unknown $translate response (expected a 'valueCoding' part): " + jsonResponse);
                        }
                    }
                }
            }
        }
        if (translatedCode == null) {
            String jsonResponse = fhirClient.getFhirContext().newJsonParser().encodeResourceToString(translationResponse);
            System.err.println("Found a ConceptMap that will map " + valueSetURL + " for this StructureDefinition, but the FHIR server returned an unknown $translate response: " + jsonResponse);
            continue;
        }
        System.out.printf("Found ConceptMap %s which translates (valueCode, system) = (%s, %s) for StructureDefinition %s to (valueCode, system) = (%s, %s) %n", conceptMapId, valueCode, valueSetURL, structureDefinitionURL, translatedCode.getCode(), translatedCode.getSystem());
        String translatedStructuredData = valueSetForStructureDefinition.get(translatedCode.getSystem());
        if (translatedStructuredData == null) {
            System.err.printf("Cannot find the mapping from ValueSet '%s' to its corresponding StructureData for this translation, make sure the corresponding mappings configuration file has it.%n", translatedCode.getSystem());
            continue;
        }
        ((ObjectNode) extension).set(URL_OBJECT, JsonNodeFactory.instance.textNode(translatedStructuredData));
        ((ObjectNode) extension).set(VALUE_CODE_OBJECT, JsonNodeFactory.instance.textNode(translatedCode.getCode()));
        translatedSomething = true;
    }
    return translatedSomething;
}
Also used : Parameters(org.hl7.fhir.r4.model.Parameters) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) Bundle(org.hl7.fhir.r4.model.Bundle) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) Resource(org.hl7.fhir.r4.model.Resource) JsonNode(com.fasterxml.jackson.databind.JsonNode) Coding(org.hl7.fhir.r4.model.Coding) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) ConceptMap(org.hl7.fhir.r4.model.ConceptMap) ParametersParameterComponent(org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent)

Example 12 with ConceptMap

use of org.hl7.fhir.r4b.model.ConceptMap in project cqf-ruler by DBCG.

the class TransformProvider method transformObservations.

@Operation(name = "$transform", idempotent = false, type = Observation.class)
public Bundle transformObservations(@OperationParam(name = "observations") Bundle observationsBundle, @OperationParam(name = "conceptMapURL") String conceptMapURL) {
    if (null == observationsBundle) {
        throw new IllegalArgumentException("Unable to perform operation Observation$transform.  No Observation bundle passed in.");
    }
    if (null == conceptMapURL) {
        throw new IllegalArgumentException("Unable to perform operation Observation$transform.  No concept map url specified.");
    }
    String replaceCode = mySdcProperties.getTransform().getReplaceCode();
    // String username = mySdcProperties.getTransform().getUsername();
    // String password = mySdcProperties.getTransform().getPassword();
    String endpoint = mySdcProperties.getTransform().getEndpoint();
    IGenericClient client = Clients.forUrl(fhirContext, endpoint);
    ConceptMap transformConceptMap = client.read().resource(ConceptMap.class).withUrl(conceptMapURL).execute();
    if (null == transformConceptMap) {
        throw new IllegalArgumentException("Unable to perform operation Observation$transform.  Unable to get concept map.");
    }
    List<Observation> observations = BundleUtil.toListOfResources(fhirContext, observationsBundle).stream().filter(resource -> resource instanceof Observation).map(Observation.class::cast).collect(Collectors.toList());
    /**
     * TODO - There must be a more efficient way to loop through this, but so far I
     * have not come up with it.
     */
    transformConceptMap.getGroup().forEach(group -> {
        HashMap<String, ConceptMap.TargetElementComponent> codeMappings = new HashMap<>();
        String targetSystem = group.getTarget();
        group.getElement().forEach(codeElement -> {
            codeMappings.put(codeElement.getCode(), codeElement.getTarget().get(0));
        });
        observations.forEach(observation -> {
            if (observation.getValue().fhirType().equalsIgnoreCase("codeableconcept")) {
                String obsValueCode = observation.getValueCodeableConcept().getCoding().get(0).getCode();
                if (obsValueCode != null && codeMappings.get(observation.getValueCodeableConcept().getCoding().get(0).getCode()) != null) {
                    if (replaceCode != null) {
                        observation.getValueCodeableConcept().getCoding().get(0).setCode(codeMappings.get(obsValueCode).getCode());
                        observation.getValueCodeableConcept().getCoding().get(0).setDisplay(codeMappings.get(obsValueCode).getDisplay());
                        observation.getValueCodeableConcept().getCoding().get(0).setSystem(targetSystem);
                    } else {
                        Coding newCoding = new Coding();
                        newCoding.setSystem(targetSystem);
                        newCoding.setCode(codeMappings.get(obsValueCode).getCode());
                        newCoding.setDisplay(codeMappings.get(obsValueCode).getDisplay());
                        observation.getValueCodeableConcept().getCoding().add(newCoding);
                    }
                }
            }
        });
    });
    return observationsBundle;
}
Also used : HashMap(java.util.HashMap) Coding(org.hl7.fhir.dstu3.model.Coding) IGenericClient(ca.uhn.fhir.rest.client.api.IGenericClient) Observation(org.hl7.fhir.dstu3.model.Observation) ConceptMap(org.hl7.fhir.dstu3.model.ConceptMap) Operation(ca.uhn.fhir.rest.annotation.Operation)

Example 13 with ConceptMap

use of org.hl7.fhir.r4b.model.ConceptMap in project cqf-ruler by DBCG.

the class TransformProvider method transformObservations.

@Operation(name = "$transform", idempotent = false, type = Observation.class)
public Bundle transformObservations(@OperationParam(name = "observations") Bundle observationsBundle, @OperationParam(name = "conceptMapURL") String conceptMapURL) {
    if (null == observationsBundle) {
        throw new IllegalArgumentException("Unable to perform operation Observation$transform.  No Observation bundle passed in.");
    }
    if (null == conceptMapURL) {
        throw new IllegalArgumentException("Unable to perform operation Observation$transform.  No concept map url specified.");
    }
    String replaceCode = mySdcProperties.getTransform().getReplaceCode();
    // String username = mySdcProperties.getTransform().getUsername();
    // String password = mySdcProperties.getTransform().getPassword();
    String endpoint = mySdcProperties.getTransform().getEndpoint();
    IGenericClient client = Clients.forUrl(fhirContext, endpoint);
    ConceptMap transformConceptMap = client.read().resource(ConceptMap.class).withUrl(conceptMapURL).execute();
    if (null == transformConceptMap) {
        throw new IllegalArgumentException("Unable to perform operation Observation$transform.  Unable to get concept map.");
    }
    List<Observation> observations = BundleUtil.toListOfResources(fhirContext, observationsBundle).stream().filter(resource -> resource instanceof Observation).map(Observation.class::cast).collect(Collectors.toList());
    /**
     * TODO - There must be a more efficient way to loop through this, but so far I
     * have not come up with it.
     */
    transformConceptMap.getGroup().forEach(group -> {
        HashMap<String, ConceptMap.TargetElementComponent> codeMappings = new HashMap<>();
        String targetSystem = group.getTarget();
        group.getElement().forEach(codeElement -> {
            codeMappings.put(codeElement.getCode(), codeElement.getTarget().get(0));
        });
        observations.forEach(observation -> {
            if (observation.getValue().fhirType().equalsIgnoreCase("codeableconcept")) {
                String obsValueCode = observation.getValueCodeableConcept().getCoding().get(0).getCode();
                if (obsValueCode != null && codeMappings.get(observation.getValueCodeableConcept().getCoding().get(0).getCode()) != null) {
                    if (replaceCode != null) {
                        observation.getValueCodeableConcept().getCoding().get(0).setCode(codeMappings.get(obsValueCode).getCode());
                        observation.getValueCodeableConcept().getCoding().get(0).setDisplay(codeMappings.get(obsValueCode).getDisplay());
                        observation.getValueCodeableConcept().getCoding().get(0).setSystem(targetSystem);
                    } else {
                        Coding newCoding = new Coding();
                        newCoding.setSystem(targetSystem);
                        newCoding.setCode(codeMappings.get(obsValueCode).getCode());
                        newCoding.setDisplay(codeMappings.get(obsValueCode).getDisplay());
                        observation.getValueCodeableConcept().getCoding().add(newCoding);
                    }
                }
            }
        });
    });
    return observationsBundle;
}
Also used : HashMap(java.util.HashMap) Coding(org.hl7.fhir.r4.model.Coding) IGenericClient(ca.uhn.fhir.rest.client.api.IGenericClient) Observation(org.hl7.fhir.r4.model.Observation) ConceptMap(org.hl7.fhir.r4.model.ConceptMap) Operation(ca.uhn.fhir.rest.annotation.Operation)

Example 14 with ConceptMap

use of org.hl7.fhir.r4b.model.ConceptMap in project openmrs-module-fhir2 by openmrs.

the class ConceptTranslatorImplTest method shouldTranslateCIELMappingForCIELMappedConcept.

@Test
public void shouldTranslateCIELMappingForCIELMappedConcept() {
    Collection<ConceptMap> conceptMaps = new ArrayList<>();
    ConceptMap conceptMap = mock(ConceptMap.class);
    conceptMaps.add(conceptMap);
    ConceptReferenceTerm conceptReferenceTerm = mock(ConceptReferenceTerm.class);
    ConceptSource conceptSource = mock(ConceptSource.class);
    ConceptMapType conceptMapType = mock(ConceptMapType.class);
    when(conceptMap.getConceptMapType()).thenReturn(conceptMapType);
    when(conceptMapType.getName()).thenReturn("SAME-AS");
    when(conceptMap.getConceptReferenceTerm()).thenReturn(conceptReferenceTerm);
    when(conceptReferenceTerm.getConceptSource()).thenReturn(conceptSource);
    when(conceptReferenceTerm.getCode()).thenReturn("1650");
    when(conceptSource.getName()).thenReturn("CIEL");
    when(concept.getConceptMappings()).thenReturn(conceptMaps);
    FhirConceptSource ciel = new FhirConceptSource();
    ConceptSource cielConceptSource = new ConceptSource();
    cielConceptSource.setName("CIEL");
    ciel.setConceptSource(cielConceptSource);
    ciel.setUrl(FhirTestConstants.CIEL_SYSTEM_URN);
    when(conceptSourceService.getFhirConceptSourceByConceptSourceName("CIEL")).thenReturn(Optional.of(ciel));
    CodeableConcept result = conceptTranslator.toFhirResource(concept);
    assertThat(result, notNullValue());
    assertThat(result.getCoding(), not(empty()));
    assertThat(result.getCoding(), hasItem(hasProperty("system", equalTo(FhirTestConstants.CIEL_SYSTEM_URN))));
    assertThat(result.getCoding(), hasItem(hasProperty("code", equalTo("1650"))));
    assertThat(result.getCoding(), hasItem(hasProperty("display", equalTo(CONCEPT_NAME))));
}
Also used : ConceptMapType(org.openmrs.ConceptMapType) FhirConceptSource(org.openmrs.module.fhir2.model.FhirConceptSource) ArrayList(java.util.ArrayList) ConceptSource(org.openmrs.ConceptSource) FhirConceptSource(org.openmrs.module.fhir2.model.FhirConceptSource) ConceptMap(org.openmrs.ConceptMap) ConceptReferenceTerm(org.openmrs.ConceptReferenceTerm) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept) Test(org.junit.Test)

Example 15 with ConceptMap

use of org.hl7.fhir.r4b.model.ConceptMap in project openmrs-module-fhir2 by openmrs.

the class ConceptTranslatorImplTest method shouldTranslateLOINCCodeableConceptToConcept.

@Test
public void shouldTranslateLOINCCodeableConceptToConcept() {
    CodeableConcept codeableConcept = new CodeableConcept();
    Coding loincCoding = codeableConcept.addCoding();
    loincCoding.setSystem(FhirTestConstants.LOINC_SYSTEM_URL);
    loincCoding.setCode("1000-1");
    Concept concept = new Concept();
    ConceptMap conceptMap = new ConceptMap();
    ConceptReferenceTerm conceptReferenceTerm = new ConceptReferenceTerm();
    ConceptSource loinc = new ConceptSource();
    loinc.setName("LOINC");
    conceptReferenceTerm.setConceptSource(loinc);
    conceptReferenceTerm.setCode("1000-1");
    conceptMap.setConceptReferenceTerm(conceptReferenceTerm);
    ConceptMapType conceptMapType = new ConceptMapType();
    conceptMapType.setName("SAME-AS");
    conceptMap.setConceptMapType(conceptMapType);
    concept.addConceptMapping(conceptMap);
    when(conceptService.getConceptBySourceNameAndCode("LOINC", "1000-1")).thenReturn(Optional.of(concept));
    FhirConceptSource fhirLoincSource = new FhirConceptSource();
    fhirLoincSource.setConceptSource(loinc);
    fhirLoincSource.setUrl(FhirTestConstants.LOINC_SYSTEM_URL);
    when(conceptSourceService.getFhirConceptSourceByUrl(FhirTestConstants.LOINC_SYSTEM_URL)).thenReturn(Optional.of(fhirLoincSource));
    Concept result = conceptTranslator.toOpenmrsType(codeableConcept);
    assertThat(result, notNullValue());
    assertThat(result.getConceptMappings(), notNullValue());
    assertThat(result.getConceptMappings(), not(empty()));
    assertThat(result.getConceptMappings(), hasItem(hasProperty("conceptReferenceTerm", hasProperty("code", equalTo("1000-1")))));
}
Also used : CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept) Concept(org.openmrs.Concept) ConceptMapType(org.openmrs.ConceptMapType) Coding(org.hl7.fhir.r4.model.Coding) FhirConceptSource(org.openmrs.module.fhir2.model.FhirConceptSource) ConceptSource(org.openmrs.ConceptSource) FhirConceptSource(org.openmrs.module.fhir2.model.FhirConceptSource) ConceptMap(org.openmrs.ConceptMap) ConceptReferenceTerm(org.openmrs.ConceptReferenceTerm) CodeableConcept(org.hl7.fhir.r4.model.CodeableConcept) Test(org.junit.Test)

Aggregations

ConceptMap (org.hl7.fhir.dstu3.model.ConceptMap)34 Test (org.junit.Test)31 ArrayList (java.util.ArrayList)29 HashMap (java.util.HashMap)27 FHIRException (org.hl7.fhir.exceptions.FHIRException)26 ConceptMap (org.hl7.fhir.r4.model.ConceptMap)23 XhtmlNode (org.hl7.fhir.utilities.xhtml.XhtmlNode)23 ConceptMap (org.hl7.fhir.r5.model.ConceptMap)22 ConceptMapGroupComponent (org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent)17 ConceptMapGroupComponent (org.hl7.fhir.dstu3.model.ConceptMap.ConceptMapGroupComponent)15 HashSet (java.util.HashSet)13 ConceptMapGroupComponent (org.hl7.fhir.r4.model.ConceptMap.ConceptMapGroupComponent)13 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)12 FileOutputStream (java.io.FileOutputStream)11 ValueSet (org.hl7.fhir.r5.model.ValueSet)11 SourceElementComponent (org.hl7.fhir.dstu3.model.ConceptMap.SourceElementComponent)10 Test (org.junit.jupiter.api.Test)10 ConceptMap (org.hl7.fhir.dstu2016may.model.ConceptMap)9 Coding (org.hl7.fhir.r4.model.Coding)9 SourceElementComponent (org.hl7.fhir.r4.model.ConceptMap.SourceElementComponent)9