Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement death mapping #178

Open
wants to merge 3 commits into
base: beta
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public static class FhirSystems {
private String miiCsOnkoSystemischeTherapieArt;
private String miiCsOnkoSeitenlokalisation;
private String miiCsTherapieGrundEnde;
private String miiCsOnkoTodInterpretation;
private String conditionVerStatus;
private String icdo3MorphologieOid;
private String atcBfarm;
Expand All @@ -104,6 +105,7 @@ public static class FhirProfiles {
private String miiPrOnkoStrahlentherapie;
private String miiPrOnkoSystemischeTherapie;
private String miiPrMedicationStatement;
private String miiPrOnkoTod;
}

@Data
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.miracum.streams.ume.obdstofhir.mapper.mii;

import de.basisdatensatz.obds.v3.AllgemeinICDTyp;
import de.basisdatensatz.obds.v3.OBDS;
import java.util.Arrays;
import java.util.Objects;
import java.util.regex.Pattern;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.r4.model.*;
import org.miracum.streams.ume.obdstofhir.FhirProperties;
import org.miracum.streams.ume.obdstofhir.mapper.ObdsToFhirMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TodMapper extends ObdsToFhirMapper {

private static final Logger LOG = LoggerFactory.getLogger(TodMapper.class);
private static final Pattern icdVersionPattern =
Pattern.compile("^(10 (?<versionYear>20\\d{2}) ((GM)|(WHO))|Sonstige)$");

@Autowired
public TodMapper(FhirProperties fhirProperties) {
super(fhirProperties);
}

public Observation map(
OBDS.MengePatient.Patient.MengeMeldung.Meldung meldung, Reference patient) {
// Validation
Objects.requireNonNull(meldung.getTod());
Objects.requireNonNull(patient);
// Objects.requireNonNull(condition);

Validate.notBlank(meldung.getTod().getAbschlussID(), "Required ABSCHLUSS_ID is unset");
Validate.isTrue(
Objects.equals(
patient.getReferenceElement().getResourceType(),
Enumerations.ResourceType.PATIENT.toCode()),
"The subject reference should point to a Patient resource");
/*
Validate.isTrue(
Objects.equals(
condition.getReferenceElement().getResourceType(), Enumerations.ResourceType.CONDITION.toCode()),
"The condition reference should point to a Condition resource");
*/

var observation = new Observation();
observation.getMeta().addProfile(fhirProperties.getProfiles().getMiiPrOnkoTod());
observation.setStatus(Observation.ObservationStatus.FINAL);

// Code | 184305005 | Cause of death (observable entity)
var snomedCode = new CodeableConcept();
snomedCode.addCoding().setSystem(fhirProperties.getSystems().getSnomed()).setCode("184305005");
observation.setCode(snomedCode);

// Subject
observation.setSubject(patient);

// Effective | Sterbedatum
var todesZeitpunkt = convertObdsDatumToDateTimeType(meldung.getTod().getSterbedatum());
if (todesZeitpunkt.isPresent()) {
observation.setEffective(todesZeitpunkt.get());
}

/*
// Focus | Bezugsdiagnose
var focusList = new ArrayList<Reference>();
focusList.add(condition);
observation.setFocus(focusList);
*/

// Value | Todesursache(n) ICD10GM
if (meldung.getTod().getMengeTodesursachen() != null) {
var todesursacheConcept = new CodeableConcept();
for (AllgemeinICDTyp todesursache :
meldung.getTod().getMengeTodesursachen().getTodesursacheICD()) {
todesursacheConcept
.addCoding()
.setSystem(fhirProperties.getSystems().getIcd10gm())
.setCode(todesursache.getCode())
.setVersion(todesursache.getVersion());
}
observation.setValue(todesursacheConcept);
}

// Interpretation | Tod Tumorbedingt
if (meldung.getTod().getTodTumorbedingt() != null) {
var interpretation = new CodeableConcept();
interpretation
.addCoding()
.setSystem(fhirProperties.getSystems().getMiiCsOnkoTodInterpretation())
.setCode(meldung.getTod().getTodTumorbedingt().value());
observation.setInterpretation(Arrays.asList(interpretation));
}

return observation;
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ fhir:
mii-cs-onko-seitenlokalisation: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/CodeSystem/mii-cs-onko-seitenlokalisation"
mii-cs-onko-systemische-therapie-art: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/CodeSystem/mii-cs-onko-therapie-typ"
mii-cs-therapie-grund-ende: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/CodeSystem/mii-cs-therapie-grund-ende"
mii-cs-onko-tod-interpretation: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/CodeSystem/mii-cs-onko-tod"
atcBfarm: "http://fhir.de/CodeSystem/bfarm/atc"
atcWho: "http://www.whocc.no/atc"
profiles:
Expand All @@ -90,6 +91,7 @@ fhir:
mii-pr-onko-strahlentherapie: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-strahlentherapie"
mii-pr-onko-systemische-therapie: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-systemische-therapie"
mii-pr-medication-statement: "https://www.medizininformatik-initiative.de/fhir/core/modul-medikation/StructureDefinition/MedicationStatement"
mii-pr-onko-tod: "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-tod"
display:
histologyLoinc: "Histology and Behavior ICD-O-3 Cancer"
gradingLoinc: "Grade pathology value Cancer"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.miracum.streams.ume.obdstofhir.mapper.mii;

import static org.assertj.core.api.Assertions.assertThat;

import ca.uhn.fhir.context.FhirContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationModule;
import de.basisdatensatz.obds.v3.OBDS;
import java.io.IOException;
import org.approvaltests.Approvals;
import org.hl7.fhir.r4.model.Reference;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.miracum.streams.ume.obdstofhir.FhirProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(classes = {FhirProperties.class})
@EnableConfigurationProperties
class TodMapperTest {
private static TodMapper tm;

@BeforeAll
static void beforeEach(@Autowired FhirProperties fhirProps) {
tm = new TodMapper(fhirProps);
}

@ParameterizedTest
@CsvSource({"Testpatient_1.xml"})
void map_withGivenObds_shouldCreateValidProcedure(String sourceFile) throws IOException {
final var resource = this.getClass().getClassLoader().getResource("obds3/" + sourceFile);
assertThat(resource).isNotNull();

final var xmlMapper =
XmlMapper.builder()
.defaultUseWrapper(false)
.addModule(new JakartaXmlBindAnnotationModule())
.addModule(new Jdk8Module())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.build();

final var obds = xmlMapper.readValue(resource.openStream(), OBDS.class);

var obdsPatient = obds.getMengePatient().getPatient().getFirst();

var subject = new Reference("Patient/any");
var tMeldung =
obdsPatient.getMengeMeldung().getMeldung().stream()
.filter(m -> m.getTod() != null)
.findFirst()
.get();
var procedure = tm.map(tMeldung, subject);

var fhirParser = FhirContext.forR4().newJsonParser().setPrettyPrint(true);
var fhirJson = fhirParser.encodeResourceToString(procedure);
Approvals.verify(
fhirJson, Approvals.NAMES.withParameters(sourceFile).forFile().withExtension(".fhir.json"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"resourceType": "Observation",
"meta": {
"profile": [ "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/StructureDefinition/mii-pr-onko-tod" ]
},
"status": "final",
"code": {
"coding": [ {
"system": "http://snomed.info/sct",
"code": "184305005"
} ]
},
"subject": {
"reference": "Patient/any"
},
"effectiveDateTime": "2022-08-01",
"valueCodeableConcept": {
"coding": [ {
"system": "http://fhir.de/CodeSystem/bfarm/icd-10-gm",
"version": "10 2020 GM",
"code": "C50.9"
}, {
"system": "http://fhir.de/CodeSystem/bfarm/icd-10-gm",
"version": "10 2020 GM",
"code": "T57.3"
} ]
},
"interpretation": [ {
"coding": [ {
"system": "https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/CodeSystem/mii-cs-onko-tod",
"code": "J"
} ]
} ]
}
Loading