in clns-acuity-vahub/vahub-model/src/main/java/com/acuity/visualisations/rawdatamodel/dataproviders/DrugDoseDatasetsDataProvider.java [112:281]
public Collection<DrugDoseIntermediate> getJavaPrecalculatedData(Dataset dataset) {
Collection<ExacerbationRaw> exacerbationRaws = exacerbationDatasetsDataProvider.getData(dataset);
Collection<Subject> subjects = populationDatasetsDataProvider.getData(dataset);
Collection<String> subjectsWithExacerbationsIds = exacerbationRaws.stream()
.map(ExacerbationRaw::getSubjectId)
.collect(Collectors.toList());
Collection<String> subjectsWithFirstDose = subjects.stream()
.filter((Subject subject) -> !subject.getDrugFirstDoseDate().isEmpty())
.map(Subject::getSubjectId)
.collect(Collectors.toList());
// "demo"
Collection<String> subjectsOfInterest = CollectionUtils.union(subjectsWithExacerbationsIds, subjectsWithFirstDose);
Collection<DrugDoseIntermediate> dosesOfInterests = drugDoseRepository.getRawData(dataset.getId()).stream()
.filter(dose -> subjectsOfInterest.contains(dose.getSubjectId()))
.map(dose -> {
Optional<DrugDoseRaw> doseOptional = Optional.of(dose).filter(d -> d.getDose() > 0);
return DrugDoseIntermediate.builder()
.subjectId(dose.getSubjectId())
.drug(dose.getDrug())
.startDate(dose.getStartDate())
.endDate(dose.getEndDate())
.periodType(doseOptional.map(d -> PeriodType.ACTIVE.name()).orElse(PeriodType.INACTIVE.name()))
.dose(doseOptional.map(DrugDoseRaw::getDose).orElse(0.0d))
.doseUnit(doseOptional.map(DrugDoseRaw::getDoseUnit).orElse(null))
.frequencyName(doseOptional.map(DrugDoseRaw::getFrequencyName).orElse(null))
.frequencyRank(doseOptional.map(DrugDoseRaw::getFrequencyRank).orElse(null))
.build();
}
)
.collect(Collectors.toList());
Collection<DoseDisc> discsOfInterest = doseDiscDatasetsDataProvider.loadData(Datasets.toAcuityDataset(dataset.getId())).stream()
.filter(disc -> subjectsOfInterest.contains(disc.getSubject().getId()))
.collect(Collectors.toList());
Date studyLastUpdated = studyInfoDataProvider.getData(dataset).stream()
.findAny()
.map(StudyInfo::getLastUpdatedDate)
.orElseThrow(() -> new IllegalStateException("It's just impossible!"));
Collection<DrugDoseIntermediate> dosesOfInterestConverted = dosesOfInterests.stream()
.map(dose -> {
Optional<DrugDoseIntermediate> doseOptional = Optional.of(dose).filter(d -> d.getDose() > 0);
return DrugDoseIntermediate.builder()
.subjectId(dose.getSubjectId())
.drug(dose.getDrug())
.startDate(dose.getStartDate())
.periodType(doseOptional.map(d -> PeriodType.ACTIVE.name()).orElse(PeriodType.INACTIVE.name()))
.dose(doseOptional.map(DrugDoseIntermediate::getDose).orElse(0.0d))
.doseUnit(doseOptional.map(DrugDoseIntermediate::getDoseUnit).orElse(null))
.frequencyName(doseOptional.map(DrugDoseIntermediate::getFrequencyName).orElse(null))
.frequencyRank(doseOptional.map(DrugDoseIntermediate::getFrequencyRank).orElse("0"))
.build();
}).collect(Collectors.toList());
Map<MultiKey<Object>, DoseDisc> discsBySubjectDrugAndDate = StreamEx.of(discsOfInterest)
.mapToEntry(
disc -> new MultiKey<Object>(disc.getSubjectId(), disc.getStudyDrug(), disc.getDiscDate()),
Function.identity()
).toMap();
Collection<DrugDoseIntermediate> dosesAfterDoses = dosesOfInterests.stream()
.filter(dose -> dose.getEndDate() != null)
.map(dose -> {
MultiKey<Object> key = new MultiKey<>(dose.getSubjectId(), dose.getDrug(), dose.getEndDate());
DoseDisc disc = discsBySubjectDrugAndDate.get(key);
return DrugDoseIntermediate.builder()
.subjectId(dose.getSubjectId())
.drug(dose.getDrug())
.startDate(dose.getEndDate()) // sic!
.periodType(disc != null ? PeriodType.DISCONTINUED.name() : PeriodType.INACTIVE.name())
.dose(0.0d)
.frequencyRank("0")
.build();
})
.collect(Collectors.toList());
Collection<DrugDoseIntermediate> discBasedDoses = discsOfInterest.stream()
.map(disc -> DrugDoseIntermediate.builder()
.subjectId(disc.getSubjectId())
.drug(disc.getStudyDrug())
.startDate(disc.getDiscDate())
.periodType(PeriodType.DISCONTINUED.name())
.dose(0.0d)
.frequencyRank("0")
.build())
.collect(Collectors.toList());
return StreamEx.of(
dosesOfInterestConverted.stream(),
discBasedDoses.stream(),
dosesAfterDoses.stream())
.flatMap(Function.identity())
.distinct()
.peek(dose -> dose.setEndDate(null))
.sorted(SUBJECT_AND_DRUG_COMPARATOR)
.groupRuns((dose1, dose2) -> SUBJECT_AND_DRUG_COMPARATOR.compare(dose1, dose2) == 0)
.peek(doses -> StreamEx.of(doses)
.sorted(START_DATE_AND_PERIOD_TYPE_COMPARATOR)
.forPairs((previousDose, nextDose) -> previousDose.setEndDate(nextDose.getStartDate())))
.flatMap(Collection::stream)
.sorted(SUBJECT_DRUG_AND_START_DATE_COMPARATOR) // "ticks"
.filter(Objects::nonNull)
.sorted(SEPARATING_FOR_NEW_INTERVAL_MARK_COMPARATOR)
.groupRuns((dose1, dose2) -> SEPARATING_FOR_NEW_INTERVAL_MARK_COMPARATOR.compare(dose1, dose2) == 0)
.flatMap(doses -> {
List<DrugDoseIntermediate> orderedDoses = doses.stream()
.sorted(Comparator.comparing(DrugDoseIntermediate::getStartDate))
.collect(toList());
Date prevMaxEndDate = null;
List<Map.Entry<DrugDoseIntermediate, Integer>> entries = new ArrayList<>(doses.size());
for (DrugDoseIntermediate dose : orderedDoses) {
int doseInterval;
if (prevMaxEndDate != null && dose.getStartDate() != null && !dose.getStartDate().after(prevMaxEndDate)) {
doseInterval = 0;
} else {
doseInterval = 1;
}
entries.add(Pair.of(dose, doseInterval));
Date endDate = dose.getEndDate();
if (prevMaxEndDate == null || (endDate != null && endDate.after(prevMaxEndDate))) {
prevMaxEndDate = endDate;
}
}
return entries.stream();
}) // "newIntervalMarks"
.sorted(Map.Entry.comparingByKey(SUBJECT_AND_DRUG_COMPARATOR))
.groupRuns((e1, e2) -> Map.Entry.<DrugDoseIntermediate, Integer>comparingByKey(SUBJECT_AND_DRUG_COMPARATOR).compare(e1, e2) == 0)
.flatMap(doseEntries -> {
List<Map.Entry<DrugDoseIntermediate, Integer>> orderedDoses = doseEntries.stream()
.sorted(Map.Entry.comparingByKey(START_DATE_AND_PERIOD_TYPE_COMPARATOR))
.collect(toList());
int intervalRank = 0;
List<Map.Entry<DrugDoseIntermediate, Integer>> res = new ArrayList<>(orderedDoses.size());
for (Map.Entry<DrugDoseIntermediate, Integer> doseEntry : orderedDoses) {
intervalRank += doseEntry.getValue();
res.add(Pair.of(doseEntry.getKey(), intervalRank));
}
return res.stream();
}) // "doseIntervalRanks"
.sorted(SUBJECT_DRUG_AND_INTERVAL_RANK_COMPARATOR)
.groupRuns((de1, de2) -> SUBJECT_DRUG_AND_INTERVAL_RANK_COMPARATOR.compare(de1, de2) == 0)
.flatMap(doseEntries -> {
Date startDate = doseEntries.stream()
.map(Map.Entry::getKey)
.map(DrugDoseIntermediate::getStartDate).min(Comparator.naturalOrder()).orElse(null);
Date endDate = doseEntries.stream()
.map(Map.Entry::getKey)
.map(DrugDoseIntermediate::getEndDate)
.filter(Objects::nonNull)
.max(Comparator.naturalOrder()).orElse(studyLastUpdated); // differs "result" and "periods"; no separate "periods" written in Java
return doseEntries.stream()
.map(Map.Entry::getKey)
.peek(dose -> {
dose.setStartDate(startDate);
dose.setEndDate(endDate);
});
})
.distinct()
.sorted(SUBJECT_DRUG_AND_START_DATE_COMPARATOR
.thenComparing(DrugDoseIntermediate::getPeriodType))
.collect(toList());
}