use of org.hl7.fhir.r4.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;
}
use of org.hl7.fhir.r4.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;
}
use of org.hl7.fhir.r4.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;
}
use of org.hl7.fhir.r4.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))));
}
use of org.hl7.fhir.r4.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")))));
}
Aggregations