use of com.hartwig.hmftools.common.ecrf.datamodel.ValidationFinding 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.common.ecrf.datamodel.ValidationFinding in project hmftools by hartwigmedical.
the class PatientValidator method validateBiopsies.
@NotNull
@VisibleForTesting
static List<ValidationFinding> validateBiopsies(@NotNull final String patientIdentifier, @NotNull final List<BiopsyData> biopsies, @NotNull final List<BiopsyTreatmentData> treatments) {
final List<ValidationFinding> findings = Lists.newArrayList();
biopsies.forEach(biopsy -> findings.addAll(validateBiopsyData(patientIdentifier, biopsy)));
if (biopsies.isEmpty()) {
findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, FORM_BIOPS, "no biopsies found", FormStatusState.UNKNOWN, false));
}
if (biopsies.size() > 0 && treatments.size() > 0) {
biopsies.sort(comparing(BiopsyData::date, nullsLast(naturalOrder())));
Collections.sort(treatments);
final LocalDate firstBiopsyDate = biopsies.get(0).date();
final LocalDate firstTreatmentStart = treatments.get(0).startDate();
if (firstBiopsyDate != null && firstTreatmentStart != null && firstTreatmentStart.isBefore(firstBiopsyDate)) {
findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, fields(FORM_TREATMENT, FORM_BIOPS), "first treatment start is before first biopsy date", FormStatusState.best(biopsies.get(0).formStatus(), treatments.get(0).formStatus()), biopsies.get(0).formLocked() || treatments.get(0).formLocked()));
}
}
return findings;
}
use of com.hartwig.hmftools.common.ecrf.datamodel.ValidationFinding in project hmftools by hartwigmedical.
the class PatientValidator method validateTreatments.
@NotNull
@VisibleForTesting
static List<ValidationFinding> validateTreatments(@NotNull final String patientIdentifier, @NotNull final List<BiopsyTreatmentData> treatments) {
final List<ValidationFinding> findings = Lists.newArrayList();
treatments.forEach(treatment -> findings.addAll(validateTreatmentData(patientIdentifier, treatment)));
Collections.sort(treatments);
if (treatments.size() > 1) {
for (int index = 1; index < treatments.size(); index++) {
final BiopsyTreatmentData currentTreatment = treatments.get(index);
final LocalDate startDate = currentTreatment.startDate();
final LocalDate previousTreatmentEnd = treatments.get(index - 1).endDate();
if (startDate != null && (previousTreatmentEnd == null || startDate.isBefore(previousTreatmentEnd))) {
findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, FORM_TREATMENT, "subsequent treatment starts before the end of previous treatment", currentTreatment.formStatus(), currentTreatment.formLocked()));
}
}
final List<BiopsyTreatmentData> nonFinishedTreatments = treatments.stream().filter(treatment -> treatment.endDate() == null).collect(Collectors.toList());
if (nonFinishedTreatments.size() > 1) {
nonFinishedTreatments.forEach(treatment -> findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, FORM_TREATMENT, "end of at least 1 non-final treatment is missing", treatment.formStatus(), treatment.formLocked())));
}
}
return findings;
}
use of com.hartwig.hmftools.common.ecrf.datamodel.ValidationFinding in project hmftools by hartwigmedical.
the class PatientValidator method validateDeathDate.
@NotNull
@VisibleForTesting
static List<ValidationFinding> validateDeathDate(@NotNull final String patientIdentifier, @NotNull final BaselineData baselineData, @NotNull final List<BiopsyTreatmentData> treatments) {
final List<ValidationFinding> findings = Lists.newArrayList();
final LocalDate deathDate = baselineData.deathDate();
if (deathDate != null && !treatments.isEmpty()) {
treatments.sort(comparing(BiopsyTreatmentData::endDate, nullsLast(naturalOrder())));
final BiopsyTreatmentData lastTreatment = treatments.get(treatments.size() - 1);
final LocalDate lastTreatmentEndDate = lastTreatment.endDate();
final LocalDate firstTreatmentStart = treatments.get(0).startDate();
if (lastTreatmentEndDate == null || lastTreatmentEndDate.isAfter(deathDate)) {
String details = "death date (" + deathDate + ") before end of last treatment (" + lastTreatmentEndDate + ")" + " and start treatment is (" + firstTreatmentStart + ")";
findings.add(ValidationFinding.of(ECRF_LEVEL, patientIdentifier, fields(FIELD_DEATH_DATE, FORM_TREATMENT), "death date before end of last treatment", FormStatusState.best(baselineData.deathStatus(), lastTreatment.formStatus()), baselineData.deathLocked() || lastTreatment.formLocked(), details));
}
}
return findings;
}
use of com.hartwig.hmftools.common.ecrf.datamodel.ValidationFinding in project hmftools by hartwigmedical.
the class BiopsyMatcher method matchBiopsiesToTumorSamples.
@NotNull
public static MatchResult<BiopsyData> matchBiopsiesToTumorSamples(@NotNull final String patientId, @NotNull final List<SampleData> sequencedBiopsies, @NotNull final List<BiopsyData> clinicalBiopsies) {
final List<BiopsyData> matchedBiopsies = Lists.newArrayList();
final List<ValidationFinding> findings = Lists.newArrayList();
if (clinicalBiopsies.size() < sequencedBiopsies.size()) {
findings.add(biopsyMatchFinding(patientId, "less ecrf biopsies than biopsies sequenced.", "ecrf biopsies: " + clinicalBiopsies.size() + "; sequenced: " + sequencedBiopsies.size()));
}
List<BiopsyData> remainingBiopsies = clinicalBiopsies;
for (final SampleData sequencedBiopsy : sequencedBiopsies) {
final Map<Boolean, List<BiopsyData>> partitions = remainingBiopsies.stream().collect(Collectors.partitioningBy(clinicalBiopsy -> isPossibleMatch(sequencedBiopsy, clinicalBiopsy)));
final List<BiopsyData> possibleMatches = partitions.get(true);
if (possibleMatches.size() == 1 && possibleMatches.get(0).date() != null) {
final BiopsyData clinicalBiopsy = possibleMatches.get(0);
matchedBiopsies.add(ImmutableBiopsyData.builder().from(clinicalBiopsy).sampleId(sequencedBiopsy.sampleId()).build());
if (hasMismatchOnSamplingDate(sequencedBiopsy, clinicalBiopsy)) {
findings.add(biopsyMatchFinding(patientId, "sampling date does not equal biopsy date in matched biopsy", "sampling date: " + sequencedBiopsy.samplingDate() + "; ecrf biopsy date: " + clinicalBiopsy.date()));
}
remainingBiopsies = partitions.get(false);
} else if (possibleMatches.size() == 0 || (possibleMatches.size() == 1 && possibleMatches.get(0).date() == null)) {
findings.add(biopsyMatchFinding(patientId, "could not match any clinical biopsy with sequenced sample.", "sample: " + sampleDataToString(sequencedBiopsy) + "; ecrf biopsies: " + clinicalBiopsies.stream().map(BiopsyData::date).collect(Collectors.toList()) + ". match criteria: " + getMatchDateCriteria(sequencedBiopsy)));
// MIVO: abort finding new matches if we can't match one sequenced biopsy
return new MatchResult<>(clinicalBiopsies, findings);
} else if (possibleMatches.size() > 1) {
findings.add(biopsyMatchFinding(patientId, "more than 1 possible clinical biopsy match for sequenced sample.", "sample: " + sampleDataToString(sequencedBiopsy) + "; ecrf biopsies: " + clinicalBiopsies.stream().map(BiopsyData::date).collect(Collectors.toList()) + ". match criteria: " + getMatchDateCriteria(sequencedBiopsy)));
// MIVO: abort finding new matches if we can't match one sequenced biopsy
return new MatchResult<>(clinicalBiopsies, findings);
}
}
matchedBiopsies.addAll(remainingBiopsies);
return new MatchResult<>(matchedBiopsies, findings);
}
Aggregations