use of com.hartwig.hmftools.patientdb.data.BiopsyTreatmentData in project hmftools by hartwigmedical.
the class PatientReader method read.
@NotNull
public Patient read(@NotNull final EcrfPatient ecrfPatient, @NotNull final List<SampleData> sequencedSamples) throws IOException {
LOGGER.info("Reading patient " + ecrfPatient.patientId() + " with samples: " + sequencedSamples);
final BaselineData baselineData = cpctPatientReader.read(ecrfPatient);
final PreTreatmentData preTreatmentData = preTreatmentReader.read(ecrfPatient);
final List<BiopsyData> clinicalBiopsies = BiopsyReader.read(ecrfPatient);
final List<BiopsyTreatmentData> treatments = biopsyTreatmentReader.read(ecrfPatient);
final List<BiopsyTreatmentResponseData> treatmentResponses = BiopsyTreatmentResponseReader.read(ecrfPatient);
final List<TumorMarkerData> tumorMarkers = TumorMarkerReader.read(ecrfPatient);
final MatchResult<BiopsyData> matchedBiopsies = BiopsyMatcher.matchBiopsiesToTumorSamples(ecrfPatient.patientId(), sequencedSamples, clinicalBiopsies);
final MatchResult<BiopsyTreatmentData> matchedTreatments = TreatmentMatcher.matchTreatmentsToBiopsies(ecrfPatient.patientId(), clinicalBiopsies, treatments);
final MatchResult<BiopsyTreatmentResponseData> matchedResponses = TreatmentResponseMatcher.matchTreatmentResponsesToTreatments(ecrfPatient.patientId(), treatments, treatmentResponses);
final List<ValidationFinding> findings = Lists.newArrayList();
findings.addAll(matchedBiopsies.findings());
findings.addAll(matchedTreatments.findings());
findings.addAll(matchedResponses.findings());
return new Patient(ecrfPatient.patientId(), baselineData, preTreatmentData, sequencedSamples, matchedBiopsies.values(), matchedTreatments.values(), matchedResponses.values(), tumorMarkers, findings);
}
use of com.hartwig.hmftools.patientdb.data.BiopsyTreatmentData in project hmftools by hartwigmedical.
the class PatientValidator method validateTreatmentResponses.
@NotNull
@VisibleForTesting
static List<ValidationFinding> validateTreatmentResponses(@NotNull final String patientIdentifier, @NotNull final List<BiopsyTreatmentData> treatments, @NotNull final List<BiopsyTreatmentResponseData> responses) {
final List<ValidationFinding> findings = Lists.newArrayList();
for (int i = 0; i < responses.size(); i++) {
findings.addAll(validateTreatmentResponse(patientIdentifier, responses.get(i), i == 0));
}
Collections.sort(treatments);
Collections.sort(responses);
if (treatments.isEmpty() && !responses.isEmpty()) {
findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, FORM_TREATMENT, "treatment response filled in, but treatment data missing", FormStatusState.UNKNOWN, false));
}
if (!treatments.isEmpty() && !responses.isEmpty()) {
final LocalDate firstResponseDate = responses.get(0).date();
final LocalDate firstTreatmentStart = treatments.get(0).startDate();
if (firstResponseDate != null && firstTreatmentStart != null && firstResponseDate.isAfter(firstTreatmentStart)) {
findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, fields(FORM_TREATMENT, FORM_TUMOR_MEASUREMENT), "first (baseline) measurement date is after first treatment start", FormStatusState.best(treatments.get(0).formStatus(), responses.get(0).formStatus()), treatments.get(0).formLocked() || responses.get(0).formLocked(), "first treatment response: " + firstResponseDate + "; first treatment start: " + firstTreatmentStart));
}
}
final List<BiopsyTreatmentData> treatmentsMissingResponse = treatments.stream().filter(treatment -> shouldHaveResponse(treatment) && !hasResponse(treatment.id(), responses)).collect(Collectors.toList());
if (treatmentsMissingResponse.size() > 0) {
findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, FORM_TUMOR_MEASUREMENT, "no treatment response for at least 1 treatment", FormStatusState.UNKNOWN, false, "treatments " + treatmentsMissingResponse.stream().map(BiopsyTreatmentData::toString).collect(Collectors.toList()) + " should have response since they lasted more than " + Config.IMMEDIATE_TREATMENT_END_THRESHOLD + " days and started more than " + Config.START_DATE_RESPONSE_THRESHOLD + " days ago"));
}
return findings;
}
use of com.hartwig.hmftools.patientdb.data.BiopsyTreatmentData in project hmftools by hartwigmedical.
the class PatientReaderTest method canReadCpctPatientTreatments.
@Test
public void canReadCpctPatientTreatments() throws IOException {
final CpctEcrfModel model = loadTestEcrf();
assertEquals(1, model.patientCount());
final EcrfPatient cpctPatient = model.patients().iterator().next();
final List<BiopsyTreatmentData> treatments = new BiopsyTreatmentReader(createTreatmentCurator()).read(cpctPatient);
assertEquals(1, treatments.size());
assertEquals(1, treatments.get(0).drugs().size());
final LocalDate startDate = LocalDate.parse("2012-02-18", DATE_FORMATTER);
final LocalDate endDate = LocalDate.parse("2012-04-02", DATE_FORMATTER);
assertEquals("Bevacizumab", treatments.get(0).drugs().get(0).name());
assertEquals(startDate, treatments.get(0).drugs().get(0).startDate());
assertEquals(endDate, treatments.get(0).drugs().get(0).endDate());
assertEquals(startDate, treatments.get(0).startDate());
assertEquals(endDate, treatments.get(0).endDate());
assertEquals("Bevacizumab", treatments.get(0).treatmentName());
assertEquals("Yes", treatments.get(0).treatmentGiven());
}
use of com.hartwig.hmftools.patientdb.data.BiopsyTreatmentData in project hmftools by hartwigmedical.
the class TreatmentMatcher method matchTreatmentsToBiopsies.
@NotNull
public static MatchResult<BiopsyTreatmentData> matchTreatmentsToBiopsies(@NotNull final String patientId, @NotNull final List<BiopsyData> biopsies, @NotNull final List<BiopsyTreatmentData> treatments) {
final List<BiopsyTreatmentData> matchedTreatments = Lists.newArrayList();
final List<ValidationFinding> findings = Lists.newArrayList();
List<BiopsyData> remainingBiopsies = biopsies;
for (final BiopsyTreatmentData treatment : treatments) {
final String treatmentGiven = treatment.treatmentGiven();
if (treatmentGiven == null || treatmentGiven.toLowerCase().equals("no")) {
matchedTreatments.add(treatment);
continue;
}
final Map<Boolean, List<BiopsyData>> partitions = remainingBiopsies.stream().collect(Collectors.partitioningBy(clinicalBiopsy -> isPossibleMatch(clinicalBiopsy.date(), treatment.startDate())));
final List<BiopsyData> possibleMatches = partitions.get(true);
if (possibleMatches.size() == 0) {
findings.add(treatmentMatchFinding(patientId, "no biopsy match for treatment", treatment.toString()));
matchedTreatments.add(treatment);
} else if (possibleMatches.size() > 1) {
findings.add(treatmentMatchFinding(patientId, "multiple biopsy matches for treatment", treatment + ". biopsies: " + possibleMatches.stream().map(BiopsyData::toString).collect(Collectors.toList())));
matchedTreatments.add(treatment);
} else if (possibleMatches.get(0).date() == null) {
findings.add(treatmentMatchFinding(patientId, "treatment matched biopsy with null date.", treatment.toString()));
matchedTreatments.add(treatment);
} else {
final BiopsyData clinicalBiopsy = possibleMatches.get(0);
matchedTreatments.add(ImmutableBiopsyTreatmentData.builder().from(treatment).biopsyId(clinicalBiopsy.id()).build());
remainingBiopsies = partitions.get(false);
}
}
return new MatchResult<>(matchedTreatments, findings);
}
use of com.hartwig.hmftools.patientdb.data.BiopsyTreatmentData in project hmftools by hartwigmedical.
the class TreatmentResponseMatcher method hasOverlappingTreatments.
private static boolean hasOverlappingTreatments(@NotNull List<BiopsyTreatmentData> sortedTreatments) {
Iterator<BiopsyTreatmentData> iterator = sortedTreatments.iterator();
BiopsyTreatmentData current = iterator.hasNext() ? iterator.next() : null;
while (iterator.hasNext()) {
assert current != null;
BiopsyTreatmentData next = iterator.next();
LocalDate currentEndDate = current.endDate();
LocalDate nextStartDate = next.startDate();
assert nextStartDate != null;
if (currentEndDate == null || currentEndDate.isAfter(nextStartDate)) {
return true;
}
current = next;
}
return false;
}
Aggregations