From 4f82993431aa7e8a4215c1551cfa91b01c3cdf28 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Sun, 6 Jul 2025 17:27:43 +0200 Subject: [PATCH] feat: add Histologie and related specimens --- README.md | 11 +- .../mapper/KpaHistologieDataMapper.java | 118 ++++++++++++++++++ .../MolekulargenetikToSpecimenDataMapper.java | 15 ++- .../onco/datamapper/mapper/MtbDataMapper.java | 24 ++-- 4 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 src/main/java/dev/pcvolkmer/onco/datamapper/mapper/KpaHistologieDataMapper.java diff --git a/README.md b/README.md index 53ee241..c761adc 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,11 @@ var jsonResult = Converter.toJsonString( | ECOG-Verlauf | ✅ | | | Tumor-Proben | ⛅ | Best effort: Formular OS.Molekulargenetik erfüllt nicht alle Anforderungen (1) | | vorherige Molekular-Diagnostik | ✅ | | -| Histologie-Berichte | ⌛ | Aktuell in Arbeit | +| Histologie-Berichte | ✅ | Hinweis (2) | | IHC-Berichte | ⌛ | Aktuell in Arbeit | | MSI-Befunde | ⌛ | Aktuell in Arbeit | -| NGS-Berichte | ⛅ | Best effort: Formular OS.Molekulargenetik erfüllt nicht alle Anforderungen (2) | -| MTB-Beschlüsse | ✅ | Stützende molekulare Alteration(en) für einfache Variante und CNV (3) | +| NGS-Berichte | ⛅ | Best effort: Formular OS.Molekulargenetik erfüllt nicht alle Anforderungen (3) | +| MTB-Beschlüsse | ✅ | Stützende molekulare Alteration(en) für einfache Variante und CNV (4) | | Follow-Up Verlauf | | | | Antrag Kostenübernahme | | | | Antwort Kostenübernahme | | | @@ -61,9 +61,10 @@ var jsonResult = Converter.toJsonString( ### Hinweise 1. Nicht alle möglichen Ausprägungen in `OS.Molekulargenetik` vorhanden. -2. Aktuell nicht alle Angaben effektiv im Formular `OS.Molekulargenetik` wie gefordert angebbar. +2. Aktuell wird die Version der Morphologie nicht mit exportiert, nur der Wert. +3. Aktuell nicht alle Angaben effektiv im Formular `OS.Molekulargenetik` wie gefordert angebbar. Hinweis: Tumorzellgehalt-Methode problematisch, wenn auch im NGS-Bericht histologisch festgestellt. -3. Implementierung des Mappings von HGNC-Symbol (Gen-Name) zu HGNC-ID über enthaltene Gen-Liste. +4. Implementierung des Mappings von HGNC-Symbol (Gen-Name) zu HGNC-ID über enthaltene Gen-Liste. ## Enthaltene Liste mit Genen diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/KpaHistologieDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/KpaHistologieDataMapper.java new file mode 100644 index 0000000..245dc43 --- /dev/null +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/KpaHistologieDataMapper.java @@ -0,0 +1,118 @@ +/* + * This file is part of mv64e-onkostar-data + * + * Copyright (C) 2025 Paul-Christian Volkmer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +package dev.pcvolkmer.onco.datamapper.mapper; + +import dev.pcvolkmer.mv64e.mtb.*; +import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; +import dev.pcvolkmer.onco.datamapper.ResultSet; +import dev.pcvolkmer.onco.datamapper.datacatalogues.HistologieCatalogue; +import dev.pcvolkmer.onco.datamapper.datacatalogues.MolekulargenetikCatalogue; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Mapper class to load and map prozedur data from database table 'dk_dnpm_vorbefunde' + * + * @author Paul-Christian Volkmer + * @since 0.1 + */ +public class KpaHistologieDataMapper extends AbstractSubformDataMapper { + + private final MolekulargenetikCatalogue molekulargenetikCatalogue; + private final PropertyCatalogue propertyCatalogue; + + public KpaHistologieDataMapper( + final HistologieCatalogue catalogue, + final MolekulargenetikCatalogue molekulargenetikCatalogue, + final PropertyCatalogue propertyCatalogue + ) { + super(catalogue); + this.molekulargenetikCatalogue = molekulargenetikCatalogue; + this.propertyCatalogue = propertyCatalogue; + } + + /** + * Loads and maps Prozedur related by database id + * + * @param id The database id of the procedure data set + * @return The loaded data set + */ + @Override + public HistologyReport getById(final int id) { + var data = catalogue.getById(id); + return this.map(data); + } + + @Override + public List getByParentId(final int parentId) { + return catalogue.getAllByParentId(parentId) + .stream() + .map(this::map) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + } + + @Override + protected HistologyReport map(final ResultSet resultSet) { + var builder = HistologyReport.builder(); + + var osMolGen = molekulargenetikCatalogue.getById(resultSet.getInteger("histologie")); + + if (null != osMolGen) { + builder + .id(resultSet.getId().toString()) + .patient(resultSet.getPatientReference()) + .issuedOn(resultSet.getDate("erstellungsdatum")) + .specimen(Reference.builder().id(osMolGen.getId().toString()).type("Specimen").build()) + .results( + HistologyReportResults.builder() + .tumorCellContent( + TumorCellContent.builder() + .id(resultSet.getId().toString()) + .patient(resultSet.getPatientReference()) + .specimen(Reference.builder().id(osMolGen.getId().toString()).type("Specimen").build()) + .value(resultSet.getLong("tumorzellgehalt")) + // Nicht in OS.Molekulargenetik + //.method() + .build() + ) + .tumorMorphology( + TumorMorphology.builder() + .id(resultSet.getId().toString()) + .patient(resultSet.getPatientReference()) + .specimen(Reference.builder().id(osMolGen.getId().toString()).type("Specimen").build()) + .value(Coding.builder().code(resultSet.getString("morphologie")).build()) + .build() + ) + .build() + ) + ; + + return builder.build(); + } + + return null; + } + +} diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java index ea29366..4f47320 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MolekulargenetikToSpecimenDataMapper.java @@ -21,7 +21,6 @@ package dev.pcvolkmer.onco.datamapper.mapper; import dev.pcvolkmer.mv64e.mtb.*; -import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.datacatalogues.*; @@ -43,6 +42,7 @@ public class MolekulargenetikToSpecimenDataMapper implements DataMapper rs.getInteger("histologie")) + .map(molekulargenetikCatalogue::getById) + .map(ResultSet::getId) + .collect(Collectors.toList()) + ); + return osMolGen.stream() .filter(Objects::nonNull) .distinct() diff --git a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java index 1d6963a..b150a5a 100644 --- a/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java +++ b/src/main/java/dev/pcvolkmer/onco/datamapper/mapper/MtbDataMapper.java @@ -21,7 +21,6 @@ package dev.pcvolkmer.onco.datamapper.mapper; import dev.pcvolkmer.mv64e.mtb.Mtb; -import dev.pcvolkmer.mv64e.mtb.PriorDiagnosticReport; import dev.pcvolkmer.mv64e.mtb.Reference; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.*; @@ -121,7 +120,8 @@ public class MtbDataMapper implements DataMapper { catalogueFactory.catalogue(RebiopsieCatalogue.class), catalogueFactory.catalogue(ReevaluationCatalogue.class), einzelempfehlungCatalogue, - catalogueFactory.catalogue(VorbefundeCatalogue.class) + catalogueFactory.catalogue(VorbefundeCatalogue.class), + catalogueFactory.catalogue(HistologieCatalogue.class) ); var kpaMolekulargenetikDataMapper = new KpaMolekulargenetikDataMapper(molekulargenetikCatalogue, catalogueFactory.catalogue(MolekulargenuntersuchungCatalogue.class), propertyCatalogue); @@ -132,6 +132,12 @@ public class MtbDataMapper implements DataMapper { propertyCatalogue ); + var kpaHistologieDataMapper = new KpaHistologieDataMapper( + catalogueFactory.catalogue(HistologieCatalogue.class), + molekulargenetikCatalogue, + propertyCatalogue + ); + var resultBuilder = Mtb.builder(); try { @@ -152,6 +158,8 @@ public class MtbDataMapper implements DataMapper { .familyMemberHistories(verwandteDataMapper.getByParentId(kpaId)) // Vorbefunde .priorDiagnosticReports(kpaVorbefundeDataMapper.getByParentId(kpaId)) + // Histologie-Berichte + .histologyReports(kpaHistologieDataMapper.getByParentId(kpaId)) // DNPM Therapieplan .carePlans( therapieplanCatalogue @@ -161,14 +169,14 @@ public class MtbDataMapper implements DataMapper { ) // Tumorproben .specimens( - molekulargenetikToSpecimenDataMapper.getAllByKpaId( - kpaId, - Reference.builder().id(diagnosis.getId()).type("MTBDiagnosis").build() - ) + molekulargenetikToSpecimenDataMapper.getAllByKpaId( + kpaId, + Reference.builder().id(diagnosis.getId()).type("MTBDiagnosis").build() + ) ) // NGS Berichte .ngsReports( - kpaMolekulargenetikDataMapper.getAllByKpaId(kpaId) + kpaMolekulargenetikDataMapper.getAllByKpaId(kpaId) ) ; @@ -195,7 +203,7 @@ public class MtbDataMapper implements DataMapper { * Loads and maps a Mtb file using the patient id and tumor id * * @param patientId The patients id (not database id) - * @param tumorId The tumor identification + * @param tumorId The tumor identification * @return The loaded Mtb file */ public Mtb getLatestByPatientIdAndTumorId(String patientId, int tumorId) {