1
0
mirror of https://github.com/pcvolkmer/mv64e-onkostar-data.git synced 2025-09-13 16:02:52 +00:00

feat: add Tumor-Proben

This commit is contained in:
2025-06-30 00:46:07 +02:00
parent 69af1663e0
commit 60cbb0ff8a
11 changed files with 964 additions and 23 deletions

View File

@@ -71,6 +71,12 @@ public class DataCatalogueFactory {
return TherapieplanCatalogue.create(jdbcTemplate);
} else if (c == EinzelempfehlungCatalogue.class) {
return EinzelempfehlungCatalogue.create(jdbcTemplate);
} else if (c == MolekulargenetikCatalogue.class) {
return MolekulargenetikCatalogue.create(jdbcTemplate);
} else if (c == RebiopsieCatalogue.class) {
return RebiopsieCatalogue.create(jdbcTemplate);
} else if (c == ReevaluationCatalogue.class) {
return ReevaluationCatalogue.create(jdbcTemplate);
}
throw new DataCatalogueCreationException(clazz);
});

View File

@@ -0,0 +1,26 @@
package dev.pcvolkmer.onco.datamapper.datacatalogues;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Load raw result sets from database table 'dk_molekulargenetik'
*
* @author Paul-Christian Volkmer
* @since 0.1
*/
public class MolekulargenetikCatalogue extends AbstractSubformDataCatalogue {
private MolekulargenetikCatalogue(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "dk_molekulargenetik";
}
public static MolekulargenetikCatalogue create(JdbcTemplate jdbcTemplate) {
return new MolekulargenetikCatalogue(jdbcTemplate);
}
}

View File

@@ -0,0 +1,26 @@
package dev.pcvolkmer.onco.datamapper.datacatalogues;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Load raw result sets from database table 'dk_dnpm_uf_rebiopsie'
*
* @author Paul-Christian Volkmer
* @since 0.1
*/
public class RebiopsieCatalogue extends AbstractSubformDataCatalogue {
private RebiopsieCatalogue(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "dk_dnpm_uf_rebiopsie";
}
public static RebiopsieCatalogue create(JdbcTemplate jdbcTemplate) {
return new RebiopsieCatalogue(jdbcTemplate);
}
}

View File

@@ -0,0 +1,26 @@
package dev.pcvolkmer.onco.datamapper.datacatalogues;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Load raw result sets from database table 'dk_dnpm_uf_reevaluation'
*
* @author Paul-Christian Volkmer
* @since 0.1
*/
public class ReevaluationCatalogue extends AbstractSubformDataCatalogue {
private ReevaluationCatalogue(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
protected String getTableName() {
return "dk_dnpm_uf_reevaluation";
}
public static ReevaluationCatalogue create(JdbcTemplate jdbcTemplate) {
return new ReevaluationCatalogue(jdbcTemplate);
}
}

View File

@@ -0,0 +1,215 @@
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.*;
import java.util.List;
import java.util.stream.Collectors;
import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReference;
/**
* Mapper class to load and map patient data from database table 'dk_molekulargenetik'
*
* @author Paul-Christian Volkmer
* @since 0.1
*/
public class MolekulargenetikToSpecimenDataMapper implements DataMapper<TumorSpecimen> {
private final MolekulargenetikCatalogue molekulargenetikCatalogue;
private final TherapieplanCatalogue therapieplanCatalogue;
private final RebiopsieCatalogue rebiopsieCatalogue;
private final ReevaluationCatalogue reevaluationCatalogue;
private final EinzelempfehlungCatalogue einzelempfehlungCatalogue;
private final PropertyCatalogue propertyCatalogue;
public MolekulargenetikToSpecimenDataMapper(
final MolekulargenetikCatalogue molekulargenetikCatalogue,
final TherapieplanCatalogue therapieplanCatalogue,
final RebiopsieCatalogue rebiopsieCatalogue,
final ReevaluationCatalogue reevaluationCatalogue,
final EinzelempfehlungCatalogue einzelempfehlungCatalogue,
final PropertyCatalogue propertyCatalogue
) {
this.molekulargenetikCatalogue = molekulargenetikCatalogue;
this.therapieplanCatalogue = therapieplanCatalogue;
this.rebiopsieCatalogue = rebiopsieCatalogue;
this.reevaluationCatalogue = reevaluationCatalogue;
this.einzelempfehlungCatalogue = einzelempfehlungCatalogue;
this.propertyCatalogue = propertyCatalogue;
}
/**
* Loads and maps a specimen using the database id
* The result does not include a diagnosis reference!
*
* @param id The database id of the procedure data set
* @return The loaded Patient data
*/
@Override
public TumorSpecimen getById(int id) {
var data = molekulargenetikCatalogue.getById(id);
var builder = TumorSpecimen.builder();
builder
.id(data.getString("id"))
.patient(getPatientReference(data.getString("patient_id")))
.type(getTumorSpecimenCoding(data.getString("materialfixierung")))
.collection(getCollection(data))
// TODO add diagnosis later
;
return builder.build();
}
/**
* Loads and maps specimens by using the referencing KPA database id
*
* @param kpaId The database id of the referencing KPA procedure data set
* @param diagnoseReferenz The reference object to the diagnosis
* @return The loaded Patient data
*/
public List<TumorSpecimen> getAllByKpaId(int kpaId, Reference diagnoseReferenz) {
var therapieplanIds = therapieplanCatalogue.getByKpaId(kpaId);
var osMolGen = therapieplanIds.stream()
.map(einzelempfehlungCatalogue::getAllByParentId)
.flatMap(einzelempfehlungen ->
einzelempfehlungen
.stream()
.map(einzelempfehlung -> einzelempfehlung.getInteger("ref_molekulargenetik"))
)
.collect(Collectors.toSet());
// Addition: Rebiopsie
osMolGen.addAll(
therapieplanIds.stream()
.map(rebiopsieCatalogue::getAllByParentId)
.flatMap(einzelempfehlungen ->
einzelempfehlungen
.stream()
.map(einzelempfehlung -> einzelempfehlung.getInteger("ref_molekulargenetik"))
)
.collect(Collectors.toSet())
);
// Addition: Reevaluation
osMolGen.addAll(
therapieplanIds.stream()
.map(reevaluationCatalogue::getAllByParentId)
.flatMap(einzelempfehlungen ->
einzelempfehlungen
.stream()
.map(einzelempfehlung -> einzelempfehlung.getInteger("ref_molekulargenetik"))
)
.collect(Collectors.toSet())
);
return osMolGen.stream()
.map(this::getById)
.peek(it -> it.setDiagnosis(diagnoseReferenz))
.collect(Collectors.toList());
}
// TODO: Kein genaues Mapping mit Formular OS.Molekulargenetik möglich - best effort
private TumorSpecimenCoding getTumorSpecimenCoding(String value) {
if (value == null) {
return null;
}
var resultBuilder = TumorSpecimenCoding.builder()
.system("dnpm-dip/mtb/tumor-specimen/type");
switch (value) {
case "2":
resultBuilder
.code(TumorSpecimenCodingCode.CRYO_FROZEN)
.display("Cryo-frozen");
break;
case "3":
resultBuilder
.code(TumorSpecimenCodingCode.FFPE)
.display("FFPE");
break;
default:
resultBuilder
.code(TumorSpecimenCodingCode.UNKNOWN)
.display("Unbekannt");
break;
}
return resultBuilder.build();
}
private Collection getCollection(ResultSet data) {
if (data == null || data.getString("entnahmemethode") == null || data.getString("probenmaterial") == null) {
return null;
}
var methodBuilder = TumorSpecimenCollectionMethodCoding.builder()
.system("dnpm-dip/mtb/tumor-specimen/collection/method");
switch (data.getString("entnahmemethode")) {
case "B":
methodBuilder
.code(TumorSpecimenCollectionMethodCodingCode.BIOPSY)
.display("Biopsie");
break;
case "R":
methodBuilder
.code(TumorSpecimenCollectionMethodCodingCode.RESECTION)
.display("Resektat");
break;
case "LB":
methodBuilder
.code(TumorSpecimenCollectionMethodCodingCode.LIQUID_BIOPSY)
.display("Liquid Biopsy");
break;
case "Z":
methodBuilder
.code(TumorSpecimenCollectionMethodCodingCode.CYTOLOGY)
.display("Zytologie");
break;
case "U":
default:
methodBuilder
.code(TumorSpecimenCollectionMethodCodingCode.UNKNOWN)
.display("Unbekannt");
break;
}
// TODO: Kein genaues Mapping mit Formular OS.Molekulargenetik möglich - best effort
var localizationBuilder = TumorSpecimenCollectionLocalizationCoding.builder()
.system("dnpm-dip/mtb/tumor-specimen/collection/localization");
switch (data.getString("probenmaterial")) {
case "T":
localizationBuilder
.code(TumorSpecimenCollectionLocalizationCodingCode.PRIMARY_TUMOR)
.display("Primärtumor");
break;
case "LK":
case "M":
case "ITM":
case "SM":
localizationBuilder
.code(TumorSpecimenCollectionLocalizationCodingCode.METASTASIS)
.display("Metastase");
break;
default:
localizationBuilder
.code(TumorSpecimenCollectionLocalizationCodingCode.UNKNOWN)
.display("Unbekannt");
break;
}
return Collection.builder()
.method(methodBuilder.build())
.localization(localizationBuilder.build())
.build();
}
}

View File

@@ -1,6 +1,7 @@
package dev.pcvolkmer.onco.datamapper.mapper;
import dev.pcvolkmer.mv64e.mtb.Mtb;
import dev.pcvolkmer.mv64e.mtb.Reference;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.*;
import dev.pcvolkmer.onco.datamapper.exceptions.DataAccessException;
@@ -80,15 +81,26 @@ public class MtbDataMapper implements DataMapper<Mtb> {
catalogueFactory.catalogue(EcogCatalogue.class)
);
var einzelempfehlungCatalogue = catalogueFactory.catalogue(EinzelempfehlungCatalogue.class);
var therapieplanCatalogue = catalogueFactory.catalogue(TherapieplanCatalogue.class);
var therapieplanDataMapper = new TherapieplanDataMapper(
therapieplanCatalogue,
catalogueFactory.catalogue(EinzelempfehlungCatalogue.class),
einzelempfehlungCatalogue,
propertyCatalogue
);
var verwandteDataMapper = new KpaVerwandteDataMapper(catalogueFactory.catalogue(VerwandteCatalogue.class));
var molekulargenetikCatalogue = catalogueFactory.catalogue(MolekulargenetikCatalogue.class);
var molekulargenetikToSpecimenDataMapper = new MolekulargenetikToSpecimenDataMapper(
molekulargenetikCatalogue,
therapieplanCatalogue,
catalogueFactory.catalogue(RebiopsieCatalogue.class),
catalogueFactory.catalogue(ReevaluationCatalogue.class),
einzelempfehlungCatalogue,
propertyCatalogue
);
var resultBuilder = Mtb.builder();
try {
@@ -96,11 +108,13 @@ public class MtbDataMapper implements DataMapper<Mtb> {
var patient = patientDataMapper.getById(Integer.parseInt(kpaPatient.getId()));
kpaPatient.setAddress(patient.getAddress());
var diagnosis = diagnosisDataMapper.getById(kpaId);
resultBuilder
.patient(kpaPatient)
.episodesOfCare(List.of(mtbEpisodeDataMapper.getById(kpaId)))
// DNPM Klinik/Anamnese
.diagnoses(List.of(diagnosisDataMapper.getById(kpaId)))
.diagnoses(List.of(diagnosis))
.guidelineProcedures(prozedurMapper.getByParentId(kpaId))
.guidelineTherapies(therapielinieMapper.getByParentId(kpaId))
.performanceStatus(ecogMapper.getByParentId(kpaId))
@@ -112,6 +126,13 @@ public class MtbDataMapper implements DataMapper<Mtb> {
.map(therapieplanDataMapper::getById)
.collect(Collectors.toList())
)
// Tumorproben
.specimens(
molekulargenetikToSpecimenDataMapper.getAllByKpaId(
kpaId,
Reference.builder().id(diagnosis.getId()).type("MTBDiagnosis").build()
)
)
;
} catch (DataAccessException e) {
logger.error("Error while getting Mtb.", e);