public Collection getJavaPrecalculatedData()

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());
    }