From 4d7f35aac97f7daf0a5deb3670e5d6c9bcd4e417 Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Thu, 13 Feb 2025 13:17:30 -0500 Subject: [PATCH 1/9] Add all usecases for studyview service --- .../repository/AlterationRepository.java | 23 + .../usecase/AlterationCountByGeneUseCase.java | 215 +++++ .../application/rest/mapper/SampleMapper.java | 25 + .../rest/request/StudyViewFilterDTO.java | 239 ++++++ .../application/rest/response/SampleDTO.java | 7 + .../ColumnarStoreStudyViewController.java | 55 ++ .../repository/CancerStudyRepository.java | 3 + .../usecase/GetFilteredStudyIdsUseCase.java | 23 + .../ClinicalAttributesRepository.java | 12 + ...tClinicalAttributesDataTypeMapUseCase.java | 24 + ...etClinicalAttributesForStudiesUseCase.java | 22 + .../repository/ClinicalDataRepository.java | 16 + .../usecase/ClinicalDataUseCases.java | 14 + .../usecase/GetClinicalDataCountsUseCase.java | 64 ++ .../GetClinicalDataForXyPlotUseCase.java | 118 +++ .../GetPatientClinicalDataUseCase.java | 23 + .../usecase/GetSampleClinicalDataUseCase.java | 23 + .../repository/ClinicalEventRepository.java | 10 + .../GetClinicalEventTypeCountsUseCase.java | 23 + .../repository/GenericAssayRepository.java | 20 + .../usecase/GenericAssayUseCases.java | 14 + ...eredMolecularProfilesByAlterationType.java | 27 + .../usecase/GetGenericAssayDataBinCounts.java | 24 + .../GetGenericAssayDataCountsUseCase.java | 25 + .../GetGenericAssayProfilesUseCase.java | 22 + .../repository/GenomicDataRepository.java | 24 + .../usecase/GenomicDataUseCases.java | 15 + .../GetCNACountsByGeneSpecificUseCase.java | 26 + .../GetGenomicDataBinCountsUseCase.java | 25 + ...etMolecularProfileSampleCountsUseCase.java | 24 + .../GetMutationCountsByTypeUseCase.java | 25 + .../usecase/GetMutationCountsUseCase.java | 25 + .../ClickhouseAlterationMapper.java | 25 + .../ClickhouseAlterationRepository.java | 103 +++ .../ClickhouseCancerStudyMapper.java | 4 + .../ClickhouseCancerStudyRepository.java | 10 + .../ClickhouseClinicalAttributesMapper.java | 10 + ...lickhouseClinicalAttributesRepository.java | 64 ++ .../ClickhouseClinicalDataMapper.java | 13 + .../ClickhouseClinicalDataRepository.java | 55 ++ .../ClickhouseClinicalEventMapper.java | 11 + .../ClickhouseClinicalEventRepository.java | 29 + .../ClickhouseGenericAssayMapper.java | 20 + .../ClickhouseGenericAssayRepository.java | 62 ++ .../ClickhouseGenomicDataMapper.java | 22 + .../ClickhouseGenomicDataRepository.java | 75 ++ .../patient/ClickhousePatientMapper.java | 11 + .../patient/ClickhousePatientRepository.java | 38 + .../sample/ClickhouseSampleMapper.java | 12 + .../sample/ClickhouseSampleRepository.java | 38 + .../ClickhouseStudyViewFilterMapper.java | 4 + .../treatment/ClickhouseTreatmentMapper.java | 15 + .../ClickhouseTreatmentRepository.java | 56 ++ ...ategorizedGenericAssayDataCountFilter.java | 44 + .../patient/repository/PatientRepository.java | 11 + .../usecase/GetCaseListDataCountsUseCase.java | 24 + .../GetFilteredPatientCountUseCase.java | 20 + .../java/org/cbioportal/sample/Sample.java | 27 + .../org/cbioportal/sample/SampleType.java | 37 + .../sample/repository/SampleRepository.java | 11 + .../GetFilteredSamplesCountUseCase.java | 21 + .../usecase/GetFilteredSamplesUseCase.java | 24 + .../org/cbioportal/shared/DataFilterUtil.java | 132 +++ .../util/ClinicalDataCountItemUtil.java | 22 + .../studyview/StudyViewFilterContext.java | 58 ++ .../studyview/StudyViewFilterFactory.java | 56 ++ .../studyview/StudyViewService.java | 205 +++++ .../repository/TreatmentRepository.java | 14 + .../FilteredTreatmentCountReportUseCase.java | 43 + .../ClickhouseAlterationFilterMapper.xml | 120 +++ .../alteration/ClickhouseAlterationMapper.xml | 134 +++ .../cancerstudy/CancerStudyMapper.xml | 9 + .../ClickhouseClinicalAttributesMapper.xml | 33 + .../ClickhouseClinicalDataMapper.xml | 123 +++ .../ClickhouseClinicalEventMapper.xml | 17 + .../generic_assay/GenericAssayMapper.xml | 156 ++++ .../ClickhouseGenomicDataMapper.xml | 190 +++++ .../patient/ClickhousePatientMapper.xml | 30 + .../sample/ClickhouseSampleMapper.xml | 41 + .../ClickhouseStudyViewFilterMapper.xml | 806 ++++++++++++++++++ .../treatment/ClickhouseTreatmentMapper.xml | 110 +++ 81 files changed, 4430 insertions(+) create mode 100644 src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java create mode 100644 src/main/java/org/cbioportal/alteration/usecase/AlterationCountByGeneUseCase.java create mode 100644 src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java create mode 100644 src/main/java/org/cbioportal/application/rest/request/StudyViewFilterDTO.java create mode 100644 src/main/java/org/cbioportal/application/rest/response/SampleDTO.java create mode 100644 src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java create mode 100644 src/main/java/org/cbioportal/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java create mode 100644 src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java create mode 100644 src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java create mode 100644 src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java create mode 100644 src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java create mode 100644 src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java create mode 100644 src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java create mode 100644 src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java create mode 100644 src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java create mode 100644 src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java create mode 100644 src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java create mode 100644 src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java create mode 100644 src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java create mode 100644 src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java create mode 100644 src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java create mode 100644 src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java create mode 100644 src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java create mode 100644 src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java create mode 100644 src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java create mode 100644 src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java create mode 100644 src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java create mode 100644 src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java create mode 100644 src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java create mode 100644 src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java create mode 100644 src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/studyview/ClickhouseStudyViewFilterMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java create mode 100644 src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java create mode 100644 src/main/java/org/cbioportal/patient/repository/PatientRepository.java create mode 100644 src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java create mode 100644 src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java create mode 100644 src/main/java/org/cbioportal/sample/Sample.java create mode 100644 src/main/java/org/cbioportal/sample/SampleType.java create mode 100644 src/main/java/org/cbioportal/sample/repository/SampleRepository.java create mode 100644 src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java create mode 100644 src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesUseCase.java create mode 100644 src/main/java/org/cbioportal/shared/DataFilterUtil.java create mode 100644 src/main/java/org/cbioportal/shared/util/ClinicalDataCountItemUtil.java create mode 100644 src/main/java/org/cbioportal/studyview/StudyViewFilterContext.java create mode 100644 src/main/java/org/cbioportal/studyview/StudyViewFilterFactory.java create mode 100644 src/main/java/org/cbioportal/studyview/StudyViewService.java create mode 100644 src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java create mode 100644 src/main/java/org/cbioportal/treatment/usecase/FilteredTreatmentCountReportUseCase.java create mode 100644 src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationFilterMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/clinical_data/ClickhouseClinicalDataMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/genomic_data/ClickhouseGenomicDataMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/studyview/ClickhouseStudyViewFilterMapper.xml create mode 100644 src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml diff --git a/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java b/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java new file mode 100644 index 00000000000..2ec5cef394d --- /dev/null +++ b/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java @@ -0,0 +1,23 @@ +package org.cbioportal.alteration.repository; + +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.CopyNumberCountByGene; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public interface AlterationRepository { + List getMutatedGenes(StudyViewFilterContext studyViewFilterContext); + List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext); + List getCnaGenes(StudyViewFilterContext studyViewFilterContext); + int getTotalProfiledCountsByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType); + Map getTotalProfiledCounts(StudyViewFilterContext studyViewFilterContext, + String alterationType, List molecularProfiles); + Map> getMatchingGenePanelIds(StudyViewFilterContext studyViewFilterContext, + String alterationType); + int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType); + +} diff --git a/src/main/java/org/cbioportal/alteration/usecase/AlterationCountByGeneUseCase.java b/src/main/java/org/cbioportal/alteration/usecase/AlterationCountByGeneUseCase.java new file mode 100644 index 00000000000..b0923c3369a --- /dev/null +++ b/src/main/java/org/cbioportal/alteration/usecase/AlterationCountByGeneUseCase.java @@ -0,0 +1,215 @@ +package org.cbioportal.alteration.usecase; + +import org.apache.commons.math3.util.Pair; +import org.cbioportal.alteration.repository.AlterationRepository; +import org.cbioportal.cancerstudy.usecase.GetFilteredStudyIdsUseCase; +import org.cbioportal.generic_assay.usecase.GetFilteredMolecularProfilesByAlterationType; +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.AlterationType; +import org.cbioportal.legacy.model.CopyNumberCountByGene; +import org.cbioportal.legacy.model.Gistic; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.model.MutSig; +import org.cbioportal.legacy.service.SignificantCopyNumberRegionService; +import org.cbioportal.legacy.service.SignificantlyMutatedGeneService; +import org.cbioportal.legacy.service.exception.StudyNotFoundException; +import org.cbioportal.legacy.service.util.AlterationCountServiceUtil; +import org.cbioportal.legacy.web.parameter.Projection; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +@Profile("clickhouse") +public class AlterationCountByGeneUseCase { + + private final AlterationRepository alterationRepository; + private final GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType; + private final GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase; + private final SignificantlyMutatedGeneService significantlyMutatedGeneService; + private final SignificantCopyNumberRegionService significantCopyNumberRegionService; + + public AlterationCountByGeneUseCase(AlterationRepository alterationRepository, GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType, + GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase, + SignificantlyMutatedGeneService significantlyMutatedGeneService, + SignificantCopyNumberRegionService significantCopyNumberRegionService) { + this.alterationRepository = alterationRepository; + this.getFilteredMolecularProfilesByAlterationType = getFilteredMolecularProfilesByAlterationType; + this.getFilteredStudyIdsUseCase = getFilteredStudyIdsUseCase; + this.significantlyMutatedGeneService = significantlyMutatedGeneService; + this.significantCopyNumberRegionService = significantCopyNumberRegionService; + } + + public List getMutatedGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException{ + var alterationCountByGenes = + populateAlterationCounts(AlterationCountServiceUtil.combineAlterationCountsWithConflictingHugoSymbols(alterationRepository.getMutatedGenes(studyViewFilterContext)), + studyViewFilterContext, AlterationType.MUTATION_EXTENDED); + return populateAlterationCountsWithMutSigQValue(alterationCountByGenes, studyViewFilterContext); + } + + /** + * Retrieves a list of genes with copy number alterations (CNA) and their alteration counts for a given filter context. + * + * @param studyViewFilterContext Context containing filter criteria. + * @return List of CopyNumberCountByGene objects representing genes with CNAs. + * @throws StudyNotFoundException if the specified study is not found. + */ + public List getCnaGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + var copyNumberAlterationCounts = + populateAlterationCounts(AlterationCountServiceUtil.combineCopyNumberCountsWithConflictingHugoSymbols(alterationRepository.getCnaGenes(studyViewFilterContext)), studyViewFilterContext, AlterationType.COPY_NUMBER_ALTERATION); + return populateAlterationCountsWithCNASigQValue(copyNumberAlterationCounts, studyViewFilterContext); + } + + /** + * Retrieves a list of structural variant genes and their alteration counts for a given filter context. + * + * @param studyViewFilterContext Context containing filter criteria. + * @return List of AlterationCountByGene objects representing structural variant genes. + * @throws StudyNotFoundException if the specified study is not found. + */ + public List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + var alterationCountByGenes = + populateAlterationCounts(AlterationCountServiceUtil.combineAlterationCountsWithConflictingHugoSymbols(alterationRepository.getStructuralVariantGenes(studyViewFilterContext)), + studyViewFilterContext, AlterationType.STRUCTURAL_VARIANT); + return populateAlterationCountsWithMutSigQValue(alterationCountByGenes, studyViewFilterContext); + } + + /** + * Populates alteration counts with profile data, including the total profiled count and matching gene panel IDs. + * + * @param alterationCounts List of alteration counts to enrich. + * @param studyViewFilterContext Context containing filter criteria. + * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). + * @param The type of alteration count. + * @return List of enriched alteration counts. + */ + private List populateAlterationCounts(@NonNull List alterationCounts, + @NonNull StudyViewFilterContext studyViewFilterContext, + @NonNull AlterationType alterationType) { + final var firstMolecularProfileForEachStudy = getFirstMolecularProfileGroupedByStudy(studyViewFilterContext, + alterationType); + final int totalProfiledCount = alterationRepository.getTotalProfiledCountsByAlterationType(studyViewFilterContext, + alterationType.toString()); + var profiledCountsMap = alterationRepository.getTotalProfiledCounts(studyViewFilterContext, alterationType.toString(), + firstMolecularProfileForEachStudy); + final var matchingGenePanelIdsMap = alterationRepository.getMatchingGenePanelIds(studyViewFilterContext, + alterationType.toString()); + final int sampleProfileCountWithoutGenePanelData = + alterationRepository.getSampleProfileCountWithoutPanelData(studyViewFilterContext, alterationType.toString()); + + alterationCounts.parallelStream() + .forEach(alterationCountByGene -> { + String hugoGeneSymbol = alterationCountByGene.getHugoGeneSymbol(); + Set matchingGenePanelIds = matchingGenePanelIdsMap.get(hugoGeneSymbol) != null ? + matchingGenePanelIdsMap.get(hugoGeneSymbol) : Collections.emptySet(); + + int alterationTotalProfiledCount = AlterationCountServiceUtil.computeTotalProfiledCount(AlterationCountServiceUtil.hasGenePanelData(matchingGenePanelIds), + profiledCountsMap.getOrDefault(hugoGeneSymbol, 0), + sampleProfileCountWithoutGenePanelData, totalProfiledCount); + + alterationCountByGene.setNumberOfProfiledCases(alterationTotalProfiledCount); + + alterationCountByGene.setMatchingGenePanelIds(matchingGenePanelIds); + + }); + return alterationCounts; + } + + /** + * Updates alteration counts with MutSig Q-value data for significance. + * + * @param alterationCountByGenes List of alteration counts to update. + * @param studyViewFilterContext Context containing filter criteria. + * @return List of alteration counts updated with MutSig Q-value. + * @throws StudyNotFoundException if the specified study is not found. + */ + private List populateAlterationCountsWithMutSigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + final var mutSigs = getMutSigs(studyViewFilterContext); + // If MutSig is not empty update Mutated Genes + return AlterationCountServiceUtil.updateAlterationCountsWithMutSigQValue(alterationCountByGenes, mutSigs); + } + + /** + * Updates copy number alteration counts with GISTIC significance data. + * + * @param alterationCountByGenes List of alteration counts to update. + * @param studyViewFilterContext Context containing filter criteria. + * @return List of alteration counts updated with GISTIC significance data. + * @throws StudyNotFoundException if the specified study is not found. + */ + private List populateAlterationCountsWithCNASigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + final var gisticMap = getGisticMap(studyViewFilterContext); + return AlterationCountServiceUtil.updateAlterationCountsWithCNASigQValue(alterationCountByGenes, gisticMap); + } + + /** + * Retrieves the first molecular profile for each study based on the alteration type. + * + * @param studyViewFilterContext Context containing filter criteria. + * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). + * @return List of MolecularProfile objects representing the first profile for each study. + */ + private List getFirstMolecularProfileGroupedByStudy(StudyViewFilterContext studyViewFilterContext, AlterationType alterationType) { + final var molecularProfiles = + getFilteredMolecularProfilesByAlterationType.excute(studyViewFilterContext, alterationType.toString()); + return AlterationCountServiceUtil.getFirstMolecularProfileGroupedByStudy(molecularProfiles); + } + + /** + * Retrieves MutSig data for significantly mutated genes in the specified studies. + * + * @param studyViewFilterContext Context containing filter criteria. + * @return Map of MutSig objects keyed by Hugo gene symbol. + * @throws StudyNotFoundException if the specified study is not found. + */ + private Map getMutSigs(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + var distinctStudyIds = getFilteredStudyIdsUseCase.execute(studyViewFilterContext); + Map mutSigs = new HashMap<>(); + if (distinctStudyIds.size() == 1) { + var studyId = distinctStudyIds.getFirst(); + mutSigs = significantlyMutatedGeneService.getSignificantlyMutatedGenes( + studyId, + Projection.SUMMARY.name(), + null, + null, + null, + null) + .stream() + .collect(Collectors.toMap(MutSig::getHugoGeneSymbol, Function.identity())); + } + return mutSigs; + } + + /** + * Retrieves GISTIC data for significant copy number alterations in the specified studies. + * + * @param studyViewFilterContext Context containing filter criteria. + * @return Map of GISTIC objects keyed by gene and G-score rank. + * @throws StudyNotFoundException if the specified study is not found. + */ + private Map, Gistic> getGisticMap(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + var distinctStudyIds = getFilteredStudyIdsUseCase.execute(studyViewFilterContext); + Map, Gistic> gisticMap = new HashMap<>(); + if (distinctStudyIds.size() == 1) { + var studyId = distinctStudyIds.getFirst(); + List gisticList = significantCopyNumberRegionService.getSignificantCopyNumberRegions( + studyId, + Projection.SUMMARY.name(), + null, + null, + null, + null); + AlterationCountServiceUtil.setupGisticMap(gisticList, gisticMap); + } + return gisticMap; + } +} diff --git a/src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java b/src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java new file mode 100644 index 00000000000..0c6986ed643 --- /dev/null +++ b/src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java @@ -0,0 +1,25 @@ +package org.cbioportal.application.rest.mapper; + +import org.cbioportal.application.rest.response.SampleDTO; +import org.cbioportal.legacy.utils.Encoder; +import org.cbioportal.sample.Sample; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper( imports = Encoder.class) +public interface SampleMapper { + SampleMapper INSTANCE = Mappers.getMapper(SampleMapper.class); + + @Mapping(target = "patientId", source = "patientStableId") + @Mapping(target = "sampleId", source = "stableId") + @Mapping(target = "studyId", source = "cancerStudyIdentifier") + @Mapping(target = "uniqueSampleKey", expression = "java( Encoder.calculateBase64(sample.stableId()," + + "sample.cancerStudyIdentifier()) )") + @Mapping(target = "uniquePatientKey", expression = "java( Encoder.calculateBase64(sample.patientStableId(), " + + "sample.cancerStudyIdentifier()) )") + SampleDTO toSampleDTO(Sample sample); + List toDtos(List samples); +} diff --git a/src/main/java/org/cbioportal/application/rest/request/StudyViewFilterDTO.java b/src/main/java/org/cbioportal/application/rest/request/StudyViewFilterDTO.java new file mode 100644 index 00000000000..623d8cd4deb --- /dev/null +++ b/src/main/java/org/cbioportal/application/rest/request/StudyViewFilterDTO.java @@ -0,0 +1,239 @@ +package org.cbioportal.application.rest.request; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import jakarta.validation.Valid; +import jakarta.validation.constraints.AssertTrue; +import jakarta.validation.constraints.Size; +import org.cbioportal.legacy.model.AlterationFilter; +import org.cbioportal.legacy.model.GeneFilter; +import org.cbioportal.legacy.model.StudyViewStructuralVariantFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; +import org.cbioportal.legacy.web.parameter.DataFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.legacy.web.parameter.MutationDataFilter; +import org.cbioportal.legacy.web.parameter.SampleIdentifier; +import org.cbioportal.legacy.web.parameter.filter.AndedPatientTreatmentFilters; +import org.cbioportal.legacy.web.parameter.filter.AndedSampleTreatmentFilters; + +import java.util.List; +import java.util.Objects; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(Include.NON_NULL) +public class StudyViewFilterDTO { + + @Size(min = 1) + private List sampleIdentifiers; + @Size(min = 1) + private List studyIds; + private List clinicalDataFilters; + private List geneFilters; + @Valid + private List structuralVariantFilters; + private AndedSampleTreatmentFilters sampleTreatmentFilters; + private AndedSampleTreatmentFilters sampleTreatmentGroupFilters; + private AndedSampleTreatmentFilters sampleTreatmentTargetFilters; + private AndedPatientTreatmentFilters patientTreatmentFilters; + private AndedPatientTreatmentFilters patientTreatmentGroupFilters; + private AndedPatientTreatmentFilters patientTreatmentTargetFilters; + private List> genomicProfiles; + private List genomicDataFilters; + private List genericAssayDataFilters; + private List> caseLists; + private List customDataFilters; + private AlterationFilter alterationFilter; + private List clinicalEventFilters; + private List mutationDataFilters; + + @AssertTrue + private boolean isEitherSampleIdentifiersOrStudyIdsPresent() { + return sampleIdentifiers != null ^ studyIds != null; + } + + @AssertTrue + private boolean isEitherValueOrRangePresentInClinicalDataIntervalFilters() { + return validateDataFilters(clinicalDataFilters); + } + + @AssertTrue + private boolean isEitherValueOrRangePresentInGenomicDataIntervalFilters() { + return validateDataFilters(genomicDataFilters); + } + + @AssertTrue + private boolean isEitherValueOrRangePresentInGenericAssayDataIntervalFilters() { + return validateDataFilters(genericAssayDataFilters); + } + + @AssertTrue + private boolean isEitherValueOrRangePresentInCustomDataFilters() { + return validateDataFilters(customDataFilters); + } + + private boolean validateDataFilters(List dataFilters) { + long invalidCount = 0; + + if (dataFilters != null) { + invalidCount = dataFilters.stream() + .flatMap(f -> f.getValues().stream()) + .filter(Objects::nonNull) + .filter(v -> v.getValue() != null == (v.getStart() != null || v.getEnd() != null)) + .count(); + } + + return invalidCount == 0; + } + + public List getSampleIdentifiers() { + return sampleIdentifiers; + } + + public void setSampleIdentifiers(List sampleIdentifiers) { + this.sampleIdentifiers = sampleIdentifiers; + } + + public List getStudyIds() { + return studyIds; + } + + public void setStudyIds(List studyIds) { + this.studyIds = studyIds; + } + + public List getClinicalDataFilters() { + return clinicalDataFilters; + } + + public void setClinicalDataFilters(List clinicalDataFilters) { + this.clinicalDataFilters = clinicalDataFilters; + } + + public List getGeneFilters() { + return geneFilters; + } + + public void setGeneFilters(List geneFilters) { + this.geneFilters = geneFilters; + } + + public List getStructuralVariantFilters() { + return structuralVariantFilters; + } + + public void setStructuralVariantFilters(List structuralVariantFilters) { + this.structuralVariantFilters = (structuralVariantFilters != null) ? structuralVariantFilters : List.of(); + } + + public List> getGenomicProfiles() { + return genomicProfiles; + } + + public void setGenomicProfiles(List> genomicProfiles) { + this.genomicProfiles = genomicProfiles; + } + + public List getGenomicDataFilters() { + return genomicDataFilters; + } + + public void setGenomicDataFilters(List genomicDataFilters) { + this.genomicDataFilters = genomicDataFilters; + } + + public AndedSampleTreatmentFilters getSampleTreatmentFilters() { + return sampleTreatmentFilters; + } + + public void setSampleTreatmentFilters(AndedSampleTreatmentFilters sampleTreatmentFilters) { + this.sampleTreatmentFilters = sampleTreatmentFilters; + } + + public AndedPatientTreatmentFilters getPatientTreatmentFilters() { + return patientTreatmentFilters; + } + + public void setPatientTreatmentFilters(AndedPatientTreatmentFilters patientTreatmentFilters) { + this.patientTreatmentFilters = patientTreatmentFilters; + } + + public List> getCaseLists() { + return caseLists; + } + + public void setCaseLists(List> caseLists) { + this.caseLists = caseLists; + } + + public List getGenericAssayDataFilters() { + return genericAssayDataFilters; + } + + public void setGenericAssayDataFilters(List genericAssayDataFilters) { + this.genericAssayDataFilters = genericAssayDataFilters; + } + + public List getCustomDataFilters() { + return customDataFilters; + } + + public void setCustomDataFilters(List customDataFilters) { + this.customDataFilters = customDataFilters; + } + + public AlterationFilter getAlterationFilter() { + return alterationFilter; + } + + public void setAlterationFilter(AlterationFilter alterationFilter) { + this.alterationFilter = (alterationFilter != null) ? alterationFilter : new AlterationFilter(); + } + + public AndedSampleTreatmentFilters getSampleTreatmentGroupFilters() { + return sampleTreatmentGroupFilters; + } + + public void setSampleTreatmentGroupFilters(AndedSampleTreatmentFilters sampleTreatmentGroupFilters) { + this.sampleTreatmentGroupFilters = sampleTreatmentGroupFilters; + } + + public AndedPatientTreatmentFilters getPatientTreatmentGroupFilters() { + return patientTreatmentGroupFilters; + } + + public void setPatientTreatmentGroupFilters(AndedPatientTreatmentFilters patientTreatmentGroupFilters) { + this.patientTreatmentGroupFilters = patientTreatmentGroupFilters; + } + + public AndedSampleTreatmentFilters getSampleTreatmentTargetFilters() { + return sampleTreatmentTargetFilters; + } + + public void setSampleTreatmentTargetFilters(AndedSampleTreatmentFilters sampleTreatmentTargetFilters) { + this.sampleTreatmentTargetFilters = sampleTreatmentTargetFilters; + } + + public AndedPatientTreatmentFilters getPatientTreatmentTargetFilters() { + return patientTreatmentTargetFilters; + } + + public void setPatientTreatmentTargetFilters(AndedPatientTreatmentFilters patientTreatmentTagetFilters) { + this.patientTreatmentTargetFilters = patientTreatmentTagetFilters; + } + + public List getClinicalEventFilters() { + return clinicalEventFilters; + } + + public void setClinicalEventFilters(List clinicalEventFilters) { + this.clinicalEventFilters = clinicalEventFilters; + } + + public List getMutationDataFilters() { return mutationDataFilters; } + + public void setMutationDataFilters(List mutationDataFilters) { + this.mutationDataFilters = mutationDataFilters; + } +} diff --git a/src/main/java/org/cbioportal/application/rest/response/SampleDTO.java b/src/main/java/org/cbioportal/application/rest/response/SampleDTO.java new file mode 100644 index 00000000000..d9690abed93 --- /dev/null +++ b/src/main/java/org/cbioportal/application/rest/response/SampleDTO.java @@ -0,0 +1,7 @@ +package org.cbioportal.application.rest.response; + +import org.cbioportal.sample.SampleType; + +public record SampleDTO(String sampleId, SampleType sampleType, String patientId, String studyId, Boolean sequenced, + Boolean copyNumberSegmentPresent, String uniqueSampleKey, String uniquePatientKey) { +} diff --git a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java new file mode 100644 index 00000000000..062479c4605 --- /dev/null +++ b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java @@ -0,0 +1,55 @@ +package org.cbioportal.application.rest.vcolumnstore; + +import io.swagger.v3.oas.annotations.Hidden; +import org.cbioportal.application.rest.mapper.SampleMapper; +import org.cbioportal.application.rest.response.SampleDTO; +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.service.exception.StudyNotFoundException; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.cbioportal.studyview.StudyViewService; +import org.springframework.context.annotation.Profile; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collection; +import java.util.List; + +@RestController +@RequestMapping("/api/column-store") +@Profile("clickhouse") +public class ColumnarStoreStudyViewController { + + private final StudyViewService studyViewService; + + public ColumnarStoreStudyViewController(StudyViewService studyViewService) { + this.studyViewService = studyViewService; + } + + @Hidden + @PostMapping(value = "/v1/filtered-samples/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> fetchFilteredSamples( + @RequestParam(defaultValue = "false") Boolean negateFilters, + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter, + @RequestBody(required = false) StudyViewFilter studyViewFilter) { + return ResponseEntity.ok(SampleMapper.INSTANCE.toDtos(studyViewService.getFilteredSamples(studyViewFilter)) + ); + } + + @Hidden // should unhide when we remove legacy controller + @PostMapping(value = "/v1/mutated-genes/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> fetchMutatedGenes( + @RequestBody(required = false) StudyViewFilter studyViewFilter + ) throws StudyNotFoundException { + return ResponseEntity.ok(studyViewService.getMutatedGenes(studyViewFilter) + ); + } +} diff --git a/src/main/java/org/cbioportal/cancerstudy/repository/CancerStudyRepository.java b/src/main/java/org/cbioportal/cancerstudy/repository/CancerStudyRepository.java index fe9856e7c9c..db436085c48 100644 --- a/src/main/java/org/cbioportal/cancerstudy/repository/CancerStudyRepository.java +++ b/src/main/java/org/cbioportal/cancerstudy/repository/CancerStudyRepository.java @@ -2,6 +2,7 @@ import org.cbioportal.cancerstudy.CancerStudyMetadata; import org.cbioportal.shared.SortAndSearchCriteria; +import org.cbioportal.studyview.StudyViewFilterContext; import java.util.List; @@ -74,4 +75,6 @@ public interface CancerStudyRepository { * are found. */ List getCancerStudiesMetadataSummary(SortAndSearchCriteria sortAndSearchCriteria); + + List getFilteredStudyIds(StudyViewFilterContext studyViewFilterContext); } diff --git a/src/main/java/org/cbioportal/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java b/src/main/java/org/cbioportal/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java new file mode 100644 index 00000000000..2f2ebebc0d7 --- /dev/null +++ b/src/main/java/org/cbioportal/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java @@ -0,0 +1,23 @@ +package org.cbioportal.cancerstudy.usecase; + +import org.cbioportal.cancerstudy.repository.CancerStudyRepository; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetFilteredStudyIdsUseCase { + + private final CancerStudyRepository studyRepository; + + public GetFilteredStudyIdsUseCase(CancerStudyRepository studyRepository) { + this.studyRepository = studyRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext) { + return this.studyRepository.getFilteredStudyIds(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java b/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java new file mode 100644 index 00000000000..1b8462d8e2f --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java @@ -0,0 +1,12 @@ +package org.cbioportal.clinical_attributes.repository; + +import org.cbioportal.legacy.model.ClinicalAttribute; +import org.cbioportal.legacy.web.parameter.ClinicalDataType; + +import java.util.List; +import java.util.Map; + +public interface ClinicalAttributesRepository { + List getClinicalAttributesForStudies(List studyIds); + Map getClinicalAttributeDatatypeMap(); +} diff --git a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java new file mode 100644 index 00000000000..f355a061829 --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java @@ -0,0 +1,24 @@ +package org.cbioportal.clinical_attributes.usecase; + +import org.cbioportal.clinical_attributes.repository.ClinicalAttributesRepository; +import org.cbioportal.legacy.web.parameter.ClinicalDataType; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +@Profile("clickhouse") +public class GetClinicalAttributesDataTypeMapUseCase { + + private final ClinicalAttributesRepository clinicalAttributesRepository; + + + public GetClinicalAttributesDataTypeMapUseCase(ClinicalAttributesRepository clinicalAttributesRepository) { + this.clinicalAttributesRepository = clinicalAttributesRepository; + } + + public Map execute() { + return clinicalAttributesRepository.getClinicalAttributeDatatypeMap(); + } +} diff --git a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java new file mode 100644 index 00000000000..bd218f0fc69 --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java @@ -0,0 +1,22 @@ +package org.cbioportal.clinical_attributes.usecase; + +import org.cbioportal.clinical_attributes.repository.ClinicalAttributesRepository; +import org.cbioportal.legacy.model.ClinicalAttribute; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetClinicalAttributesForStudiesUseCase { + private final ClinicalAttributesRepository clinicalAttributesRepository; + + public GetClinicalAttributesForStudiesUseCase(ClinicalAttributesRepository clinicalAttributesRepository) { + this.clinicalAttributesRepository = clinicalAttributesRepository; + } + + public List execute(List studyIds){ + return clinicalAttributesRepository.getClinicalAttributesForStudies(studyIds); + } +} diff --git a/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java b/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java new file mode 100644 index 00000000000..a6d2883e9ac --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java @@ -0,0 +1,16 @@ +package org.cbioportal.clinical_data.repository; + +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClinicalDataRepository { + List getPatientClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes); + List getSampleClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes); + List getClinicalDataCounts(StudyViewFilterContext studyViewFilterContext, + List filteredAttributes); + + +} diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java b/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java new file mode 100644 index 00000000000..0edbc1831d0 --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java @@ -0,0 +1,14 @@ +package org.cbioportal.clinical_data.usecase; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +@Service +@Profile("clickhouse") +public record ClinicalDataUseCases( + GetClinicalDataCountsUseCase getClinicalDataCountsUseCase, + GetClinicalDataForXyPlotUseCase getClinicalDataForXyPlotUseCase, + GetPatientClinicalDataUseCase getPatientClinicalDataUseCase, + GetSampleClinicalDataUseCase getSampleClinicalDataUseCase +) { +} diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java new file mode 100644 index 00000000000..1d82641e894 --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java @@ -0,0 +1,64 @@ +package org.cbioportal.clinical_data.usecase; + +import org.cbioportal.clinical_attributes.usecase.GetClinicalAttributesForStudiesUseCase; +import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; +import org.cbioportal.patient.usecase.GetFilteredPatientCountUseCase; +import org.cbioportal.sample.usecase.GetFilteredSamplesCountUseCase; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetClinicalDataCountsUseCase { + private final ClinicalDataRepository clinicalDataRepository; + private final GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase; + private final GetFilteredSamplesCountUseCase getFilteredSamplesCountUseCase; + private final GetFilteredPatientCountUseCase getFilteredPatientCountUseCase; + + + public GetClinicalDataCountsUseCase(ClinicalDataRepository clinicalDataRepository, GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase, GetFilteredSamplesCountUseCase getFilteredSamplesCountUseCase, GetFilteredPatientCountUseCase getFilteredPatientCountUseCase) { + this.clinicalDataRepository = clinicalDataRepository; + this.getClinicalAttributesForStudiesUseCase = getClinicalAttributesForStudiesUseCase; + this.getFilteredSamplesCountUseCase = getFilteredSamplesCountUseCase; + this.getFilteredPatientCountUseCase = getFilteredPatientCountUseCase; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, + List filteredAttributes){ + + List involvedCancerStudies = studyViewFilterContext.customDataFilterCancerStudies(); + + var result = clinicalDataRepository.getClinicalDataCounts(studyViewFilterContext, filteredAttributes); + + // normalize data counts so that values like TRUE, True, and true are all merged in one count + result.forEach(item -> item.setCounts(StudyViewColumnarServiceUtil.normalizeDataCounts(item.getCounts()))); + + // attributes may be missing in result set because they have been filtered out + // e.g. if the filtered samples happen to have no SEX data, they will not appear in the list + // even though the inferred value of those attributes is NA + // the following code restores these counts for missing attributes + if (result.size() != filteredAttributes.size()) { + var attributes = getClinicalAttributesForStudiesUseCase.execute(involvedCancerStudies) + .stream() + .filter(attribute -> filteredAttributes.contains(attribute.getAttrId())) + .toList(); + + Integer filteredSampleCount = getFilteredSamplesCountUseCase.execute(studyViewFilterContext); + Integer filteredPatientCount = getFilteredPatientCountUseCase.execute(studyViewFilterContext); + + result = StudyViewColumnarServiceUtil.addClinicalDataCountsForMissingAttributes( + result, + attributes, + filteredSampleCount, + filteredPatientCount + ); + } + + return StudyViewColumnarServiceUtil.mergeClinicalDataCounts(result); + } +} diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java new file mode 100644 index 00000000000..49312293800 --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java @@ -0,0 +1,118 @@ +package org.cbioportal.clinical_data.usecase; + +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.sample.Sample; +import org.cbioportal.sample.usecase.GetFilteredSamplesUseCase; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Service +@Profile("clickhouse") +public class GetClinicalDataForXyPlotUseCase { + private final GetPatientClinicalDataUseCase getPatientClinicalDataUseCase; + private final GetSampleClinicalDataUseCase getSampleClinicalDataUseCase; + private final GetFilteredSamplesUseCase getFilteredSamplesUseCase; + + public GetClinicalDataForXyPlotUseCase(GetPatientClinicalDataUseCase getPatientClinicalDataUseCase, GetSampleClinicalDataUseCase getSampleClinicalDataUseCase, GetFilteredSamplesUseCase getFilteredSamplesUseCase) { + this.getPatientClinicalDataUseCase = getPatientClinicalDataUseCase; + this.getSampleClinicalDataUseCase = getSampleClinicalDataUseCase; + this.getFilteredSamplesUseCase = getFilteredSamplesUseCase; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, List attributeIds, + boolean shouldFilterNonEmptyClinicalData){ + + List sampleClinicalDataList = getSampleClinicalDataUseCase.execute(studyViewFilterContext, attributeIds); + List patientClinicalDataList = getPatientClinicalDataUseCase.execute(studyViewFilterContext, attributeIds); + + List samples = List.of(); + + if (!patientClinicalDataList.isEmpty()) { + // fetch samples for the given study view filter. + // we need this to construct the complete patient to sample map. + samples = getFilteredSamplesUseCase.execute(studyViewFilterContext); + } + + return combineClinicalDataForXyPlot(sampleClinicalDataList, patientClinicalDataList, samples, shouldFilterNonEmptyClinicalData); + + } + + private List combineClinicalDataForXyPlot( + List sampleClinicalDataList, + List patientClinicalDataList, + List samples, + boolean shouldFilterNonEmptyClinicalData + ) { + List combinedClinicalDataList; + + if (shouldFilterNonEmptyClinicalData) { + sampleClinicalDataList = filterNonEmptyClinicalData(sampleClinicalDataList); + patientClinicalDataList = filterNonEmptyClinicalData(patientClinicalDataList); + } + + if (patientClinicalDataList.isEmpty()) { + combinedClinicalDataList = sampleClinicalDataList; + } else { + combinedClinicalDataList = Stream.concat( + sampleClinicalDataList.stream(), + convertPatientClinicalDataToSampleClinicalData(patientClinicalDataList, samples).stream() + ).toList(); + } + + return combinedClinicalDataList; + } + + private List filterNonEmptyClinicalData(List clinicalData) { + return clinicalData + .stream() + .filter(data -> !data.getAttrValue().isEmpty()) + .toList(); + } + + private List convertPatientClinicalDataToSampleClinicalData( + List patientClinicalDataList, + List samplesWithoutNumericalFilter + ) { + List sampleClinicalDataList = new ArrayList<>(); + + Map>> patientToSamples = samplesWithoutNumericalFilter + .stream() + .collect(Collectors.groupingBy( + Sample::patientStableId, + Collectors.groupingBy(Sample::cancerStudyIdentifier) + )); + + // put all clinical data into sample form + for (ClinicalData d: patientClinicalDataList) { + List samplesForPatient = patientToSamples.get(d.getPatientId()).get(d.getStudyId()); + if (samplesForPatient != null) { + for (Sample s: samplesForPatient) { + ClinicalData newData = new ClinicalData(); + + newData.setInternalId(s.internalId()); + newData.setAttrId(d.getAttrId()); + newData.setPatientId(d.getPatientId()); + newData.setStudyId(d.getStudyId()); + newData.setAttrValue(d.getAttrValue()); + newData.setSampleId(s.stableId()); + + sampleClinicalDataList.add(newData); + } + } else { + // TODO ignoring for now rather than throwing an error + // patient has no samples - this shouldn't happen and could affect the integrity + // of the data analysis + // return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + return sampleClinicalDataList; + } +} diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java new file mode 100644 index 00000000000..40d7f61ab08 --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java @@ -0,0 +1,23 @@ +package org.cbioportal.clinical_data.usecase; + +import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetPatientClinicalDataUseCase { + private final ClinicalDataRepository clinicalDataRepository; + + public GetPatientClinicalDataUseCase(ClinicalDataRepository clinicalDataRepository) { + this.clinicalDataRepository = clinicalDataRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, List filteredAttributes){ + return clinicalDataRepository.getPatientClinicalData(studyViewFilterContext, filteredAttributes); + } +} diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java new file mode 100644 index 00000000000..0fdeed0b20b --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java @@ -0,0 +1,23 @@ +package org.cbioportal.clinical_data.usecase; + +import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetSampleClinicalDataUseCase { + private final ClinicalDataRepository clinicalDataRepository; + + public GetSampleClinicalDataUseCase(ClinicalDataRepository clinicalDataRepository) { + this.clinicalDataRepository = clinicalDataRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, List filteredAttributes){ + return clinicalDataRepository.getSampleClinicalData(studyViewFilterContext, filteredAttributes); + } +} diff --git a/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java b/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java new file mode 100644 index 00000000000..8d22b780fc1 --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java @@ -0,0 +1,10 @@ +package org.cbioportal.clinical_event.repository; + +import org.cbioportal.legacy.model.ClinicalEventTypeCount; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClinicalEventRepository { + List getClinicalEventTypeCounts(StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java b/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java new file mode 100644 index 00000000000..0420890eb6f --- /dev/null +++ b/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java @@ -0,0 +1,23 @@ +package org.cbioportal.clinical_event.usecase; + +import org.cbioportal.clinical_event.repository.ClinicalEventRepository; +import org.cbioportal.legacy.model.ClinicalEventTypeCount; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetClinicalEventTypeCountsUseCase { + private final ClinicalEventRepository clinicalEventRepository; + + public GetClinicalEventTypeCountsUseCase(ClinicalEventRepository clinicalEventRepository) { + this.clinicalEventRepository = clinicalEventRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext){ + return this.clinicalEventRepository.getClinicalEventTypeCounts(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java b/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java new file mode 100644 index 00000000000..e222b4352f1 --- /dev/null +++ b/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java @@ -0,0 +1,20 @@ +package org.cbioportal.generic_assay.repository; + +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.GenericAssayDataCountItem; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface GenericAssayRepository { + List getGenericAssayProfiles(); + List getFilteredMolecularProfilesByAlterationType(StudyViewFilterContext studyViewFilterContext, + String alterationType); + List getGenericAssayDataBinCounts(StudyViewFilterContext studyViewFilterContext, + List genericAssayDataBinFilters); + List getGenericAssayDataCounts(StudyViewFilterContext studyViewFilterContext, + List genericAssayDataFilters); +} diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java b/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java new file mode 100644 index 00000000000..0f5ed4b980e --- /dev/null +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java @@ -0,0 +1,14 @@ +package org.cbioportal.generic_assay.usecase; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +@Service +@Profile("clickhouse") +public record GenericAssayUseCases( + GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType, + GetGenericAssayDataBinCounts getGenericAssayDataBinCounts, + GetGenericAssayDataCountsUseCase getGenericAssayDataCountsUseCase, + GetGenericAssayProfilesUseCase getGenericAssayProfilesUseCase +) { +} diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java new file mode 100644 index 00000000000..873ccad186c --- /dev/null +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java @@ -0,0 +1,27 @@ +package org.cbioportal.generic_assay.usecase; + +import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetFilteredMolecularProfilesByAlterationType { + + private final GenericAssayRepository genericAssayRepository; + + public GetFilteredMolecularProfilesByAlterationType(GenericAssayRepository genericAssayRepository) { + this.genericAssayRepository = genericAssayRepository; + } + + + public List excute(StudyViewFilterContext studyViewFilterContext, + String alterationType) { + return genericAssayRepository.getFilteredMolecularProfilesByAlterationType(studyViewFilterContext, alterationType); + } + +} diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java new file mode 100644 index 00000000000..67f589093a5 --- /dev/null +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java @@ -0,0 +1,24 @@ +package org.cbioportal.generic_assay.usecase; + +import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetGenericAssayDataBinCounts { + private final GenericAssayRepository genericAssayRepository; + public GetGenericAssayDataBinCounts(GenericAssayRepository genericAssayRepository) { + this.genericAssayRepository = genericAssayRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, + List genericAssayDataBinFilters){ + return genericAssayRepository.getGenericAssayDataBinCounts(studyViewFilterContext, genericAssayDataBinFilters); + } +} diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java new file mode 100644 index 00000000000..faf6a12ebc6 --- /dev/null +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java @@ -0,0 +1,25 @@ +package org.cbioportal.generic_assay.usecase; + +import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.legacy.model.GenericAssayDataCountItem; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetGenericAssayDataCountsUseCase { + private final GenericAssayRepository genericAssayRepository; + + public GetGenericAssayDataCountsUseCase(GenericAssayRepository genericAssayRepository) { + this.genericAssayRepository = genericAssayRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, + List genericAssayDataFilters){ + return genericAssayRepository.getGenericAssayDataCounts(studyViewFilterContext, genericAssayDataFilters); + } +} diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java new file mode 100644 index 00000000000..cc8b59b687b --- /dev/null +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java @@ -0,0 +1,22 @@ +package org.cbioportal.generic_assay.usecase; + +import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.legacy.model.MolecularProfile; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetGenericAssayProfilesUseCase { + private final GenericAssayRepository repository; + + public GetGenericAssayProfilesUseCase(GenericAssayRepository repository) { + this.repository = repository; + } + + public List execute() { + return repository.getGenericAssayProfiles(); + } +} diff --git a/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java b/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java new file mode 100644 index 00000000000..e7aff66384f --- /dev/null +++ b/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java @@ -0,0 +1,24 @@ +package org.cbioportal.genomic_data.repository; + +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.GenomicDataCount; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; +import java.util.Map; + +public interface GenomicDataRepository { + List getMolecularProfileSampleCounts(StudyViewFilterContext studyViewFilterContext); + + List getGenomicDataBinCounts(StudyViewFilterContext studyViewFilterContext, + List genomicDataBinFilters); + + List getCNACounts(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); + Map getMutationCounts(StudyViewFilterContext studyViewFilterContext, GenomicDataFilter mutationFilters); + List getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, + List genomicDataFilters); + +} diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java b/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java new file mode 100644 index 00000000000..03653b6b811 --- /dev/null +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java @@ -0,0 +1,15 @@ +package org.cbioportal.genomic_data.usecase; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +@Service +@Profile("clickhouse") +public record GenomicDataUseCases( + GetCNACountsByGeneSpecificUseCase getCNACountsByGeneSpecificUseCase, + GetGenomicDataBinCountsUseCase getGenomicDataBinCountsUseCase, + GetMolecularProfileSampleCountsUseCase getMolecularProfileSampleCountsUseCase, + GetMutationCountsByTypeUseCase getMutationCountsByTypeUseCase, + GetMutationCountsUseCase getMutationCountsUseCase +) { +} diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java new file mode 100644 index 00000000000..6a49f96e521 --- /dev/null +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java @@ -0,0 +1,26 @@ +package org.cbioportal.genomic_data.usecase; + +import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetCNACountsByGeneSpecificUseCase { + + private final GenomicDataRepository repository; + + public GetCNACountsByGeneSpecificUseCase(GenomicDataRepository repository) { + this.repository = repository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, + List genomicDataFilters){ + return repository.getCNACounts(studyViewFilterContext, genomicDataFilters); + } +} diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java new file mode 100644 index 00000000000..a0433a17d5a --- /dev/null +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java @@ -0,0 +1,25 @@ +package org.cbioportal.genomic_data.usecase; + +import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetGenomicDataBinCountsUseCase { + private final GenomicDataRepository genomicDataRepository; + + public GetGenomicDataBinCountsUseCase(GenomicDataRepository genomicDataRepository) { + this.genomicDataRepository = genomicDataRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, + List genomicDataFilters){ + return genomicDataRepository.getGenomicDataBinCounts(studyViewFilterContext, genomicDataFilters); + } +} diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java new file mode 100644 index 00000000000..f413a68b390 --- /dev/null +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java @@ -0,0 +1,24 @@ +package org.cbioportal.genomic_data.usecase; + +import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.legacy.model.GenomicDataCount; +import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetMolecularProfileSampleCountsUseCase { + private final GenomicDataRepository genomicDataRepository; + + public GetMolecularProfileSampleCountsUseCase(GenomicDataRepository genomicDataRepository) { + this.genomicDataRepository = genomicDataRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext){ + return StudyViewColumnarServiceUtil.mergeGenomicDataCounts(genomicDataRepository.getMolecularProfileSampleCounts(studyViewFilterContext)); + } +} diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java new file mode 100644 index 00000000000..9f75e2bc1f6 --- /dev/null +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java @@ -0,0 +1,25 @@ +package org.cbioportal.genomic_data.usecase; + +import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetMutationCountsByTypeUseCase { + + private final GenomicDataRepository repository; + public GetMutationCountsByTypeUseCase(GenomicDataRepository repository) { + this.repository = repository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext, + List genomicDataFilters){ + return repository.getMutationCountsByType(studyViewFilterContext, genomicDataFilters); + } +} diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java new file mode 100644 index 00000000000..71d02a0491f --- /dev/null +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java @@ -0,0 +1,25 @@ +package org.cbioportal.genomic_data.usecase; + +import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +@Profile("clickhouse") +public class GetMutationCountsUseCase { + private final GenomicDataRepository repository; + + + public GetMutationCountsUseCase(GenomicDataRepository repository) { + this.repository = repository; + } + + public Map execute(StudyViewFilterContext studyViewFilterContext, + GenomicDataFilter genomicDataFilter){ + return repository.getMutationCounts(studyViewFilterContext, genomicDataFilter); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java new file mode 100644 index 00000000000..63745e1ed30 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java @@ -0,0 +1,25 @@ +package org.cbioportal.infrastructure.repository.clickhouse.alteration; + +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.CopyNumberCountByGene; +import org.cbioportal.legacy.model.GenePanelToGene; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.persistence.helper.AlterationFilterHelper; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClickhouseAlterationMapper { + List getMutatedGenes(StudyViewFilterContext studyViewFilterContext, AlterationFilterHelper alterationFilterHelper); + + List getCnaGenes(StudyViewFilterContext studyViewFilterContext, AlterationFilterHelper alterationFilterHelper); + + List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext, + AlterationFilterHelper alterationFilterHelper); + + int getTotalProfiledCountByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType); + List getMatchingGenePanelIds(StudyViewFilterContext studyViewFilterContext, String alterationType); + List getTotalProfiledCounts(StudyViewFilterContext studyViewFilterContext, String alterationType, List molecularProfiles); + int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType); + +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java new file mode 100644 index 00000000000..dbf3ecb9522 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java @@ -0,0 +1,103 @@ +package org.cbioportal.infrastructure.repository.clickhouse.alteration; + +import org.cbioportal.alteration.repository.AlterationRepository; +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.CopyNumberCountByGene; +import org.cbioportal.legacy.model.GenePanelToGene; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.persistence.helper.AlterationFilterHelper; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Repository +@Profile("clickhouse") +public class ClickhouseAlterationRepository implements AlterationRepository { + + private final ClickhouseAlterationMapper mapper; + + public ClickhouseAlterationRepository(ClickhouseAlterationMapper mapper) { + this.mapper = mapper; + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getMutatedGenes(StudyViewFilterContext studyViewFilterContext) { + return mapper.getMutatedGenes(studyViewFilterContext, + AlterationFilterHelper.build(studyViewFilterContext.alterationFilter())); + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext) { + return mapper.getStructuralVariantGenes(studyViewFilterContext, AlterationFilterHelper.build(studyViewFilterContext.alterationFilter())); + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getCnaGenes(StudyViewFilterContext studyViewFilterContext) { + return mapper.getCnaGenes(studyViewFilterContext, AlterationFilterHelper.build(studyViewFilterContext.alterationFilter())); + } + + /** + * @param studyViewFilterContext + * @param alterationType + * @return + */ + @Override + public int getTotalProfiledCountsByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType) { + return mapper.getTotalProfiledCountByAlterationType(studyViewFilterContext, alterationType); + } + + /** + * @param studyViewFilterContext + * @param alterationType + * @param molecularProfiles + * @return + */ + @Override + public Map getTotalProfiledCounts(StudyViewFilterContext studyViewFilterContext, String alterationType, List molecularProfiles) { + return mapper.getTotalProfiledCounts(studyViewFilterContext,alterationType,molecularProfiles) + .stream() + .collect(Collectors.groupingBy(AlterationCountByGene::getHugoGeneSymbol, + Collectors.mapping(AlterationCountByGene::getNumberOfProfiledCases, Collectors.summingInt(Integer::intValue)))); + } + + /** + * @param studyViewFilterContext + * @param alterationType + * @return + */ + @Override + public Map> getMatchingGenePanelIds(StudyViewFilterContext studyViewFilterContext, String alterationType) { + return mapper.getMatchingGenePanelIds(studyViewFilterContext, alterationType) + .stream() + .collect(Collectors.groupingBy(GenePanelToGene::getHugoGeneSymbol, + Collectors.mapping(GenePanelToGene::getGenePanelId, Collectors.toSet()))); + } + + /** + * @param studyViewFilterContext + * @param alterationType + * @return + */ + @Override + public int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType) { + return mapper.getSampleProfileCountWithoutPanelData(studyViewFilterContext, alterationType); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java index 68ae7968782..bd292da0782 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java @@ -1,7 +1,9 @@ package org.cbioportal.infrastructure.repository.clickhouse.cancerstudy; +import org.apache.ibatis.annotations.Param; import org.cbioportal.cancerstudy.CancerStudyMetadata; import org.cbioportal.shared.SortAndSearchCriteria; +import org.cbioportal.studyview.StudyViewFilterContext; import java.util.List; @@ -43,4 +45,6 @@ public interface ClickhouseCancerStudyMapper { * The list may be empty if no studies match the criteria. */ List getCancerStudiesMetadataSummary(SortAndSearchCriteria sortAndSearchCriteria, List studyIds); + + List getFilteredStudyIds(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); } diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java index a523ee1f5f4..795efa8aff1 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java @@ -3,6 +3,7 @@ import org.cbioportal.cancerstudy.CancerStudyMetadata; import org.cbioportal.cancerstudy.repository.CancerStudyRepository; import org.cbioportal.shared.SortAndSearchCriteria; +import org.cbioportal.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; @@ -50,4 +51,13 @@ public List getCancerStudiesMetadata(SortAndSearchCriteria public List getCancerStudiesMetadataSummary(SortAndSearchCriteria sortAndSearchCriteria) { return cancerStudyMapper.getCancerStudiesMetadataSummary(sortAndSearchCriteria, List.of()); } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getFilteredStudyIds(StudyViewFilterContext studyViewFilterContext) { + return cancerStudyMapper.getFilteredStudyIds(studyViewFilterContext); + } } diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java new file mode 100644 index 00000000000..38ba7be55bc --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java @@ -0,0 +1,10 @@ +package org.cbioportal.infrastructure.repository.clickhouse.clinical_attributes; + +import org.cbioportal.legacy.model.ClinicalAttribute; + +import java.util.List; + +public interface ClickhouseClinicalAttributesMapper { + List getClinicalAttributes(); + List getClinicalAttributesForStudies(List studyIds); +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java new file mode 100644 index 00000000000..9d0b187d87f --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java @@ -0,0 +1,64 @@ +package org.cbioportal.infrastructure.repository.clickhouse.clinical_attributes; + +import org.cbioportal.clinical_attributes.repository.ClinicalAttributesRepository; +import org.cbioportal.legacy.model.ClinicalAttribute; +import org.cbioportal.legacy.persistence.enums.DataSource; +import org.cbioportal.legacy.web.parameter.ClinicalDataType; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Repository +@Profile("clickhouse") +public class ClickhouseClinicalAttributesRepository implements ClinicalAttributesRepository { + + private Map> clinicalAttributesMap = new EnumMap<>(DataSource.class); + + private final ClickhouseClinicalAttributesMapper mapper; + + public ClickhouseClinicalAttributesRepository(ClickhouseClinicalAttributesMapper mapper) { + this.mapper = mapper; + } + + /** + * @param studyIds + * @return + */ + @Override + public List getClinicalAttributesForStudies(List studyIds) { + return mapper.getClinicalAttributesForStudies(studyIds); + } + + /** + * @return + */ + @Override + public Map getClinicalAttributeDatatypeMap() { + if (clinicalAttributesMap.isEmpty()) { + buildClinicalAttributeNameMap(); + } + + Map attributeDatatypeMap = new HashMap<>(); + + clinicalAttributesMap + .get(DataSource.SAMPLE) + .forEach(attribute -> attributeDatatypeMap.put(attribute.getAttrId(), ClinicalDataType.SAMPLE)); + + clinicalAttributesMap + .get(DataSource.PATIENT) + .forEach(attribute -> attributeDatatypeMap.put(attribute.getAttrId(), ClinicalDataType.PATIENT)); + + return attributeDatatypeMap; + } + + private void buildClinicalAttributeNameMap() { + clinicalAttributesMap = mapper.getClinicalAttributes() + .stream() + .collect(Collectors.groupingBy(ca -> ca.getPatientAttribute().booleanValue() ? DataSource.PATIENT : DataSource.SAMPLE)); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java new file mode 100644 index 00000000000..9f6fa913ae5 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java @@ -0,0 +1,13 @@ +package org.cbioportal.infrastructure.repository.clickhouse.clinical_data; + +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClickhouseClinicalDataMapper { + List getClinicalDataCounts(StudyViewFilterContext studyViewFilterContext, List attributeIds, List filteredAttributeValues); + List getSampleClinicalDataFromStudyViewFilter(StudyViewFilterContext studyViewFilterContext, List attributeIds); + List getPatientClinicalDataFromStudyViewFilter(StudyViewFilterContext studyViewFilterContext, List attributeIds); +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java new file mode 100644 index 00000000000..d512414b0f6 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java @@ -0,0 +1,55 @@ +package org.cbioportal.infrastructure.repository.clickhouse.clinical_data; + +import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.Collections; +import java.util.List; + +@Repository +@Profile("clickhouse") +public class ClickhouseClinicalDataRepository implements ClinicalDataRepository { + + private static final List FILTERED_CLINICAL_ATTR_VALUES = Collections.emptyList(); + + private final ClickhouseClinicalDataMapper mapper; + + public ClickhouseClinicalDataRepository(ClickhouseClinicalDataMapper mapper) { + this.mapper = mapper; + } + + + /** + * @param studyViewFilterContext + * @param filteredAttributes + * @return + */ + @Override + public List getPatientClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { + return mapper.getPatientClinicalDataFromStudyViewFilter(studyViewFilterContext, filteredAttributes); + } + + /** + * @param studyViewFilterContext + * @param filteredAttributes + * @return + */ + @Override + public List getSampleClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { + return mapper.getSampleClinicalDataFromStudyViewFilter(studyViewFilterContext, filteredAttributes); + } + + /** + * @param studyViewFilterContext + * @param filteredAttributes + * @return + */ + @Override + public List getClinicalDataCounts(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { + return mapper.getClinicalDataCounts(studyViewFilterContext, filteredAttributes, FILTERED_CLINICAL_ATTR_VALUES); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java new file mode 100644 index 00000000000..51954ee4a33 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java @@ -0,0 +1,11 @@ +package org.cbioportal.infrastructure.repository.clickhouse.clinical_event; + +import org.apache.ibatis.annotations.Param; +import org.cbioportal.legacy.model.ClinicalEventTypeCount; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClickhouseClinicalEventMapper { + List getClinicalEventTypeCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java new file mode 100644 index 00000000000..328412a2c47 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java @@ -0,0 +1,29 @@ +package org.cbioportal.infrastructure.repository.clickhouse.clinical_event; + +import org.cbioportal.clinical_event.repository.ClinicalEventRepository; +import org.cbioportal.legacy.model.ClinicalEventTypeCount; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@Profile("clickhouse") +public class ClickhouseClinicalEventRepository implements ClinicalEventRepository { + + private final ClickhouseClinicalEventMapper mapper; + + public ClickhouseClinicalEventRepository(ClickhouseClinicalEventMapper mapper) { + this.mapper = mapper; + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getClinicalEventTypeCounts(StudyViewFilterContext studyViewFilterContext) { + return mapper.getClinicalEventTypeCounts(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java new file mode 100644 index 00000000000..66d9f60c620 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java @@ -0,0 +1,20 @@ +package org.cbioportal.infrastructure.repository.clickhouse.generic_assay; + +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.GenericAssayDataCountItem; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClickhouseGenericAssayMapper { + List getGenericAssayProfiles(); + List getFilteredMolecularProfilesByAlterationType(StudyViewFilterContext studyViewFilterContext, + String alterationType); + List getGenericAssayDataBinCounts(StudyViewFilterContext studyViewFilterContext, + List genericAssayDataBinFilters); + List getGenericAssayDataCounts(StudyViewFilterContext studyViewFilterContext, + List genericAssayDataFilters); +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java new file mode 100644 index 00000000000..ff4041a5a74 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java @@ -0,0 +1,62 @@ +package org.cbioportal.infrastructure.repository.clickhouse.generic_assay; + +import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.GenericAssayDataCountItem; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@Profile("clickhouse") +public class ClickhouseGenericAssayRepository implements GenericAssayRepository { + + private final ClickhouseGenericAssayMapper mapper; + + public ClickhouseGenericAssayRepository(ClickhouseGenericAssayMapper mapper) { + this.mapper = mapper; + } + + /** + * @return + */ + @Override + public List getGenericAssayProfiles() { + return mapper.getGenericAssayProfiles(); + } + + /** + * @param studyViewFilterContext + * @param alterationType + * @return + */ + @Override + public List getFilteredMolecularProfilesByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType) { + return mapper.getFilteredMolecularProfilesByAlterationType(studyViewFilterContext, alterationType); + } + + /** + * @param studyViewFilterContext + * @param genericAssayDataBinFilters + * @return + */ + @Override + public List getGenericAssayDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataBinFilters) { + return mapper.getGenericAssayDataBinCounts(studyViewFilterContext, genericAssayDataBinFilters); + } + + /** + * @param studyViewFilterContext + * @param genericAssayDataFilters + * @return + */ + @Override + public List getGenericAssayDataCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataFilters) { + return mapper.getGenericAssayDataCounts(studyViewFilterContext, genericAssayDataFilters); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java new file mode 100644 index 00000000000..59053c5fa2e --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java @@ -0,0 +1,22 @@ +package org.cbioportal.infrastructure.repository.clickhouse.genomic_data; + +import org.apache.ibatis.annotations.Param; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.GenomicDataCount; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; +import java.util.Map; + +public interface ClickhouseGenomicDataMapper { + List getMolecularProfileSampleCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + List getGenomicDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genomicDataBinFilters); + List getCNACounts(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); + Map getMutationCounts(StudyViewFilterContext studyViewFilterContext, + GenomicDataFilter genomicDataFilter); + List getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); + +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java new file mode 100644 index 00000000000..7692a2fbc9a --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java @@ -0,0 +1,75 @@ +package org.cbioportal.infrastructure.repository.clickhouse.genomic_data; + +import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.GenomicDataCount; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Repository +@Profile("clickhouse") +public class ClickhouseGenomicDataRepository implements GenomicDataRepository { + + private final ClickhouseGenomicDataMapper mapper; + + public ClickhouseGenomicDataRepository(ClickhouseGenomicDataMapper mapper) { + this.mapper = mapper; + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getMolecularProfileSampleCounts(StudyViewFilterContext studyViewFilterContext) { + return mapper.getMolecularProfileSampleCounts(studyViewFilterContext); + } + + /** + * @param studyViewFilterContext + * @param genomicDataBinFilters + * @return + */ + @Override + public List getGenomicDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genomicDataBinFilters) { + return mapper.getGenomicDataBinCounts(studyViewFilterContext, genomicDataBinFilters); + } + + /** + * @param studyViewFilterContext + * @param genomicDataFilters + * @return + */ + @Override + public List getCNACounts(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters) { + return mapper.getCNACounts(studyViewFilterContext, genomicDataFilters); + } + + /** + * @param studyViewFilterContext + * @param genomicDataFilter + * @return + */ + @Override + public Map getMutationCounts(StudyViewFilterContext studyViewFilterContext, + GenomicDataFilter genomicDataFilter) { + return mapper.getMutationCounts(studyViewFilterContext, genomicDataFilter); + } + + /** + * @param studyViewFilterContext + * @param genomicDataFilters + * @return + */ + @Override + public List getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters) { + return mapper.getMutationCountsByType(studyViewFilterContext, genomicDataFilters); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java new file mode 100644 index 00000000000..7ee30077a94 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java @@ -0,0 +1,11 @@ +package org.cbioportal.infrastructure.repository.clickhouse.patient; + +import org.cbioportal.legacy.model.CaseListDataCount; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClickhousePatientMapper { + int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext); + List getCaseListDataCount(StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java new file mode 100644 index 00000000000..d0c33e2087b --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java @@ -0,0 +1,38 @@ +package org.cbioportal.infrastructure.repository.clickhouse.patient; + +import org.cbioportal.legacy.model.CaseListDataCount; +import org.cbioportal.patient.repository.PatientRepository; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@Profile("clickhouse") +public class ClickhousePatientRepository implements PatientRepository { + + private final ClickhousePatientMapper mapper; + + public ClickhousePatientRepository(ClickhousePatientMapper mapper) { + this.mapper = mapper; + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext) { + return mapper.getFilteredPatientCount(studyViewFilterContext); + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getCaseListDataCounts(StudyViewFilterContext studyViewFilterContext) { + return mapper.getCaseListDataCount(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java new file mode 100644 index 00000000000..3a34c1d7176 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java @@ -0,0 +1,12 @@ +package org.cbioportal.infrastructure.repository.clickhouse.sample; + +import org.apache.ibatis.annotations.Param; +import org.cbioportal.sample.Sample; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClickhouseSampleMapper { + List getFilteredSamples(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + int getSampleCount(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java new file mode 100644 index 00000000000..625d1a12c86 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java @@ -0,0 +1,38 @@ +package org.cbioportal.infrastructure.repository.clickhouse.sample; + +import org.cbioportal.sample.Sample; +import org.cbioportal.sample.repository.SampleRepository; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@Profile("clickhouse") +public class ClickhouseSampleRepository implements SampleRepository { + + private final ClickhouseSampleMapper mapper; + + public ClickhouseSampleRepository(ClickhouseSampleMapper clickhouseSampleMapper) { + this.mapper = clickhouseSampleMapper; + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getFilteredSamples(StudyViewFilterContext studyViewFilterContext) { + return mapper.getFilteredSamples(studyViewFilterContext); + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public int getFilteredSamplesCount(StudyViewFilterContext studyViewFilterContext) { + return mapper.getSampleCount(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/studyview/ClickhouseStudyViewFilterMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/studyview/ClickhouseStudyViewFilterMapper.java new file mode 100644 index 00000000000..cc3760b7f63 --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/studyview/ClickhouseStudyViewFilterMapper.java @@ -0,0 +1,4 @@ +package org.cbioportal.infrastructure.repository.clickhouse.studyview; + +public interface ClickhouseStudyViewFilterMapper { +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java new file mode 100644 index 00000000000..afdce64b1bb --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java @@ -0,0 +1,15 @@ +package org.cbioportal.infrastructure.repository.clickhouse.treatment; + +import org.apache.ibatis.annotations.Param; +import org.cbioportal.legacy.model.PatientTreatment; +import org.cbioportal.legacy.model.SampleTreatment; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface ClickhouseTreatmentMapper { + List getPatientTreatments(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + int getPatientTreatmentCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + List getSampleTreatmentCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + int getTotalSampleTreatmentCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java new file mode 100644 index 00000000000..a48fdc993ed --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java @@ -0,0 +1,56 @@ +package org.cbioportal.infrastructure.repository.clickhouse.treatment; + +import org.cbioportal.legacy.model.PatientTreatment; +import org.cbioportal.legacy.model.SampleTreatment; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.treatment.repository.TreatmentRepository; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@Profile("clickhouse") +public class ClickhouseTreatmentRepository implements TreatmentRepository { + private final ClickhouseTreatmentMapper mapper; + + public ClickhouseTreatmentRepository(ClickhouseTreatmentMapper mapper) { + this.mapper = mapper; + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getPatientTreatments(StudyViewFilterContext studyViewFilterContext) { + return mapper.getPatientTreatments(studyViewFilterContext); + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public int getTotalPatientTreatmentCount(StudyViewFilterContext studyViewFilterContext) { + return mapper.getPatientTreatmentCounts(studyViewFilterContext); + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public List getSampleTreatments(StudyViewFilterContext studyViewFilterContext) { + return mapper.getSampleTreatmentCounts(studyViewFilterContext); + } + + /** + * @param studyViewFilterContext + * @return + */ + @Override + public int getTotalSampleTreatmentCount(StudyViewFilterContext studyViewFilterContext) { + return mapper.getTotalSampleTreatmentCounts(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java b/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java index f46ff86da14..d5a371434f2 100644 --- a/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java +++ b/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java @@ -1,13 +1,25 @@ package org.cbioportal.legacy.web.parameter; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.persistence.enums.DataSource; +import org.springframework.lang.Nullable; + import java.util.List; +import java.util.Map; +// TODO Remove public final class CategorizedGenericAssayDataCountFilter { public static Builder getBuilder() { return new Builder(); } + public static Builder getBuilder(@Nullable Map> genericAssayProfilesMap, StudyViewFilter studyViewFilter) { + if (genericAssayProfilesMap == null) { + return new Builder(); + } + return new Builder(genericAssayProfilesMap, studyViewFilter); + } private final List sampleNumericalGenericAssayDataFilters; private final List sampleCategoricalGenericAssayDataFilters; private final List patientNumericalGenericAssayDataFilters; @@ -45,6 +57,38 @@ private Builder(){ } + private Builder(Map> genericAssayProfilesMap, StudyViewFilter studyViewFilter){ + + // No BINARY in the database yet + if (genericAssayProfilesMap.containsKey(DataSource.SAMPLE)) { + List sampleNumericalProfileTypes = genericAssayProfilesMap.get(DataSource.SAMPLE) + .stream().filter(profile -> profile.getDatatype().equals("LIMIT-VALUE")) + .map(profile -> profile.getStableId().replace(profile.getCancerStudyIdentifier() + "_", "")) + .toList(); + sampleNumericalGenericAssayDataFilters = studyViewFilter.getGenericAssayDataFilters().stream() + .filter(genericAssayDataFilter -> sampleNumericalProfileTypes.contains(genericAssayDataFilter.getProfileType())) + .toList(); + List sampleCategoricalProfileTypes = genericAssayProfilesMap.get(DataSource.SAMPLE) + .stream().filter(profile -> profile.getDatatype().equals("CATEGORICAL") || profile.getDatatype().equals("BINARY")) + .map(profile -> profile.getStableId().replace(profile.getCancerStudyIdentifier() + "_", "")) + .toList(); + sampleCategoricalGenericAssayDataFilters = studyViewFilter.getGenericAssayDataFilters().stream() + .filter(genericAssayDataFilter -> sampleCategoricalProfileTypes.contains(genericAssayDataFilter.getProfileType())) + .toList(); + } + + // patient level profile only have categorical for now + if (genericAssayProfilesMap.containsKey(DataSource.PATIENT)) { + List patientCategoricalProfileTypes = genericAssayProfilesMap.get(DataSource.PATIENT) + .stream().filter(profile -> profile.getDatatype().equals("CATEGORICAL") || profile.getDatatype().equals("BINARY")) + .map(profile -> profile.getStableId().replace(profile.getCancerStudyIdentifier() + "_", "")) + .toList(); + patientCategoricalGenericAssayDataFilters = studyViewFilter.getGenericAssayDataFilters().stream() + .filter(genericAssayDataFilter -> patientCategoricalProfileTypes.contains(genericAssayDataFilter.getProfileType())) + .toList(); + } + } + public Builder setSampleCategoricalGenericAssayDataFilters(List sampleCategoricalGenericAssayDataFilters) { this.sampleCategoricalGenericAssayDataFilters = sampleCategoricalGenericAssayDataFilters; return this; diff --git a/src/main/java/org/cbioportal/patient/repository/PatientRepository.java b/src/main/java/org/cbioportal/patient/repository/PatientRepository.java new file mode 100644 index 00000000000..8bd6b923de5 --- /dev/null +++ b/src/main/java/org/cbioportal/patient/repository/PatientRepository.java @@ -0,0 +1,11 @@ +package org.cbioportal.patient.repository; + +import org.cbioportal.legacy.model.CaseListDataCount; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface PatientRepository { + int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext); + List getCaseListDataCounts(StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java b/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java new file mode 100644 index 00000000000..53c4c3fcb3d --- /dev/null +++ b/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java @@ -0,0 +1,24 @@ +package org.cbioportal.patient.usecase; + +import org.cbioportal.legacy.model.CaseListDataCount; +import org.cbioportal.patient.repository.PatientRepository; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public class GetCaseListDataCountsUseCase { + + private final PatientRepository patientRepository; + + public GetCaseListDataCountsUseCase(PatientRepository patientRepository) { + this.patientRepository = patientRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext){ + return patientRepository.getCaseListDataCounts(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java b/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java new file mode 100644 index 00000000000..7fc6f85c5e5 --- /dev/null +++ b/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java @@ -0,0 +1,20 @@ +package org.cbioportal.patient.usecase; + +import org.cbioportal.patient.repository.PatientRepository; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +@Service +@Profile("clickhouse") +public class GetFilteredPatientCountUseCase { + private final PatientRepository patientRepository; + + public GetFilteredPatientCountUseCase(PatientRepository patientRepository) { + this.patientRepository = patientRepository; + } + + public int execute(StudyViewFilterContext studyViewFilterContext) { + return patientRepository.getFilteredPatientCount(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/sample/Sample.java b/src/main/java/org/cbioportal/sample/Sample.java new file mode 100644 index 00000000000..85f07c9eeec --- /dev/null +++ b/src/main/java/org/cbioportal/sample/Sample.java @@ -0,0 +1,27 @@ +package org.cbioportal.sample; + +import org.cbioportal.legacy.model.Patient; + +import java.util.Objects; + +public record Sample (Integer internalId, String stableId, SampleType sampleType, Integer patientId, + String patientStableId, Patient patient, + String cancerStudyIdentifier, Boolean sequenced, Boolean copyNumberSegmentPresent, + String uniqueSampleKey, String uniquePatientKey) { + + public Sample(Integer internalId, String stableId, String patientStableId, String cancerStudyIdentifier){ + this(internalId,stableId,null,null,patientStableId,null, cancerStudyIdentifier, null, null,null, null); + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Sample)) return false; + Sample sample = (Sample) o; + return stableId.equals(sample.stableId) && cancerStudyIdentifier.equals(sample.cancerStudyIdentifier); + } + + @Override + public int hashCode() { + return Objects.hash(stableId, cancerStudyIdentifier); + } +} diff --git a/src/main/java/org/cbioportal/sample/SampleType.java b/src/main/java/org/cbioportal/sample/SampleType.java new file mode 100644 index 00000000000..9216753db70 --- /dev/null +++ b/src/main/java/org/cbioportal/sample/SampleType.java @@ -0,0 +1,37 @@ +package org.cbioportal.sample; + +public enum SampleType { + PRIMARY_SOLID_TUMOR("Primary Solid Tumor"), + RECURRENT_SOLID_TUMOR("Recurrent Solid Tumor"), + PRIMARY_BLOOD_TUMOR("Primary Blood Tumor"), + RECURRENT_BLOOD_TUMOR("Recurrent Blood Tumor"), + METASTATIC("Metastatic"), + BLOOD_NORMAL("Blood Derived Normal"), + SOLID_NORMAL("Solid Tissues Normal"); + + private String value; + + SampleType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static SampleType fromString(String value) { + + if (value != null) { + for (SampleType sampleType : SampleType.values()) { + if (value.equalsIgnoreCase(sampleType.value)) { + return sampleType; + } + } + } + return null; + } + @Override + public String toString() { + return value; + } +} diff --git a/src/main/java/org/cbioportal/sample/repository/SampleRepository.java b/src/main/java/org/cbioportal/sample/repository/SampleRepository.java new file mode 100644 index 00000000000..0610b094904 --- /dev/null +++ b/src/main/java/org/cbioportal/sample/repository/SampleRepository.java @@ -0,0 +1,11 @@ +package org.cbioportal.sample.repository; + +import org.cbioportal.sample.Sample; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface SampleRepository { + List getFilteredSamples(StudyViewFilterContext studyViewFilterContext); + int getFilteredSamplesCount(StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java b/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java new file mode 100644 index 00000000000..5a0672c0e9f --- /dev/null +++ b/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java @@ -0,0 +1,21 @@ +package org.cbioportal.sample.usecase; + +import org.cbioportal.sample.repository.SampleRepository; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + + +@Service +@Profile("clickhouse") +public class GetFilteredSamplesCountUseCase { + private final SampleRepository sampleRepository; + + public GetFilteredSamplesCountUseCase(SampleRepository sampleRepository) { + this.sampleRepository = sampleRepository; + } + + public int execute(StudyViewFilterContext studyViewFilterContext) { + return sampleRepository.getFilteredSamplesCount(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesUseCase.java b/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesUseCase.java new file mode 100644 index 00000000000..f71a8ed9901 --- /dev/null +++ b/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesUseCase.java @@ -0,0 +1,24 @@ +package org.cbioportal.sample.usecase; + +import org.cbioportal.sample.Sample; +import org.cbioportal.sample.repository.SampleRepository; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@Profile("clickhouse") +public final class GetFilteredSamplesUseCase { + + private final SampleRepository sampleRepository; + + public GetFilteredSamplesUseCase(SampleRepository sampleRepository) { + this.sampleRepository = sampleRepository; + } + + public List execute(StudyViewFilterContext studyViewFilterContext) { + return this.sampleRepository.getFilteredSamples(studyViewFilterContext); + } +} diff --git a/src/main/java/org/cbioportal/shared/DataFilterUtil.java b/src/main/java/org/cbioportal/shared/DataFilterUtil.java new file mode 100644 index 00000000000..a0733f7e8c7 --- /dev/null +++ b/src/main/java/org/cbioportal/shared/DataFilterUtil.java @@ -0,0 +1,132 @@ +package org.cbioportal.shared; + +import org.cbioportal.legacy.web.parameter.DataFilter; +import org.cbioportal.legacy.web.parameter.DataFilterValue; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +public abstract class DataFilterUtil { + private DataFilterUtil(){} + + /** + * Merge the range of numerical bins in DataFilters to reduce the number of scans that runs on the database when filtering. + */ + public static List mergeDataFilters(List filters) { + // this should throw error or move to all binning endpoints in the future for input validation + if (!areValidFilters(filters)) { + return filters; + } + + boolean hasNumericalValue = false; + List mergedDataFilters = new ArrayList<>(); + + for (T filter : filters) { + List mergedValues = new ArrayList<>(); + List nonNumericalValues = new ArrayList<>(); + + // record the start and end of current merging range + BigDecimal mergedStart = null; + BigDecimal mergedEnd = null; + // for each value + for (DataFilterValue dataFilterValue : filter.getValues()) { + // if it is non-numerical, leave it as is + if (dataFilterValue.getValue() != null) { + nonNumericalValues.add(dataFilterValue); + continue; + } + // else it is numerical so start merging process + hasNumericalValue = true; + BigDecimal start = dataFilterValue.getStart(); + BigDecimal end = dataFilterValue.getEnd(); + + // if current merging range is null, we take current bin's range + if (mergedStart == null && mergedEnd == null) { + mergedStart = start; + mergedEnd = end; + } + // else we already has a merging range, we check if this one is consecutive of our range + else if (mergedEnd.equals(start)) { + // if true, we expand our range + mergedEnd = end; + } + else { + // otherwise it's a gap, so we save our current range first, and then use current bin to start the next range + mergedValues.add(new DataFilterValue(mergedStart, mergedEnd)); + mergedStart = start; + mergedEnd = end; + } + } + + // in the end we need to save the final range, but if everything is non-numerical then no need to + if (hasNumericalValue) { + mergedValues.add(new DataFilterValue(mergedStart, mergedEnd)); + } + mergedValues.addAll(nonNumericalValues); + filter.setValues(mergedValues); + mergedDataFilters.add(filter); + } + + return mergedDataFilters; + } + + public static boolean areValidFilters(List filters) { + if (filters == null || filters.isEmpty()) { + return false; + } + + for (T filter : filters) { + if (!isValidFilter(filter)) { + return false; + } + } + return true; + } + + private static boolean isValidFilter(T filter) { + if (filter == null || filter.getValues() == null || filter.getValues().isEmpty()) { + return false; + } + + BigDecimal start = null; + BigDecimal end = null; + for (DataFilterValue value : filter.getValues()) { + if (!validateDataFilterValue(value, start, end)) { + return false; + } + // update start and end values to check next bin range + if (value.getStart() != null) { + start = value.getStart(); + } + if (value.getEnd() != null) { + end = value.getEnd(); + } + } + return true; + } + + private static boolean validateDataFilterValue(DataFilterValue value, BigDecimal lastStart, BigDecimal lastEnd) { + // non-numerical value should not have numerical value + if (value.getValue() != null) { + return value.getStart() == null && value.getEnd() == null; + } + + // check if start < end + if (value.getStart() != null && value.getEnd() != null + && value.getStart().compareTo(value.getEnd()) >= 0) { + return false; + } + + // check if start stays increasing and no overlapping + if (value.getStart() != null + && ((lastStart != null && lastStart.compareTo(value.getStart()) >= 0) + || (lastEnd != null && value.getStart().compareTo(lastEnd) < 0))) { + return false; + } + + // check if end stays increasing + return value.getEnd() == null || lastEnd == null + || lastEnd.compareTo(value.getEnd()) < 0; + } +} diff --git a/src/main/java/org/cbioportal/shared/util/ClinicalDataCountItemUtil.java b/src/main/java/org/cbioportal/shared/util/ClinicalDataCountItemUtil.java new file mode 100644 index 00000000000..a502a98b50d --- /dev/null +++ b/src/main/java/org/cbioportal/shared/util/ClinicalDataCountItemUtil.java @@ -0,0 +1,22 @@ +package org.cbioportal.shared.util; + +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; + +import java.util.List; +import java.util.stream.Collectors; + +public abstract class ClinicalDataCountItemUtil { + private ClinicalDataCountItemUtil() {} + + public static List generateDataCountItems(List dataCounts){ + return dataCounts.stream().collect(Collectors.groupingBy(ClinicalDataCount::getAttributeId)) + .entrySet().parallelStream().map(e -> { + ClinicalDataCountItem item = new ClinicalDataCountItem(); + item.setAttributeId(e.getKey()); + item.setCounts(StudyViewColumnarServiceUtil.normalizeDataCounts(e.getValue())); + return item; + }).toList(); + } +} diff --git a/src/main/java/org/cbioportal/studyview/StudyViewFilterContext.java b/src/main/java/org/cbioportal/studyview/StudyViewFilterContext.java new file mode 100644 index 00000000000..3d60ab566cf --- /dev/null +++ b/src/main/java/org/cbioportal/studyview/StudyViewFilterContext.java @@ -0,0 +1,58 @@ +package org.cbioportal.studyview; + +import org.cbioportal.legacy.model.AlterationFilter; +import org.cbioportal.legacy.model.GeneFilter; +import org.cbioportal.legacy.model.StudyViewStructuralVariantFilter; +import org.cbioportal.legacy.web.parameter.CategorizedGenericAssayDataCountFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; +import org.cbioportal.legacy.web.parameter.CustomSampleIdentifier; +import org.cbioportal.legacy.web.parameter.DataFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.legacy.web.parameter.MutationDataFilter; +import org.cbioportal.legacy.web.parameter.SampleIdentifier; +import org.cbioportal.legacy.web.parameter.filter.AndedSampleTreatmentFilters; +import org.cbioportal.legacy.web.parameter.filter.AndedPatientTreatmentFilters; + +import java.util.List; + +public record StudyViewFilterContext( + List sampleIdentifiers, + List studyIds, + List clinicalDataFilters, + List geneFilters, + List structuralVariantFilters, + AndedSampleTreatmentFilters sampleTreatmentFilters, + AndedSampleTreatmentFilters sampleTreatmentGroupFilters, + AndedSampleTreatmentFilters sampleTreatmentTargetFilters, + AndedPatientTreatmentFilters patientTreatmentFilters, + AndedPatientTreatmentFilters patientTreatmentGroupFilters, + AndedPatientTreatmentFilters patientTreatmentTargetFilters, + List> genomicProfiles, + List genomicDataFilters, + List genericAssayDataFilters, + List> caseLists, + List customDataFilters, + AlterationFilter alterationFilter, + List clinicalEventFilters, + List mutationDataFilters, + List customSampleIdentifiers, + List customDataFilterCancerStudies, + CategorizedGenericAssayDataCountFilter categorizedGenericAssayDataCountFilter +) { + + public String[] filteredSampleIdentifiers() { + if (sampleIdentifiers != null) { + return sampleIdentifiers.stream() + .map(sampleIdentifier -> sampleIdentifier.getStudyId() + "_" + sampleIdentifier.getSampleId()) + .toArray(String[]::new); + } else { + return new String[0]; + } + } + + public boolean isCategoricalClinicalDataFilter(ClinicalDataFilter clinicalDataFilter) { + var filterValue = clinicalDataFilter.getValues().getFirst(); + return filterValue.getValue() != null; + } +} diff --git a/src/main/java/org/cbioportal/studyview/StudyViewFilterFactory.java b/src/main/java/org/cbioportal/studyview/StudyViewFilterFactory.java new file mode 100644 index 00000000000..8d18087cb7d --- /dev/null +++ b/src/main/java/org/cbioportal/studyview/StudyViewFilterFactory.java @@ -0,0 +1,56 @@ +package org.cbioportal.studyview; + +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.persistence.enums.DataSource; +import org.cbioportal.legacy.web.columnar.util.CustomDataFilterUtil; +import org.cbioportal.legacy.web.parameter.CategorizedGenericAssayDataCountFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; +import org.cbioportal.legacy.web.parameter.CustomSampleIdentifier; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.cbioportal.shared.DataFilterUtil; + +import java.util.List; +import java.util.Map; + +public abstract class StudyViewFilterFactory { + private StudyViewFilterFactory() {} + + public static StudyViewFilterContext make(StudyViewFilter base, + CustomDataFilterUtil customDataFilterUtil, + Map> genericAssayProfilesMap) { + List customSampleIdentifiers = customDataFilterUtil.extractCustomDataSamples(base); + List involvedCancerStudies = customDataFilterUtil.extractInvolvedCancerStudies(base); + CategorizedGenericAssayDataCountFilter categorizedGenericAssayDataCountFilter = + CategorizedGenericAssayDataCountFilter.getBuilder(genericAssayProfilesMap, base).build(); + + + // Merge data filters + if (base.getGenomicDataFilters() != null && !base.getGenomicDataFilters().isEmpty()) { + List mergedGenomicDataFilters = + DataFilterUtil.mergeDataFilters(base.getGenomicDataFilters()); + base.setGenomicDataFilters(mergedGenomicDataFilters); + } + if (base.getClinicalDataFilters() != null && !base.getClinicalDataFilters().isEmpty()) { + List mergedClinicalDataFilters = + DataFilterUtil.mergeDataFilters(base.getClinicalDataFilters()); + base.setClinicalDataFilters(mergedClinicalDataFilters); + } + if (base.getGenericAssayDataFilters() != null && !base.getGenericAssayDataFilters().isEmpty()) { + List mergedGenericAssayDataFilters = + DataFilterUtil.mergeDataFilters(base.getGenericAssayDataFilters()); + base.setGenericAssayDataFilters(mergedGenericAssayDataFilters); + } + + return new StudyViewFilterContext(base.getSampleIdentifiers(), base.getStudyIds(), + base.getClinicalDataFilters(), base.getGeneFilters(), base.getStructuralVariantFilters(), + base.getSampleTreatmentFilters(), base.getSampleTreatmentGroupFilters(), + base.getSampleTreatmentTargetFilters(), base.getPatientTreatmentFilters(), + base.getPatientTreatmentGroupFilters(), base.getPatientTreatmentTargetFilters(), + base.getGenomicProfiles(), base.getGenomicDataFilters(), base.getGenericAssayDataFilters(), + base.getCaseLists(), base.getCustomDataFilters(), base.getAlterationFilter(), + base.getClinicalEventFilters(), base.getMutationDataFilters(),customSampleIdentifiers, + involvedCancerStudies, categorizedGenericAssayDataCountFilter); + } +} diff --git a/src/main/java/org/cbioportal/studyview/StudyViewService.java b/src/main/java/org/cbioportal/studyview/StudyViewService.java new file mode 100644 index 00000000000..66800dbd5d2 --- /dev/null +++ b/src/main/java/org/cbioportal/studyview/StudyViewService.java @@ -0,0 +1,205 @@ +package org.cbioportal.studyview; + +import org.cbioportal.alteration.usecase.AlterationCountByGeneUseCase; +import org.cbioportal.clinical_attributes.usecase.GetClinicalAttributesDataTypeMapUseCase; +import org.cbioportal.clinical_attributes.usecase.GetClinicalAttributesForStudiesUseCase; +import org.cbioportal.clinical_data.usecase.ClinicalDataUseCases; +import org.cbioportal.clinical_event.usecase.GetClinicalEventTypeCountsUseCase; +import org.cbioportal.generic_assay.usecase.GenericAssayUseCases; +import org.cbioportal.genomic_data.usecase.GenomicDataUseCases; +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.CaseListDataCount; +import org.cbioportal.legacy.model.ClinicalAttribute; +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.legacy.model.ClinicalEventTypeCount; +import org.cbioportal.legacy.model.CopyNumberCountByGene; +import org.cbioportal.legacy.model.GenericAssayDataCountItem; +import org.cbioportal.legacy.model.GenomicDataCount; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.model.MolecularProfile; +import org.cbioportal.legacy.model.PatientTreatmentReport; +import org.cbioportal.legacy.model.SampleTreatmentReport; +import org.cbioportal.legacy.persistence.enums.DataSource; +import org.cbioportal.legacy.service.exception.StudyNotFoundException; +import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; +import org.cbioportal.legacy.web.columnar.util.CustomDataFilterUtil; +import org.cbioportal.legacy.web.parameter.ClinicalDataType; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.cbioportal.patient.usecase.GetCaseListDataCountsUseCase; +import org.cbioportal.sample.Sample; +import org.cbioportal.sample.usecase.GetFilteredSamplesUseCase; +import org.cbioportal.shared.util.ClinicalDataCountItemUtil; +import org.cbioportal.treatment.usecase.FilteredTreatmentCountReportUseCase; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class StudyViewService { + + private final GetFilteredSamplesUseCase getFilteredSamplesUseCase; + private final AlterationCountByGeneUseCase alterationCountByGeneUseCase; + private final GetClinicalEventTypeCountsUseCase getClinicalEventTypeCountsUseCase; + private final FilteredTreatmentCountReportUseCase filteredTreatmentCountReportUseCase; + private final GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase; + private final GetCaseListDataCountsUseCase getCaseListDataCountsUseCase; + private final GetClinicalAttributesDataTypeMapUseCase getClinicalAttributesDataTypeMapUseCase; + private final ClinicalDataUseCases clinicalDataUseCases; + private final GenomicDataUseCases genomicDataUseCases; + private final GenericAssayUseCases genericAssayUseCases; + private final CustomDataFilterUtil customDataFilterUtil; + + private Map> genericAssayProfilesMap = new EnumMap<>(DataSource.class); + + + public StudyViewService(GetFilteredSamplesUseCase getFilteredSamplesUseCase, + AlterationCountByGeneUseCase alterationCountByGeneUseCase, + GetClinicalEventTypeCountsUseCase getClinicalEventTypeCountsUseCase, + FilteredTreatmentCountReportUseCase filteredTreatmentCountReportUseCase, + GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase, + GetCaseListDataCountsUseCase getCaseListDataCountsUseCase, + GetClinicalAttributesDataTypeMapUseCase getClinicalAttributesDataTypeMapUseCase, + ClinicalDataUseCases clinicalDataUseCases, + GenomicDataUseCases genomicDataUseCases, GenericAssayUseCases genericAssayUseCases, + CustomDataFilterUtil customDataFilterUtil) { + this.getFilteredSamplesUseCase = getFilteredSamplesUseCase; + this.alterationCountByGeneUseCase = alterationCountByGeneUseCase; + this.clinicalDataUseCases = clinicalDataUseCases; + this.genomicDataUseCases = genomicDataUseCases; + this.getClinicalEventTypeCountsUseCase = getClinicalEventTypeCountsUseCase; + this.filteredTreatmentCountReportUseCase = filteredTreatmentCountReportUseCase; + this.getClinicalAttributesForStudiesUseCase = getClinicalAttributesForStudiesUseCase; + this.getCaseListDataCountsUseCase = getCaseListDataCountsUseCase; + this.getClinicalAttributesDataTypeMapUseCase = getClinicalAttributesDataTypeMapUseCase; + this.genericAssayUseCases = genericAssayUseCases; + this.customDataFilterUtil = customDataFilterUtil; + } + + + public List getFilteredSamples(StudyViewFilter studyViewFilter){ + return getFilteredSamplesUseCase.execute(buildStudyViewFilterContext(studyViewFilter)); + } + + public List getMutatedGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { + return alterationCountByGeneUseCase.getMutatedGenes(buildStudyViewFilterContext(studyViewFilter)); + } + + public List getCnaGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { + return alterationCountByGeneUseCase.getCnaGenes(buildStudyViewFilterContext(studyViewFilter)); + } + + public List getStructuralVariantGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { + return alterationCountByGeneUseCase.getStructuralVariantGenes(buildStudyViewFilterContext(studyViewFilter)); + } + + public List getMolecularProfileSampleCounts(StudyViewFilter studyViewFilter) throws StudyNotFoundException { + return genomicDataUseCases.getMolecularProfileSampleCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter)); + } + + public List getClinicalEventTypeCounts(StudyViewFilter studyViewFilter) { + return getClinicalEventTypeCountsUseCase.execute(buildStudyViewFilterContext(studyViewFilter)); + } + + public PatientTreatmentReport getPatientTreatmentReport(StudyViewFilter studyViewFilter) { + return filteredTreatmentCountReportUseCase.getFilteredPatientTreatmentReport(buildStudyViewFilterContext(studyViewFilter)); + } + + public SampleTreatmentReport getSampleTreatmentReport(StudyViewFilter studyViewFilter) { + return filteredTreatmentCountReportUseCase.getFilteredSampleTreatmentReport(buildStudyViewFilterContext(studyViewFilter)); + } + + public List getGenomicDataBinCounts(StudyViewFilter studyViewFilter, + List genomicDataBinFilters) { + return ClinicalDataCountItemUtil.generateDataCountItems(genomicDataUseCases.getGenomicDataBinCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genomicDataBinFilters)); + } + + public List getGenericAssayDataBinCounts(StudyViewFilter studyViewFilter, + List genericAssayDataBinFilters) { + return ClinicalDataCountItemUtil.generateDataCountItems(genericAssayUseCases.getGenericAssayDataBinCounts().execute(buildStudyViewFilterContext(studyViewFilter), genericAssayDataBinFilters)); + } + + public Map getClinicalAttributeDataTypeMap(StudyViewFilter studyViewFilter) { + return getClinicalAttributesDataTypeMapUseCase.execute(); + } + + public List getClinicalDataCounts(StudyViewFilter studyViewFilter, + List filteredAttributes){ + return clinicalDataUseCases.getClinicalDataCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter) + , filteredAttributes); + } + + public List getClinicalAttributesForStudies(List studyIds){ + return getClinicalAttributesForStudiesUseCase.execute(studyIds); + } + + public List getCaseListDataCounts(StudyViewFilter studyViewFilter){ + return StudyViewColumnarServiceUtil.mergeCaseListCounts(getCaseListDataCountsUseCase.execute(buildStudyViewFilterContext(studyViewFilter))); + } + + public List getPatientClinicalData(StudyViewFilter studyViewFilter, List attributeIds){ + return clinicalDataUseCases.getPatientClinicalDataUseCase().execute(buildStudyViewFilterContext(studyViewFilter), attributeIds); + } + + public List getSampleClinicalData(StudyViewFilter studyViewFilter,List attributeIds){ + return clinicalDataUseCases.getSampleClinicalDataUseCase().execute(buildStudyViewFilterContext(studyViewFilter), attributeIds); + } + + public List getCNACountsByGeneSpecific(StudyViewFilter studyViewFilter, + List genomicDataFilters){ + return genomicDataUseCases.getCNACountsByGeneSpecificUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genomicDataFilters); + } + + public List getGenericAssayDataCounts(StudyViewFilter studyViewFilter, + List genericAssayDataFilters){ + return genericAssayUseCases.getGenericAssayDataCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genericAssayDataFilters); + } + + public List getMutationCountsByGeneSpecific(StudyViewFilter studyViewFilter, + List genomicDataFilters){ + List genomicDataCountItemList = new ArrayList<>(); + for (GenomicDataFilter genomicDataFilter : genomicDataFilters) { + Map counts = + genomicDataUseCases.getMutationCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genomicDataFilter); + genomicDataCountItemList.add(StudyViewColumnarServiceUtil.createGenomicDataCountItemFromMutationCounts(genomicDataFilter, counts)); + } + return genomicDataCountItemList; + } + + public List getMutationTypeCountsByGeneSpecific(StudyViewFilter studyViewFilter, + List genomicDataFilters){ + return genomicDataUseCases.getMutationCountsByTypeUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genomicDataFilters); + } + + public List getClinicalDataForXyPlot(StudyViewFilter studyViewFilter, List attributeIds, + boolean shouldFilterNonEmptyClinicalData){ + return clinicalDataUseCases.getClinicalDataForXyPlotUseCase().execute(buildStudyViewFilterContext(studyViewFilter),attributeIds, + shouldFilterNonEmptyClinicalData); + } + + private StudyViewFilterContext buildStudyViewFilterContext(StudyViewFilter studyViewFilter){ + return StudyViewFilterFactory.make(studyViewFilter,this.customDataFilterUtil, genericAssayProfilesMap); + } + + private Map> getGenericAssayProfilesMap() { + if (genericAssayProfilesMap.isEmpty()) { + buildGenericAssayProfilesMap(); + } + return genericAssayProfilesMap; + } + + private void buildGenericAssayProfilesMap() { + genericAssayProfilesMap = genericAssayUseCases.getGenericAssayProfilesUseCase().execute() + .stream() + .collect(Collectors.groupingBy(ca -> ca.getPatientLevel() ? DataSource.PATIENT : DataSource.SAMPLE)); + } + +} diff --git a/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java b/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java new file mode 100644 index 00000000000..8a2403ca49a --- /dev/null +++ b/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java @@ -0,0 +1,14 @@ +package org.cbioportal.treatment.repository; + +import org.cbioportal.legacy.model.PatientTreatment; +import org.cbioportal.legacy.model.SampleTreatment; +import org.cbioportal.studyview.StudyViewFilterContext; + +import java.util.List; + +public interface TreatmentRepository { + List getPatientTreatments(StudyViewFilterContext studyViewFilterContext); + int getTotalPatientTreatmentCount(StudyViewFilterContext studyViewFilterContext); + List getSampleTreatments(StudyViewFilterContext studyViewFilterContext); + int getTotalSampleTreatmentCount(StudyViewFilterContext studyViewFilterContext); +} diff --git a/src/main/java/org/cbioportal/treatment/usecase/FilteredTreatmentCountReportUseCase.java b/src/main/java/org/cbioportal/treatment/usecase/FilteredTreatmentCountReportUseCase.java new file mode 100644 index 00000000000..241743ba883 --- /dev/null +++ b/src/main/java/org/cbioportal/treatment/usecase/FilteredTreatmentCountReportUseCase.java @@ -0,0 +1,43 @@ +package org.cbioportal.treatment.usecase; + +import org.cbioportal.legacy.model.PatientTreatmentReport; +import org.cbioportal.legacy.model.SampleTreatmentReport; +import org.cbioportal.legacy.model.SampleTreatmentRow; +import org.cbioportal.legacy.model.TemporalRelation; +import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.treatment.repository.TreatmentRepository; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.Set; +import java.util.stream.Stream; + +@Service +@Profile("clickhouse") +public class FilteredTreatmentCountReportUseCase { + + private final TreatmentRepository treatmentRepository; + + public FilteredTreatmentCountReportUseCase(TreatmentRepository treatmentRepository) { + this.treatmentRepository = treatmentRepository; + } + + public PatientTreatmentReport getFilteredPatientTreatmentReport(StudyViewFilterContext studyViewFilterContext){ + var patientTreatments = treatmentRepository.getPatientTreatments(studyViewFilterContext); + var totalPatientTreatmentCount = treatmentRepository.getTotalPatientTreatmentCount(studyViewFilterContext); + return new PatientTreatmentReport(totalPatientTreatmentCount, 0, patientTreatments); + } + + public SampleTreatmentReport getFilteredSampleTreatmentReport(StudyViewFilterContext studyViewFilterContext){ + var sampleTreatments = treatmentRepository.getSampleTreatments(studyViewFilterContext) + .stream() + .flatMap(sampleTreatment -> + Stream.of(new SampleTreatmentRow(TemporalRelation.Pre, sampleTreatment.treatment(), sampleTreatment.preSampleCount(), Set.of()), + new SampleTreatmentRow(TemporalRelation.Post, sampleTreatment.treatment(), sampleTreatment.postSampleCount(), Set.of() )) + ) + .filter(sampleTreatment -> sampleTreatment.getCount() > 0 ) + .toList(); + var totalSampleTreatmentCount = treatmentRepository.getTotalSampleTreatmentCount(studyViewFilterContext); + return new SampleTreatmentReport(totalSampleTreatmentCount, sampleTreatments); + } +} diff --git a/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationFilterMapper.xml b/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationFilterMapper.xml new file mode 100644 index 00000000000..b320f223b17 --- /dev/null +++ b/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationFilterMapper.xml @@ -0,0 +1,120 @@ + + + + + + + NULL + + AND + lower(genomic_event_derived.mutation_type) + + + NOT IN + + + IN + + + + lower(#{type}) + + + + + + + + + + NULL + + AND + genomic_event_derived.cna_alteration IN + + #{type} + + + + + + + + + + + + OR + lower(genomic_event_derived.mutation_status) LIKE '%germline%' + + + OR + lower(genomic_event_derived.mutation_status) = 'somatic' + + + OR + lower(genomic_event_derived.mutation_status) != 'somatic' AND lower(genomic_event_derived.mutation_status) NOT LIKE '%germline%' + + + + + AND NULL + + + + + + + + + + + + + OR lower(driver_filter) = 'putative_driver' + + + OR lower(driver_filter) = 'putative_passenger' + + + OR driver_filter IS NULL + OR lower(driver_filter) IN ('unknown', 'na', '') + + + + + AND NULL + + + + + + + + + + + + + + OR driver_tiers_filter IN + + #{item} + + + + OR driver_tiers_filter IS NULL + OR lower(driver_tiers_filter) IN ('', 'na', 'unknown') + + + + + AND NULL + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml b/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml new file mode 100644 index 00000000000..6637790a6fa --- /dev/null +++ b/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml b/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml index fbdc8b4c720..e322525c28e 100644 --- a/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml +++ b/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml @@ -196,4 +196,13 @@ + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.xml b/src/main/resources/mappers/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.xml new file mode 100644 index 00000000000..7d1df775ed5 --- /dev/null +++ b/src/main/resources/mappers/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/clinical_data/ClickhouseClinicalDataMapper.xml b/src/main/resources/mappers/clickhouse/clinical_data/ClickhouseClinicalDataMapper.xml new file mode 100644 index 00000000000..d4aa6b46be7 --- /dev/null +++ b/src/main/resources/mappers/clickhouse/clinical_data/ClickhouseClinicalDataMapper.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + ( + WITH clinical_data_query AS ( + SELECT + attribute_name AS attributeId, + attribute_value AS value, + cast(count(*) AS INTEGER) as count + FROM clinical_data_derived + + type='${type}' + AND + + + + != 'NA' + AND + + + + + + + + + AND attribute_name IN + + #{attributeId} + + + GROUP BY attribute_name, value ), + clinical_data_sum AS (SELECT attributeId, sum(count) AS sum FROM clinical_data_query GROUP BY attributeId) + + SELECT * FROM clinical_data_query + UNION ALL + SELECT attributeId, + 'NA' AS value, + (( + + + + + + + + + ) - clinical_data_sum.sum) AS count + FROM clinical_data_sum + + count > 0 + + ) + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml b/src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml new file mode 100644 index 00000000000..c1dc9be8fc5 --- /dev/null +++ b/src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml b/src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml new file mode 100644 index 00000000000..322c963d9d0 --- /dev/null +++ b/src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/genomic_data/ClickhouseGenomicDataMapper.xml b/src/main/resources/mappers/clickhouse/genomic_data/ClickhouseGenomicDataMapper.xml new file mode 100644 index 00000000000..9b257688c23 --- /dev/null +++ b/src/main/resources/mappers/clickhouse/genomic_data/ClickhouseGenomicDataMapper.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml b/src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml new file mode 100644 index 00000000000..500995b9e9f --- /dev/null +++ b/src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml @@ -0,0 +1,30 @@ + + + + + + + SELECT count(distinct patient_unique_id) as count + FROM sample_derived + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml b/src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml new file mode 100644 index 00000000000..b0ee0ba1fcb --- /dev/null +++ b/src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + SELECT count(distinct sample_unique_id) as count + FROM sample_derived + + + + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/studyview/ClickhouseStudyViewFilterMapper.xml b/src/main/resources/mappers/clickhouse/studyview/ClickhouseStudyViewFilterMapper.xml new file mode 100644 index 00000000000..9028134e052 --- /dev/null +++ b/src/main/resources/mappers/clickhouse/studyview/ClickhouseStudyViewFilterMapper.xml @@ -0,0 +1,806 @@ + + + + + + + + INTERSECT + SELECT sample_unique_id + FROM sample_derived + WHERE cancer_study_identifier IN + + #{studyId} + + + + + INTERSECT + -- case list filtering allows both UNION (OR) and INTERSECTION (AND) LOGIC + -- caseLists is an array of arrays wherein the top level is INTERSECTION + -- AND THE INTERNAL ARRAYS ARE UNION (OR) + SELECT * FROM ( + + SELECT sample_unique_id + FROM sample_list_list sll + LEFT JOIN sample_derived s ON sll.sample_id=s.internal_id + LEFT JOIN sample_list sl on sll.list_id=sl.list_id + WHERE + + sl.stable_id LIKE concat('%_', #{list}) + + + ) + + + + INTERSECT + SELECT * FROM ( + + SELECT sample_derived.sample_unique_id + FROM sample_profile GYMP + JOIN genetic_profile gp ON sample_profile.genetic_profile_id = gp.genetic_profile_id + JOIN cancer_study cs ON gp.cancer_study_id = cs.cancer_study_id + JOIN sample_derived on sample_profile.sample_id = sample_derived.internal_id + + + sample_derived.cancer_study_identifier IN + + #{studyId} + + AND + + + gp.stable_id=concat(#{studyId}, '_', #{genomicProfileId}) + + + + + + ) + + + + + INTERSECT + SELECT sample_unique_id + FROM sample_derived + WHERE sample_unique_id IN + ( + #{filteredSampleIdentifiers, typeHandler=org.apache.ibatis.type.ArrayTypeHandler} + ) + + + INTERSECT + SELECT sample_unique_id + FROM sample_derived + WHERE + + + + AND + ( + + + + sample_unique_id IN ( + '', + + + #{sampleIdentifier.uniqueSampleId} + + + ) + + + + + OR + sample_unique_id NOT IN ( + '', + + + #{sampleIdentifier.uniqueSampleId} + + + ) + + + ) + + + + + + + SELECT sample_unique_id + FROM genomic_event_derived + + genetic_profile_stable_id IN + + #{molecularProfileId} + + + + hugo_gene_symbol = #{geneFilterQuery.hugoGeneSymbol} + + + cna_alteration = #{alteration.code} + + + + + + + + + + + + + + + + + + + + ( + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT concat(ced.cancer_study_identifier, '_', ced.sample_id) AS sample_unique_id + FROM ( + + SELECT + ced.value AS sample_id, + ced.patient_unique_id AS patient_unique_id, + min(ced.start_date) AS time_taken, + ced.cancer_study_identifier AS cancer_study_identifier + FROM clinical_event_derived ced + + key = 'SAMPLE_ID' + AND (event_type ILIKE 'Sample Acquisition' OR event_type ILIKE 'SPECIMEN') + + GROUP BY patient_unique_id, ced.value, cancer_study_identifier + ) ced + INNER JOIN ( + + SELECT + patient_unique_id, + value AS treatment, + argMin(start_date, start_date) AS treatment_time_taken + FROM clinical_event_derived + WHERE lower(event_type) = 'treatment' + AND key = 'AGENT' + GROUP BY patient_unique_id, value + ) ced_inner ON ced_inner.patient_unique_id = ced.patient_unique_id + + + ced_inner.treatment = #{sampleTreatmentFilter.treatment} + + + AND ced.time_taken <= ced_inner.treatment_time_taken + + + AND ced.time_taken > ced_inner.treatment_time_taken + + + + + GROUP BY patient_unique_id, ced.sample_id, ced.time_taken, ced.cancer_study_identifier, ced_inner.treatment, ced_inner.treatment_time_taken + + + + + + SELECT sample_unique_id + FROM sample_derived + WHERE patient_unique_id in ( + SELECT patient_unique_id + FROM clinical_event_derived + + + event_type = #{dataFilterValue.value} + + + ) + + + + + + SELECT sample_unique_id + FROM sample_derived + WHERE patient_unique_id in ( + SELECT patient_unique_id + FROM clinical_event_derived + + lower(event_type) = 'treatment' + AND key = 'AGENT' + AND value = #{patientTreatmentFilter.treatment} + + + ) + + + + + + + + + AND + + + + + + + AND + ${attribute_value} ILIKE #{dataFilterValue.value} + + + + AND match(${attribute_value}, '^>?=?[-+]?[0-9]*[.,]?[0-9]+$') + + + AND match(${attribute_value}, '^<?=?[-+]?[0-9]*[.,]?[0-9]+$') + + + AND match(${attribute_value}, '^[-+]?[0-9]*[.,]?[0-9]+$') + + + + + + AND abs( + minus( + + + , + cast(#{dataFilterValue.start} as float) + ) + ) < exp(-11) + + + + AND + + + > cast(#{dataFilterValue.start} as float) + + + AND + + + <= cast(#{dataFilterValue.end} as float) + + + + + + + + + + + + ( + + + + + + + + + + + + + + + + + + UNION DISTINCT + SELECT sample_unique_id + FROM sample_derived + WHERE patient_unique_id in ( + + + + + + + + + + + + + + + + + ) + ) + + + + + + + + + + + + + + + + + + + ( + + + SELECT DISTINCT ${unique_id} + FROM sample_derived sd + LEFT JOIN () AS categorical_clinical_data + ON + + + sd.sample_unique_id = categorical_clinical_data.sample_unique_id + + + sd.patient_unique_id = categorical_clinical_data.patient_unique_id + + + WHERE empty(attribute_value) + AND EXISTS () + + + + + UNION ALL + + + + + SELECT ${unique_id} + FROM ${table_name} + WHERE attribute_name = #{clinicalDataFilter.attributeId} AND + type='${type}' + AND + + + + + + ) + + + + SELECT sample_unique_id, patient_unique_id, attribute_value + FROM clinical_data_derived + WHERE attribute_name = #{clinicalDataFilter.attributeId} AND type='${type}' + + AND cancer_study_identifier IN + + #{studyId} + + + + + + ( + SELECT ${unique_id} + FROM sample_derived sd + LEFT JOIN () AS categorical_clinical_data + ON + + + sd.sample_unique_id = categorical_clinical_data.sample_unique_id + + + sd.patient_unique_id = categorical_clinical_data.patient_unique_id + + + WHERE + + + + empty(attribute_value) + OR + + + = 'NA' + + + attribute_value ILIKE #{dataFilterValue.value} + + + + AND EXISTS () + ) + + + + + + + + + + + + + + + + + + + SELECT DISTINCT sd.sample_unique_id + FROM sample_derived sd + LEFT JOIN () AS genomic_numerical_query ON sd.sample_unique_id = genomic_numerical_query.sample_unique_id + WHERE alteration_value IS null + + + + UNION ALL + + + + SELECT DISTINCT sample_unique_id + FROM () AS genomic_numerical_query + WHERE + + + + + + + + + SELECT sample_unique_id, alteration_value + FROM genetic_alteration_derived + WHERE profile_type = #{genomicDataFilter.profileType} + AND hugo_gene_symbol = #{genomicDataFilter.hugoGeneSymbol} + + AND cancer_study_identifier IN + + #{studyId} + + + + + + + + ( + + + + ) + + + + + ( + + + + ) + + + -- patient level profile only have categorical for now + + + ( + + + + ) + + + + + + SELECT sample_unique_id, patient_unique_id, value, datatype + FROM generic_assay_data_derived + WHERE profile_type = #{genericAssayDataFilter.profileType} + AND entity_stable_id = #{genericAssayDataFilter.stableId} + + + + + + + + + + + + + + + + + + + + SELECT DISTINCT sd.sample_unique_id + FROM sample_derived sd + LEFT JOIN () AS generic_numerical_query ON sd.sample_unique_id = generic_numerical_query.sample_unique_id + WHERE datatype = 'LIMIT-VALUE' + AND value IS null OR + + + = 'NA' + + + + UNION ALL + + + + SELECT DISTINCT sample_unique_id + FROM () AS generic_numerical_query + WHERE + datatype = 'LIMIT-VALUE' + AND + + + != 'NA' + AND + + + + + + + + + SELECT sample_unique_id + FROM sample_derived sd + LEFT JOIN () AS generic_assay_query + ON + + + sd.sample_unique_id = generic_assay_query.sample_unique_id + + + sd.patient_unique_id = generic_assay_query.patient_unique_id + + + + datatype != 'LIMIT-VALUE' + + + + value IS null OR + + + = 'NA' + + + value ILIKE #{dataFilterValue.value} + + + + + + + + + + WITH all_samples AS ( + SELECT sample_unique_id + FROM sample_derived + WHERE cancer_study_identifier IN + + + #{studyId} + + + ), + profiled_samples AS ( + SELECT DISTINCT sgp.sample_unique_id + FROM sample_to_gene_panel_derived sgp + JOIN gene_panel_to_gene_derived gpg ON sgp.gene_panel_id = gpg.gene_panel_id + WHERE + + cancer_study_identifier IN + + #{studyId} + + AND + + gpg.gene = #{mutationDataFilter.hugoGeneSymbol} + AND sgp.alteration_type = 'MUTATION_EXTENDED' + ), + mutated_samples AS ( + SELECT DISTINCT sample_unique_id + FROM genomic_event_derived + WHERE + + cancer_study_identifier IN + + #{studyId} + + AND + + hugo_gene_symbol = #{mutationDataFilter.hugoGeneSymbol} + AND variant_type = 'mutation' + ) + SELECT DISTINCT sample_unique_id + FROM + + + + SELECT sample_unique_id FROM mutated_samples + + + SELECT sample_unique_id FROM profiled_samples + WHERE sample_unique_id NOT IN (SELECT sample_unique_id FROM mutated_samples) + + + SELECT sample_unique_id FROM all_samples + WHERE sample_unique_id NOT IN (SELECT sample_unique_id FROM profiled_samples) + + + + + + + + SELECT DISTINCT sample_unique_id + FROM genomic_event_derived + WHERE hugo_gene_symbol = #{mutationDataFilter.hugoGeneSymbol} + AND variant_type = 'mutation' + AND mutation_type IN + + #{dataFilterValue.value} + + + + + + + + WITH cna_query AS ( + SELECT sample_unique_id as sampleUniqueId, alteration_value + FROM genetic_alteration_derived + WHERE profile_type = #{genomicDataFilter.profileType} + AND hugo_gene_symbol = #{genomicDataFilter.hugoGeneSymbol} + + AND cancer_study_identifier IN + + #{studyId} + + + ) + SELECT DISTINCT sd.sample_unique_id + + FROM sample_derived sd + LEFT JOIN cna_query ON sd.sample_unique_id = cna_query.sampleUniqueId + WHERE + + cancer_study_identifier IN + + #{studyId} + + AND + + + + + alteration_value IS null + + alteration_value == #{dataFilterValue.value} + + + + + + + multiIf( + -- This condition is to prevent casting non numerical values to float + NOT match(${attribute_value}, '^[><]?=?[-+]?[0-9]*[.,]?[0-9]+$'), + NULL, + (startsWith(${attribute_value}, '<=') OR startsWith(${attribute_value}, '>=')), + cast(substr(${attribute_value}, 3) as float), + startsWith(${attribute_value}, '<'), + cast(substr(${attribute_value}, 2) as float) - exp(-10), + startsWith(${attribute_value}, '>'), + cast(substr(${attribute_value}, 2) as float) + exp(-10), + cast(${attribute_value} as float) + ) + + + + + ${attribute_value}='' + OR upperUTF8(${attribute_value})='NA' + OR upperUTF8(${attribute_value})='NAN' + OR upperUTF8(${attribute_value})='N/A' + + + + multiIf( + + + , + 'NA', + ${attribute_value} + ) + + + + patient_unique_id in ( + SELECT patient_unique_id + FROM sample_derived + + sample_unique_id IN () + + ) + + + + sample_unique_id IN () + + \ No newline at end of file diff --git a/src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml b/src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml new file mode 100644 index 00000000000..1b1a0c8cebd --- /dev/null +++ b/src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + patient_unique_id in ( + SELECT patient_unique_id + FROM sample_derived + + sample_unique_id IN () + + ) + + \ No newline at end of file From 5aea7b27bd2e19a31019f0f44426193c6df42521 Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Mon, 17 Feb 2025 09:49:05 -0500 Subject: [PATCH 2/9] Fix apiTests --- .../ColumnarStoreStudyViewController.java | 516 +++++++++++++++++- .../config/ClickhouseMyBatisConfig.java | 23 +- .../patient/ClickhousePatientMapper.java | 5 +- .../patient/ClickhousePatientRepository.java | 4 +- .../service/BasicDataBinner.java | 379 +++++++++++++ .../service/ClinicalDataBinner.java | 130 +++++ .../mybatis/config/PersistenceConfig.java | 17 +- .../CustomDataSourceConfiguration.java | 4 +- .../legacy/service/ViolinPlotService.java | 3 +- .../service/impl/ViolinPlotServiceImpl.java | 17 +- .../legacy/web/StudyViewController.java | 11 +- .../StudyViewColumnStoreController.java | 29 +- .../columnar/util/NewStudyViewFilterUtil.java | 39 +- ...ategorizedGenericAssayDataCountFilter.java | 3 + ...volvedCancerStudyExtractorInterceptor.java | 2 +- .../studyview/StudyViewService.java | 2 +- .../alteration/ClickhouseAlterationMapper.xml | 14 +- .../ClickhouseClinicalEventMapper.xml | 2 +- .../generic_assay/GenericAssayMapper.xml | 7 +- .../patient/ClickhousePatientMapper.xml | 6 +- .../treatment/ClickhouseTreatmentMapper.xml | 32 +- .../impl/ViolinPlotServiceImplTest.java | 7 +- 22 files changed, 1180 insertions(+), 72 deletions(-) create mode 100644 src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java create mode 100644 src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java diff --git a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java index 062479c4605..4071bcd7b99 100644 --- a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java +++ b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java @@ -1,24 +1,79 @@ package org.cbioportal.application.rest.vcolumnstore; import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.validation.Valid; import org.cbioportal.application.rest.mapper.SampleMapper; import org.cbioportal.application.rest.response.SampleDTO; +import org.cbioportal.infrastructure.service.BasicDataBinner; +import org.cbioportal.infrastructure.service.ClinicalDataBinner; import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.CaseListDataCount; +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.legacy.model.ClinicalDataBin; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.legacy.model.ClinicalEventKeyCode; +import org.cbioportal.legacy.model.ClinicalEventTypeCount; +import org.cbioportal.legacy.model.ClinicalViolinPlotData; +import org.cbioportal.legacy.model.CopyNumberCountByGene; +import org.cbioportal.legacy.model.DensityPlotData; +import org.cbioportal.legacy.model.GenericAssayDataBin; +import org.cbioportal.legacy.model.GenericAssayDataCountItem; +import org.cbioportal.legacy.model.GenomicDataBin; +import org.cbioportal.legacy.model.GenomicDataCount; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.model.PatientTreatmentReport; +import org.cbioportal.legacy.model.SampleTreatmentReport; +import org.cbioportal.legacy.service.ClinicalDataDensityPlotService; +import org.cbioportal.legacy.service.CustomDataService; +import org.cbioportal.legacy.service.ViolinPlotService; import org.cbioportal.legacy.service.exception.StudyNotFoundException; +import org.cbioportal.legacy.service.util.CustomDataSession; +import org.cbioportal.legacy.web.columnar.util.CustomDataFilterUtil; +import org.cbioportal.legacy.web.columnar.util.NewStudyViewFilterUtil; +import org.cbioportal.legacy.web.parameter.ClinicalDataBinCountFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataCountFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; +import org.cbioportal.legacy.web.parameter.DataBinMethod; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinCountFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataCountFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataBinCountFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataCountFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.legacy.web.parameter.MutationOption; +import org.cbioportal.legacy.web.parameter.Projection; +import org.cbioportal.legacy.web.parameter.SampleIdentifier; import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.cbioportal.legacy.web.util.DensityPlotParameters; +import org.cbioportal.sample.Sample; import org.cbioportal.studyview.StudyViewService; import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.Collection; +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toSet; @RestController @RequestMapping("/api/column-store") @@ -26,25 +81,36 @@ public class ColumnarStoreStudyViewController { private final StudyViewService studyViewService; + private final BasicDataBinner basicDataBinner; + private final ClinicalDataBinner clinicalDataBinner; + private final ClinicalDataDensityPlotService clinicalDataDensityPlotService; + private final ViolinPlotService violinPlotService; + private final CustomDataService customDataService; + private final CustomDataFilterUtil customDataFilterUtil; + - public ColumnarStoreStudyViewController(StudyViewService studyViewService) { + public ColumnarStoreStudyViewController(StudyViewService studyViewService, BasicDataBinner basicDataBinner, ClinicalDataBinner clinicalDataBinner, ClinicalDataDensityPlotService clinicalDataDensityPlotService, ViolinPlotService violinPlotService, CustomDataService customDataService, CustomDataFilterUtil customDataFilterUtil) { this.studyViewService = studyViewService; + this.basicDataBinner = basicDataBinner; + this.clinicalDataBinner = clinicalDataBinner; + this.clinicalDataDensityPlotService = clinicalDataDensityPlotService; + this.violinPlotService = violinPlotService; + this.customDataService = customDataService; + this.customDataFilterUtil = customDataFilterUtil; } @Hidden - @PostMapping(value = "/v1/filtered-samples/fetch", + @PostMapping(value = "/filtered-samples/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> fetchFilteredSamples( @RequestParam(defaultValue = "false") Boolean negateFilters, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter, @RequestBody(required = false) StudyViewFilter studyViewFilter) { return ResponseEntity.ok(SampleMapper.INSTANCE.toDtos(studyViewService.getFilteredSamples(studyViewFilter)) ); } @Hidden // should unhide when we remove legacy controller - @PostMapping(value = "/v1/mutated-genes/fetch", + @PostMapping(value = "/mutated-genes/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> fetchMutatedGenes( @RequestBody(required = false) StudyViewFilter studyViewFilter @@ -52,4 +118,440 @@ public ResponseEntity> fetchMutatedGenes( return ResponseEntity.ok(studyViewService.getMutatedGenes(studyViewFilter) ); } + + @Hidden // should unhide when we remove legacy controller + @PostMapping(value = "/molecular-profile-sample-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch sample counts by study view filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataCount.class)))) + public ResponseEntity> fetchMolecularProfileSampleCounts( + @Parameter(required = true, description = "Study view filter") + @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter + ) throws StudyNotFoundException { + return ResponseEntity.ok( + studyViewService.getMolecularProfileSampleCounts(studyViewFilter)); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/cna-genes/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> fetchCnaGenes( + @RequestBody(required = false) StudyViewFilter studyViewFilter + ) throws StudyNotFoundException { + return ResponseEntity.ok(studyViewService.getCnaGenes(studyViewFilter)); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/structuralvariant-genes/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch structural variant genes by study view filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = AlterationCountByGene.class)))) + public ResponseEntity> fetchStructuralVariantGenes( + @Parameter(required = true, description = "Study view filter") + @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter + ) throws StudyNotFoundException { + return ResponseEntity.ok(studyViewService.getStructuralVariantGenes(studyViewFilter)); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/clinical-data-counts/fetch", + method=RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> fetchClinicalDataCounts( + @RequestBody(required = false) ClinicalDataCountFilter clinicalDataCountFilter) + { + + List attributes = clinicalDataCountFilter.getAttributes(); + StudyViewFilter studyViewFilter = clinicalDataCountFilter.getStudyViewFilter(); + + if (attributes.size() == 1) { + NewStudyViewFilterUtil.removeClinicalDataFilter(attributes.getFirst().getAttributeId(), studyViewFilter.getClinicalDataFilters()); + } + List result = studyViewService.getClinicalDataCounts( + studyViewFilter, + attributes.stream().map(ClinicalDataFilter::getAttributeId).collect(Collectors.toList())); + return ResponseEntity.ok(result); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/sample-lists-counts/fetch", method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch case list sample counts by study view filter") + public List fetchCaseListCounts( + @Parameter(required = true, description = "Study view filter") + @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter) { + + return studyViewService.getCaseListDataCounts(studyViewFilter); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/clinical-data-bin-counts/fetch", method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> fetchClinicalDataBinCounts( + @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, + @RequestBody(required = false) ClinicalDataBinCountFilter clinicalDataBinCountFilter) { + List clinicalDataBins = clinicalDataBinner.fetchClinicalDataBinCounts( + dataBinMethod, + clinicalDataBinCountFilter, + true + ); + return new ResponseEntity<>(clinicalDataBins, HttpStatus.OK); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/clinical-data-density-plot/fetch", + method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch clinical data density plot bins by study view filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = DensityPlotData.class))) + @Validated + public ResponseEntity fetchClinicalDataDensityPlot( + @Parameter(required = true, description = "Clinical Attribute ID of the X axis") + @RequestParam String xAxisAttributeId, + @Parameter(description = "Number of the bins in X axis") + @RequestParam(defaultValue = "50") Integer xAxisBinCount, + @Parameter(description = "Starting point of the X axis, if different than smallest value") + @RequestParam(required = false) BigDecimal xAxisStart, + @Parameter(description = "Starting point of the X axis, if different than largest value") + @RequestParam(required = false) BigDecimal xAxisEnd, + @Parameter(required = true, description = "Clinical Attribute ID of the Y axis") + @RequestParam String yAxisAttributeId, + @Parameter(description = "Number of the bins in Y axis") + @RequestParam(defaultValue = "50") Integer yAxisBinCount, + @Parameter(description = "Starting point of the Y axis, if different than smallest value") + @RequestParam(required = false) BigDecimal yAxisStart, + @Parameter(description = "Starting point of the Y axis, if different than largest value") + @RequestParam(required = false) BigDecimal yAxisEnd, + @Parameter(description="Use log scale for X axis") + @RequestParam(required = false, defaultValue = "false") Boolean xAxisLogScale, + @Schema(defaultValue = "false") + @Parameter(description="Use log scale for Y axis") + @RequestParam(required = false, defaultValue = "false") Boolean yAxisLogScale, + @Parameter(required = true, description = "Study view filter") + @RequestBody(required = false) StudyViewFilter studyViewFilter + ) { + DensityPlotParameters densityPlotParameters = + new DensityPlotParameters.Builder() + .xAxisAttributeId(xAxisAttributeId) + .yAxisAttributeId(yAxisAttributeId) + .xAxisBinCount(xAxisBinCount) + .yAxisBinCount(yAxisBinCount) + .xAxisStart(xAxisStart) + .yAxisStart(yAxisStart) + .xAxisEnd(xAxisEnd) + .yAxisEnd(yAxisEnd) + .xAxisLogScale(xAxisLogScale) + .yAxisLogScale(yAxisLogScale) + .build(); + + List combinedClinicalDataList = studyViewService.getClinicalDataForXyPlot( + studyViewFilter, + List.of(xAxisAttributeId, yAxisAttributeId), + false + ); + + DensityPlotData result = clinicalDataDensityPlotService.getDensityPlotData( + combinedClinicalDataList, + densityPlotParameters, + studyViewFilter + ); + + return new ResponseEntity<>(result, HttpStatus.OK); + } + + @Hidden // should unhide when we remove legacy controller + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/clinical-data-violin-plots/fetch", + method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch violin plot curves per categorical clinical data value, filtered by study view filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = ClinicalViolinPlotData.class))) + public ResponseEntity fetchClinicalDataViolinPlots( + @Parameter(required = true, description = "Clinical Attribute ID of the categorical attribute") + @RequestParam String categoricalAttributeId, + @Parameter(required = true, description = "Clinical Attribute ID of the numerical attribute") + @RequestParam String numericalAttributeId, + @Parameter(description = "Starting point of the violin plot axis, if different than smallest value") + @RequestParam(required = false) BigDecimal axisStart, + @Parameter(description = "Ending point of the violin plot axis, if different than largest value") + @RequestParam(required = false) BigDecimal axisEnd, + @Parameter(description = "Number of points in the curve") + @RequestParam(required = false, defaultValue = "100") BigDecimal numCurvePoints, + @Parameter(description="Use log scale for the numerical attribute") + @RequestParam(required = false, defaultValue = "false") Boolean logScale, + @Parameter(description="Sigma stepsize multiplier") + @RequestParam(required = false, defaultValue = "1") BigDecimal sigmaMultiplier, + @Parameter(required = true, description = "Study view filter") + @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter + ) { + // fetch the samples by using the provided study view filter + List filteredSamples = studyViewService.getFilteredSamples(studyViewFilter); + + // remove the numerical clinical data filter from the study view filter. + // this new modified filter is used to fetch sample and patient clinical data. + // this is required to get the complete violin plot data. + // filteredSamples reflects only the original unmodified study view filter. + // we will need to fetch samples again to get the samples corresponding to this modified filter, + // otherwise patient to sample mapping may be incomplete. + if (studyViewFilter.getClinicalDataFilters() != null) { + studyViewFilter.getClinicalDataFilters().stream() + .filter(f->f.getAttributeId().equals(numericalAttributeId)) + .findAny() + .ifPresent(f->studyViewFilter.getClinicalDataFilters().remove(f)); + } + + List combinedClinicalDataList = studyViewService.getClinicalDataForXyPlot( + studyViewFilter, + List.of(numericalAttributeId, categoricalAttributeId), + true // filter out clinical data with empty attribute values due to Clickhouse migration + ); + + // Only mutation count can use log scale + boolean useLogScale = logScale && numericalAttributeId.equals("MUTATION_COUNT"); + + Set sampleIdsSet = filteredSamples + .stream() + .map(s -> s.internalId()) + .collect(toSet()); + + ClinicalViolinPlotData result = violinPlotService.getClinicalViolinPlotData( + combinedClinicalDataList, + sampleIdsSet, + axisStart, + axisEnd, + numCurvePoints, + useLogScale, + sigmaMultiplier, + studyViewFilter + ); + + return new ResponseEntity<>(result, HttpStatus.OK); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/genomic-data-counts/fetch", + method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch genomic data counts by GenomicDataCountFilter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataCountItem.class)))) + public ResponseEntity> fetchGenomicDataCounts( + @Parameter(required = true, description = "Genomic data count filter") + @Valid @RequestBody(required = false) + GenomicDataCountFilter genomicDataCountFilter) throws StudyNotFoundException { + List genomicDataFilters = genomicDataCountFilter.getGenomicDataFilters(); + StudyViewFilter studyViewFilter = genomicDataCountFilter.getStudyViewFilter(); + // when there is only one filter, it means study view is doing a single chart filter operation + // remove filter from studyViewFilter to return all data counts + // the reason we do this is to make sure after chart get filtered, user can still see unselected portion of the chart + if (genomicDataFilters.size() == 1) { + NewStudyViewFilterUtil.removeSelfFromGenomicDataFilter( + genomicDataFilters.get(0).getHugoGeneSymbol(), + genomicDataFilters.get(0).getProfileType(), + studyViewFilter); + } + + // This endpoint is CNA specific. The name choice of "genomic data" does not imply it support other genomic data types + List result = studyViewService.getCNACountsByGeneSpecific(studyViewFilter, genomicDataFilters); + + return new ResponseEntity<>(result, HttpStatus.OK); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/generic-assay-data-counts/fetch", + method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch generic assay data counts by study view filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenericAssayDataCountItem.class)))) + public ResponseEntity> fetchGenericAssayDataCounts( + @Parameter(required = true, description = "Generic assay data count filter") + @Valid @RequestBody(required = false) + GenericAssayDataCountFilter genericAssayDataCountFilter) { + + List gaFilters = genericAssayDataCountFilter.getGenericAssayDataFilters(); + StudyViewFilter studyViewFilter = genericAssayDataCountFilter.getStudyViewFilter(); + // when there is only one filter, it means study view is doing a single chart filter operation + // remove filter from studyViewFilter to return all data counts + // the reason we do this is to make sure after chart get filtered, user can still see unselected portion of the chart + + if (gaFilters.size() == 1) { + NewStudyViewFilterUtil.removeSelfFromGenericAssayFilter(gaFilters.getFirst().getStableId(), studyViewFilter); + } + + return ResponseEntity.ok(studyViewService.getGenericAssayDataCounts(studyViewFilter, gaFilters)); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/mutation-data-counts/fetch", + method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch mutation data counts by GenomicDataCountFilter") + public ResponseEntity> fetchMutationDataCounts( + @Parameter(description = "Level of detail of the response") + @RequestParam(defaultValue = "SUMMARY") Projection projection, + @Parameter(required = true, description = "Genomic data count filter") + @Valid @RequestBody(required = false) GenomicDataCountFilter genomicDataCountFilter + ) { + List genomicDataFilters = genomicDataCountFilter.getGenomicDataFilters(); + StudyViewFilter studyViewFilter = genomicDataCountFilter.getStudyViewFilter(); + // when there is only one filter, it means study view is doing a single chart filter operation + // remove filter from studyViewFilter to return all data counts + // the reason we do this is to make sure after chart get filtered, user can still see unselected portion of the chart + if (genomicDataFilters.size() == 1 && projection == Projection.SUMMARY) { + NewStudyViewFilterUtil.removeSelfFromMutationDataFilter( + genomicDataFilters.get(0).getHugoGeneSymbol(), + genomicDataFilters.get(0).getProfileType(), + MutationOption.MUTATED, + studyViewFilter); + } + + List result = projection == Projection.SUMMARY ? + studyViewService.getMutationCountsByGeneSpecific(studyViewFilter, genomicDataFilters) : + studyViewService.getMutationTypeCountsByGeneSpecific(studyViewFilter, genomicDataFilters); + + return ResponseEntity.ok(result); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/clinical-event-type-counts/fetch", + method = RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Get Counts of Clinical Event Types by Study View Filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalEventTypeCount.class)))) + public ResponseEntity> getClinicalEventTypeCounts( + @Parameter(required = true, description = "Study view filter") + @Valid + @RequestBody(required = false) + StudyViewFilter studyViewFilter) { + return ResponseEntity.ok(studyViewService.getClinicalEventTypeCounts(studyViewFilter)); + } + + @RequestMapping(value = "/treatments/patient-counts/fetch", + method = RequestMethod.POST, + produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Get all patient level treatments") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = PatientTreatmentReport.class))) + public ResponseEntity fetchPatientTreatmentCounts( + @Parameter(required = false ) + @RequestParam(name = "tier", required = false, defaultValue = "Agent") + ClinicalEventKeyCode tier, + + @Parameter(required = true, description = "Study view filter") + @Valid + @RequestBody(required = false) + StudyViewFilter studyViewFilter) { + return ResponseEntity.ok(studyViewService.getPatientTreatmentReport(studyViewFilter)); + } + + @RequestMapping(value = "/treatments/sample-counts/fetch", + method = RequestMethod.POST, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = SampleTreatmentReport.class))) + public ResponseEntity fetchSampleTreatmentCounts( + @Parameter(required = false ) + @RequestParam(name = "tier", required = false, defaultValue = "Agent") + ClinicalEventKeyCode tier, + + @Parameter(required = true, description = "Study view filter") + @Valid + @RequestBody(required = false) + StudyViewFilter studyViewFilter) { + return ResponseEntity.ok(studyViewService.getSampleTreatmentReport(studyViewFilter)); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/custom-data-counts/fetch", + method=RequestMethod.POST, + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch custom data counts by study view filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalDataCountItem.class)))) + public ResponseEntity> fetchCustomDataCounts( + @Parameter(required = true, description = "Custom data count filter") @Valid @RequestBody(required = + false) ClinicalDataCountFilter clinicalDataCountFilter){ + + List attributes = clinicalDataCountFilter.getAttributes(); + StudyViewFilter studyViewFilter = clinicalDataCountFilter.getStudyViewFilter(); + if (attributes.size() == 1) { + NewStudyViewFilterUtil.removeClinicalDataFilter(attributes.getFirst().getAttributeId(), studyViewFilter.getCustomDataFilters()); + } + + List filteredSampleIdentifiers = + studyViewService.getFilteredSamples(studyViewFilter) + .stream() + .map(sample -> NewStudyViewFilterUtil.buildSampleIdentifier(sample.cancerStudyIdentifier(), sample.stableId())) + .toList(); + + if (filteredSampleIdentifiers.isEmpty()) { + return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK); + } + + final List attributeIds = attributes.stream().map(ClinicalDataFilter::getAttributeId).toList(); + Map customDataSessionsMap = customDataService.getCustomDataSessions(attributeIds); + + List result = customDataFilterUtil.getCustomDataCounts(filteredSampleIdentifiers, customDataSessionsMap); + + return new ResponseEntity<>(result, HttpStatus.OK); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/custom-data-bin-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, method= RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(description = "Fetch custom data bin counts by study view filter") + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalDataBin.class)))) + public ResponseEntity> fetchCustomDataBinCounts( + @Parameter(description = "Method for data binning") + @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, + @Parameter(required = true, description = "Clinical data bin count filter") + @Valid @RequestBody(required = false) ClinicalDataBinCountFilter clinicalDataBinCountFilter) { + List customDataBins = basicDataBinner.getDataBins( + dataBinMethod, + clinicalDataBinCountFilter, + true + ); + return ResponseEntity.ok(customDataBins); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/genomic-data-bin-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataBin.class)))) + public ResponseEntity> fetchGenomicDataBinCounts( + @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, + @RequestBody(required = false) GenomicDataBinCountFilter genomicDataBinCountFilter) { + List genomicDataBins = basicDataBinner.getDataBins( + dataBinMethod, + genomicDataBinCountFilter, + true + ); + return ResponseEntity.ok(genomicDataBins); + } + + @Hidden // should unhide when we remove legacy controller + @RequestMapping(value = "/generic-assay-data-bin-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenericAssayDataBin.class)))) + public ResponseEntity> fetchGenericAssayDataBinCounts( + @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, + @RequestBody(required = false) GenericAssayDataBinCountFilter genericAssayDataBinCountFilter) { + List genericAssayDataBins = basicDataBinner.getDataBins( + dataBinMethod, + genericAssayDataBinCountFilter, + true + ); + return ResponseEntity.ok(genericAssayDataBins); + } } diff --git a/src/main/java/org/cbioportal/infrastructure/config/ClickhouseMyBatisConfig.java b/src/main/java/org/cbioportal/infrastructure/config/ClickhouseMyBatisConfig.java index a60a7365661..5ce2455341a 100644 --- a/src/main/java/org/cbioportal/infrastructure/config/ClickhouseMyBatisConfig.java +++ b/src/main/java/org/cbioportal/infrastructure/config/ClickhouseMyBatisConfig.java @@ -1,18 +1,31 @@ package org.cbioportal.infrastructure.config; +import org.cbioportal.legacy.persistence.mybatis.typehandler.SampleTypeTypeHandler; import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import javax.sql.DataSource; import java.io.IOException; @Configuration +@Profile("clickhouse") +@MapperScan(value= "org.cbioportal.infrastructure.repository.clickhouse", + sqlSessionFactoryRef = "sqlColumnarSessionFactory") public class ClickhouseMyBatisConfig { - - public void addClickhouseMybatisConfig( @Qualifier("sqlColumnarSessionFactory") SqlSessionFactoryBean sqlSessionFactoryBean, - ApplicationContext applicationContext) throws IOException { - sqlSessionFactoryBean.addMapperLocations( - applicationContext.getResources("classpath:mappers/clickhouse/**/*.xml")); + + @Bean("sqlColumnarSessionFactory") + public SqlSessionFactoryBean sqlColumnarSessionFactory(@Qualifier("clickhouseDataSource") DataSource dataSource, ApplicationContext applicationContext) throws IOException { + SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); + sessionFactory.setDataSource(dataSource); + sessionFactory.addMapperLocations( + applicationContext.getResources("classpath:mappers/clickhouse/**/*.xml")); + + sessionFactory.setTypeHandlers(new SampleTypeTypeHandler()); + return sessionFactory; } } diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java index 7ee30077a94..fe6fc4fcc0e 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java @@ -1,11 +1,12 @@ package org.cbioportal.infrastructure.repository.clickhouse.patient; +import org.apache.ibatis.annotations.Param; import org.cbioportal.legacy.model.CaseListDataCount; import org.cbioportal.studyview.StudyViewFilterContext; import java.util.List; public interface ClickhousePatientMapper { - int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext); - List getCaseListDataCount(StudyViewFilterContext studyViewFilterContext); + int getPatientCount(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + List getCaseListDataCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); } diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java index d0c33e2087b..5b147116c8b 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java @@ -24,7 +24,7 @@ public ClickhousePatientRepository(ClickhousePatientMapper mapper) { */ @Override public int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext) { - return mapper.getFilteredPatientCount(studyViewFilterContext); + return mapper.getPatientCount(studyViewFilterContext); } /** @@ -33,6 +33,6 @@ public int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext */ @Override public List getCaseListDataCounts(StudyViewFilterContext studyViewFilterContext) { - return mapper.getCaseListDataCount(studyViewFilterContext); + return mapper.getCaseListDataCounts(studyViewFilterContext); } } diff --git a/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java b/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java new file mode 100644 index 00000000000..f6fe169becc --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java @@ -0,0 +1,379 @@ +package org.cbioportal.infrastructure.service; + +import org.cbioportal.legacy.model.Binnable; +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.legacy.model.ClinicalDataBin; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.legacy.model.DataBin; +import org.cbioportal.legacy.model.GenericAssayDataBin; +import org.cbioportal.legacy.model.GenomicDataBin; +import org.cbioportal.legacy.service.CustomDataService; +import org.cbioportal.legacy.service.StudyViewColumnarService; +import org.cbioportal.legacy.service.util.CustomDataSession; +import org.cbioportal.legacy.web.columnar.util.CustomDataFilterUtil; +import org.cbioportal.legacy.web.columnar.util.NewClinicalDataBinUtil; +import org.cbioportal.legacy.web.parameter.ClinicalDataBinCountFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataBinFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataType; +import org.cbioportal.legacy.web.parameter.DataBinCountFilter; +import org.cbioportal.legacy.web.parameter.DataBinFilter; +import org.cbioportal.legacy.web.parameter.DataBinMethod; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinCountFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataBinCountFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; +import org.cbioportal.legacy.web.parameter.SampleIdentifier; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.cbioportal.legacy.web.util.DataBinner; +import org.cbioportal.legacy.web.util.StudyViewFilterUtil; +import org.cbioportal.studyview.StudyViewService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toMap; + +// BasicDataBinner is a generalized class derived from ClinicalDataBinner +// BasicDataBinner should eventually deprecate ClinicalDataBinner +// we are using BasicDataBinner for genomic data, generic assay, and custom data bin counts now +// but BasicDataBinner can support clinical data counts too +// after we switched clinical data counts to use this, then We can remove ClinicalDataBinner +@Component +@Profile("clickhouse") +public class BasicDataBinner { + private final StudyViewService studyViewService; + private final DataBinner dataBinner; + private final CustomDataFilterUtil customDataFilterUtil; + private final CustomDataService customDataService; + private final StudyViewFilterUtil studyViewFilterUtil; + + @Autowired + public BasicDataBinner( + StudyViewService studyViewService, + DataBinner dataBinner, + CustomDataFilterUtil customDataFilterUtil, + CustomDataService customDataService, + StudyViewFilterUtil studyViewFilterUtil + ) { + this.studyViewService = studyViewService; + this.dataBinner = dataBinner; + this.customDataFilterUtil = customDataFilterUtil; + this.customDataService = customDataService; + this.studyViewFilterUtil = studyViewFilterUtil; + } + + // convert from counts to clinical data + private List convertCountsToData(List clinicalDataCounts) + { + return clinicalDataCounts + .stream() + .map(NewClinicalDataBinUtil::generateClinicalDataFromClinicalDataCount) + .flatMap(Collection::stream) + .toList(); + } + + @Cacheable(cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()") + public List getDataBins( + DataBinMethod dataBinMethod, + T dataBinCountFilter, + boolean shouldRemoveSelfFromFilter) { + // get data bin filters based on the type of the filter + // either Genomic data or Generic Assay data or custom data or clinical data + List dataBinFilters = fetchDataBinFilters(dataBinCountFilter); + StudyViewFilter studyViewFilter = dataBinCountFilter.getStudyViewFilter(); + // define result variables + List resultDataBins = Collections.emptyList(); + // if no data bin filters or no study view filer object is passed in + // return empty result + if (dataBinFilters.isEmpty() || studyViewFilter == null) { + return resultDataBins; + } + + if (shouldRemoveSelfFromFilter && dataBinFilters.size() == 1) { + removeSelfFromFilter(dataBinFilters.get(0), studyViewFilter); + } + + List uniqueKeys = dataBinFilters.stream().map(this::getDataBinFilterUniqueKey).toList(); + + // a new StudyView filter to partially filter by study and sample ids only + // we need this additional partial filter because we always need to know the bins generated for the initial state + // which allows us to keep the number of bins and bin ranges consistent even if there are additional data filters. + // we only want to update the counts for each bin, we don't want to regenerate the bins for the filtered data. + // NOTE: partial filter is only needed when dataBinMethod == DataBinMethod.STATIC but that's always the case + // for the frontend implementation. we can't really use dataBinMethod == DataBinMethod.DYNAMIC because of the + // complication it brings to the frontend visualization and filtering + StudyViewFilter partialFilter = new StudyViewFilter(); + partialFilter.setStudyIds(studyViewFilter.getStudyIds()); + partialFilter.setSampleIdentifiers(studyViewFilter.getSampleIdentifiers()); + + // we need to fetch data for the partial filter in order to generate the bins for initial state + // we use the filtered data to calculate the counts for each bin, we do not regenerate bins for the filtered data + List unfilteredClinicalDataCounts; + List filteredClinicalDataCounts; + Map attributeDatatypeMap; + switch (dataBinCountFilter) { + // TODO: first case is to support clinical data, but clinical data is not using this now. We should update controller to use this method later + case ClinicalDataBinCountFilter clinicalDataBinCountFilter when !customDataService.getCustomDataSessions(uniqueKeys).isEmpty() -> { + Map customDataSessions = customDataService.getCustomDataSessions(uniqueKeys); + List unfilteredSampleIdentifiers = + studyViewService.getFilteredSamples(partialFilter) + .stream() + .map(sample -> studyViewFilterUtil.buildSampleIdentifier(sample.cancerStudyIdentifier(), sample.stableId())) + .toList(); + unfilteredClinicalDataCounts = customDataFilterUtil.getCustomDataCounts(unfilteredSampleIdentifiers, customDataSessions); + List filteredSampleIdentifiers = studyViewService.getFilteredSamples(studyViewFilter) + .stream() + .map(sample -> studyViewFilterUtil.buildSampleIdentifier(sample.cancerStudyIdentifier(), sample.stableId())) + .toList(); + filteredClinicalDataCounts = customDataFilterUtil.getCustomDataCounts(filteredSampleIdentifiers, customDataSessions); + attributeDatatypeMap = customDataSessions.entrySet().stream().collect(toMap( + Map.Entry::getKey, + NewClinicalDataBinUtil::getDataType + )); + } + case ClinicalDataBinCountFilter clinicalDataBinCountFilter -> { + unfilteredClinicalDataCounts = studyViewService.getClinicalDataCounts(partialFilter, uniqueKeys); + filteredClinicalDataCounts = studyViewService.getClinicalDataCounts(studyViewFilter, uniqueKeys); + attributeDatatypeMap = studyViewService.getClinicalAttributeDataTypeMap(studyViewFilter); + } + case GenomicDataBinCountFilter genomicDataBinCountFilter -> { + unfilteredClinicalDataCounts = studyViewService.getGenomicDataBinCounts(partialFilter, genomicDataBinCountFilter.getGenomicDataBinFilters()); + filteredClinicalDataCounts = studyViewService.getGenomicDataBinCounts(studyViewFilter, genomicDataBinCountFilter.getGenomicDataBinFilters()); + attributeDatatypeMap = Collections.emptyMap(); + } + case GenericAssayDataBinCountFilter genericAssayDataBinCountFilter -> { + unfilteredClinicalDataCounts = studyViewService.getGenericAssayDataBinCounts(partialFilter, genericAssayDataBinCountFilter.getGenericAssayDataBinFilters()); + filteredClinicalDataCounts = studyViewService.getGenericAssayDataBinCounts(studyViewFilter, genericAssayDataBinCountFilter.getGenericAssayDataBinFilters()); + attributeDatatypeMap = Collections.emptyMap(); + } + default -> { + unfilteredClinicalDataCounts = Collections.emptyList(); + filteredClinicalDataCounts = Collections.emptyList(); + attributeDatatypeMap = Collections.emptyMap(); + } + } + + // TODO ignoring conflictingPatientAttributeIds for now + List unfilteredClinicalData = convertCountsToData( + unfilteredClinicalDataCounts.stream().flatMap(c -> c.getCounts().stream()).toList() + ); + List filteredClinicalData = convertCountsToData( + filteredClinicalDataCounts.stream().flatMap(c -> c.getCounts().stream()).toList() + ); + + Map> unfilteredClinicalDataByAttributeId = + unfilteredClinicalData.stream().collect(Collectors.groupingBy(Binnable::getAttrId)); + + Map> filteredClinicalDataByAttributeId = + filteredClinicalData.stream().collect(Collectors.groupingBy(Binnable::getAttrId)); + + // TODO: need to update attributeDatatypeMap to include patient level data for Generic Assay Profiles + if (dataBinMethod == DataBinMethod.STATIC) { + if (!unfilteredClinicalData.isEmpty()) { + resultDataBins = calculateStaticDataBins( + dataBinner, + dataBinFilters, + attributeDatatypeMap, + unfilteredClinicalDataByAttributeId, + filteredClinicalDataByAttributeId + ); + } + } + // TODO: need to update attributeDatatypeMap to include patient level data for Generic Assay Profiles + else { // dataBinMethod == DataBinMethod.DYNAMIC + // TODO we should consider removing dynamic binning support + // we never use dynamic binning in the frontend because number of bins and the bin ranges can change + // each time there is a new filter which makes the frontend implementation complicated + if (!filteredClinicalData.isEmpty()) { + resultDataBins = calculateDynamicDataBins( + dataBinner, + dataBinFilters, + attributeDatatypeMap, + filteredClinicalDataByAttributeId + ); + } + } + + return resultDataBins; + } + + private void removeSelfFromFilter(S dataBinFilter, StudyViewFilter studyViewFilter) { + switch (dataBinFilter) { + case ClinicalDataBinFilter clinicalDataBinFilter -> { + if (studyViewFilter.getClinicalDataFilters() != null) { + studyViewFilter.getClinicalDataFilters().removeIf(f -> f.getAttributeId().equals(clinicalDataBinFilter.getAttributeId())); + } + if (studyViewFilter.getCustomDataFilters() != null) { + studyViewFilter.getCustomDataFilters().removeIf(f -> f.getAttributeId().equals(clinicalDataBinFilter.getAttributeId())); + } + } + case GenomicDataBinFilter genomicDataBinFilter when studyViewFilter.getGenomicDataFilters() != null -> + studyViewFilter.getGenomicDataFilters().removeIf(f -> + f.getHugoGeneSymbol().equals(genomicDataBinFilter.getHugoGeneSymbol()) + && f.getProfileType().equals(genomicDataBinFilter.getProfileType()) + ); + case GenericAssayDataBinFilter genericAssayDataBinFilter when studyViewFilter.getGenericAssayDataFilters() != null -> + studyViewFilter.getGenericAssayDataFilters().removeIf(f -> + f.getStableId().equals(genericAssayDataBinFilter.getStableId()) + && f.getProfileType().equals(genericAssayDataBinFilter.getProfileType()) + ); + default -> { + // Do not remove any filters + } + } + } + + private List fetchDataBinFilters(T dataBinCountFilter) { + switch (dataBinCountFilter) { + case ClinicalDataBinCountFilter clinicalDataBinCountFilter -> { + return (List) clinicalDataBinCountFilter.getAttributes(); + } + case GenomicDataBinCountFilter genomicDataBinCountFilter -> { + return (List) genomicDataBinCountFilter.getGenomicDataBinFilters(); + } + case GenericAssayDataBinCountFilter genericAssayDataBinCountFilter -> { + return (List) genericAssayDataBinCountFilter.getGenericAssayDataBinFilters(); + } + default -> { + return new ArrayList<>(); + } + } + } + + private String getDataBinFilterUniqueKey(S dataBinFilter) { + switch (dataBinFilter) { + case ClinicalDataBinFilter clinicalDataBinFilter -> { + return clinicalDataBinFilter.getAttributeId(); + } + case GenomicDataBinFilter genomicDataBinFilter -> { + return genomicDataBinFilter.getHugoGeneSymbol() + genomicDataBinFilter.getProfileType(); + } + case GenericAssayDataBinFilter genericAssayDataBinFilter -> { + return genericAssayDataBinFilter.getStableId() + genericAssayDataBinFilter.getProfileType(); + } + default -> { + return null; + } + } + } + + private List calculateStaticDataBins( + DataBinner dataBinner, + List dataBinFilters, + Map attributeDatatypeMap, + Map> unfilteredClinicalDataByAttributeId, + Map> filteredClinicalDataByAttributeId + ) { + List result = new ArrayList<>(); + + for (T dataBinFilter : dataBinFilters) { + // if there is data for requested attribute + if (attributeDatatypeMap.isEmpty() || attributeDatatypeMap.containsKey(getDataBinFilterUniqueKey(dataBinFilter))) { + List dataBins = dataBinner + .calculateClinicalDataBins( + dataBinFilter, + filteredClinicalDataByAttributeId.getOrDefault(getDataBinFilterUniqueKey(dataBinFilter), emptyList()), + unfilteredClinicalDataByAttributeId.getOrDefault(getDataBinFilterUniqueKey(dataBinFilter), emptyList()) + ) + .stream() + .map(dataBin -> (U) transform(dataBinFilter, dataBin)) + .toList(); + + result.addAll(dataBins); + } + } + + return result; + } + + private List calculateDynamicDataBins( + DataBinner dataBinner, + List dataBinFilters, + Map attributeDatatypeMap, + Map> filteredClinicalDataByAttributeId + ) { + List result = new ArrayList<>(); + + for (T dataBinFilter : dataBinFilters) { + // if there is data for requested attribute + if (attributeDatatypeMap.isEmpty() || attributeDatatypeMap.containsKey(getDataBinFilterUniqueKey(dataBinFilter))) { + List dataBins = dataBinner + .calculateDataBins( + dataBinFilter, + filteredClinicalDataByAttributeId.getOrDefault(getDataBinFilterUniqueKey(dataBinFilter), emptyList()) + ) + .stream() + .map(dataBin -> (U) transform(dataBinFilter, dataBin)) + .toList(); + result.addAll(dataBins); + } + } + + return result; + } + + private T transform(S dataBinFilter, DataBin dataBin) { + switch (dataBinFilter) { + case ClinicalDataBinFilter clinicalDataBinFilter -> { + return (T) dataBinToClinicalDataBin(clinicalDataBinFilter, dataBin); + } + case GenomicDataBinFilter genomicDataBinFilter -> { + return (T) dataBintoGenomicDataBin(genomicDataBinFilter, dataBin); + } + case GenericAssayDataBinFilter genericAssayDataBinFilter -> { + return (T) dataBintoGenericAssayDataBin(genericAssayDataBinFilter, dataBin); + } + default -> { + return null; + } + } + } + + private ClinicalDataBin dataBinToClinicalDataBin(ClinicalDataBinFilter attribute, DataBin dataBin) { + ClinicalDataBin clinicalDataBin = new ClinicalDataBin(); + clinicalDataBin.setAttributeId(attribute.getAttributeId()); + setCommonDataBinProperties(dataBin, clinicalDataBin); + return clinicalDataBin; + } + + private GenomicDataBin dataBintoGenomicDataBin(GenomicDataBinFilter genomicDataBinFilter, DataBin dataBin) { + GenomicDataBin genomicDataBin = new GenomicDataBin(); + genomicDataBin.setHugoGeneSymbol(genomicDataBinFilter.getHugoGeneSymbol()); + genomicDataBin.setProfileType(genomicDataBinFilter.getProfileType()); + setCommonDataBinProperties(dataBin, genomicDataBin); + return genomicDataBin; + } + + private GenericAssayDataBin dataBintoGenericAssayDataBin(GenericAssayDataBinFilter genericAssayDataBinFilter, + DataBin dataBin) { + GenericAssayDataBin genericAssayDataBin = new GenericAssayDataBin(); + genericAssayDataBin.setStableId(genericAssayDataBinFilter.getStableId()); + genericAssayDataBin.setProfileType(genericAssayDataBinFilter.getProfileType()); + setCommonDataBinProperties(dataBin, genericAssayDataBin); + return genericAssayDataBin; + } + + private void setCommonDataBinProperties(DataBin originalDataBin, U targetDatabin) { + targetDatabin.setCount(originalDataBin.getCount()); + if (originalDataBin.getSpecialValue() != null) { + targetDatabin.setSpecialValue(originalDataBin.getSpecialValue()); + } + if (originalDataBin.getStart() != null) { + targetDatabin.setStart(originalDataBin.getStart()); + } + if (originalDataBin.getEnd() != null) { + targetDatabin.setEnd(originalDataBin.getEnd()); + } + } + +} diff --git a/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java b/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java new file mode 100644 index 00000000000..61abcaf227f --- /dev/null +++ b/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java @@ -0,0 +1,130 @@ +package org.cbioportal.infrastructure.service; + +import org.cbioportal.legacy.model.Binnable; +import org.cbioportal.legacy.model.ClinicalData; +import org.cbioportal.legacy.model.ClinicalDataBin; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.ClinicalDataCountItem; +import org.cbioportal.legacy.web.columnar.util.NewClinicalDataBinUtil; +import org.cbioportal.legacy.web.parameter.ClinicalDataBinCountFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataBinFilter; +import org.cbioportal.legacy.web.parameter.ClinicalDataType; +import org.cbioportal.legacy.web.parameter.DataBinMethod; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.cbioportal.legacy.web.util.DataBinner; +import org.cbioportal.studyview.StudyViewService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +@Profile("clickhouse") +public class ClinicalDataBinner { + private final StudyViewService studyViewService; + private final DataBinner dataBinner; + + @Autowired + public ClinicalDataBinner( + StudyViewService studyViewService, + DataBinner dataBinner + ) { + this.studyViewService = studyViewService; + this.dataBinner = dataBinner; + } + + private List convertCountsToData(List clinicalDataCounts) + { + return clinicalDataCounts + .stream() + .map(NewClinicalDataBinUtil::generateClinicalDataFromClinicalDataCount) + .flatMap(Collection::stream) + .toList(); + } + + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabled()" + ) + public List fetchClinicalDataBinCounts( + DataBinMethod dataBinMethod, + ClinicalDataBinCountFilter dataBinCountFilter, + boolean shouldRemoveSelfFromFilter + ) { + List attributes = dataBinCountFilter.getAttributes(); + StudyViewFilter studyViewFilter = dataBinCountFilter.getStudyViewFilter(); + + if (shouldRemoveSelfFromFilter) { + studyViewFilter = NewClinicalDataBinUtil.removeSelfFromFilter(dataBinCountFilter); + } + + List attributeIds = attributes.stream().map(ClinicalDataBinFilter::getAttributeId).collect(Collectors.toList()); + + // a new StudyView filter to partially filter by study and sample ids only + // we need this additional partial filter because we always need to know the bins generated for the initial state + // which allows us to keep the number of bins and bin ranges consistent even if there are additional data filters. + // we only want to update the counts for each bin, we don't want to regenerate the bins for the filtered data. + // NOTE: partial filter is only needed when dataBinMethod == DataBinMethod.STATIC but that's always the case + // for the frontend implementation. we can't really use dataBinMethod == DataBinMethod.DYNAMIC because of the + // complication it brings to the frontend visualization and filtering + StudyViewFilter partialFilter = new StudyViewFilter(); + partialFilter.setStudyIds(studyViewFilter.getStudyIds()); + partialFilter.setSampleIdentifiers(studyViewFilter.getSampleIdentifiers()); + + // we need the clinical data for the partial filter in order to generate the bins for initial state + // we use the filtered data to calculate the counts for each bin, we do not regenerate bins for the filtered data + List unfilteredClinicalDataCounts = studyViewService.getClinicalDataCounts(partialFilter, attributeIds); + List filteredClinicalDataCounts = studyViewService.getClinicalDataCounts(studyViewFilter, attributeIds); + + // TODO ignoring conflictingPatientAttributeIds for now + List unfilteredClinicalData = convertCountsToData( + unfilteredClinicalDataCounts.stream().flatMap(c -> c.getCounts().stream()).toList() + ); + List filteredClinicalData = convertCountsToData( + filteredClinicalDataCounts.stream().flatMap(c -> c.getCounts().stream()).toList() + ); + + Map attributeDatatypeMap = studyViewService.getClinicalAttributeDataTypeMap(studyViewFilter); + + Map> unfilteredClinicalDataByAttributeId = + unfilteredClinicalData.stream().collect(Collectors.groupingBy(Binnable::getAttrId)); + + Map> filteredClinicalDataByAttributeId = + filteredClinicalData.stream().collect(Collectors.groupingBy(Binnable::getAttrId)); + + List clinicalDataBins = Collections.emptyList(); + + if (dataBinMethod == DataBinMethod.STATIC) { + if (!unfilteredClinicalData.isEmpty()) { + clinicalDataBins = NewClinicalDataBinUtil.calculateStaticDataBins( + dataBinner, + attributes, + attributeDatatypeMap, + unfilteredClinicalDataByAttributeId, + filteredClinicalDataByAttributeId + ); + } + } + else { // dataBinMethod == DataBinMethod.DYNAMIC + // TODO we should consider removing dynamic binning support + // we never use dynamic binning in the frontend because number of bins and the bin ranges can change + // each time there is a new filter which makes the frontend implementation complicated + if (!filteredClinicalData.isEmpty()) { + clinicalDataBins = NewClinicalDataBinUtil.calculateDynamicDataBins( + dataBinner, + attributes, + attributeDatatypeMap, + filteredClinicalDataByAttributeId + ); + } + } + + return clinicalDataBins; + } +} diff --git a/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java b/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java index 0e93dbbbfa3..5ecde0e555f 100644 --- a/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java +++ b/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java @@ -10,6 +10,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @@ -35,16 +36,17 @@ public void customize(org.apache.ibatis.session.Configuration configuration) { } @Bean("sqlSessionFactory") - @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") + //@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") + @Profile("clickhouse") public SqlSessionFactoryBean sqlSessionFactorySpecifyDataSource(@Qualifier("mysqlDataSource") DataSource dataSource, ApplicationContext applicationContext) throws IOException { return sqlSessionFactory(dataSource, applicationContext); } - @Bean("sqlSessionFactory") - @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "false", matchIfMissing = true) - public SqlSessionFactoryBean sqlSessionFactoryDefault(DataSource dataSource, ApplicationContext applicationContext) throws IOException { - return sqlSessionFactory(dataSource, applicationContext); - } +// @Bean("sqlSessionFactory") +// @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "false", matchIfMissing = true) +// public SqlSessionFactoryBean sqlSessionFactoryDefault(DataSource dataSource, ApplicationContext applicationContext) throws IOException { +// return sqlSessionFactory(dataSource, applicationContext); +// } private SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource, ApplicationContext applicationContext) throws IOException { @@ -58,7 +60,8 @@ private SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource, Applicati } @Bean - @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") + //@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") + @Profile("clickhouse") public DataSourceTransactionManager transactionManager(@Qualifier("mysqlDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } diff --git a/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java b/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java index d2b78d4e4e9..dd8b4c61fc7 100644 --- a/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java +++ b/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java @@ -5,11 +5,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import javax.sql.DataSource; @Configuration -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") +//@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") +@Profile("clickhouse") public class CustomDataSourceConfiguration { @Bean @ConfigurationProperties("spring.datasource.mysql") diff --git a/src/main/java/org/cbioportal/legacy/service/ViolinPlotService.java b/src/main/java/org/cbioportal/legacy/service/ViolinPlotService.java index e3177b33b72..28498e8b351 100644 --- a/src/main/java/org/cbioportal/legacy/service/ViolinPlotService.java +++ b/src/main/java/org/cbioportal/legacy/service/ViolinPlotService.java @@ -7,11 +7,12 @@ import java.math.BigDecimal; import java.util.List; +import java.util.Set; public interface ViolinPlotService { ClinicalViolinPlotData getClinicalViolinPlotData( List sampleClinicalDataForViolinPlot, - List samplesForSampleCounts, + Set samplesForSampleCountsIds, BigDecimal axisStart, BigDecimal axisEnd, BigDecimal numCurvePoints, diff --git a/src/main/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImpl.java b/src/main/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImpl.java index 545edd70595..3bb0666b73c 100644 --- a/src/main/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImpl.java +++ b/src/main/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImpl.java @@ -15,7 +15,13 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; @Service @@ -30,7 +36,7 @@ public class ViolinPlotServiceImpl implements ViolinPlotService { ) public ClinicalViolinPlotData getClinicalViolinPlotData( List sampleClinicalDataForViolinPlot, - List samplesForSampleCounts, + Set samplesForSampleCountsIds, BigDecimal axisStart, BigDecimal axisEnd, BigDecimal numCurvePoints, @@ -43,12 +49,7 @@ public ClinicalViolinPlotData getClinicalViolinPlotData( result.setAxisEnd(Double.NEGATIVE_INFINITY); result.setRows(new ArrayList<>()); - // collect filtered samples into a set for quick lookup - Set samplesForSampleCountsIds = - samplesForSampleCounts.stream() - .map(Sample::getInternalId) - .collect(Collectors.toSet()); - + // clinicalDataMap is a map sampleId->studyId->data Map>> clinicalDataMap = sampleClinicalDataForViolinPlot.stream() .collect(Collectors.groupingBy(ClinicalData::getSampleId, Collectors.groupingBy(ClinicalData::getStudyId))); diff --git a/src/main/java/org/cbioportal/legacy/web/StudyViewController.java b/src/main/java/org/cbioportal/legacy/web/StudyViewController.java index 2db202c5db9..42f526adca6 100644 --- a/src/main/java/org/cbioportal/legacy/web/StudyViewController.java +++ b/src/main/java/org/cbioportal/legacy/web/StudyViewController.java @@ -95,9 +95,12 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import static java.util.stream.Collectors.toSet; + @InternalApi @RestController() @RequestMapping("/api") @@ -856,10 +859,14 @@ public ResponseEntity fetchClinicalDataViolinPlots( boolean useLogScale = logScale && StudyViewController.isLogScalePossibleForAttribute(numericalAttributeId); - + + Set sampleIdsSet = filteredSamples + .stream() + .map(s -> s.getInternalId()) + .collect(toSet()); result = violinPlotService.getClinicalViolinPlotData( sampleClinicalDataList, - filteredSamples, + sampleIdsSet, axisStart, axisEnd, numCurvePoints, diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java b/src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java index 3686d3ad7f6..4750880ee2b 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java @@ -71,8 +71,11 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; +import static java.util.stream.Collectors.toSet; + @InternalApi @RestController() @RequestMapping("/api") @@ -195,7 +198,8 @@ public ResponseEntity> fetchStructuralVariantGenes( } @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils" + + ".security.AccessLevel).READ)") @RequestMapping(value = "/column-store/clinical-data-counts/fetch", method=RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @@ -374,16 +378,21 @@ public ResponseEntity fetchClinicalDataViolinPlots( // Only mutation count can use log scale boolean useLogScale = logScale && numericalAttributeId.equals("MUTATION_COUNT"); - + + Set sampleIdsSet = filteredSamples + .stream() + .map(s -> s.getInternalId()) + .collect(toSet()); + ClinicalViolinPlotData result = violinPlotService.getClinicalViolinPlotData( - combinedClinicalDataList, - filteredSamples, - axisStart, - axisEnd, - numCurvePoints, - useLogScale, - sigmaMultiplier, - interceptedStudyViewFilter + combinedClinicalDataList, + sampleIdsSet, + axisStart, + axisEnd, + numCurvePoints, + useLogScale, + sigmaMultiplier, + interceptedStudyViewFilter ); return new ResponseEntity<>(result, HttpStatus.OK); diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java b/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java index d42bb7e8786..778f5dd0da7 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java @@ -2,14 +2,51 @@ import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; +import org.cbioportal.legacy.web.parameter.MutationOption; +import org.cbioportal.legacy.web.parameter.SampleIdentifier; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; import java.util.List; -public class NewStudyViewFilterUtil { +public abstract class NewStudyViewFilterUtil { + + private NewStudyViewFilterUtil() {} public static void removeClinicalDataFilter(String attributeId, List dataFilterList ) { if (dataFilterList != null) { dataFilterList.removeIf(f -> f.getAttributeId().equals(attributeId)); } } + + public static void removeSelfFromGenomicDataFilter(String hugoGeneSymbol, String profileType, + StudyViewFilter studyViewFilter) { + if (studyViewFilter != null && studyViewFilter.getGenomicDataFilters() != null) { + studyViewFilter.getGenomicDataFilters().removeIf(f -> + f.getHugoGeneSymbol().equals(hugoGeneSymbol) && f.getProfileType().equals(profileType) + ); + } + } + + public static void removeSelfFromGenericAssayFilter(String stableId, StudyViewFilter studyViewFilter) { + if (studyViewFilter != null && studyViewFilter.getGenericAssayDataFilters() != null) { + studyViewFilter.getGenericAssayDataFilters().removeIf(f -> f.getStableId().equals(stableId)); + } + } + + public static void removeSelfFromMutationDataFilter(String hugoGeneSymbol, String profileType, + MutationOption categorization, StudyViewFilter studyViewFilter) { + if (studyViewFilter != null && studyViewFilter.getMutationDataFilters() != null) { + studyViewFilter.getMutationDataFilters().removeIf(f -> + f.getHugoGeneSymbol().equals(hugoGeneSymbol) && + f.getProfileType().equals(profileType) && + f.getCategorization().equals(categorization) + ); + } + } + public static SampleIdentifier buildSampleIdentifier(String studyId, String sampleId) { + SampleIdentifier sampleIdentifier = new SampleIdentifier(); + sampleIdentifier.setStudyId(studyId); + sampleIdentifier.setSampleId(sampleId); + return sampleIdentifier; + } } diff --git a/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java b/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java index d5a371434f2..0e160c6ea25 100644 --- a/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java +++ b/src/main/java/org/cbioportal/legacy/web/parameter/CategorizedGenericAssayDataCountFilter.java @@ -58,6 +58,9 @@ private Builder(){ } private Builder(Map> genericAssayProfilesMap, StudyViewFilter studyViewFilter){ + if ((studyViewFilter.getGenericAssayDataFilters() == null || genericAssayProfilesMap.isEmpty())) { + return ; + } // No BINARY in the database yet if (genericAssayProfilesMap.containsKey(DataSource.SAMPLE)) { diff --git a/src/main/java/org/cbioportal/legacy/web/util/InvolvedCancerStudyExtractorInterceptor.java b/src/main/java/org/cbioportal/legacy/web/util/InvolvedCancerStudyExtractorInterceptor.java index 9cc19225fe2..2ff92a20a2c 100644 --- a/src/main/java/org/cbioportal/legacy/web/util/InvolvedCancerStudyExtractorInterceptor.java +++ b/src/main/java/org/cbioportal/legacy/web/util/InvolvedCancerStudyExtractorInterceptor.java @@ -145,7 +145,7 @@ public class InvolvedCancerStudyExtractorInterceptor implements HandlerIntercept // reset this to 'String requestPathInfo = request.getPathInfo();' String requestPathInfo = request.getPathInfo() == null? request.getServletPath() : request.getPathInfo(); requestPathInfo = requestPathInfo.replaceFirst("^/api", ""); - requestPathInfo = StringUtils.removeStart(requestPathInfo, "/column-store"); + //requestPathInfo = StringUtils.removeStart(requestPathInfo, "/column-store"); if (requestPathInfo.equals(PATIENT_FETCH_PATH)) { return extractAttributesFromPatientFilter(request); } else if (requestPathInfo.equals(SAMPLE_FETCH_PATH)) { diff --git a/src/main/java/org/cbioportal/studyview/StudyViewService.java b/src/main/java/org/cbioportal/studyview/StudyViewService.java index 66800dbd5d2..f354e8afb80 100644 --- a/src/main/java/org/cbioportal/studyview/StudyViewService.java +++ b/src/main/java/org/cbioportal/studyview/StudyViewService.java @@ -186,7 +186,7 @@ public List getClinicalDataForXyPlot(StudyViewFilter studyViewFilt } private StudyViewFilterContext buildStudyViewFilterContext(StudyViewFilter studyViewFilter){ - return StudyViewFilterFactory.make(studyViewFilter,this.customDataFilterUtil, genericAssayProfilesMap); + return StudyViewFilterFactory.make(studyViewFilter,this.customDataFilterUtil, getGenericAssayProfilesMap() ); } private Map> getGenericAssayProfilesMap() { diff --git a/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml b/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml index 6637790a6fa..06c9d462cc8 100644 --- a/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml +++ b/src/main/resources/mappers/clickhouse/alteration/ClickhouseAlterationMapper.xml @@ -17,7 +17,7 @@ variant_type = 'mutation' AND mutation_status != 'UNCALLED' AND - sample_unique_id IN ( ) + @@ -37,7 +37,7 @@ FROM genomic_event_derived variant_type = 'cna' AND - sample_unique_id IN ( ) + @@ -54,7 +54,7 @@ FROM genomic_event_derived variant_type = 'structural_variant' AND - sample_unique_id IN ( ) + GROUP BY entrez_gene_id, hugo_gene_symbol @@ -82,7 +82,7 @@ totalProfiled Count per gene in java. AND - sample_unique_id IN ( ) + GROUP BY gptg.gene @@ -97,7 +97,7 @@ is the case we use the current sample count from the cohort as the totalProfiled stgp.alteration_type = #{alterationType} AND - sample_unique_id IN ( ) + @@ -114,7 +114,7 @@ is the case we use the current sample count from the cohort as the totalProfiled alteration_type = #{alterationType} AND - sample_unique_id IN ( ) + ) @@ -127,7 +127,7 @@ is the case we use the current sample count from the cohort as the totalProfiled alteration_type = #{alterationType} AND gene_panel_id = 'WES' AND - sample_unique_id IN ( ) + diff --git a/src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml b/src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml index c1dc9be8fc5..b3df3a75def 100644 --- a/src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml +++ b/src/main/resources/mappers/clickhouse/clinical_event/ClickhouseClinicalEventMapper.xml @@ -10,7 +10,7 @@ count(DISTINCT patient_unique_id) as count FROM clinical_event_derived - sample_unique_id IN ( ) + GROUP BY event_type diff --git a/src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml b/src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml index 322c963d9d0..e82fa21273e 100644 --- a/src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml +++ b/src/main/resources/mappers/clickhouse/generic_assay/GenericAssayMapper.xml @@ -30,7 +30,7 @@ DISTINCT cancer_study_identifier FROM sample_derived - sample_unique_id IN ( ) + ) SELECT @@ -132,9 +132,10 @@ FROM genetic_profile WHERE patient_level = 1 - + AND stable_id IN - + concat(#{studyId}, '_', #{profileType}) diff --git a/src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml b/src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml index 500995b9e9f..7486f242023 100644 --- a/src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml +++ b/src/main/resources/mappers/clickhouse/patient/ClickhousePatientMapper.xml @@ -12,8 +12,12 @@ + + - SELECT name AS label, REPLACE(stable_id, CONCAT(cancer_study_identifier, '_'), '') AS value, diff --git a/src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml b/src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml index 1b1a0c8cebd..4f3ba5a1421 100644 --- a/src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml +++ b/src/main/resources/mappers/clickhouse/treatment/ClickhouseTreatmentMapper.xml @@ -19,11 +19,30 @@ lower(event_type) = 'treatment' AND key = 'AGENT' AND - + GROUP BY value + + - - patient_unique_id in ( - SELECT patient_unique_id - FROM sample_derived - - sample_unique_id IN () - - ) - \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImplTest.java b/src/test/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImplTest.java index e879097dccb..5e944efd3b7 100644 --- a/src/test/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImplTest.java +++ b/src/test/java/org/cbioportal/legacy/service/impl/ViolinPlotServiceImplTest.java @@ -16,6 +16,7 @@ import java.math.BigDecimal; import java.util.*; +import static java.util.stream.Collectors.toSet; import static org.mockito.ArgumentMatchers.anyList; @RunWith(MockitoJUnitRunner.Silent.class) @@ -72,9 +73,13 @@ public void getClinicalViolinPlotData() throws Exception { } final int NUM_CURVE_POINTS = 100; + Set sampleIdsSet = filteredSamples + .stream() + .map(s -> s.getInternalId()) + .collect(toSet()); ClinicalViolinPlotData result = violinPlotService.getClinicalViolinPlotData( sampleClinicalData, - filteredSamples, + sampleIdsSet, new BigDecimal(0), new BigDecimal(1), new BigDecimal(NUM_CURVE_POINTS), From d10e8799f50f3381f75637422060c2b3409a5a1f Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Mon, 17 Feb 2025 11:29:20 -0500 Subject: [PATCH 3/9] :memo: Add docs for new clickhouse classes --- .../repository/AlterationRepository.java | 58 ++++++++++++++- .../ClinicalAttributesRepository.java | 15 +++- ...tClinicalAttributesDataTypeMapUseCase.java | 15 ++++ ...etClinicalAttributesForStudiesUseCase.java | 17 +++++ .../repository/ClinicalDataRepository.java | 29 +++++++- .../usecase/ClinicalDataUseCases.java | 10 +++ .../usecase/GetClinicalDataCountsUseCase.java | 34 ++++++++- .../GetClinicalDataForXyPlotUseCase.java | 73 +++++++++++++++---- .../GetPatientClinicalDataUseCase.java | 21 +++++- .../usecase/GetSampleClinicalDataUseCase.java | 21 +++++- .../repository/ClinicalEventRepository.java | 10 +++ .../GetClinicalEventTypeCountsUseCase.java | 18 ++++- .../repository/GenericAssayRepository.java | 35 ++++++++- .../usecase/GenericAssayUseCases.java | 11 +++ ...eredMolecularProfilesByAlterationType.java | 28 +++++-- .../usecase/GetGenericAssayDataBinCounts.java | 26 ++++++- .../GetGenericAssayDataCountsUseCase.java | 23 +++++- .../GetGenericAssayProfilesUseCase.java | 15 ++++ .../repository/GenomicDataRepository.java | 51 ++++++++++++- .../usecase/GenomicDataUseCases.java | 11 +++ .../GetCNACountsByGeneSpecificUseCase.java | 20 ++++- .../GetGenomicDataBinCountsUseCase.java | 20 ++++- ...etMolecularProfileSampleCountsUseCase.java | 19 ++++- .../GetMutationCountsByTypeUseCase.java | 21 +++++- .../usecase/GetMutationCountsUseCase.java | 24 +++++- .../ClickhouseAlterationMapper.java | 60 ++++++++++++++- .../ClickhouseClinicalAttributesMapper.java | 18 +++++ .../ClickhouseClinicalDataMapper.java | 30 ++++++++ .../ClickhouseClinicalEventMapper.java | 12 +++ .../ClickhouseGenericAssayMapper.java | 45 ++++++++++-- .../ClickhouseGenomicDataMapper.java | 50 ++++++++++++- .../patient/ClickhousePatientMapper.java | 19 +++++ .../sample/ClickhouseSampleMapper.java | 19 +++++ .../treatment/ClickhouseTreatmentMapper.java | 33 +++++++++ .../patient/repository/PatientRepository.java | 19 +++++ .../usecase/GetCaseListDataCountsUseCase.java | 21 +++++- .../GetFilteredPatientCountUseCase.java | 18 +++++ .../sample/repository/SampleRepository.java | 20 +++++ .../GetFilteredSamplesCountUseCase.java | 18 +++++ .../repository/TreatmentRepository.java | 33 +++++++++ 40 files changed, 986 insertions(+), 54 deletions(-) diff --git a/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java b/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java index 2ec5cef394d..ba7c7c20140 100644 --- a/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java +++ b/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java @@ -10,14 +10,68 @@ import java.util.Set; public interface AlterationRepository { + + /** + * Retrieves a list of mutated genes along with their alteration counts based on the given study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @return A list of {@link AlterationCountByGene} representing mutated genes and their counts. + */ List getMutatedGenes(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves a list of structural variant genes along with their alteration counts based on the given study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @return A list of {@link AlterationCountByGene} representing structural variant genes and their counts. + */ List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves a list of copy number alteration (CNA) genes along with their alteration counts based on the given study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @return A list of {@link CopyNumberCountByGene} representing CNA genes and their counts. + */ List getCnaGenes(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the total number of profiled samples for a specific alteration type based on the given study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param alterationType The type of alteration (e.g., MUTATION, CNA, SV). + * @return The total number of profiled samples for the specified alteration type. + */ int getTotalProfiledCountsByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType); + + /** + * Retrieves the total number of profiled samples categorized by molecular profile and alteration type. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param alterationType The type of alteration (e.g., MUTATION, CNA, SV). + * @param molecularProfiles A list of molecular profiles to consider. + * @return A map where the key is the molecular profile ID and the value is the total count of profiled samples. + */ Map getTotalProfiledCounts(StudyViewFilterContext studyViewFilterContext, - String alterationType, List molecularProfiles); + String alterationType, List molecularProfiles); + + /** + * Retrieves a mapping of alteration types to the corresponding gene panel IDs that match the given study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param alterationType The type of alteration (e.g., MUTATION, CNA, SV). + * @return A map where the key is the alteration type and the value is a set of matching gene panel IDs. + */ Map> getMatchingGenePanelIds(StudyViewFilterContext studyViewFilterContext, String alterationType); - int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType); + /** + * Retrieves the count of sample profiles that do not have associated gene panel data for a given alteration type. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param alterationType The type of alteration (e.g., MUTATION, CNA, SV). + * @return The number of sample profiles without gene panel data for the specified alteration type. + */ + int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType); } + diff --git a/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java b/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java index 1b8462d8e2f..a1a489b7417 100644 --- a/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java +++ b/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java @@ -7,6 +7,19 @@ import java.util.Map; public interface ClinicalAttributesRepository { + + /** + * Retrieves a list of clinical attributes for the specified studies. + * + * @param studyIds A list of study IDs. + * @return A list of {@link ClinicalAttribute} representing the clinical attributes for the given studies. + */ List getClinicalAttributesForStudies(List studyIds); + + /** + * Retrieves a mapping of clinical attribute names to their corresponding data types. + * + * @return A map where the key is the clinical attribute name and the value is the corresponding {@link ClinicalDataType}. + */ Map getClinicalAttributeDatatypeMap(); -} +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java index f355a061829..62410b903a1 100644 --- a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java +++ b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java @@ -9,15 +9,30 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving a mapping of clinical attribute names to their corresponding data types. + * This class interacts with the {@link ClinicalAttributesRepository} to fetch the required data. + */ public class GetClinicalAttributesDataTypeMapUseCase { private final ClinicalAttributesRepository clinicalAttributesRepository; + /** + * Constructs a use case for retrieving the clinical attribute data type map. + * + * @param clinicalAttributesRepository The repository used to fetch clinical attribute data types. + */ public GetClinicalAttributesDataTypeMapUseCase(ClinicalAttributesRepository clinicalAttributesRepository) { this.clinicalAttributesRepository = clinicalAttributesRepository; } + + /** + * Executes the use case to retrieve a mapping of clinical attribute names to their corresponding data types. + * + * @return A map where the key is the clinical attribute name and the value is the corresponding {@link ClinicalDataType}. + */ public Map execute() { return clinicalAttributesRepository.getClinicalAttributeDatatypeMap(); } diff --git a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java index bd218f0fc69..1c5c93ca5f7 100644 --- a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java +++ b/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java @@ -9,14 +9,31 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving clinical attributes for specified studies. + * This class interacts with the {@link ClinicalAttributesRepository} to fetch the required data. + */ public class GetClinicalAttributesForStudiesUseCase { + private final ClinicalAttributesRepository clinicalAttributesRepository; + /** + * Constructs a use case for retrieving clinical attributes for studies. + * + * @param clinicalAttributesRepository The repository used to fetch clinical attributes. + */ public GetClinicalAttributesForStudiesUseCase(ClinicalAttributesRepository clinicalAttributesRepository) { this.clinicalAttributesRepository = clinicalAttributesRepository; } + /** + * Executes the use case to retrieve clinical attributes for the given list of study IDs. + * + * @param studyIds A list of study IDs. + * @return A list of {@link ClinicalAttribute} representing the clinical attributes for the given studies. + */ public List execute(List studyIds){ return clinicalAttributesRepository.getClinicalAttributesForStudies(studyIds); } } + diff --git a/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java b/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java index a6d2883e9ac..610a33f601f 100644 --- a/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java +++ b/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java @@ -6,11 +6,36 @@ import java.util.List; +/** + * Repository interface for retrieving clinical data related to patients and samples. + */ public interface ClinicalDataRepository { + + /** + * Retrieves clinical data for patients based on the given study view filter context and filtered attributes. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param filteredAttributes A list of attributes to filter the clinical data. + * @return A list of {@link ClinicalData} representing patient clinical data. + */ List getPatientClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes); + + /** + * Retrieves clinical data for samples based on the given study view filter context and filtered attributes. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param filteredAttributes A list of attributes to filter the clinical data. + * @return A list of {@link ClinicalData} representing sample clinical data. + */ List getSampleClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes); + + /** + * Retrieves counts of clinical data records based on the given study view filter context and filtered attributes. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param filteredAttributes A list of attributes to filter the clinical data. + * @return A list of {@link ClinicalDataCountItem} representing clinical data counts. + */ List getClinicalDataCounts(StudyViewFilterContext studyViewFilterContext, List filteredAttributes); - - } diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java b/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java index 0edbc1831d0..88884de1cea 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java +++ b/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java @@ -5,6 +5,16 @@ @Service @Profile("clickhouse") +/** + * A record representing a collection of use cases related to clinical data operations. + * This record encapsulates instances of various use case classes, providing a centralized + * way to access and manage clinical data-related operations. + * + * @param getClinicalDataCountsUseCase the use case for retrieving and processing clinical data counts + * @param getClinicalDataForXyPlotUseCase the use case for retrieving clinical data for XY plots + * @param getPatientClinicalDataUseCase the use case for retrieving clinical data for patients + * @param getSampleClinicalDataUseCase the use case for retrieving clinical data for samples + */ public record ClinicalDataUseCases( GetClinicalDataCountsUseCase getClinicalDataCountsUseCase, GetClinicalDataForXyPlotUseCase getClinicalDataForXyPlotUseCase, diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java index 1d82641e894..acbc8713821 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java @@ -14,28 +14,53 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving and processing clinical data counts. + * This class orchestrates the retrieval of clinical data counts from the repository, + * normalizes the data, and ensures that missing attributes are accounted for in the result. + */ public class GetClinicalDataCountsUseCase { + private final ClinicalDataRepository clinicalDataRepository; private final GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase; private final GetFilteredSamplesCountUseCase getFilteredSamplesCountUseCase; private final GetFilteredPatientCountUseCase getFilteredPatientCountUseCase; - - public GetClinicalDataCountsUseCase(ClinicalDataRepository clinicalDataRepository, GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase, GetFilteredSamplesCountUseCase getFilteredSamplesCountUseCase, GetFilteredPatientCountUseCase getFilteredPatientCountUseCase) { + /** + * Constructs a {@code GetClinicalDataCountsUseCase} with the provided use cases and repository. + * + * @param clinicalDataRepository the repository to be used for retrieving clinical data counts + * @param getClinicalAttributesForStudiesUseCase the use case for retrieving clinical attributes for studies + * @param getFilteredSamplesCountUseCase the use case for retrieving filtered sample counts + * @param getFilteredPatientCountUseCase the use case for retrieving filtered patient counts + */ + public GetClinicalDataCountsUseCase( + ClinicalDataRepository clinicalDataRepository, + GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase, + GetFilteredSamplesCountUseCase getFilteredSamplesCountUseCase, + GetFilteredPatientCountUseCase getFilteredPatientCountUseCase) { this.clinicalDataRepository = clinicalDataRepository; this.getClinicalAttributesForStudiesUseCase = getClinicalAttributesForStudiesUseCase; this.getFilteredSamplesCountUseCase = getFilteredSamplesCountUseCase; this.getFilteredPatientCountUseCase = getFilteredPatientCountUseCase; } + /** + * Executes the use case to retrieve and process clinical data counts. + * It normalizes the data counts and ensures that missing attributes are restored. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @param filteredAttributes a list of filtered clinical attribute IDs + * @return a list of {@link ClinicalDataCountItem} containing the normalized and complete clinical data counts + */ public List execute(StudyViewFilterContext studyViewFilterContext, - List filteredAttributes){ + List filteredAttributes) { List involvedCancerStudies = studyViewFilterContext.customDataFilterCancerStudies(); var result = clinicalDataRepository.getClinicalDataCounts(studyViewFilterContext, filteredAttributes); - // normalize data counts so that values like TRUE, True, and true are all merged in one count + // Normalize data counts so that values like TRUE, True, and true are all merged in one count result.forEach(item -> item.setCounts(StudyViewColumnarServiceUtil.normalizeDataCounts(item.getCounts()))); // attributes may be missing in result set because they have been filtered out @@ -62,3 +87,4 @@ public List execute(StudyViewFilterContext studyViewFilte return StudyViewColumnarServiceUtil.mergeClinicalDataCounts(result); } } + diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java index 49312293800..7649db8bd83 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java @@ -15,19 +15,43 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving and combining clinical data for an XY plot. + * This class orchestrates the fetching of clinical data for both patients and samples, + * then combines them based on the provided context and filter options, preparing them for XY plot visualization. + */ public class GetClinicalDataForXyPlotUseCase { + private final GetPatientClinicalDataUseCase getPatientClinicalDataUseCase; private final GetSampleClinicalDataUseCase getSampleClinicalDataUseCase; private final GetFilteredSamplesUseCase getFilteredSamplesUseCase; - public GetClinicalDataForXyPlotUseCase(GetPatientClinicalDataUseCase getPatientClinicalDataUseCase, GetSampleClinicalDataUseCase getSampleClinicalDataUseCase, GetFilteredSamplesUseCase getFilteredSamplesUseCase) { + /** + * Constructs a {@code GetClinicalDataForXyPlotUseCase} with the provided use cases. + * + * @param getPatientClinicalDataUseCase the use case for retrieving patient clinical data + * @param getSampleClinicalDataUseCase the use case for retrieving sample clinical data + * @param getFilteredSamplesUseCase the use case for filtering samples + */ + public GetClinicalDataForXyPlotUseCase( + GetPatientClinicalDataUseCase getPatientClinicalDataUseCase, + GetSampleClinicalDataUseCase getSampleClinicalDataUseCase, + GetFilteredSamplesUseCase getFilteredSamplesUseCase) { this.getPatientClinicalDataUseCase = getPatientClinicalDataUseCase; this.getSampleClinicalDataUseCase = getSampleClinicalDataUseCase; this.getFilteredSamplesUseCase = getFilteredSamplesUseCase; } + /** + * Executes the use case to retrieve and combine clinical data for an XY plot. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @param attributeIds a list of attribute IDs to filter the clinical data + * @param shouldFilterNonEmptyClinicalData flag indicating whether to filter out clinical data with empty values + * @return a list of {@link ClinicalData} ready for XY plot visualization + */ public List execute(StudyViewFilterContext studyViewFilterContext, List attributeIds, - boolean shouldFilterNonEmptyClinicalData){ + boolean shouldFilterNonEmptyClinicalData) { List sampleClinicalDataList = getSampleClinicalDataUseCase.execute(studyViewFilterContext, attributeIds); List patientClinicalDataList = getPatientClinicalDataUseCase.execute(studyViewFilterContext, attributeIds); @@ -41,15 +65,23 @@ public List execute(StudyViewFilterContext studyViewFilterContext, } return combineClinicalDataForXyPlot(sampleClinicalDataList, patientClinicalDataList, samples, shouldFilterNonEmptyClinicalData); - } + /** + * Combines the clinical data for samples and patients into a single list, optionally filtering non-empty data. + * + * @param sampleClinicalDataList a list of clinical data for samples + * @param patientClinicalDataList a list of clinical data for patients + * @param samples a list of samples to map patient data to + * @param shouldFilterNonEmptyClinicalData flag indicating whether to filter out clinical data with empty values + * @return a list of combined {@link ClinicalData} for XY plot visualization + */ private List combineClinicalDataForXyPlot( List sampleClinicalDataList, List patientClinicalDataList, List samples, - boolean shouldFilterNonEmptyClinicalData - ) { + boolean shouldFilterNonEmptyClinicalData) { + List combinedClinicalDataList; if (shouldFilterNonEmptyClinicalData) { @@ -69,6 +101,12 @@ private List combineClinicalDataForXyPlot( return combinedClinicalDataList; } + /** + * Filters out clinical data items with empty attribute values. + * + * @param clinicalData the list of clinical data to filter + * @return a filtered list of {@link ClinicalData} containing only non-empty attribute values + */ private List filterNonEmptyClinicalData(List clinicalData) { return clinicalData .stream() @@ -76,24 +114,31 @@ private List filterNonEmptyClinicalData(List clinica .toList(); } + /** + * Converts patient clinical data into sample clinical data, mapping each patient to their corresponding samples. + * + * @param patientClinicalDataList a list of clinical data for patients + * @param samplesWithoutNumericalFilter a list of samples to map patient data to + * @return a list of {@link ClinicalData} representing the patient's clinical data in sample form + */ private List convertPatientClinicalDataToSampleClinicalData( List patientClinicalDataList, - List samplesWithoutNumericalFilter - ) { + List samplesWithoutNumericalFilter) { + List sampleClinicalDataList = new ArrayList<>(); Map>> patientToSamples = samplesWithoutNumericalFilter .stream() .collect(Collectors.groupingBy( - Sample::patientStableId, + Sample::patientStableId, Collectors.groupingBy(Sample::cancerStudyIdentifier) )); - // put all clinical data into sample form - for (ClinicalData d: patientClinicalDataList) { + // Put all clinical data into sample form + for (ClinicalData d : patientClinicalDataList) { List samplesForPatient = patientToSamples.get(d.getPatientId()).get(d.getStudyId()); if (samplesForPatient != null) { - for (Sample s: samplesForPatient) { + for (Sample s : samplesForPatient) { ClinicalData newData = new ClinicalData(); newData.setInternalId(s.internalId()); @@ -106,13 +151,13 @@ private List convertPatientClinicalDataToSampleClinicalData( sampleClinicalDataList.add(newData); } } else { - // TODO ignoring for now rather than throwing an error + // TODO: Ignoring for now rather than throwing an error // patient has no samples - this shouldn't happen and could affect the integrity - // of the data analysis + // of the data analysis // return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); } } return sampleClinicalDataList; } -} +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java index 40d7f61ab08..897488998ae 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java @@ -10,14 +10,33 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving clinical data for a patient from the repository. + * This class encapsulates the business logic for fetching clinical data based on + * the provided study view filter context and filtered attributes. + */ public class GetPatientClinicalDataUseCase { + private final ClinicalDataRepository clinicalDataRepository; + /** + * Constructs a {@code GetPatientClinicalDataUseCase} with the provided repository. + * + * @param clinicalDataRepository the repository to be used for fetching patient clinical data + */ public GetPatientClinicalDataUseCase(ClinicalDataRepository clinicalDataRepository) { this.clinicalDataRepository = clinicalDataRepository; } - public List execute(StudyViewFilterContext studyViewFilterContext, List filteredAttributes){ + /** + * Executes the use case to retrieve clinical data for a patient. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @param filteredAttributes a list of attributes to filter the clinical data + * @return a list of {@link ClinicalData} representing the patient's clinical data + */ + public List execute(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { return clinicalDataRepository.getPatientClinicalData(studyViewFilterContext, filteredAttributes); } } + diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java b/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java index 0fdeed0b20b..1c850736be9 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java +++ b/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java @@ -10,14 +10,33 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving clinical data for a sample from the repository. + * This class encapsulates the business logic for fetching clinical data based on + * the provided study view filter context and filtered attributes. + */ public class GetSampleClinicalDataUseCase { + private final ClinicalDataRepository clinicalDataRepository; + /** + * Constructs a {@code GetSampleClinicalDataUseCase} with the provided repository. + * + * @param clinicalDataRepository the repository to be used for fetching sample clinical data + */ public GetSampleClinicalDataUseCase(ClinicalDataRepository clinicalDataRepository) { this.clinicalDataRepository = clinicalDataRepository; } - public List execute(StudyViewFilterContext studyViewFilterContext, List filteredAttributes){ + /** + * Executes the use case to retrieve clinical data for a sample. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @param filteredAttributes a list of attributes to filter the clinical data + * @return a list of {@link ClinicalData} representing the sample's clinical data + */ + public List execute(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { return clinicalDataRepository.getSampleClinicalData(studyViewFilterContext, filteredAttributes); } } + diff --git a/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java b/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java index 8d22b780fc1..ffdf0560113 100644 --- a/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java +++ b/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java @@ -5,6 +5,16 @@ import java.util.List; +/** + * Repository interface for retrieving clinical events and related data. + */ public interface ClinicalEventRepository { + + /** + * Retrieves counts of different clinical event types based on the given study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @return A list of {@link ClinicalEventTypeCount} representing the counts of clinical event types. + */ List getClinicalEventTypeCounts(StudyViewFilterContext studyViewFilterContext); } diff --git a/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java b/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java index 0420890eb6f..a826276fed9 100644 --- a/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java +++ b/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java @@ -10,14 +10,30 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving counts of different clinical event types. + * This class interacts with the {@link ClinicalEventRepository} to fetch the required data. + */ public class GetClinicalEventTypeCountsUseCase { + private final ClinicalEventRepository clinicalEventRepository; + /** + * Constructs a use case for retrieving clinical event type counts. + * + * @param clinicalEventRepository The repository used to fetch clinical event type counts. + */ public GetClinicalEventTypeCountsUseCase(ClinicalEventRepository clinicalEventRepository) { this.clinicalEventRepository = clinicalEventRepository; } + /** + * Executes the use case to retrieve counts of different clinical event types based on the study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @return A list of {@link ClinicalEventTypeCount} representing the counts of clinical event types. + */ public List execute(StudyViewFilterContext studyViewFilterContext){ return this.clinicalEventRepository.getClinicalEventTypeCounts(studyViewFilterContext); } -} +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java b/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java index e222b4352f1..56c7dc9f9dd 100644 --- a/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java +++ b/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java @@ -9,12 +9,45 @@ import java.util.List; +/** + * Repository interface for retrieving molecular profiles and assay-related data. + */ public interface GenericAssayRepository { + + /** + * Retrieves all generic assay molecular profiles. + * + * @return A list of {@link MolecularProfile} representing generic assay profiles. + */ List getGenericAssayProfiles(); + + /** + * Retrieves molecular profiles filtered by alteration type based on the study view filter context. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param alterationType The type of alteration to filter the molecular profiles. + * @return A list of {@link MolecularProfile} matching the criteria. + */ List getFilteredMolecularProfilesByAlterationType(StudyViewFilterContext studyViewFilterContext, - String alterationType); + String alterationType); + + /** + * Retrieves bin counts for generic assay data based on the study view filter context and specified bin filters. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param genericAssayDataBinFilters A list of bin filters to apply to the assay data. + * @return A list of {@link ClinicalDataCount} representing bin counts for the generic assay data. + */ List getGenericAssayDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataBinFilters); + + /** + * Retrieves counts for generic assay data based on the study view filter context and specified data filters. + * + * @param studyViewFilterContext The filter criteria for the study view. + * @param genericAssayDataFilters A list of data filters to apply to the assay data. + * @return A list of {@link GenericAssayDataCountItem} representing assay data counts. + */ List getGenericAssayDataCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataFilters); } diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java b/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java index 0f5ed4b980e..18364c8e0df 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java @@ -5,6 +5,17 @@ @Service @Profile("clickhouse") +/** + * A record representing a collection of use cases related to generic assay data operations. + * This record encapsulates instances of various use case classes, providing a centralized + * way to access and manage them. + * + * @param getFilteredMolecularProfilesByAlterationType the use case for retrieving molecular profiles + * filtered by alteration type. + * @param getGenericAssayDataBinCounts the use case for retrieving binned counts of generic assay data. + * @param getGenericAssayDataCountsUseCase the use case for retrieving counts of generic assay data. + * @param getGenericAssayProfilesUseCase the use case for retrieving generic assay profiles. + */ public record GenericAssayUseCases( GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType, GetGenericAssayDataBinCounts getGenericAssayDataBinCounts, diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java index 873ccad186c..67c8f5ea889 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java @@ -10,18 +10,36 @@ @Service @Profile("clickhouse") +/** + * A use case class responsible for retrieving molecular profiles filtered by a specific alteration type. + * This class acts as an intermediary between the application logic and the data repository, + * delegating the data retrieval to the {@link GenericAssayRepository}. + */ public class GetFilteredMolecularProfilesByAlterationType { - private final GenericAssayRepository genericAssayRepository; + /** + * Constructs a new instance of {@link GetFilteredMolecularProfilesByAlterationType}. + * + * @param genericAssayRepository the repository used to access molecular profile data. + * Must not be {@code null}. + */ public GetFilteredMolecularProfilesByAlterationType(GenericAssayRepository genericAssayRepository) { this.genericAssayRepository = genericAssayRepository; } - - public List excute(StudyViewFilterContext studyViewFilterContext, - String alterationType) { + /** + * Executes the use case to retrieve molecular profiles filtered by a specific alteration type. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param alterationType the type of alteration used to filter molecular profiles. + * Must not be {@code null}. + * @return a list of {@link MolecularProfile} objects representing the molecular profiles + * that match the provided alteration type. The list may be empty if no profiles match the criteria. + */ + public List execute(StudyViewFilterContext studyViewFilterContext, + String alterationType) { return genericAssayRepository.getFilteredMolecularProfilesByAlterationType(studyViewFilterContext, alterationType); } - } diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java index 67f589093a5..e4773c5b0c3 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java @@ -11,14 +11,36 @@ @Service @Profile("clickhouse") +/** + * A use case class responsible for retrieving binned counts of generic assay data based on the provided filters. + * This class acts as an intermediary between the application logic and the data repository, + * delegating the data retrieval to the {@link GenericAssayRepository}. + */ public class GetGenericAssayDataBinCounts { private final GenericAssayRepository genericAssayRepository; + + /** + * Constructs a new instance of {@link GetGenericAssayDataBinCounts}. + * + * @param genericAssayRepository the repository used to access generic assay data. + * Must not be {@code null}. + */ public GetGenericAssayDataBinCounts(GenericAssayRepository genericAssayRepository) { this.genericAssayRepository = genericAssayRepository; } + /** + * Executes the use case to retrieve binned counts of generic assay data based on the provided filters. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param genericAssayDataBinFilters a list of filters to apply to the generic assay data for binning. + * Must not be {@code null}. + * @return a list of {@link ClinicalDataCount} objects representing the binned counts of generic assay data + * that match the provided filters. The list may be empty if no data matches the filters. + */ public List execute(StudyViewFilterContext studyViewFilterContext, - List genericAssayDataBinFilters){ + List genericAssayDataBinFilters) { return genericAssayRepository.getGenericAssayDataBinCounts(studyViewFilterContext, genericAssayDataBinFilters); } -} +} \ No newline at end of file diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java index faf6a12ebc6..77c74ab6e16 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java @@ -11,15 +11,36 @@ @Service @Profile("clickhouse") +/** + * A use case class responsible for retrieving counts of generic assay data based on the provided filters. + * This class acts as an intermediary between the application logic and the data repository, + * delegating the data retrieval to the {@link GenericAssayRepository}. + */ public class GetGenericAssayDataCountsUseCase { private final GenericAssayRepository genericAssayRepository; + /** + * Constructs a new instance of {@link GetGenericAssayDataCountsUseCase}. + * + * @param genericAssayRepository the repository used to access generic assay data. + * Must not be {@code null}. + */ public GetGenericAssayDataCountsUseCase(GenericAssayRepository genericAssayRepository) { this.genericAssayRepository = genericAssayRepository; } + /** + * Executes the use case to retrieve counts of generic assay data based on the provided filters. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param genericAssayDataFilters a list of filters to apply to the generic assay data. + * Must not be {@code null}. + * @return a list of {@link GenericAssayDataCountItem} objects representing the counts of generic assay data + * that match the provided filters. The list may be empty if no data matches the filters. + */ public List execute(StudyViewFilterContext studyViewFilterContext, - List genericAssayDataFilters){ + List genericAssayDataFilters) { return genericAssayRepository.getGenericAssayDataCounts(studyViewFilterContext, genericAssayDataFilters); } } diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java index cc8b59b687b..53747dce590 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java +++ b/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java @@ -9,13 +9,28 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving generic assay molecular profiles. + * This class interacts with the {@link GenericAssayRepository} to fetch the required data. + */ public class GetGenericAssayProfilesUseCase { + private final GenericAssayRepository repository; + /** + * Constructs a use case for retrieving generic assay profiles. + * + * @param repository The repository used to fetch generic assay profiles. + */ public GetGenericAssayProfilesUseCase(GenericAssayRepository repository) { this.repository = repository; } + /** + * Executes the use case to retrieve all generic assay profiles. + * + * @return A list of {@link MolecularProfile} representing generic assay profiles. + */ public List execute() { return repository.getGenericAssayProfiles(); } diff --git a/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java b/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java index e7aff66384f..1ae329542fe 100644 --- a/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java +++ b/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java @@ -10,15 +10,64 @@ import java.util.List; import java.util.Map; +/** + * An interface defining the contract for a repository that provides access to genomic data. + * This repository is responsible for retrieving various types of genomic data counts and statistics. + */ public interface GenomicDataRepository { + + /** + * Retrieves the sample counts for molecular profiles based on the provided study view filter context. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @return a list of {@link GenomicDataCount} objects representing the sample counts for molecular profiles. + */ List getMolecularProfileSampleCounts(StudyViewFilterContext studyViewFilterContext); + /** + * Retrieves binned genomic data counts based on the provided study view filter context and bin filters. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param genomicDataBinFilters a list of filters to apply to the genomic data for binning. + * Must not be {@code null}. + * @return a list of {@link ClinicalDataCount} objects representing the binned genomic data counts. + */ List getGenomicDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genomicDataBinFilters); + /** + * Retrieves copy number alteration (CNA) counts based on the provided study view filter context and genomic data filters. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param genomicDataFilters a list of filters to apply to the genomic data. + * Must not be {@code null}. + * @return a list of {@link GenomicDataCountItem} objects representing the CNA counts. + */ List getCNACounts(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); + + /** + * Retrieves mutation counts based on the provided study view filter context and mutation filters. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param mutationFilters the filter to apply to the mutation data. + * Must not be {@code null}. + * @return a map where the key is a string representing a mutation type and the value is the count of mutations. + */ Map getMutationCounts(StudyViewFilterContext studyViewFilterContext, GenomicDataFilter mutationFilters); + + /** + * Retrieves mutation counts grouped by mutation type based on the provided study view filter context and genomic data filters. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param genomicDataFilters a list of filters to apply to the genomic data. + * Must not be {@code null}. + * @return a list of {@link GenomicDataCountItem} objects representing the mutation counts by type. + */ List getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); - } diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java b/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java index 03653b6b811..342176ea9ea 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java @@ -5,6 +5,17 @@ @Service @Profile("clickhouse") +/** + * A record representing a collection of use cases related to genomic data operations. + * This record encapsulates instances of various genomic data use cases, providing a centralized + * way to access and manage them. + * + * @param getCNACountsByGeneSpecificUseCase the use case for retrieving CNA counts by gene-specific data. + * @param getGenomicDataBinCountsUseCase the use case for retrieving genomic data bin counts. + * @param getMolecularProfileSampleCountsUseCase the use case for retrieving molecular profile sample counts. + * @param getMutationCountsByTypeUseCase the use case for retrieving mutation counts by type. + * @param getMutationCountsUseCase the use case for retrieving mutation counts. + */ public record GenomicDataUseCases( GetCNACountsByGeneSpecificUseCase getCNACountsByGeneSpecificUseCase, GetGenomicDataBinCountsUseCase getGenomicDataBinCountsUseCase, diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java index 6a49f96e521..1f3f7e15de1 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java @@ -11,16 +11,34 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving CNA counts by gene-specific data from the repository. + * This class encapsulates the business logic for fetching CNA counts based on + * the provided study view filter context and genomic data filters. + */ public class GetCNACountsByGeneSpecificUseCase { private final GenomicDataRepository repository; + /** + * Constructs a {@code GetCNACountsByGeneSpecificUseCase} with the provided repository. + * + * @param repository the repository to be used for fetching CNA counts by gene-specific data + */ public GetCNACountsByGeneSpecificUseCase(GenomicDataRepository repository) { this.repository = repository; } + /** + * Executes the use case to retrieve CNA counts by gene-specific data. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @param genomicDataFilters a list of genomic data filters to apply + * @return a list of {@link GenomicDataCountItem} representing the CNA counts by gene + */ public List execute(StudyViewFilterContext studyViewFilterContext, - List genomicDataFilters){ + List genomicDataFilters) { return repository.getCNACounts(studyViewFilterContext, genomicDataFilters); } } + diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java index a0433a17d5a..78a4a2a24eb 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java @@ -11,15 +11,33 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving genomic data bin counts from the repository. + * This class encapsulates the business logic for fetching genomic data + * bin counts based on the provided study view filter context and genomic data filters. + */ public class GetGenomicDataBinCountsUseCase { + private final GenomicDataRepository genomicDataRepository; + /** + * Constructs a {@code GetGenomicDataBinCountsUseCase} with the provided repository. + * + * @param genomicDataRepository the repository to be used for fetching genomic data bin counts + */ public GetGenomicDataBinCountsUseCase(GenomicDataRepository genomicDataRepository) { this.genomicDataRepository = genomicDataRepository; } + /** + * Executes the use case to retrieve genomic data bin counts. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @param genomicDataFilters a list of genomic data bin filters to apply + * @return a list of {@link ClinicalDataCount} representing the genomic data bin counts + */ public List execute(StudyViewFilterContext studyViewFilterContext, - List genomicDataFilters){ + List genomicDataFilters) { return genomicDataRepository.getGenomicDataBinCounts(studyViewFilterContext, genomicDataFilters); } } diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java index f413a68b390..ba3d700f963 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java @@ -11,14 +11,31 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving molecular profile sample counts from the repository. + * This class encapsulates the business logic for fetching molecular profile + * sample counts and merging them into a final result. + */ public class GetMolecularProfileSampleCountsUseCase { + private final GenomicDataRepository genomicDataRepository; + /** + * Constructs a {@code GetMolecularProfileSampleCountsUseCase} with the provided repository. + * + * @param genomicDataRepository the repository to be used for fetching molecular profile sample counts + */ public GetMolecularProfileSampleCountsUseCase(GenomicDataRepository genomicDataRepository) { this.genomicDataRepository = genomicDataRepository; } - public List execute(StudyViewFilterContext studyViewFilterContext){ + /** + * Executes the use case to retrieve and merge molecular profile sample counts. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @return a list of {@link GenomicDataCount} representing the molecular profile sample counts + */ + public List execute(StudyViewFilterContext studyViewFilterContext) { return StudyViewColumnarServiceUtil.mergeGenomicDataCounts(genomicDataRepository.getMolecularProfileSampleCounts(studyViewFilterContext)); } } diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java index 9f75e2bc1f6..a051519a8f8 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java @@ -11,15 +11,34 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving mutation counts by type from the repository. + * This class encapsulates the business logic for fetching mutation counts + * based on the provided study view filter context and genomic data filters. + */ public class GetMutationCountsByTypeUseCase { private final GenomicDataRepository repository; + + /** + * Constructs a {@code GetMutationCountsByTypeUseCase} with the provided repository. + * + * @param repository the repository to be used for fetching mutation counts + */ public GetMutationCountsByTypeUseCase(GenomicDataRepository repository) { this.repository = repository; } + /** + * Executes the use case to retrieve mutation counts by type. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @param genomicDataFilters a list of genomic data filters to apply + * @return a list of {@link GenomicDataCountItem} representing the mutation counts by type + */ public List execute(StudyViewFilterContext studyViewFilterContext, - List genomicDataFilters){ + List genomicDataFilters) { return repository.getMutationCountsByType(studyViewFilterContext, genomicDataFilters); } } + diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java index 71d02a0491f..46b4961c2d1 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java +++ b/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java @@ -10,16 +10,36 @@ @Service @Profile("clickhouse") +/** + * A use case class responsible for retrieving mutation counts based on the provided study view filter context + * and genomic data filter. This class acts as an intermediary between the application logic and the data repository, + * delegating the data retrieval to the {@link GenomicDataRepository}. + */ public class GetMutationCountsUseCase { private final GenomicDataRepository repository; - + /** + * Constructs a new instance of {@link GetMutationCountsUseCase}. + * + * @param repository the repository used to access genomic data. + * Must not be {@code null}. + */ public GetMutationCountsUseCase(GenomicDataRepository repository) { this.repository = repository; } + /** + * Executes the use case to retrieve mutation counts based on the provided study view filter context + * and genomic data filter. + * + * @param studyViewFilterContext the context containing study view filter criteria. + * Must not be {@code null}. + * @param genomicDataFilter the filter to apply to the genomic data for retrieving mutation counts. + * Must not be {@code null}. + * @return a map where the key is a string representing a mutation type and the value is the count of mutations. + */ public Map execute(StudyViewFilterContext studyViewFilterContext, - GenomicDataFilter genomicDataFilter){ + GenomicDataFilter genomicDataFilter) { return repository.getMutationCounts(studyViewFilterContext, genomicDataFilter); } } diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java index 63745e1ed30..38d77f8abfd 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java @@ -9,17 +9,75 @@ import java.util.List; +/** + * Mapper interface for retrieving alteration-related data from ClickHouse. + * This interface provides methods for fetching mutated gene counts, copy number alteration counts, + * structural variant gene counts, and more, based on the provided study view filter context and alteration filters. + */ public interface ClickhouseAlterationMapper { + + /** + * Retrieves mutated gene counts based on the study view filter context and alteration filter. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationFilterHelper the helper for applying alteration filters + * @return a list of mutated genes with their respective counts + */ List getMutatedGenes(StudyViewFilterContext studyViewFilterContext, AlterationFilterHelper alterationFilterHelper); + /** + * Retrieves copy number alteration (CNA) gene counts based on the study view filter context and alteration filter. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationFilterHelper the helper for applying alteration filters + * @return a list of CNA genes with their respective counts + */ List getCnaGenes(StudyViewFilterContext studyViewFilterContext, AlterationFilterHelper alterationFilterHelper); + /** + * Retrieves structural variant gene counts based on the study view filter context and alteration filter. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationFilterHelper the helper for applying alteration filters + * @return a list of structural variant genes with their respective counts + */ List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext, AlterationFilterHelper alterationFilterHelper); + /** + * Retrieves the total profiled count for a given alteration type. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationType the type of alteration (e.g., mutation, CNA, etc.) + * @return the total profiled count for the given alteration type + */ int getTotalProfiledCountByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType); + + /** + * Retrieves the matching gene panel IDs for a given alteration type. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationType the type of alteration (e.g., mutation, CNA, etc.) + * @return a list of matching gene panel IDs + */ List getMatchingGenePanelIds(StudyViewFilterContext studyViewFilterContext, String alterationType); + + /** + * Retrieves the total profiled counts for a given alteration type and molecular profiles. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationType the type of alteration (e.g., mutation, CNA, etc.) + * @param molecularProfiles the list of molecular profiles to be considered + * @return a list of alteration counts by gene + */ List getTotalProfiledCounts(StudyViewFilterContext studyViewFilterContext, String alterationType, List molecularProfiles); - int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType); + /** + * Retrieves the sample profile count without panel data for a given alteration type. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationType the type of alteration (e.g., mutation, CNA, etc.) + * @return the sample profile count without panel data + */ + int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType); } diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java index 38ba7be55bc..41a97b85bf5 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesMapper.java @@ -4,7 +4,25 @@ import java.util.List; +/** + * Mapper interface for retrieving clinical attributes data from ClickHouse. + * This interface provides methods to fetch clinical attributes either globally or for specific studies. + */ public interface ClickhouseClinicalAttributesMapper { + + /** + * Retrieves the list of all clinical attributes. + * + * @return a list of clinical attributes + */ List getClinicalAttributes(); + + /** + * Retrieves the list of clinical attributes for the specified study IDs. + * + * @param studyIds the list of study IDs to filter by + * @return a list of clinical attributes for the given studies + */ List getClinicalAttributesForStudies(List studyIds); } + diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java index 9f6fa913ae5..14ec4815508 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java @@ -6,8 +6,38 @@ import java.util.List; +/** + * Mapper interface for retrieving clinical data from ClickHouse. + * This interface provides methods to fetch clinical data counts and clinical data for samples and patients. + */ public interface ClickhouseClinicalDataMapper { + + /** + * Retrieves clinical data counts based on the study view filter context, attribute IDs, and filtered attribute values. + * + * @param studyViewFilterContext the context of the study view filter + * @param attributeIds the list of attribute IDs to filter by + * @param filteredAttributeValues the list of filtered attribute values + * @return a list of clinical data count items + */ List getClinicalDataCounts(StudyViewFilterContext studyViewFilterContext, List attributeIds, List filteredAttributeValues); + + /** + * Retrieves sample clinical data based on the study view filter context and attribute IDs. + * + * @param studyViewFilterContext the context of the study view filter + * @param attributeIds the list of attribute IDs to filter by + * @return a list of sample clinical data + */ List getSampleClinicalDataFromStudyViewFilter(StudyViewFilterContext studyViewFilterContext, List attributeIds); + + /** + * Retrieves patient clinical data based on the study view filter context and attribute IDs. + * + * @param studyViewFilterContext the context of the study view filter + * @param attributeIds the list of attribute IDs to filter by + * @return a list of patient clinical data + */ List getPatientClinicalDataFromStudyViewFilter(StudyViewFilterContext studyViewFilterContext, List attributeIds); } + diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java index 51954ee4a33..188a70bffea 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java @@ -6,6 +6,18 @@ import java.util.List; +/** + * Mapper interface for retrieving clinical event type data from ClickHouse. + * This interface provides a method to fetch clinical event type counts based on the study view filter context. + */ public interface ClickhouseClinicalEventMapper { + + /** + * Retrieves the clinical event type counts based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return a list of clinical event type counts + */ List getClinicalEventTypeCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); } + diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java index 66d9f60c620..593864b6c08 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java @@ -9,12 +9,45 @@ import java.util.List; +/** + * Mapper interface for retrieving generic assay data from ClickHouse. + * This interface provides methods to fetch molecular profiles and generic assay data counts, + * as well as filtered molecular profiles by alteration type. + */ public interface ClickhouseGenericAssayMapper { + + /** + * Retrieves the list of molecular profiles from the generic assay data. + * + * @return a list of molecular profiles + */ List getGenericAssayProfiles(); - List getFilteredMolecularProfilesByAlterationType(StudyViewFilterContext studyViewFilterContext, - String alterationType); - List getGenericAssayDataBinCounts(StudyViewFilterContext studyViewFilterContext, - List genericAssayDataBinFilters); - List getGenericAssayDataCounts(StudyViewFilterContext studyViewFilterContext, - List genericAssayDataFilters); + + /** + * Retrieves the filtered molecular profiles based on the study view filter context and alteration type. + * + * @param studyViewFilterContext the context of the study view filter + * @param alterationType the alteration type (e.g., mutation, CNA) + * @return a list of filtered molecular profiles + */ + List getFilteredMolecularProfilesByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType); + + /** + * Retrieves the generic assay data bin counts based on the study view filter context and the provided bin filters. + * + * @param studyViewFilterContext the context of the study view filter + * @param genericAssayDataBinFilters the list of bin filters + * @return a list of generic assay data bin counts + */ + List getGenericAssayDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataBinFilters); + + /** + * Retrieves the generic assay data counts based on the study view filter context and the provided data filters. + * + * @param studyViewFilterContext the context of the study view filter + * @param genericAssayDataFilters the list of data filters + * @return a list of generic assay data counts + */ + List getGenericAssayDataCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataFilters); } + diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java index 59053c5fa2e..1d3d8c339b3 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java @@ -11,12 +11,56 @@ import java.util.List; import java.util.Map; +/** + * Mapper interface for retrieving genomic data from ClickHouse. + * This interface provides methods to fetch genomic data counts, including mutation counts and CNAs, + * based on the study view filter context and genomic data filters. + */ public interface ClickhouseGenomicDataMapper { + + /** + * Retrieves the molecular profile sample counts based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return a list of genomic data counts by molecular profile + */ List getMolecularProfileSampleCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the genomic data bin counts based on the study view filter context and genomic data bin filters. + * + * @param studyViewFilterContext the context of the study view filter + * @param genomicDataBinFilters the list of genomic data bin filters + * @return a list of genomic data bin counts + */ List getGenomicDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genomicDataBinFilters); + + /** + * Retrieves CNAs counts based on the study view filter context and genomic data filters. + * + * @param studyViewFilterContext the context of the study view filter + * @param genomicDataFilters the list of genomic data filters + * @return a list of CNA counts + */ List getCNACounts(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); - Map getMutationCounts(StudyViewFilterContext studyViewFilterContext, - GenomicDataFilter genomicDataFilter); - List getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); + /** + * Retrieves mutation counts based on the study view filter context and genomic data filter. + * + * @param studyViewFilterContext the context of the study view filter + * @param genomicDataFilter the genomic data filter + * @return a map of mutation counts by gene + */ + Map getMutationCounts(StudyViewFilterContext studyViewFilterContext, GenomicDataFilter genomicDataFilter); + + /** + * Retrieves mutation counts by type based on the study view filter context and genomic data filters. + * + * @param studyViewFilterContext the context of the study view filter + * @param genomicDataFilters the list of genomic data filters + * @return a list of mutation counts by type + */ + List getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters); } + + diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java index fe6fc4fcc0e..d3822e0191d 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java @@ -6,7 +6,26 @@ import java.util.List; +/** + * Mapper interface for retrieving patient data from ClickHouse. + * This interface provides methods for fetching patient counts and case list data counts. + */ public interface ClickhousePatientMapper { + + /** + * Retrieves the patient count based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return the patient count + */ int getPatientCount(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves case list data counts based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return a list of case list data counts + */ List getCaseListDataCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); } + diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java index 3a34c1d7176..82c2af551ca 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java @@ -6,7 +6,26 @@ import java.util.List; +/** + * Mapper interface for retrieving sample data from ClickHouse. + * This interface provides methods for fetching filtered samples and sample counts based on the study view filter context. + */ public interface ClickhouseSampleMapper { + + /** + * Retrieves filtered samples based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return a list of filtered samples + */ List getFilteredSamples(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the sample count based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return the sample count + */ int getSampleCount(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); } + diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java index afdce64b1bb..3744807c420 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java @@ -7,9 +7,42 @@ import java.util.List; +/** + * Mapper interface for retrieving treatment-related data from ClickHouse. + * This interface provides methods to fetch patient treatments, sample treatment counts, and more. + */ public interface ClickhouseTreatmentMapper { + + /** + * Retrieves patient treatments based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return a list of patient treatments + */ List getPatientTreatments(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the patient treatment counts based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return the patient treatment count + */ int getPatientTreatmentCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves sample treatment counts based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return a list of sample treatment counts + */ List getSampleTreatmentCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the total sample treatment counts based on the study view filter context. + * + * @param studyViewFilterContext the context of the study view filter + * @return the total sample treatment count + */ int getTotalSampleTreatmentCounts(@Param("studyViewFilterContext") StudyViewFilterContext studyViewFilterContext); } + diff --git a/src/main/java/org/cbioportal/patient/repository/PatientRepository.java b/src/main/java/org/cbioportal/patient/repository/PatientRepository.java index 8bd6b923de5..3b73e889ccd 100644 --- a/src/main/java/org/cbioportal/patient/repository/PatientRepository.java +++ b/src/main/java/org/cbioportal/patient/repository/PatientRepository.java @@ -5,7 +5,26 @@ import java.util.List; +/** + * Repository interface for performing operations related to patient data. + * This interface defines methods for retrieving filtered patient counts and case list data counts. + */ public interface PatientRepository { + + /** + * Retrieves the count of filtered patients based on the provided study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return the count of patients that match the filter criteria + */ int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the case list data counts based on the provided study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return a list of {@link CaseListDataCount} representing the counts of case list data + */ List getCaseListDataCounts(StudyViewFilterContext studyViewFilterContext); } + diff --git a/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java b/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java index 53c4c3fcb3d..e42f08f2644 100644 --- a/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java +++ b/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java @@ -10,15 +10,32 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving case list data counts. + * This class interacts with the {@link PatientRepository} to fetch the case list data counts + * based on the filter criteria specified in the study view filter context. + */ public class GetCaseListDataCountsUseCase { private final PatientRepository patientRepository; + /** + * Constructs a {@code GetCaseListDataCountsUseCase} with the provided {@link PatientRepository}. + * + * @param patientRepository the repository to be used for retrieving the case list data counts + */ public GetCaseListDataCountsUseCase(PatientRepository patientRepository) { this.patientRepository = patientRepository; } - public List execute(StudyViewFilterContext studyViewFilterContext){ - return patientRepository.getCaseListDataCounts(studyViewFilterContext); + /** + * Executes the use case to retrieve the case list data counts based on the given study view filter context. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @return a list of {@link CaseListDataCount} representing the counts of case list data + */ + public List execute(StudyViewFilterContext studyViewFilterContext) { + return patientRepository.getCaseListDataCounts(studyViewFilterContext); } } + diff --git a/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java b/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java index 7fc6f85c5e5..175f65cf531 100644 --- a/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java +++ b/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java @@ -7,14 +7,32 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving the count of filtered patients. + * This class interacts with the {@link PatientRepository} to fetch the number of patients + * that match the given filter criteria specified in the study view filter context. + */ public class GetFilteredPatientCountUseCase { + private final PatientRepository patientRepository; + /** + * Constructs a {@code GetFilteredPatientCountUseCase} with the provided {@link PatientRepository}. + * + * @param patientRepository the repository to be used for retrieving the filtered patient count + */ public GetFilteredPatientCountUseCase(PatientRepository patientRepository) { this.patientRepository = patientRepository; } + /** + * Executes the use case to retrieve the count of filtered patients based on the given study view filter context. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @return the count of filtered patients + */ public int execute(StudyViewFilterContext studyViewFilterContext) { return patientRepository.getFilteredPatientCount(studyViewFilterContext); } } + diff --git a/src/main/java/org/cbioportal/sample/repository/SampleRepository.java b/src/main/java/org/cbioportal/sample/repository/SampleRepository.java index 0610b094904..88f0749a4d5 100644 --- a/src/main/java/org/cbioportal/sample/repository/SampleRepository.java +++ b/src/main/java/org/cbioportal/sample/repository/SampleRepository.java @@ -5,7 +5,27 @@ import java.util.List; +/** + * Repository interface for performing operations related to sample data. + * This interface defines methods for retrieving filtered samples and their respective counts + * based on the filter criteria provided in the study view filter context. + */ public interface SampleRepository { + + /** + * Retrieves the samples that match the filter criteria specified in the study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return a list of {@link Sample} representing the samples that match the filter criteria + */ List getFilteredSamples(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the total count of samples that match the filter criteria specified in the study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return the total count of filtered samples + */ int getFilteredSamplesCount(StudyViewFilterContext studyViewFilterContext); } + diff --git a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java b/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java index 5a0672c0e9f..a7e18b1d207 100644 --- a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java +++ b/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java @@ -8,14 +8,32 @@ @Service @Profile("clickhouse") +/** + * Use case for retrieving the count of filtered samples. + * This class interacts with the {@link SampleRepository} to fetch the number of samples + * that match the given filter criteria specified in the study view filter context. + */ public class GetFilteredSamplesCountUseCase { + private final SampleRepository sampleRepository; + /** + * Constructs a {@code GetFilteredSamplesCountUseCase} with the provided {@link SampleRepository}. + * + * @param sampleRepository the repository to be used for retrieving the filtered samples count + */ public GetFilteredSamplesCountUseCase(SampleRepository sampleRepository) { this.sampleRepository = sampleRepository; } + /** + * Executes the use case to retrieve the count of filtered samples based on the given study view filter context. + * + * @param studyViewFilterContext the context of the study view filter to apply + * @return the count of filtered samples + */ public int execute(StudyViewFilterContext studyViewFilterContext) { return sampleRepository.getFilteredSamplesCount(studyViewFilterContext); } } + diff --git a/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java b/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java index 8a2403ca49a..283c710ac78 100644 --- a/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java +++ b/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java @@ -6,9 +6,42 @@ import java.util.List; +/** + * Repository interface for performing operations related to patient and sample treatments. + * This interface defines methods for retrieving patient treatments, sample treatments, + * and their respective total counts based on the filter criteria provided in the study view filter context. + */ public interface TreatmentRepository { + + /** + * Retrieves the treatments associated with patients based on the provided study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return a list of {@link PatientTreatment} representing the treatments for patients + */ List getPatientTreatments(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the total count of patient treatments based on the provided study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return the total count of patient treatments + */ int getTotalPatientTreatmentCount(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the treatments associated with samples based on the provided study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return a list of {@link SampleTreatment} representing the treatments for samples + */ List getSampleTreatments(StudyViewFilterContext studyViewFilterContext); + + /** + * Retrieves the total count of sample treatments based on the provided study view filter context. + * + * @param studyViewFilterContext the context containing the filter criteria for the study view + * @return the total count of sample treatments + */ int getTotalSampleTreatmentCount(StudyViewFilterContext studyViewFilterContext); } From b02add9c84086bc4c40fa85dc15299e0aa200c36 Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Mon, 17 Feb 2025 15:47:15 -0500 Subject: [PATCH 4/9] add ability to extract study ids without involvedCancerStudy interceptor --- .../CancerStudyPermissionEvaluator.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/main/java/org/cbioportal/application/security/CancerStudyPermissionEvaluator.java b/src/main/java/org/cbioportal/application/security/CancerStudyPermissionEvaluator.java index d92ecd70a5d..d49b8a2f9a5 100644 --- a/src/main/java/org/cbioportal/application/security/CancerStudyPermissionEvaluator.java +++ b/src/main/java/org/cbioportal/application/security/CancerStudyPermissionEvaluator.java @@ -42,6 +42,11 @@ import org.cbioportal.legacy.model.SampleList; import org.cbioportal.legacy.persistence.cachemaputil.CacheMapUtil; import org.cbioportal.legacy.utils.security.AccessLevel; +import org.cbioportal.legacy.web.parameter.ClinicalDataCountFilter; +import org.cbioportal.legacy.web.parameter.DataBinCountFilter; +import org.cbioportal.legacy.web.parameter.GenericAssayDataCountFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataCountFilter; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.PermissionEvaluator; @@ -185,6 +190,43 @@ public boolean hasPermission(Authentication authentication, Serializable targetI return hasAccessToMolecularProfiles(authentication, (Collection)targetId, permission); } else if (TARGET_TYPE_COLLECTION_OF_SAMPLE_LIST_IDS.equals(targetType)) { return hasAccessToSampleLists(authentication, (Collection) targetId, permission); + } else if (targetType.contains("Filter")) { + switch (targetId) { + case StudyViewFilter studyViewFilter -> { + return hasAccessToCancerStudies(authentication, studyViewFilter.getUniqueStudyIds(), permission); + } + case ClinicalDataCountFilter clinicalDataCountFilter -> { + Set studyIds = new HashSet<>(); + if (clinicalDataCountFilter.getStudyViewFilter() != null) { + studyIds = clinicalDataCountFilter.getStudyViewFilter().getUniqueStudyIds(); + } + return hasAccessToCancerStudies(authentication, studyIds, permission); + } + case DataBinCountFilter dataBinCountFilter -> { + Set studyIds = new HashSet<>(); + if (dataBinCountFilter.getStudyViewFilter() != null) { + studyIds = dataBinCountFilter.getStudyViewFilter().getUniqueStudyIds(); + } + return hasAccessToCancerStudies(authentication,studyIds, permission); + } + case GenomicDataCountFilter genomicDataCountFilter -> { + Set studyIds = new HashSet<>(); + if (genomicDataCountFilter.getStudyViewFilter() != null) { + studyIds = genomicDataCountFilter.getStudyViewFilter().getUniqueStudyIds(); + } + return hasAccessToCancerStudies(authentication, studyIds, permission); + } + + case GenericAssayDataCountFilter genericAssayDataCountFilter -> { + Set studyIds = new HashSet<>(); + if (genericAssayDataCountFilter.getStudyViewFilter() != null) { + studyIds = genericAssayDataCountFilter.getStudyViewFilter().getUniqueStudyIds(); + } + return hasAccessToCancerStudies(authentication, studyIds, permission); + } + + default -> log.debug("hasPermission(), unknown targetType '" + targetType + "'"); + } } else { if (log.isDebugEnabled()) { log.debug("hasPermission(), unknown targetType '" + targetType + "'"); From 6a29afff80de58a3f404569949cc65a31bd35af0 Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Mon, 17 Feb 2025 15:47:37 -0500 Subject: [PATCH 5/9] Move to domain module --- .../mapper/CancerStudyMetadataMapper.java | 2 +- .../application/rest/mapper/SampleMapper.java | 2 +- .../rest/response/CancerStudyMetadataDTO.java | 2 +- .../application/rest/response/SampleDTO.java | 2 +- .../ColumnStoreStudyController.java | 2 +- .../ColumnarStoreStudyViewController.java | 25 +- .../repository/AlterationRepository.java | 4 +- .../usecase/AlterationCountByGeneUseCase.java | 12 +- .../cancerstudy/CancerStudyMetadata.java | 2 +- .../cancerstudy/TypeOfCancer.java | 2 +- .../repository/CancerStudyRepository.java | 6 +- .../GetCancerStudyMetadataUseCase.java | 6 +- .../usecase/GetFilteredStudyIdsUseCase.java | 6 +- .../ClinicalAttributesRepository.java | 2 +- ...tClinicalAttributesDataTypeMapUseCase.java | 4 +- ...etClinicalAttributesForStudiesUseCase.java | 4 +- .../repository/ClinicalDataRepository.java | 4 +- .../usecase/ClinicalDataUseCases.java | 2 +- .../usecase/GetClinicalDataCountsUseCase.java | 12 +- .../GetClinicalDataForXyPlotUseCase.java | 8 +- .../GetPatientClinicalDataUseCase.java | 6 +- .../usecase/GetSampleClinicalDataUseCase.java | 6 +- .../repository/ClinicalEventRepository.java | 4 +- .../GetClinicalEventTypeCountsUseCase.java | 6 +- .../repository/GenericAssayRepository.java | 4 +- .../usecase/GenericAssayUseCases.java | 2 +- ...eredMolecularProfilesByAlterationType.java | 6 +- .../usecase/GetGenericAssayDataBinCounts.java | 6 +- .../GetGenericAssayDataCountsUseCase.java | 6 +- .../GetGenericAssayProfilesUseCase.java | 4 +- .../repository/GenomicDataRepository.java | 4 +- .../usecase/GenomicDataUseCases.java | 2 +- .../GetCNACountsByGeneSpecificUseCase.java | 6 +- .../GetGenomicDataBinCountsUseCase.java | 6 +- ...etMolecularProfileSampleCountsUseCase.java | 6 +- .../GetMutationCountsByTypeUseCase.java | 6 +- .../usecase/GetMutationCountsUseCase.java | 6 +- .../patient/repository/PatientRepository.java | 4 +- .../usecase/GetCaseListDataCountsUseCase.java | 6 +- .../GetFilteredPatientCountUseCase.java | 6 +- .../{ => domain}/sample/Sample.java | 2 +- .../{ => domain}/sample/SampleType.java | 2 +- .../sample/repository/SampleRepository.java | 6 +- .../GetFilteredSamplesCountUseCase.java | 6 +- .../usecase/GetFilteredSamplesUseCase.java | 8 +- .../studyview/StudyViewFilterContext.java | 2 +- .../studyview/StudyViewFilterFactory.java | 2 +- .../studyview/StudyViewService.java | 117 ++- .../repository/TreatmentRepository.java | 4 +- .../FilteredTreatmentCountReportUseCase.java | 6 +- .../ClickhouseAlterationMapper.java | 2 +- .../ClickhouseAlterationRepository.java | 5 +- .../ClickhouseCancerStudyMapper.java | 4 +- .../ClickhouseCancerStudyRepository.java | 6 +- ...lickhouseClinicalAttributesRepository.java | 2 +- .../ClickhouseClinicalDataMapper.java | 2 +- .../ClickhouseClinicalDataRepository.java | 4 +- .../ClickhouseClinicalEventMapper.java | 2 +- .../ClickhouseClinicalEventRepository.java | 4 +- .../ClickhouseGenericAssayMapper.java | 2 +- .../ClickhouseGenericAssayRepository.java | 4 +- .../ClickhouseGenomicDataMapper.java | 2 +- .../ClickhouseGenomicDataRepository.java | 4 +- .../patient/ClickhousePatientMapper.java | 2 +- .../patient/ClickhousePatientRepository.java | 4 +- .../sample/ClickhouseSampleMapper.java | 4 +- .../sample/ClickhouseSampleRepository.java | 6 +- .../treatment/ClickhouseTreatmentMapper.java | 2 +- .../ClickhouseTreatmentRepository.java | 4 +- .../service/BasicDataBinner.java | 3 +- .../service/ClinicalDataBinner.java | 2 +- .../mybatis/config/PersistenceConfig.java | 13 +- .../mybatisclickhouse/StudyViewMapper.java | 1 + .../StudyViewMyBatisRepository.java | 3 +- .../config/PersistenceColumnarConfig.java | 38 - .../CustomDataSourceConfiguration.java | 2 - .../AlterationCountByGeneService.java | 14 - .../AlterationCountByGeneServiceImpl.java | 218 ------ .../ClinicalDataDensityPlotServiceImpl.java | 1 - .../impl/StudyViewColumnarServiceImpl.java | 325 --------- .../TreatmentCountReportService.java | 14 - .../TreatmentCountReportServiceImpl.java | 48 -- .../legacy/web/columnar/BasicDataBinner.java | 3 +- .../web/columnar/ClinicalDataBinner.java | 3 +- .../StudyViewColumnStoreController.java | 688 ------------------ .../legacy/web/parameter/StudyViewFilter.java | 14 + .../cancerstudy/CancerStudyMapper.xml | 10 +- .../sample/ClickhouseSampleMapper.xml | 2 +- .../GetCancerStudyMetadataUseCaseTest.java | 3 +- 89 files changed, 306 insertions(+), 1530 deletions(-) rename src/main/java/org/cbioportal/{ => domain}/alteration/repository/AlterationRepository.java (97%) rename src/main/java/org/cbioportal/{ => domain}/alteration/usecase/AlterationCountByGeneUseCase.java (96%) rename src/main/java/org/cbioportal/{ => domain}/cancerstudy/CancerStudyMetadata.java (97%) rename src/main/java/org/cbioportal/{ => domain}/cancerstudy/TypeOfCancer.java (72%) rename src/main/java/org/cbioportal/{ => domain}/cancerstudy/repository/CancerStudyRepository.java (94%) rename src/main/java/org/cbioportal/{ => domain}/cancerstudy/usecase/GetCancerStudyMetadataUseCase.java (94%) rename src/main/java/org/cbioportal/{ => domain}/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java (74%) rename src/main/java/org/cbioportal/{ => domain}/clinical_attributes/repository/ClinicalAttributesRepository.java (93%) rename src/main/java/org/cbioportal/{ => domain}/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java (90%) rename src/main/java/org/cbioportal/{ => domain}/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java (90%) rename src/main/java/org/cbioportal/{ => domain}/clinical_data/repository/ClinicalDataRepository.java (93%) rename src/main/java/org/cbioportal/{ => domain}/clinical_data/usecase/ClinicalDataUseCases.java (95%) rename src/main/java/org/cbioportal/{ => domain}/clinical_data/usecase/GetClinicalDataCountsUseCase.java (90%) rename src/main/java/org/cbioportal/{ => domain}/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java (96%) rename src/main/java/org/cbioportal/{ => domain}/clinical_data/usecase/GetPatientClinicalDataUseCase.java (88%) rename src/main/java/org/cbioportal/{ => domain}/clinical_data/usecase/GetSampleClinicalDataUseCase.java (88%) rename src/main/java/org/cbioportal/{ => domain}/clinical_event/repository/ClinicalEventRepository.java (83%) rename src/main/java/org/cbioportal/{ => domain}/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java (87%) rename src/main/java/org/cbioportal/{ => domain}/generic_assay/repository/GenericAssayRepository.java (95%) rename src/main/java/org/cbioportal/{ => domain}/generic_assay/usecase/GenericAssayUseCases.java (95%) rename src/main/java/org/cbioportal/{ => domain}/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java (91%) rename src/main/java/org/cbioportal/{ => domain}/generic_assay/usecase/GetGenericAssayDataBinCounts.java (91%) rename src/main/java/org/cbioportal/{ => domain}/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java (91%) rename src/main/java/org/cbioportal/{ => domain}/generic_assay/usecase/GetGenericAssayProfilesUseCase.java (88%) rename src/main/java/org/cbioportal/{ => domain}/genomic_data/repository/GenomicDataRepository.java (97%) rename src/main/java/org/cbioportal/{ => domain}/genomic_data/usecase/GenomicDataUseCases.java (96%) rename src/main/java/org/cbioportal/{ => domain}/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java (89%) rename src/main/java/org/cbioportal/{ => domain}/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java (89%) rename src/main/java/org/cbioportal/{ => domain}/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java (89%) rename src/main/java/org/cbioportal/{ => domain}/genomic_data/usecase/GetMutationCountsByTypeUseCase.java (89%) rename src/main/java/org/cbioportal/{ => domain}/genomic_data/usecase/GetMutationCountsUseCase.java (90%) rename src/main/java/org/cbioportal/{ => domain}/patient/repository/PatientRepository.java (90%) rename src/main/java/org/cbioportal/{ => domain}/patient/usecase/GetCaseListDataCountsUseCase.java (88%) rename src/main/java/org/cbioportal/{ => domain}/patient/usecase/GetFilteredPatientCountUseCase.java (87%) rename src/main/java/org/cbioportal/{ => domain}/sample/Sample.java (96%) rename src/main/java/org/cbioportal/{ => domain}/sample/SampleType.java (95%) rename src/main/java/org/cbioportal/{ => domain}/sample/repository/SampleRepository.java (87%) rename src/main/java/org/cbioportal/{ => domain}/sample/usecase/GetFilteredSamplesCountUseCase.java (87%) rename src/main/java/org/cbioportal/{ => domain}/sample/usecase/GetFilteredSamplesUseCase.java (71%) rename src/main/java/org/cbioportal/{ => domain}/studyview/StudyViewFilterContext.java (98%) rename src/main/java/org/cbioportal/{ => domain}/studyview/StudyViewFilterFactory.java (98%) rename src/main/java/org/cbioportal/{ => domain}/studyview/StudyViewService.java (66%) rename src/main/java/org/cbioportal/{ => domain}/treatment/repository/TreatmentRepository.java (94%) rename src/main/java/org/cbioportal/{ => domain}/treatment/usecase/FilteredTreatmentCountReportUseCase.java (91%) delete mode 100644 src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/config/PersistenceColumnarConfig.java delete mode 100644 src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneService.java delete mode 100644 src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneServiceImpl.java delete mode 100644 src/main/java/org/cbioportal/legacy/service/impl/StudyViewColumnarServiceImpl.java delete mode 100644 src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportService.java delete mode 100644 src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportServiceImpl.java delete mode 100644 src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java diff --git a/src/main/java/org/cbioportal/application/rest/mapper/CancerStudyMetadataMapper.java b/src/main/java/org/cbioportal/application/rest/mapper/CancerStudyMetadataMapper.java index cbf1467d815..fac977590ab 100644 --- a/src/main/java/org/cbioportal/application/rest/mapper/CancerStudyMetadataMapper.java +++ b/src/main/java/org/cbioportal/application/rest/mapper/CancerStudyMetadataMapper.java @@ -1,7 +1,7 @@ package org.cbioportal.application.rest.mapper; import org.cbioportal.application.rest.response.CancerStudyMetadataDTO; -import org.cbioportal.cancerstudy.CancerStudyMetadata; +import org.cbioportal.domain.cancerstudy.CancerStudyMetadata; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; diff --git a/src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java b/src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java index 0c6986ed643..786ea9e13c1 100644 --- a/src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java +++ b/src/main/java/org/cbioportal/application/rest/mapper/SampleMapper.java @@ -2,7 +2,7 @@ import org.cbioportal.application.rest.response.SampleDTO; import org.cbioportal.legacy.utils.Encoder; -import org.cbioportal.sample.Sample; +import org.cbioportal.domain.sample.Sample; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; diff --git a/src/main/java/org/cbioportal/application/rest/response/CancerStudyMetadataDTO.java b/src/main/java/org/cbioportal/application/rest/response/CancerStudyMetadataDTO.java index 448de69ca28..a5a9b6e1fd9 100644 --- a/src/main/java/org/cbioportal/application/rest/response/CancerStudyMetadataDTO.java +++ b/src/main/java/org/cbioportal/application/rest/response/CancerStudyMetadataDTO.java @@ -1,7 +1,7 @@ package org.cbioportal.application.rest.response; import io.swagger.v3.oas.annotations.media.Schema; -import org.cbioportal.cancerstudy.TypeOfCancer; +import org.cbioportal.domain.cancerstudy.TypeOfCancer; @Schema(name = "CancerStudyMetadata", description = "Represents a cancer study") public record CancerStudyMetadataDTO(String cancerStudyIdentifier, String typeOfCancerId, diff --git a/src/main/java/org/cbioportal/application/rest/response/SampleDTO.java b/src/main/java/org/cbioportal/application/rest/response/SampleDTO.java index d9690abed93..b0940a656b1 100644 --- a/src/main/java/org/cbioportal/application/rest/response/SampleDTO.java +++ b/src/main/java/org/cbioportal/application/rest/response/SampleDTO.java @@ -1,6 +1,6 @@ package org.cbioportal.application.rest.response; -import org.cbioportal.sample.SampleType; +import org.cbioportal.domain.sample.SampleType; public record SampleDTO(String sampleId, SampleType sampleType, String patientId, String studyId, Boolean sequenced, Boolean copyNumberSegmentPresent, String uniqueSampleKey, String uniquePatientKey) { diff --git a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnStoreStudyController.java b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnStoreStudyController.java index c8bcb5c28b6..2586f69e15a 100644 --- a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnStoreStudyController.java +++ b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnStoreStudyController.java @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.Parameter; import org.cbioportal.application.rest.mapper.CancerStudyMetadataMapper; import org.cbioportal.application.rest.response.CancerStudyMetadataDTO; -import org.cbioportal.cancerstudy.usecase.GetCancerStudyMetadataUseCase; +import org.cbioportal.domain.cancerstudy.usecase.GetCancerStudyMetadataUseCase; import org.cbioportal.legacy.web.parameter.Direction; import org.cbioportal.legacy.web.parameter.sort.StudySortBy; import org.cbioportal.shared.SortAndSearchCriteria; diff --git a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java index 4071bcd7b99..5856a48f452 100644 --- a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java +++ b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java @@ -51,8 +51,8 @@ import org.cbioportal.legacy.web.parameter.SampleIdentifier; import org.cbioportal.legacy.web.parameter.StudyViewFilter; import org.cbioportal.legacy.web.util.DensityPlotParameters; -import org.cbioportal.sample.Sample; -import org.cbioportal.studyview.StudyViewService; +import org.cbioportal.domain.sample.Sample; +import org.cbioportal.domain.studyview.StudyViewService; import org.springframework.context.annotation.Profile; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -102,6 +102,7 @@ public ColumnarStoreStudyViewController(StudyViewService studyViewService, Basic @Hidden @PostMapping(value = "/filtered-samples/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchFilteredSamples( @RequestParam(defaultValue = "false") Boolean negateFilters, @RequestBody(required = false) StudyViewFilter studyViewFilter) { @@ -112,6 +113,7 @@ public ResponseEntity> fetchFilteredSamples( @Hidden // should unhide when we remove legacy controller @PostMapping(value = "/mutated-genes/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchMutatedGenes( @RequestBody(required = false) StudyViewFilter studyViewFilter ) throws StudyNotFoundException { @@ -123,6 +125,7 @@ public ResponseEntity> fetchMutatedGenes( @PostMapping(value = "/molecular-profile-sample-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch sample counts by study view filter") + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataCount.class)))) public ResponseEntity> fetchMolecularProfileSampleCounts( @@ -136,6 +139,7 @@ public ResponseEntity> fetchMolecularProfileSampleCounts( @Hidden // should unhide when we remove legacy controller @RequestMapping(value = "/cna-genes/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchCnaGenes( @RequestBody(required = false) StudyViewFilter studyViewFilter ) throws StudyNotFoundException { @@ -148,6 +152,7 @@ public ResponseEntity> fetchCnaGenes( @Operation(description = "Fetch structural variant genes by study view filter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = AlterationCountByGene.class)))) + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchStructuralVariantGenes( @Parameter(required = true, description = "Study view filter") @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter @@ -159,6 +164,7 @@ public ResponseEntity> fetchStructuralVariantGenes( @RequestMapping(value = "/clinical-data-counts/fetch", method=RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasPermission(#clinicalDataCountFilter, 'ClinicalDataCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchClinicalDataCounts( @RequestBody(required = false) ClinicalDataCountFilter clinicalDataCountFilter) { @@ -179,6 +185,7 @@ public ResponseEntity> fetchClinicalDataCounts( @RequestMapping(value = "/sample-lists-counts/fetch", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch case list sample counts by study view filter") + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public List fetchCaseListCounts( @Parameter(required = true, description = "Study view filter") @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter) { @@ -189,6 +196,7 @@ public List fetchCaseListCounts( @Hidden // should unhide when we remove legacy controller @RequestMapping(value = "/clinical-data-bin-counts/fetch", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasPermission(#clinicalDataBinCountFilter, 'DataBinCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchClinicalDataBinCounts( @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, @RequestBody(required = false) ClinicalDataBinCountFilter clinicalDataBinCountFilter) { @@ -209,6 +217,7 @@ public ResponseEntity> fetchClinicalDataBinCounts( @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DensityPlotData.class))) @Validated + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity fetchClinicalDataDensityPlot( @Parameter(required = true, description = "Clinical Attribute ID of the X axis") @RequestParam String xAxisAttributeId, @@ -264,7 +273,7 @@ public ResponseEntity fetchClinicalDataDensityPlot( } @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") @RequestMapping(value = "/clinical-data-violin-plots/fetch", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @@ -340,6 +349,7 @@ public ResponseEntity fetchClinicalDataViolinPlots( @Operation(description = "Fetch genomic data counts by GenomicDataCountFilter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataCountItem.class)))) + @PreAuthorize("hasPermission(#genomicDataCountFilter, 'GenomicDataCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchGenomicDataCounts( @Parameter(required = true, description = "Genomic data count filter") @Valid @RequestBody(required = false) @@ -369,6 +379,7 @@ public ResponseEntity> fetchGenomicDataCounts( @Operation(description = "Fetch generic assay data counts by study view filter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenericAssayDataCountItem.class)))) + @PreAuthorize("hasPermission(#genericAssayDataCountFilter, 'GenericAssayDataCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchGenericAssayDataCounts( @Parameter(required = true, description = "Generic assay data count filter") @Valid @RequestBody(required = false) @@ -392,6 +403,7 @@ public ResponseEntity> fetchGenericAssayDataCoun method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch mutation data counts by GenomicDataCountFilter") + @PreAuthorize("hasPermission(#genomicDataCountFilter, 'GenomicDataCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchMutationDataCounts( @Parameter(description = "Level of detail of the response") @RequestParam(defaultValue = "SUMMARY") Projection projection, @@ -426,6 +438,7 @@ public ResponseEntity> fetchMutationDataCounts( @Operation(description = "Get Counts of Clinical Event Types by Study View Filter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalEventTypeCount.class)))) + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> getClinicalEventTypeCounts( @Parameter(required = true, description = "Study view filter") @Valid @@ -440,6 +453,7 @@ public ResponseEntity> getClinicalEventTypeCounts( @Operation(description = "Get all patient level treatments") @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = PatientTreatmentReport.class))) + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity fetchPatientTreatmentCounts( @Parameter(required = false ) @RequestParam(name = "tier", required = false, defaultValue = "Agent") @@ -457,6 +471,7 @@ public ResponseEntity fetchPatientTreatmentCounts( produces = MediaType.APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SampleTreatmentReport.class))) + @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity fetchSampleTreatmentCounts( @Parameter(required = false ) @RequestParam(name = "tier", required = false, defaultValue = "Agent") @@ -476,6 +491,7 @@ public ResponseEntity fetchSampleTreatmentCounts( @Operation(description = "Fetch custom data counts by study view filter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalDataCountItem.class)))) + @PreAuthorize("hasPermission(#clinicalDataCountFilter, 'DataCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchCustomDataCounts( @Parameter(required = true, description = "Custom data count filter") @Valid @RequestBody(required = false) ClinicalDataCountFilter clinicalDataCountFilter){ @@ -510,6 +526,7 @@ public ResponseEntity> fetchCustomDataCounts( @Operation(description = "Fetch custom data bin counts by study view filter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalDataBin.class)))) + @PreAuthorize("hasPermission(#clinicalDataBinCountFilter, 'DataBinCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchCustomDataBinCounts( @Parameter(description = "Method for data binning") @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, @@ -528,6 +545,7 @@ public ResponseEntity> fetchCustomDataBinCounts( consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataBin.class)))) + @PreAuthorize("hasPermission(#genomicDataBinCountFilter, 'DataBinCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchGenomicDataBinCounts( @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, @RequestBody(required = false) GenomicDataBinCountFilter genomicDataBinCountFilter) { @@ -544,6 +562,7 @@ public ResponseEntity> fetchGenomicDataBinCounts( consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenericAssayDataBin.class)))) + @PreAuthorize("hasPermission(#genericAssayDataBinCountFilter, 'DataBinCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchGenericAssayDataBinCounts( @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, @RequestBody(required = false) GenericAssayDataBinCountFilter genericAssayDataBinCountFilter) { diff --git a/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java b/src/main/java/org/cbioportal/domain/alteration/repository/AlterationRepository.java similarity index 97% rename from src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java rename to src/main/java/org/cbioportal/domain/alteration/repository/AlterationRepository.java index ba7c7c20140..1ffd5be7d5f 100644 --- a/src/main/java/org/cbioportal/alteration/repository/AlterationRepository.java +++ b/src/main/java/org/cbioportal/domain/alteration/repository/AlterationRepository.java @@ -1,9 +1,9 @@ -package org.cbioportal.alteration.repository; +package org.cbioportal.domain.alteration.repository; import org.cbioportal.legacy.model.AlterationCountByGene; import org.cbioportal.legacy.model.CopyNumberCountByGene; import org.cbioportal.legacy.model.MolecularProfile; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/cbioportal/alteration/usecase/AlterationCountByGeneUseCase.java b/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCase.java similarity index 96% rename from src/main/java/org/cbioportal/alteration/usecase/AlterationCountByGeneUseCase.java rename to src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCase.java index b0923c3369a..6de30053676 100644 --- a/src/main/java/org/cbioportal/alteration/usecase/AlterationCountByGeneUseCase.java +++ b/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCase.java @@ -1,9 +1,9 @@ -package org.cbioportal.alteration.usecase; +package org.cbioportal.domain.alteration.usecase; import org.apache.commons.math3.util.Pair; -import org.cbioportal.alteration.repository.AlterationRepository; -import org.cbioportal.cancerstudy.usecase.GetFilteredStudyIdsUseCase; -import org.cbioportal.generic_assay.usecase.GetFilteredMolecularProfilesByAlterationType; +import org.cbioportal.domain.alteration.repository.AlterationRepository; +import org.cbioportal.domain.cancerstudy.usecase.GetFilteredStudyIdsUseCase; +import org.cbioportal.domain.generic_assay.usecase.GetFilteredMolecularProfilesByAlterationType; import org.cbioportal.legacy.model.AlterationCountByGene; import org.cbioportal.legacy.model.AlterationType; import org.cbioportal.legacy.model.CopyNumberCountByGene; @@ -15,7 +15,7 @@ import org.cbioportal.legacy.service.exception.StudyNotFoundException; import org.cbioportal.legacy.service.util.AlterationCountServiceUtil; import org.cbioportal.legacy.web.parameter.Projection; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; @@ -160,7 +160,7 @@ private List populateAlterationCountsWithCNASigQValue(Lis */ private List getFirstMolecularProfileGroupedByStudy(StudyViewFilterContext studyViewFilterContext, AlterationType alterationType) { final var molecularProfiles = - getFilteredMolecularProfilesByAlterationType.excute(studyViewFilterContext, alterationType.toString()); + getFilteredMolecularProfilesByAlterationType.execute(studyViewFilterContext, alterationType.toString()); return AlterationCountServiceUtil.getFirstMolecularProfileGroupedByStudy(molecularProfiles); } diff --git a/src/main/java/org/cbioportal/cancerstudy/CancerStudyMetadata.java b/src/main/java/org/cbioportal/domain/cancerstudy/CancerStudyMetadata.java similarity index 97% rename from src/main/java/org/cbioportal/cancerstudy/CancerStudyMetadata.java rename to src/main/java/org/cbioportal/domain/cancerstudy/CancerStudyMetadata.java index 4631e559084..3114be6fc3c 100644 --- a/src/main/java/org/cbioportal/cancerstudy/CancerStudyMetadata.java +++ b/src/main/java/org/cbioportal/domain/cancerstudy/CancerStudyMetadata.java @@ -1,4 +1,4 @@ -package org.cbioportal.cancerstudy; +package org.cbioportal.domain.cancerstudy; import java.util.Date; diff --git a/src/main/java/org/cbioportal/cancerstudy/TypeOfCancer.java b/src/main/java/org/cbioportal/domain/cancerstudy/TypeOfCancer.java similarity index 72% rename from src/main/java/org/cbioportal/cancerstudy/TypeOfCancer.java rename to src/main/java/org/cbioportal/domain/cancerstudy/TypeOfCancer.java index a1265421641..91ae9342812 100644 --- a/src/main/java/org/cbioportal/cancerstudy/TypeOfCancer.java +++ b/src/main/java/org/cbioportal/domain/cancerstudy/TypeOfCancer.java @@ -1,4 +1,4 @@ -package org.cbioportal.cancerstudy; +package org.cbioportal.domain.cancerstudy; public record TypeOfCancer(String id, String name, String dedicatedColor, String shortName, String parent) { } diff --git a/src/main/java/org/cbioportal/cancerstudy/repository/CancerStudyRepository.java b/src/main/java/org/cbioportal/domain/cancerstudy/repository/CancerStudyRepository.java similarity index 94% rename from src/main/java/org/cbioportal/cancerstudy/repository/CancerStudyRepository.java rename to src/main/java/org/cbioportal/domain/cancerstudy/repository/CancerStudyRepository.java index db436085c48..e729b408827 100644 --- a/src/main/java/org/cbioportal/cancerstudy/repository/CancerStudyRepository.java +++ b/src/main/java/org/cbioportal/domain/cancerstudy/repository/CancerStudyRepository.java @@ -1,8 +1,8 @@ -package org.cbioportal.cancerstudy.repository; +package org.cbioportal.domain.cancerstudy.repository; -import org.cbioportal.cancerstudy.CancerStudyMetadata; +import org.cbioportal.domain.cancerstudy.CancerStudyMetadata; import org.cbioportal.shared.SortAndSearchCriteria; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/cancerstudy/usecase/GetCancerStudyMetadataUseCase.java b/src/main/java/org/cbioportal/domain/cancerstudy/usecase/GetCancerStudyMetadataUseCase.java similarity index 94% rename from src/main/java/org/cbioportal/cancerstudy/usecase/GetCancerStudyMetadataUseCase.java rename to src/main/java/org/cbioportal/domain/cancerstudy/usecase/GetCancerStudyMetadataUseCase.java index 47241038b1e..983465e747b 100644 --- a/src/main/java/org/cbioportal/cancerstudy/usecase/GetCancerStudyMetadataUseCase.java +++ b/src/main/java/org/cbioportal/domain/cancerstudy/usecase/GetCancerStudyMetadataUseCase.java @@ -1,7 +1,7 @@ -package org.cbioportal.cancerstudy.usecase; +package org.cbioportal.domain.cancerstudy.usecase; -import org.cbioportal.cancerstudy.CancerStudyMetadata; -import org.cbioportal.cancerstudy.repository.CancerStudyRepository; +import org.cbioportal.domain.cancerstudy.CancerStudyMetadata; +import org.cbioportal.domain.cancerstudy.repository.CancerStudyRepository; import org.cbioportal.shared.SortAndSearchCriteria; import org.cbioportal.shared.enums.ProjectionType; import org.springframework.context.annotation.Profile; diff --git a/src/main/java/org/cbioportal/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java b/src/main/java/org/cbioportal/domain/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java similarity index 74% rename from src/main/java/org/cbioportal/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java rename to src/main/java/org/cbioportal/domain/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java index 2f2ebebc0d7..d691f7135f0 100644 --- a/src/main/java/org/cbioportal/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java +++ b/src/main/java/org/cbioportal/domain/cancerstudy/usecase/GetFilteredStudyIdsUseCase.java @@ -1,7 +1,7 @@ -package org.cbioportal.cancerstudy.usecase; +package org.cbioportal.domain.cancerstudy.usecase; -import org.cbioportal.cancerstudy.repository.CancerStudyRepository; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.cancerstudy.repository.CancerStudyRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java b/src/main/java/org/cbioportal/domain/clinical_attributes/repository/ClinicalAttributesRepository.java similarity index 93% rename from src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java rename to src/main/java/org/cbioportal/domain/clinical_attributes/repository/ClinicalAttributesRepository.java index a1a489b7417..c0e3c8a99f4 100644 --- a/src/main/java/org/cbioportal/clinical_attributes/repository/ClinicalAttributesRepository.java +++ b/src/main/java/org/cbioportal/domain/clinical_attributes/repository/ClinicalAttributesRepository.java @@ -1,4 +1,4 @@ -package org.cbioportal.clinical_attributes.repository; +package org.cbioportal.domain.clinical_attributes.repository; import org.cbioportal.legacy.model.ClinicalAttribute; import org.cbioportal.legacy.web.parameter.ClinicalDataType; diff --git a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java b/src/main/java/org/cbioportal/domain/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java similarity index 90% rename from src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java rename to src/main/java/org/cbioportal/domain/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java index 62410b903a1..e9fc3070be9 100644 --- a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java +++ b/src/main/java/org/cbioportal/domain/clinical_attributes/usecase/GetClinicalAttributesDataTypeMapUseCase.java @@ -1,6 +1,6 @@ -package org.cbioportal.clinical_attributes.usecase; +package org.cbioportal.domain.clinical_attributes.usecase; -import org.cbioportal.clinical_attributes.repository.ClinicalAttributesRepository; +import org.cbioportal.domain.clinical_attributes.repository.ClinicalAttributesRepository; import org.cbioportal.legacy.web.parameter.ClinicalDataType; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java b/src/main/java/org/cbioportal/domain/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java similarity index 90% rename from src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java rename to src/main/java/org/cbioportal/domain/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java index 1c5c93ca5f7..3b0fbff7339 100644 --- a/src/main/java/org/cbioportal/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java +++ b/src/main/java/org/cbioportal/domain/clinical_attributes/usecase/GetClinicalAttributesForStudiesUseCase.java @@ -1,6 +1,6 @@ -package org.cbioportal.clinical_attributes.usecase; +package org.cbioportal.domain.clinical_attributes.usecase; -import org.cbioportal.clinical_attributes.repository.ClinicalAttributesRepository; +import org.cbioportal.domain.clinical_attributes.repository.ClinicalAttributesRepository; import org.cbioportal.legacy.model.ClinicalAttribute; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java b/src/main/java/org/cbioportal/domain/clinical_data/repository/ClinicalDataRepository.java similarity index 93% rename from src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java rename to src/main/java/org/cbioportal/domain/clinical_data/repository/ClinicalDataRepository.java index 610a33f601f..7b3a5c969e3 100644 --- a/src/main/java/org/cbioportal/clinical_data/repository/ClinicalDataRepository.java +++ b/src/main/java/org/cbioportal/domain/clinical_data/repository/ClinicalDataRepository.java @@ -1,8 +1,8 @@ -package org.cbioportal.clinical_data.repository; +package org.cbioportal.domain.clinical_data.repository; import org.cbioportal.legacy.model.ClinicalData; import org.cbioportal.legacy.model.ClinicalDataCountItem; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java b/src/main/java/org/cbioportal/domain/clinical_data/usecase/ClinicalDataUseCases.java similarity index 95% rename from src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java rename to src/main/java/org/cbioportal/domain/clinical_data/usecase/ClinicalDataUseCases.java index 88884de1cea..d698168e57a 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/ClinicalDataUseCases.java +++ b/src/main/java/org/cbioportal/domain/clinical_data/usecase/ClinicalDataUseCases.java @@ -1,4 +1,4 @@ -package org.cbioportal.clinical_data.usecase; +package org.cbioportal.domain.clinical_data.usecase; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetClinicalDataCountsUseCase.java similarity index 90% rename from src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java rename to src/main/java/org/cbioportal/domain/clinical_data/usecase/GetClinicalDataCountsUseCase.java index acbc8713821..b18020d4e5a 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataCountsUseCase.java +++ b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetClinicalDataCountsUseCase.java @@ -1,12 +1,12 @@ -package org.cbioportal.clinical_data.usecase; +package org.cbioportal.domain.clinical_data.usecase; -import org.cbioportal.clinical_attributes.usecase.GetClinicalAttributesForStudiesUseCase; -import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.domain.clinical_attributes.usecase.GetClinicalAttributesForStudiesUseCase; +import org.cbioportal.domain.clinical_data.repository.ClinicalDataRepository; import org.cbioportal.legacy.model.ClinicalDataCountItem; import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; -import org.cbioportal.patient.usecase.GetFilteredPatientCountUseCase; -import org.cbioportal.sample.usecase.GetFilteredSamplesCountUseCase; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.patient.usecase.GetFilteredPatientCountUseCase; +import org.cbioportal.domain.sample.usecase.GetFilteredSamplesCountUseCase; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java similarity index 96% rename from src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java rename to src/main/java/org/cbioportal/domain/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java index 7649db8bd83..83905cb1713 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java +++ b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetClinicalDataForXyPlotUseCase.java @@ -1,9 +1,9 @@ -package org.cbioportal.clinical_data.usecase; +package org.cbioportal.domain.clinical_data.usecase; import org.cbioportal.legacy.model.ClinicalData; -import org.cbioportal.sample.Sample; -import org.cbioportal.sample.usecase.GetFilteredSamplesUseCase; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.sample.Sample; +import org.cbioportal.domain.sample.usecase.GetFilteredSamplesUseCase; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetPatientClinicalDataUseCase.java similarity index 88% rename from src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java rename to src/main/java/org/cbioportal/domain/clinical_data/usecase/GetPatientClinicalDataUseCase.java index 897488998ae..dc22bb67005 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetPatientClinicalDataUseCase.java +++ b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetPatientClinicalDataUseCase.java @@ -1,8 +1,8 @@ -package org.cbioportal.clinical_data.usecase; +package org.cbioportal.domain.clinical_data.usecase; -import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.domain.clinical_data.repository.ClinicalDataRepository; import org.cbioportal.legacy.model.ClinicalData; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetSampleClinicalDataUseCase.java similarity index 88% rename from src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java rename to src/main/java/org/cbioportal/domain/clinical_data/usecase/GetSampleClinicalDataUseCase.java index 1c850736be9..540aebd0d8e 100644 --- a/src/main/java/org/cbioportal/clinical_data/usecase/GetSampleClinicalDataUseCase.java +++ b/src/main/java/org/cbioportal/domain/clinical_data/usecase/GetSampleClinicalDataUseCase.java @@ -1,8 +1,8 @@ -package org.cbioportal.clinical_data.usecase; +package org.cbioportal.domain.clinical_data.usecase; -import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.domain.clinical_data.repository.ClinicalDataRepository; import org.cbioportal.legacy.model.ClinicalData; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java b/src/main/java/org/cbioportal/domain/clinical_event/repository/ClinicalEventRepository.java similarity index 83% rename from src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java rename to src/main/java/org/cbioportal/domain/clinical_event/repository/ClinicalEventRepository.java index ffdf0560113..c2770eacd90 100644 --- a/src/main/java/org/cbioportal/clinical_event/repository/ClinicalEventRepository.java +++ b/src/main/java/org/cbioportal/domain/clinical_event/repository/ClinicalEventRepository.java @@ -1,7 +1,7 @@ -package org.cbioportal.clinical_event.repository; +package org.cbioportal.domain.clinical_event.repository; import org.cbioportal.legacy.model.ClinicalEventTypeCount; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java b/src/main/java/org/cbioportal/domain/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java similarity index 87% rename from src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java rename to src/main/java/org/cbioportal/domain/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java index a826276fed9..192b13cfdb1 100644 --- a/src/main/java/org/cbioportal/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java +++ b/src/main/java/org/cbioportal/domain/clinical_event/usecase/GetClinicalEventTypeCountsUseCase.java @@ -1,8 +1,8 @@ -package org.cbioportal.clinical_event.usecase; +package org.cbioportal.domain.clinical_event.usecase; -import org.cbioportal.clinical_event.repository.ClinicalEventRepository; +import org.cbioportal.domain.clinical_event.repository.ClinicalEventRepository; import org.cbioportal.legacy.model.ClinicalEventTypeCount; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java b/src/main/java/org/cbioportal/domain/generic_assay/repository/GenericAssayRepository.java similarity index 95% rename from src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java rename to src/main/java/org/cbioportal/domain/generic_assay/repository/GenericAssayRepository.java index 56c7dc9f9dd..45de74c77cb 100644 --- a/src/main/java/org/cbioportal/generic_assay/repository/GenericAssayRepository.java +++ b/src/main/java/org/cbioportal/domain/generic_assay/repository/GenericAssayRepository.java @@ -1,11 +1,11 @@ -package org.cbioportal.generic_assay.repository; +package org.cbioportal.domain.generic_assay.repository; import org.cbioportal.legacy.model.ClinicalDataCount; import org.cbioportal.legacy.model.GenericAssayDataCountItem; import org.cbioportal.legacy.model.MolecularProfile; import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GenericAssayUseCases.java similarity index 95% rename from src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java rename to src/main/java/org/cbioportal/domain/generic_assay/usecase/GenericAssayUseCases.java index 18364c8e0df..226db8ba47c 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GenericAssayUseCases.java +++ b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GenericAssayUseCases.java @@ -1,4 +1,4 @@ -package org.cbioportal.generic_assay.usecase; +package org.cbioportal.domain.generic_assay.usecase; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java similarity index 91% rename from src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java rename to src/main/java/org/cbioportal/domain/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java index 67c8f5ea889..9d286d6e4c2 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java +++ b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetFilteredMolecularProfilesByAlterationType.java @@ -1,8 +1,8 @@ -package org.cbioportal.generic_assay.usecase; +package org.cbioportal.domain.generic_assay.usecase; -import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.domain.generic_assay.repository.GenericAssayRepository; import org.cbioportal.legacy.model.MolecularProfile; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayDataBinCounts.java similarity index 91% rename from src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java rename to src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayDataBinCounts.java index e4773c5b0c3..ab89fae7b70 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataBinCounts.java +++ b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayDataBinCounts.java @@ -1,9 +1,9 @@ -package org.cbioportal.generic_assay.usecase; +package org.cbioportal.domain.generic_assay.usecase; -import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.domain.generic_assay.repository.GenericAssayRepository; import org.cbioportal.legacy.model.ClinicalDataCount; import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java similarity index 91% rename from src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java rename to src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java index 77c74ab6e16..7f77a4e9691 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java +++ b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayDataCountsUseCase.java @@ -1,9 +1,9 @@ -package org.cbioportal.generic_assay.usecase; +package org.cbioportal.domain.generic_assay.usecase; -import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.domain.generic_assay.repository.GenericAssayRepository; import org.cbioportal.legacy.model.GenericAssayDataCountItem; import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayProfilesUseCase.java similarity index 88% rename from src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java rename to src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayProfilesUseCase.java index 53747dce590..08c4a9f6de8 100644 --- a/src/main/java/org/cbioportal/generic_assay/usecase/GetGenericAssayProfilesUseCase.java +++ b/src/main/java/org/cbioportal/domain/generic_assay/usecase/GetGenericAssayProfilesUseCase.java @@ -1,6 +1,6 @@ -package org.cbioportal.generic_assay.usecase; +package org.cbioportal.domain.generic_assay.usecase; -import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.domain.generic_assay.repository.GenericAssayRepository; import org.cbioportal.legacy.model.MolecularProfile; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java b/src/main/java/org/cbioportal/domain/genomic_data/repository/GenomicDataRepository.java similarity index 97% rename from src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java rename to src/main/java/org/cbioportal/domain/genomic_data/repository/GenomicDataRepository.java index 1ae329542fe..7f34397a511 100644 --- a/src/main/java/org/cbioportal/genomic_data/repository/GenomicDataRepository.java +++ b/src/main/java/org/cbioportal/domain/genomic_data/repository/GenomicDataRepository.java @@ -1,11 +1,11 @@ -package org.cbioportal.genomic_data.repository; +package org.cbioportal.domain.genomic_data.repository; import org.cbioportal.legacy.model.ClinicalDataCount; import org.cbioportal.legacy.model.GenomicDataCount; import org.cbioportal.legacy.model.GenomicDataCountItem; import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GenomicDataUseCases.java similarity index 96% rename from src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java rename to src/main/java/org/cbioportal/domain/genomic_data/usecase/GenomicDataUseCases.java index 342176ea9ea..a822f85ce4a 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GenomicDataUseCases.java +++ b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GenomicDataUseCases.java @@ -1,4 +1,4 @@ -package org.cbioportal.genomic_data.usecase; +package org.cbioportal.domain.genomic_data.usecase; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java similarity index 89% rename from src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java rename to src/main/java/org/cbioportal/domain/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java index 1f3f7e15de1..1942c7f5dbd 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java +++ b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetCNACountsByGeneSpecificUseCase.java @@ -1,9 +1,9 @@ -package org.cbioportal.genomic_data.usecase; +package org.cbioportal.domain.genomic_data.usecase; -import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.domain.genomic_data.repository.GenomicDataRepository; import org.cbioportal.legacy.model.GenomicDataCountItem; import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java similarity index 89% rename from src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java rename to src/main/java/org/cbioportal/domain/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java index 78a4a2a24eb..70844ee95af 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java +++ b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetGenomicDataBinCountsUseCase.java @@ -1,9 +1,9 @@ -package org.cbioportal.genomic_data.usecase; +package org.cbioportal.domain.genomic_data.usecase; -import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.domain.genomic_data.repository.GenomicDataRepository; import org.cbioportal.legacy.model.ClinicalDataCount; import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java similarity index 89% rename from src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java rename to src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java index ba3d700f963..e2b2d810dcb 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java +++ b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMolecularProfileSampleCountsUseCase.java @@ -1,9 +1,9 @@ -package org.cbioportal.genomic_data.usecase; +package org.cbioportal.domain.genomic_data.usecase; -import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.domain.genomic_data.repository.GenomicDataRepository; import org.cbioportal.legacy.model.GenomicDataCount; import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMutationCountsByTypeUseCase.java similarity index 89% rename from src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java rename to src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMutationCountsByTypeUseCase.java index a051519a8f8..909362e8154 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsByTypeUseCase.java +++ b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMutationCountsByTypeUseCase.java @@ -1,9 +1,9 @@ -package org.cbioportal.genomic_data.usecase; +package org.cbioportal.domain.genomic_data.usecase; -import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.domain.genomic_data.repository.GenomicDataRepository; import org.cbioportal.legacy.model.GenomicDataCountItem; import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMutationCountsUseCase.java similarity index 90% rename from src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java rename to src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMutationCountsUseCase.java index 46b4961c2d1..4621e347237 100644 --- a/src/main/java/org/cbioportal/genomic_data/usecase/GetMutationCountsUseCase.java +++ b/src/main/java/org/cbioportal/domain/genomic_data/usecase/GetMutationCountsUseCase.java @@ -1,8 +1,8 @@ -package org.cbioportal.genomic_data.usecase; +package org.cbioportal.domain.genomic_data.usecase; -import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.domain.genomic_data.repository.GenomicDataRepository; import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/patient/repository/PatientRepository.java b/src/main/java/org/cbioportal/domain/patient/repository/PatientRepository.java similarity index 90% rename from src/main/java/org/cbioportal/patient/repository/PatientRepository.java rename to src/main/java/org/cbioportal/domain/patient/repository/PatientRepository.java index 3b73e889ccd..8c0bdb14c2b 100644 --- a/src/main/java/org/cbioportal/patient/repository/PatientRepository.java +++ b/src/main/java/org/cbioportal/domain/patient/repository/PatientRepository.java @@ -1,7 +1,7 @@ -package org.cbioportal.patient.repository; +package org.cbioportal.domain.patient.repository; import org.cbioportal.legacy.model.CaseListDataCount; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java b/src/main/java/org/cbioportal/domain/patient/usecase/GetCaseListDataCountsUseCase.java similarity index 88% rename from src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java rename to src/main/java/org/cbioportal/domain/patient/usecase/GetCaseListDataCountsUseCase.java index e42f08f2644..b68b621a825 100644 --- a/src/main/java/org/cbioportal/patient/usecase/GetCaseListDataCountsUseCase.java +++ b/src/main/java/org/cbioportal/domain/patient/usecase/GetCaseListDataCountsUseCase.java @@ -1,8 +1,8 @@ -package org.cbioportal.patient.usecase; +package org.cbioportal.domain.patient.usecase; import org.cbioportal.legacy.model.CaseListDataCount; -import org.cbioportal.patient.repository.PatientRepository; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.patient.repository.PatientRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java b/src/main/java/org/cbioportal/domain/patient/usecase/GetFilteredPatientCountUseCase.java similarity index 87% rename from src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java rename to src/main/java/org/cbioportal/domain/patient/usecase/GetFilteredPatientCountUseCase.java index 175f65cf531..b41ab7eb6f8 100644 --- a/src/main/java/org/cbioportal/patient/usecase/GetFilteredPatientCountUseCase.java +++ b/src/main/java/org/cbioportal/domain/patient/usecase/GetFilteredPatientCountUseCase.java @@ -1,7 +1,7 @@ -package org.cbioportal.patient.usecase; +package org.cbioportal.domain.patient.usecase; -import org.cbioportal.patient.repository.PatientRepository; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.patient.repository.PatientRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/sample/Sample.java b/src/main/java/org/cbioportal/domain/sample/Sample.java similarity index 96% rename from src/main/java/org/cbioportal/sample/Sample.java rename to src/main/java/org/cbioportal/domain/sample/Sample.java index 85f07c9eeec..a878086ba7e 100644 --- a/src/main/java/org/cbioportal/sample/Sample.java +++ b/src/main/java/org/cbioportal/domain/sample/Sample.java @@ -1,4 +1,4 @@ -package org.cbioportal.sample; +package org.cbioportal.domain.sample; import org.cbioportal.legacy.model.Patient; diff --git a/src/main/java/org/cbioportal/sample/SampleType.java b/src/main/java/org/cbioportal/domain/sample/SampleType.java similarity index 95% rename from src/main/java/org/cbioportal/sample/SampleType.java rename to src/main/java/org/cbioportal/domain/sample/SampleType.java index 9216753db70..a163560ccb7 100644 --- a/src/main/java/org/cbioportal/sample/SampleType.java +++ b/src/main/java/org/cbioportal/domain/sample/SampleType.java @@ -1,4 +1,4 @@ -package org.cbioportal.sample; +package org.cbioportal.domain.sample; public enum SampleType { PRIMARY_SOLID_TUMOR("Primary Solid Tumor"), diff --git a/src/main/java/org/cbioportal/sample/repository/SampleRepository.java b/src/main/java/org/cbioportal/domain/sample/repository/SampleRepository.java similarity index 87% rename from src/main/java/org/cbioportal/sample/repository/SampleRepository.java rename to src/main/java/org/cbioportal/domain/sample/repository/SampleRepository.java index 88f0749a4d5..9115fa165c1 100644 --- a/src/main/java/org/cbioportal/sample/repository/SampleRepository.java +++ b/src/main/java/org/cbioportal/domain/sample/repository/SampleRepository.java @@ -1,7 +1,7 @@ -package org.cbioportal.sample.repository; +package org.cbioportal.domain.sample.repository; -import org.cbioportal.sample.Sample; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.sample.Sample; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java b/src/main/java/org/cbioportal/domain/sample/usecase/GetFilteredSamplesCountUseCase.java similarity index 87% rename from src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java rename to src/main/java/org/cbioportal/domain/sample/usecase/GetFilteredSamplesCountUseCase.java index a7e18b1d207..1836e9df14a 100644 --- a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesCountUseCase.java +++ b/src/main/java/org/cbioportal/domain/sample/usecase/GetFilteredSamplesCountUseCase.java @@ -1,7 +1,7 @@ -package org.cbioportal.sample.usecase; +package org.cbioportal.domain.sample.usecase; -import org.cbioportal.sample.repository.SampleRepository; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.sample.repository.SampleRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesUseCase.java b/src/main/java/org/cbioportal/domain/sample/usecase/GetFilteredSamplesUseCase.java similarity index 71% rename from src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesUseCase.java rename to src/main/java/org/cbioportal/domain/sample/usecase/GetFilteredSamplesUseCase.java index f71a8ed9901..0176454712a 100644 --- a/src/main/java/org/cbioportal/sample/usecase/GetFilteredSamplesUseCase.java +++ b/src/main/java/org/cbioportal/domain/sample/usecase/GetFilteredSamplesUseCase.java @@ -1,8 +1,8 @@ -package org.cbioportal.sample.usecase; +package org.cbioportal.domain.sample.usecase; -import org.cbioportal.sample.Sample; -import org.cbioportal.sample.repository.SampleRepository; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.sample.Sample; +import org.cbioportal.domain.sample.repository.SampleRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/studyview/StudyViewFilterContext.java b/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterContext.java similarity index 98% rename from src/main/java/org/cbioportal/studyview/StudyViewFilterContext.java rename to src/main/java/org/cbioportal/domain/studyview/StudyViewFilterContext.java index 3d60ab566cf..0b761ba3cc6 100644 --- a/src/main/java/org/cbioportal/studyview/StudyViewFilterContext.java +++ b/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterContext.java @@ -1,4 +1,4 @@ -package org.cbioportal.studyview; +package org.cbioportal.domain.studyview; import org.cbioportal.legacy.model.AlterationFilter; import org.cbioportal.legacy.model.GeneFilter; diff --git a/src/main/java/org/cbioportal/studyview/StudyViewFilterFactory.java b/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterFactory.java similarity index 98% rename from src/main/java/org/cbioportal/studyview/StudyViewFilterFactory.java rename to src/main/java/org/cbioportal/domain/studyview/StudyViewFilterFactory.java index 8d18087cb7d..451f3db39be 100644 --- a/src/main/java/org/cbioportal/studyview/StudyViewFilterFactory.java +++ b/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterFactory.java @@ -1,4 +1,4 @@ -package org.cbioportal.studyview; +package org.cbioportal.domain.studyview; import org.cbioportal.legacy.model.MolecularProfile; import org.cbioportal.legacy.persistence.enums.DataSource; diff --git a/src/main/java/org/cbioportal/studyview/StudyViewService.java b/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java similarity index 66% rename from src/main/java/org/cbioportal/studyview/StudyViewService.java rename to src/main/java/org/cbioportal/domain/studyview/StudyViewService.java index f354e8afb80..2ef208abe58 100644 --- a/src/main/java/org/cbioportal/studyview/StudyViewService.java +++ b/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java @@ -1,12 +1,12 @@ -package org.cbioportal.studyview; - -import org.cbioportal.alteration.usecase.AlterationCountByGeneUseCase; -import org.cbioportal.clinical_attributes.usecase.GetClinicalAttributesDataTypeMapUseCase; -import org.cbioportal.clinical_attributes.usecase.GetClinicalAttributesForStudiesUseCase; -import org.cbioportal.clinical_data.usecase.ClinicalDataUseCases; -import org.cbioportal.clinical_event.usecase.GetClinicalEventTypeCountsUseCase; -import org.cbioportal.generic_assay.usecase.GenericAssayUseCases; -import org.cbioportal.genomic_data.usecase.GenomicDataUseCases; +package org.cbioportal.domain.studyview; + +import org.cbioportal.domain.alteration.usecase.AlterationCountByGeneUseCase; +import org.cbioportal.domain.clinical_attributes.usecase.GetClinicalAttributesDataTypeMapUseCase; +import org.cbioportal.domain.clinical_attributes.usecase.GetClinicalAttributesForStudiesUseCase; +import org.cbioportal.domain.clinical_data.usecase.ClinicalDataUseCases; +import org.cbioportal.domain.clinical_event.usecase.GetClinicalEventTypeCountsUseCase; +import org.cbioportal.domain.generic_assay.usecase.GenericAssayUseCases; +import org.cbioportal.domain.genomic_data.usecase.GenomicDataUseCases; import org.cbioportal.legacy.model.AlterationCountByGene; import org.cbioportal.legacy.model.CaseListDataCount; import org.cbioportal.legacy.model.ClinicalAttribute; @@ -30,11 +30,12 @@ import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; import org.cbioportal.legacy.web.parameter.GenomicDataFilter; import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.cbioportal.patient.usecase.GetCaseListDataCountsUseCase; -import org.cbioportal.sample.Sample; -import org.cbioportal.sample.usecase.GetFilteredSamplesUseCase; +import org.cbioportal.domain.patient.usecase.GetCaseListDataCountsUseCase; +import org.cbioportal.domain.sample.Sample; +import org.cbioportal.domain.sample.usecase.GetFilteredSamplesUseCase; import org.cbioportal.shared.util.ClinicalDataCountItemUtil; -import org.cbioportal.treatment.usecase.FilteredTreatmentCountReportUseCase; +import org.cbioportal.domain.treatment.usecase.FilteredTreatmentCountReportUseCase; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -44,6 +45,11 @@ import java.util.stream.Collectors; @Service +/** + * A service class responsible for handling study view-related operations, including retrieving filtered samples, + * genomic data counts, clinical data, and other study-specific information. This class acts as a central hub + * for coordinating various use cases and delegating tasks to the appropriate repositories and utilities. + */ public class StudyViewService { private final GetFilteredSamplesUseCase getFilteredSamplesUseCase; @@ -84,85 +90,160 @@ public StudyViewService(GetFilteredSamplesUseCase getFilteredSamplesUseCase, this.customDataFilterUtil = customDataFilterUtil; } - + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getFilteredSamples(StudyViewFilter studyViewFilter){ return getFilteredSamplesUseCase.execute(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getMutatedGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { return alterationCountByGeneUseCase.getMutatedGenes(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getCnaGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { return alterationCountByGeneUseCase.getCnaGenes(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getStructuralVariantGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { return alterationCountByGeneUseCase.getStructuralVariantGenes(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getMolecularProfileSampleCounts(StudyViewFilter studyViewFilter) throws StudyNotFoundException { return genomicDataUseCases.getMolecularProfileSampleCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getClinicalEventTypeCounts(StudyViewFilter studyViewFilter) { return getClinicalEventTypeCountsUseCase.execute(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public PatientTreatmentReport getPatientTreatmentReport(StudyViewFilter studyViewFilter) { return filteredTreatmentCountReportUseCase.getFilteredPatientTreatmentReport(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public SampleTreatmentReport getSampleTreatmentReport(StudyViewFilter studyViewFilter) { return filteredTreatmentCountReportUseCase.getFilteredSampleTreatmentReport(buildStudyViewFilterContext(studyViewFilter)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getGenomicDataBinCounts(StudyViewFilter studyViewFilter, List genomicDataBinFilters) { return ClinicalDataCountItemUtil.generateDataCountItems(genomicDataUseCases.getGenomicDataBinCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genomicDataBinFilters)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getGenericAssayDataBinCounts(StudyViewFilter studyViewFilter, List genericAssayDataBinFilters) { return ClinicalDataCountItemUtil.generateDataCountItems(genericAssayUseCases.getGenericAssayDataBinCounts().execute(buildStudyViewFilterContext(studyViewFilter), genericAssayDataBinFilters)); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public Map getClinicalAttributeDataTypeMap(StudyViewFilter studyViewFilter) { return getClinicalAttributesDataTypeMapUseCase.execute(); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getClinicalDataCounts(StudyViewFilter studyViewFilter, List filteredAttributes){ return clinicalDataUseCases.getClinicalDataCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter) , filteredAttributes); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getClinicalAttributesForStudies(List studyIds){ return getClinicalAttributesForStudiesUseCase.execute(studyIds); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getCaseListDataCounts(StudyViewFilter studyViewFilter){ return StudyViewColumnarServiceUtil.mergeCaseListCounts(getCaseListDataCountsUseCase.execute(buildStudyViewFilterContext(studyViewFilter))); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getPatientClinicalData(StudyViewFilter studyViewFilter, List attributeIds){ return clinicalDataUseCases.getPatientClinicalDataUseCase().execute(buildStudyViewFilterContext(studyViewFilter), attributeIds); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getSampleClinicalData(StudyViewFilter studyViewFilter,List attributeIds){ return clinicalDataUseCases.getSampleClinicalDataUseCase().execute(buildStudyViewFilterContext(studyViewFilter), attributeIds); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getCNACountsByGeneSpecific(StudyViewFilter studyViewFilter, List genomicDataFilters){ return genomicDataUseCases.getCNACountsByGeneSpecificUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genomicDataFilters); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getGenericAssayDataCounts(StudyViewFilter studyViewFilter, List genericAssayDataFilters){ return genericAssayUseCases.getGenericAssayDataCountsUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genericAssayDataFilters); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getMutationCountsByGeneSpecific(StudyViewFilter studyViewFilter, List genomicDataFilters){ List genomicDataCountItemList = new ArrayList<>(); @@ -174,11 +255,19 @@ public List getMutationCountsByGeneSpecific(StudyViewFilte return genomicDataCountItemList; } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getMutationTypeCountsByGeneSpecific(StudyViewFilter studyViewFilter, List genomicDataFilters){ return genomicDataUseCases.getMutationCountsByTypeUseCase().execute(buildStudyViewFilterContext(studyViewFilter), genomicDataFilters); } + @Cacheable( + cacheResolver = "staticRepositoryCacheOneResolver", + condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" + ) public List getClinicalDataForXyPlot(StudyViewFilter studyViewFilter, List attributeIds, boolean shouldFilterNonEmptyClinicalData){ return clinicalDataUseCases.getClinicalDataForXyPlotUseCase().execute(buildStudyViewFilterContext(studyViewFilter),attributeIds, diff --git a/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java b/src/main/java/org/cbioportal/domain/treatment/repository/TreatmentRepository.java similarity index 94% rename from src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java rename to src/main/java/org/cbioportal/domain/treatment/repository/TreatmentRepository.java index 283c710ac78..01e1cb19d67 100644 --- a/src/main/java/org/cbioportal/treatment/repository/TreatmentRepository.java +++ b/src/main/java/org/cbioportal/domain/treatment/repository/TreatmentRepository.java @@ -1,8 +1,8 @@ -package org.cbioportal.treatment.repository; +package org.cbioportal.domain.treatment.repository; import org.cbioportal.legacy.model.PatientTreatment; import org.cbioportal.legacy.model.SampleTreatment; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/treatment/usecase/FilteredTreatmentCountReportUseCase.java b/src/main/java/org/cbioportal/domain/treatment/usecase/FilteredTreatmentCountReportUseCase.java similarity index 91% rename from src/main/java/org/cbioportal/treatment/usecase/FilteredTreatmentCountReportUseCase.java rename to src/main/java/org/cbioportal/domain/treatment/usecase/FilteredTreatmentCountReportUseCase.java index 241743ba883..9fb9a43f83b 100644 --- a/src/main/java/org/cbioportal/treatment/usecase/FilteredTreatmentCountReportUseCase.java +++ b/src/main/java/org/cbioportal/domain/treatment/usecase/FilteredTreatmentCountReportUseCase.java @@ -1,11 +1,11 @@ -package org.cbioportal.treatment.usecase; +package org.cbioportal.domain.treatment.usecase; import org.cbioportal.legacy.model.PatientTreatmentReport; import org.cbioportal.legacy.model.SampleTreatmentReport; import org.cbioportal.legacy.model.SampleTreatmentRow; import org.cbioportal.legacy.model.TemporalRelation; -import org.cbioportal.studyview.StudyViewFilterContext; -import org.cbioportal.treatment.repository.TreatmentRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.domain.treatment.repository.TreatmentRepository; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java index 38d77f8abfd..424e0d8670d 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapper.java @@ -5,7 +5,7 @@ import org.cbioportal.legacy.model.GenePanelToGene; import org.cbioportal.legacy.model.MolecularProfile; import org.cbioportal.legacy.persistence.helper.AlterationFilterHelper; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java index dbf3ecb9522..6fa2dd2316a 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java @@ -1,15 +1,14 @@ package org.cbioportal.infrastructure.repository.clickhouse.alteration; -import org.cbioportal.alteration.repository.AlterationRepository; +import org.cbioportal.domain.alteration.repository.AlterationRepository; import org.cbioportal.legacy.model.AlterationCountByGene; import org.cbioportal.legacy.model.CopyNumberCountByGene; import org.cbioportal.legacy.model.GenePanelToGene; import org.cbioportal.legacy.model.MolecularProfile; import org.cbioportal.legacy.persistence.helper.AlterationFilterHelper; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; -import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java index bd292da0782..041d1e5a512 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyMapper.java @@ -1,9 +1,9 @@ package org.cbioportal.infrastructure.repository.clickhouse.cancerstudy; import org.apache.ibatis.annotations.Param; -import org.cbioportal.cancerstudy.CancerStudyMetadata; +import org.cbioportal.domain.cancerstudy.CancerStudyMetadata; import org.cbioportal.shared.SortAndSearchCriteria; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java index 795efa8aff1..c84b633cfde 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/cancerstudy/ClickhouseCancerStudyRepository.java @@ -1,9 +1,9 @@ package org.cbioportal.infrastructure.repository.clickhouse.cancerstudy; -import org.cbioportal.cancerstudy.CancerStudyMetadata; -import org.cbioportal.cancerstudy.repository.CancerStudyRepository; +import org.cbioportal.domain.cancerstudy.CancerStudyMetadata; +import org.cbioportal.domain.cancerstudy.repository.CancerStudyRepository; import org.cbioportal.shared.SortAndSearchCriteria; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java index 9d0b187d87f..043adc7591c 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java @@ -1,6 +1,6 @@ package org.cbioportal.infrastructure.repository.clickhouse.clinical_attributes; -import org.cbioportal.clinical_attributes.repository.ClinicalAttributesRepository; +import org.cbioportal.domain.clinical_attributes.repository.ClinicalAttributesRepository; import org.cbioportal.legacy.model.ClinicalAttribute; import org.cbioportal.legacy.persistence.enums.DataSource; import org.cbioportal.legacy.web.parameter.ClinicalDataType; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java index 14ec4815508..01d093ac677 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapper.java @@ -2,7 +2,7 @@ import org.cbioportal.legacy.model.ClinicalData; import org.cbioportal.legacy.model.ClinicalDataCountItem; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java index d512414b0f6..980bd427a68 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java @@ -1,9 +1,9 @@ package org.cbioportal.infrastructure.repository.clickhouse.clinical_data; -import org.cbioportal.clinical_data.repository.ClinicalDataRepository; +import org.cbioportal.domain.clinical_data.repository.ClinicalDataRepository; import org.cbioportal.legacy.model.ClinicalData; import org.cbioportal.legacy.model.ClinicalDataCountItem; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java index 188a70bffea..9b14b7449f0 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapper.java @@ -2,7 +2,7 @@ import org.apache.ibatis.annotations.Param; import org.cbioportal.legacy.model.ClinicalEventTypeCount; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java index 328412a2c47..d709b3d4e9b 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java @@ -1,8 +1,8 @@ package org.cbioportal.infrastructure.repository.clickhouse.clinical_event; -import org.cbioportal.clinical_event.repository.ClinicalEventRepository; +import org.cbioportal.domain.clinical_event.repository.ClinicalEventRepository; import org.cbioportal.legacy.model.ClinicalEventTypeCount; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java index 593864b6c08..3b9478fa89d 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapper.java @@ -5,7 +5,7 @@ import org.cbioportal.legacy.model.MolecularProfile; import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java index ff4041a5a74..7c5d54efac1 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java @@ -1,12 +1,12 @@ package org.cbioportal.infrastructure.repository.clickhouse.generic_assay; -import org.cbioportal.generic_assay.repository.GenericAssayRepository; +import org.cbioportal.domain.generic_assay.repository.GenericAssayRepository; import org.cbioportal.legacy.model.ClinicalDataCount; import org.cbioportal.legacy.model.GenericAssayDataCountItem; import org.cbioportal.legacy.model.MolecularProfile; import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java index 1d3d8c339b3..3587cf95551 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapper.java @@ -6,7 +6,7 @@ import org.cbioportal.legacy.model.GenomicDataCountItem; import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java index 7692a2fbc9a..1da746c4889 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java @@ -1,12 +1,12 @@ package org.cbioportal.infrastructure.repository.clickhouse.genomic_data; -import org.cbioportal.genomic_data.repository.GenomicDataRepository; +import org.cbioportal.domain.genomic_data.repository.GenomicDataRepository; import org.cbioportal.legacy.model.ClinicalDataCount; import org.cbioportal.legacy.model.GenomicDataCount; import org.cbioportal.legacy.model.GenomicDataCountItem; import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java index d3822e0191d..ce27293c6fa 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapper.java @@ -2,7 +2,7 @@ import org.apache.ibatis.annotations.Param; import org.cbioportal.legacy.model.CaseListDataCount; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java index 5b147116c8b..1df361db7e6 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java @@ -1,8 +1,8 @@ package org.cbioportal.infrastructure.repository.clickhouse.patient; import org.cbioportal.legacy.model.CaseListDataCount; -import org.cbioportal.patient.repository.PatientRepository; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.patient.repository.PatientRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java index 82c2af551ca..e0cdda1942c 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapper.java @@ -1,8 +1,8 @@ package org.cbioportal.infrastructure.repository.clickhouse.sample; import org.apache.ibatis.annotations.Param; -import org.cbioportal.sample.Sample; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.sample.Sample; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java index 625d1a12c86..bbf87770516 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java @@ -1,8 +1,8 @@ package org.cbioportal.infrastructure.repository.clickhouse.sample; -import org.cbioportal.sample.Sample; -import org.cbioportal.sample.repository.SampleRepository; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.sample.Sample; +import org.cbioportal.domain.sample.repository.SampleRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java index 3744807c420..16f3e7fa1d3 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapper.java @@ -3,7 +3,7 @@ import org.apache.ibatis.annotations.Param; import org.cbioportal.legacy.model.PatientTreatment; import org.cbioportal.legacy.model.SampleTreatment; -import org.cbioportal.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterContext; import java.util.List; diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java index a48fdc993ed..97fb4051550 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java @@ -2,8 +2,8 @@ import org.cbioportal.legacy.model.PatientTreatment; import org.cbioportal.legacy.model.SampleTreatment; -import org.cbioportal.studyview.StudyViewFilterContext; -import org.cbioportal.treatment.repository.TreatmentRepository; +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.domain.treatment.repository.TreatmentRepository; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java b/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java index f6fe169becc..bd46c43914f 100644 --- a/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java +++ b/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java @@ -9,7 +9,6 @@ import org.cbioportal.legacy.model.GenericAssayDataBin; import org.cbioportal.legacy.model.GenomicDataBin; import org.cbioportal.legacy.service.CustomDataService; -import org.cbioportal.legacy.service.StudyViewColumnarService; import org.cbioportal.legacy.service.util.CustomDataSession; import org.cbioportal.legacy.web.columnar.util.CustomDataFilterUtil; import org.cbioportal.legacy.web.columnar.util.NewClinicalDataBinUtil; @@ -27,7 +26,7 @@ import org.cbioportal.legacy.web.parameter.StudyViewFilter; import org.cbioportal.legacy.web.util.DataBinner; import org.cbioportal.legacy.web.util.StudyViewFilterUtil; -import org.cbioportal.studyview.StudyViewService; +import org.cbioportal.domain.studyview.StudyViewService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.annotation.Profile; diff --git a/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java b/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java index 61abcaf227f..814fec1d30c 100644 --- a/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java +++ b/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java @@ -12,7 +12,7 @@ import org.cbioportal.legacy.web.parameter.DataBinMethod; import org.cbioportal.legacy.web.parameter.StudyViewFilter; import org.cbioportal.legacy.web.util.DataBinner; -import org.cbioportal.studyview.StudyViewService; +import org.cbioportal.domain.studyview.StudyViewService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.annotation.Profile; diff --git a/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java b/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java index 5ecde0e555f..6500c692416 100644 --- a/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java +++ b/src/main/java/org/cbioportal/legacy/persistence/mybatis/config/PersistenceConfig.java @@ -36,17 +36,17 @@ public void customize(org.apache.ibatis.session.Configuration configuration) { } @Bean("sqlSessionFactory") - //@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") @Profile("clickhouse") public SqlSessionFactoryBean sqlSessionFactorySpecifyDataSource(@Qualifier("mysqlDataSource") DataSource dataSource, ApplicationContext applicationContext) throws IOException { return sqlSessionFactory(dataSource, applicationContext); } -// @Bean("sqlSessionFactory") -// @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "false", matchIfMissing = true) -// public SqlSessionFactoryBean sqlSessionFactoryDefault(DataSource dataSource, ApplicationContext applicationContext) throws IOException { -// return sqlSessionFactory(dataSource, applicationContext); -// } + @Bean("sqlSessionFactory") + @Profile("default") + @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "false", matchIfMissing = true) + public SqlSessionFactoryBean sqlSessionFactoryDefault(DataSource dataSource, ApplicationContext applicationContext) throws IOException { + return sqlSessionFactory(dataSource, applicationContext); + } private SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource, ApplicationContext applicationContext) throws IOException { @@ -60,7 +60,6 @@ private SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource, Applicati } @Bean - //@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") @Profile("clickhouse") public DataSourceTransactionManager transactionManager(@Qualifier("mysqlDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); diff --git a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java index 3a2eea2f9b2..9004df6139d 100644 --- a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java +++ b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java @@ -28,6 +28,7 @@ import java.util.Map; +@Deprecated public interface StudyViewMapper { List getFilteredSamples(@Param("studyViewFilterHelper") StudyViewFilterHelper studyViewFilterHelper); diff --git a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java index ef76a7926ca..2a04ec8e3e5 100644 --- a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java +++ b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java @@ -39,7 +39,8 @@ import java.util.stream.Collectors; @Repository -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") +@Deprecated +@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "test") public class StudyViewMyBatisRepository implements StudyViewRepository { private final StudyViewMapper studyViewMapper; diff --git a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/config/PersistenceColumnarConfig.java b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/config/PersistenceColumnarConfig.java deleted file mode 100644 index b9f09e41284..00000000000 --- a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/config/PersistenceColumnarConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse.config; - -import org.cbioportal.legacy.persistence.mybatis.typehandler.SampleTypeTypeHandler; -import org.cbioportal.legacy.utils.config.annotation.ConditionalOnProperty; -import org.mybatis.spring.SqlSessionFactoryBean; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.sql.DataSource; -import java.io.IOException; - - -@Configuration -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") -@MapperScan(value= "org.cbioportal.legacy.persistence.mybatisclickhouse", - sqlSessionFactoryRef ="sqlColumnarSessionFactory") -@MapperScan(value= "org.cbioportal.infrastructure.repository.clickhouse", - sqlSessionFactoryRef = "sqlColumnarSessionFactory") -public class PersistenceColumnarConfig { - - @Bean("sqlColumnarSessionFactory") - public SqlSessionFactoryBean sqlColumnarSessionFactory(@Qualifier("clickhouseDataSource") DataSource dataSource, ApplicationContext applicationContext) throws IOException { - SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); - sessionFactory.setDataSource(dataSource); - sessionFactory.setMapperLocations( - applicationContext.getResources("classpath:org/cbioportal/persistence/mybatisclickhouse/*.xml") - ); - sessionFactory.addMapperLocations( - applicationContext.getResources("classpath:mappers/clickhouse/**/*.xml")); - - sessionFactory.setTypeHandlers(new SampleTypeTypeHandler()); - return sessionFactory; - } - -} diff --git a/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java b/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java index dd8b4c61fc7..3a224bfae51 100644 --- a/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java +++ b/src/main/java/org/cbioportal/legacy/properties/CustomDataSourceConfiguration.java @@ -1,6 +1,5 @@ package org.cbioportal.legacy.properties; -import org.cbioportal.legacy.utils.config.annotation.ConditionalOnProperty; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -10,7 +9,6 @@ import javax.sql.DataSource; @Configuration -//@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") @Profile("clickhouse") public class CustomDataSourceConfiguration { @Bean diff --git a/src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneService.java b/src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneService.java deleted file mode 100644 index bd43d19924b..00000000000 --- a/src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneService.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.cbioportal.legacy.service.alteration; - -import org.cbioportal.legacy.model.AlterationCountByGene; -import org.cbioportal.legacy.model.CopyNumberCountByGene; -import org.cbioportal.legacy.model.StudyViewFilterContext; -import org.cbioportal.legacy.service.exception.StudyNotFoundException; - -import java.util.List; - -public interface AlterationCountByGeneService { - List getMutatedGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException; - List getCnaGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException; - List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException; -} diff --git a/src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneServiceImpl.java b/src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneServiceImpl.java deleted file mode 100644 index 18cdc722dff..00000000000 --- a/src/main/java/org/cbioportal/legacy/service/alteration/AlterationCountByGeneServiceImpl.java +++ /dev/null @@ -1,218 +0,0 @@ -package org.cbioportal.legacy.service.alteration; - -import org.apache.commons.math3.util.Pair; -import org.cbioportal.legacy.model.AlterationCountByGene; -import org.cbioportal.legacy.model.AlterationType; -import org.cbioportal.legacy.model.CopyNumberCountByGene; -import org.cbioportal.legacy.model.Gistic; -import org.cbioportal.legacy.model.MolecularProfile; -import org.cbioportal.legacy.model.MutSig; -import org.cbioportal.legacy.model.StudyViewFilterContext; -import org.cbioportal.legacy.persistence.StudyViewRepository; -import org.cbioportal.legacy.service.SignificantCopyNumberRegionService; -import org.cbioportal.legacy.service.SignificantlyMutatedGeneService; -import org.cbioportal.legacy.service.exception.StudyNotFoundException; -import org.cbioportal.legacy.service.util.AlterationCountServiceUtil; -import org.cbioportal.legacy.utils.config.annotation.ConditionalOnProperty; -import org.cbioportal.legacy.web.parameter.Projection; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Service; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * Implementation of the AlterationCountService interface, providing methods for retrieving and processing - * alteration counts for samples and patients based on various criteria. - */ -@Service -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") -public class AlterationCountByGeneServiceImpl implements AlterationCountByGeneService { - private final StudyViewRepository studyViewRepository; - private final SignificantlyMutatedGeneService significantlyMutatedGeneService; - private final SignificantCopyNumberRegionService significantCopyNumberRegionService; - - /** - * Constructor for AlterationCountByGeneServiceImpl. - * - * @param studyViewRepository Repository for study-related queries. - * @param significantlyMutatedGeneService Service for retrieving significantly mutated genes. - * @param significantCopyNumberRegionService Service for retrieving significant copy number regions. - */ - @Autowired - public AlterationCountByGeneServiceImpl(StudyViewRepository studyViewRepository, SignificantlyMutatedGeneService significantlyMutatedGeneService, SignificantCopyNumberRegionService significantCopyNumberRegionService) { - this.studyViewRepository = studyViewRepository; - this.significantlyMutatedGeneService = significantlyMutatedGeneService; - this.significantCopyNumberRegionService = significantCopyNumberRegionService; - } - - /** - * Retrieves a list of mutated genes and their alteration counts for a given filter context. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return List of AlterationCountByGene objects representing mutated genes. - * @throws StudyNotFoundException if the specified study is not found. - */ - @Override - public List getMutatedGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var alterationCountByGenes = populateAlterationCounts(AlterationCountServiceUtil.combineAlterationCountsWithConflictingHugoSymbols(studyViewRepository.getMutatedGenes(studyViewFilterContext)), - studyViewFilterContext, AlterationType.MUTATION_EXTENDED); - return populateAlterationCountsWithMutSigQValue(alterationCountByGenes, studyViewFilterContext); - } - - /** - * Retrieves a list of genes with copy number alterations (CNA) and their alteration counts for a given filter context. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return List of CopyNumberCountByGene objects representing genes with CNAs. - * @throws StudyNotFoundException if the specified study is not found. - */ - public List getCnaGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var copyNumberAlterationCounts = populateAlterationCounts(AlterationCountServiceUtil.combineCopyNumberCountsWithConflictingHugoSymbols(studyViewRepository.getCnaGenes(studyViewFilterContext)), studyViewFilterContext, AlterationType.COPY_NUMBER_ALTERATION); - return populateAlterationCountsWithCNASigQValue(copyNumberAlterationCounts, studyViewFilterContext); - } - - /** - * Retrieves a list of structural variant genes and their alteration counts for a given filter context. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return List of AlterationCountByGene objects representing structural variant genes. - * @throws StudyNotFoundException if the specified study is not found. - */ - @Override - public List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var alterationCountByGenes = populateAlterationCounts(AlterationCountServiceUtil.combineAlterationCountsWithConflictingHugoSymbols(studyViewRepository.getStructuralVariantGenes(studyViewFilterContext)), - studyViewFilterContext, AlterationType.STRUCTURAL_VARIANT); - return populateAlterationCountsWithMutSigQValue(alterationCountByGenes, studyViewFilterContext); - } - - /** - * Populates alteration counts with profile data, including the total profiled count and matching gene panel IDs. - * - * @param alterationCounts List of alteration counts to enrich. - * @param studyViewFilterContext Context containing filter criteria. - * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). - * @param The type of alteration count. - * @return List of enriched alteration counts. - */ - private List populateAlterationCounts(@NonNull List alterationCounts, - @NonNull StudyViewFilterContext studyViewFilterContext, - @NonNull AlterationType alterationType) { - final var firstMolecularProfileForEachStudy = getFirstMolecularProfileGroupedByStudy(studyViewFilterContext, alterationType); - final int totalProfiledCount = studyViewRepository.getTotalProfiledCountsByAlterationType(studyViewFilterContext, alterationType.toString()); - var profiledCountsMap = studyViewRepository.getTotalProfiledCounts(studyViewFilterContext, alterationType.toString(), firstMolecularProfileForEachStudy); - final var matchingGenePanelIdsMap = studyViewRepository.getMatchingGenePanelIds(studyViewFilterContext, alterationType.toString()); - final int sampleProfileCountWithoutGenePanelData = studyViewRepository.getSampleProfileCountWithoutPanelData(studyViewFilterContext, alterationType.toString()); - - alterationCounts.parallelStream() - .forEach(alterationCountByGene -> { - String hugoGeneSymbol = alterationCountByGene.getHugoGeneSymbol(); - Set matchingGenePanelIds = matchingGenePanelIdsMap.get(hugoGeneSymbol) != null ? - matchingGenePanelIdsMap.get(hugoGeneSymbol) : Collections.emptySet(); - - int alterationTotalProfiledCount = AlterationCountServiceUtil.computeTotalProfiledCount(AlterationCountServiceUtil.hasGenePanelData(matchingGenePanelIds), - profiledCountsMap.getOrDefault(hugoGeneSymbol, 0), - sampleProfileCountWithoutGenePanelData, totalProfiledCount); - - alterationCountByGene.setNumberOfProfiledCases(alterationTotalProfiledCount); - - alterationCountByGene.setMatchingGenePanelIds(matchingGenePanelIds); - - }); - return alterationCounts; - } - - /** - * Updates alteration counts with MutSig Q-value data for significance. - * - * @param alterationCountByGenes List of alteration counts to update. - * @param studyViewFilterContext Context containing filter criteria. - * @return List of alteration counts updated with MutSig Q-value. - * @throws StudyNotFoundException if the specified study is not found. - */ - private List populateAlterationCountsWithMutSigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - final var mutSigs = getMutSigs(studyViewFilterContext); - // If MutSig is not empty update Mutated Genes - return AlterationCountServiceUtil.updateAlterationCountsWithMutSigQValue(alterationCountByGenes, mutSigs); - } - - /** - * Updates copy number alteration counts with GISTIC significance data. - * - * @param alterationCountByGenes List of alteration counts to update. - * @param studyViewFilterContext Context containing filter criteria. - * @return List of alteration counts updated with GISTIC significance data. - * @throws StudyNotFoundException if the specified study is not found. - */ - private List populateAlterationCountsWithCNASigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - final var gisticMap = getGisticMap(studyViewFilterContext); - return AlterationCountServiceUtil.updateAlterationCountsWithCNASigQValue(alterationCountByGenes, gisticMap); - } - - /** - * Retrieves the first molecular profile for each study based on the alteration type. - * - * @param studyViewFilterContext Context containing filter criteria. - * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). - * @return List of MolecularProfile objects representing the first profile for each study. - */ - private List getFirstMolecularProfileGroupedByStudy(StudyViewFilterContext studyViewFilterContext, AlterationType alterationType) { - final var molecularProfiles = studyViewRepository.getFilteredMolecularProfilesByAlterationType(studyViewFilterContext, alterationType.toString()); - return AlterationCountServiceUtil.getFirstMolecularProfileGroupedByStudy(molecularProfiles); - } - - /** - * Retrieves MutSig data for significantly mutated genes in the specified studies. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return Map of MutSig objects keyed by Hugo gene symbol. - * @throws StudyNotFoundException if the specified study is not found. - */ - private Map getMutSigs(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var distinctStudyIds = studyViewRepository.getFilteredStudyIds(studyViewFilterContext); - Map mutSigs = new HashMap<>(); - if (distinctStudyIds.size() == 1) { - var studyId = distinctStudyIds.getFirst(); - mutSigs = significantlyMutatedGeneService.getSignificantlyMutatedGenes( - studyId, - Projection.SUMMARY.name(), - null, - null, - null, - null) - .stream() - .collect(Collectors.toMap(MutSig::getHugoGeneSymbol, Function.identity())); - } - return mutSigs; - } - - /** - * Retrieves GISTIC data for significant copy number alterations in the specified studies. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return Map of GISTIC objects keyed by gene and G-score rank. - * @throws StudyNotFoundException if the specified study is not found. - */ - private Map, Gistic> getGisticMap(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var distinctStudyIds = studyViewRepository.getFilteredStudyIds(studyViewFilterContext); - Map, Gistic> gisticMap = new HashMap<>(); - if (distinctStudyIds.size() == 1) { - var studyId = distinctStudyIds.getFirst(); - List gisticList = significantCopyNumberRegionService.getSignificantCopyNumberRegions( - studyId, - Projection.SUMMARY.name(), - null, - null, - null, - null); - AlterationCountServiceUtil.setupGisticMap(gisticList, gisticMap); - } - return gisticMap; - } -} diff --git a/src/main/java/org/cbioportal/legacy/service/impl/ClinicalDataDensityPlotServiceImpl.java b/src/main/java/org/cbioportal/legacy/service/impl/ClinicalDataDensityPlotServiceImpl.java index f153b2ef134..118f5761930 100644 --- a/src/main/java/org/cbioportal/legacy/service/impl/ClinicalDataDensityPlotServiceImpl.java +++ b/src/main/java/org/cbioportal/legacy/service/impl/ClinicalDataDensityPlotServiceImpl.java @@ -7,7 +7,6 @@ import org.cbioportal.legacy.model.DensityPlotBin; import org.cbioportal.legacy.model.DensityPlotData; import org.cbioportal.legacy.service.ClinicalDataDensityPlotService; -import org.cbioportal.legacy.web.columnar.StudyViewColumnStoreController; import org.cbioportal.legacy.web.parameter.StudyViewFilter; import org.cbioportal.legacy.web.util.DensityPlotParameters; import org.springframework.cache.annotation.Cacheable; diff --git a/src/main/java/org/cbioportal/legacy/service/impl/StudyViewColumnarServiceImpl.java b/src/main/java/org/cbioportal/legacy/service/impl/StudyViewColumnarServiceImpl.java deleted file mode 100644 index 4e24dcf881d..00000000000 --- a/src/main/java/org/cbioportal/legacy/service/impl/StudyViewColumnarServiceImpl.java +++ /dev/null @@ -1,325 +0,0 @@ -package org.cbioportal.legacy.service.impl; - -import org.cbioportal.legacy.model.AlterationCountByGene; -import org.cbioportal.legacy.model.CaseListDataCount; -import org.cbioportal.legacy.model.ClinicalAttribute; -import org.cbioportal.legacy.model.ClinicalData; -import org.cbioportal.legacy.model.ClinicalDataCount; -import org.cbioportal.legacy.model.ClinicalDataCountItem; -import org.cbioportal.legacy.model.ClinicalEventTypeCount; -import org.cbioportal.legacy.model.CopyNumberCountByGene; -import org.cbioportal.legacy.model.GenericAssayDataCountItem; -import org.cbioportal.legacy.model.GenomicDataCount; -import org.cbioportal.legacy.model.PatientTreatmentReport; -import org.cbioportal.legacy.model.GenomicDataCountItem; -import org.cbioportal.legacy.model.Sample; -import org.cbioportal.legacy.model.SampleTreatmentReport; -import org.cbioportal.legacy.model.StudyViewFilterContext; -import org.cbioportal.legacy.persistence.StudyViewRepository; -import org.cbioportal.legacy.service.StudyViewColumnarService; -import org.cbioportal.legacy.service.alteration.AlterationCountByGeneService; -import org.cbioportal.legacy.service.exception.StudyNotFoundException; -import org.cbioportal.legacy.service.treatment.TreatmentCountReportService; -import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; -import org.cbioportal.legacy.utils.config.annotation.ConditionalOnProperty; -import org.cbioportal.legacy.web.parameter.ClinicalDataType; -import org.cbioportal.legacy.web.parameter.CustomSampleIdentifier; -import org.cbioportal.legacy.web.parameter.GenericAssayDataBinFilter; -import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; -import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; -import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.cbioportal.legacy.web.columnar.util.CustomDataFilterUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; - -import static org.cbioportal.legacy.web.columnar.util.ClinicalDataXyPlotUtil.combineClinicalDataForXyPlot; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Service -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") -public class StudyViewColumnarServiceImpl implements StudyViewColumnarService { - - - private final StudyViewRepository studyViewRepository; - private final CustomDataFilterUtil customDataFilterUtil; - - private final AlterationCountByGeneService alterationCountByGeneService; - private final TreatmentCountReportService treatmentCountReportService; - - @Autowired - public StudyViewColumnarServiceImpl(StudyViewRepository studyViewRepository, AlterationCountByGeneService alterationCountByGeneService, TreatmentCountReportService treatmentCountReportService, CustomDataFilterUtil customDataFilterUtil) { - this.studyViewRepository = studyViewRepository; - this.alterationCountByGeneService = alterationCountByGeneService; - this.treatmentCountReportService = treatmentCountReportService; - this.customDataFilterUtil = customDataFilterUtil; - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getFilteredSamples(StudyViewFilter studyViewFilter) { - - return studyViewRepository.getFilteredSamples(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getMutatedGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { - return alterationCountByGeneService.getMutatedGenes(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getMolecularProfileSampleCounts(StudyViewFilter studyViewFilter) { - return studyViewRepository.getMolecularProfileSampleCounts(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getClinicalEventTypeCounts(StudyViewFilter studyViewFilter) { - return studyViewRepository.getClinicalEventTypeCounts(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public PatientTreatmentReport getPatientTreatmentReport(StudyViewFilter studyViewFilter) { - return treatmentCountReportService.getPatientTreatmentReport(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public SampleTreatmentReport getSampleTreatmentReport(StudyViewFilter studyViewFilter) { - return treatmentCountReportService.getSampleTreatmentReport(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getGenomicDataBinCounts(StudyViewFilter studyViewFilter, List genomicDataBinFilters) { - return generateDataCountItemsFromDataCounts(studyViewRepository.getGenomicDataBinCounts(createContext(studyViewFilter), genomicDataBinFilters)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getGenericAssayDataBinCounts(StudyViewFilter studyViewFilter, List genericAssayDataBinFilters) { - return generateDataCountItemsFromDataCounts(studyViewRepository.getGenericAssayDataBinCounts(createContext(studyViewFilter), genericAssayDataBinFilters)); - } - - public List getCnaGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { - return alterationCountByGeneService.getCnaGenes(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getStructuralVariantGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { - return alterationCountByGeneService.getStructuralVariantGenes(createContext(studyViewFilter)); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public Map getClinicalAttributeDatatypeMap(StudyViewFilter studyViewFilter) { - return studyViewRepository.getClinicalAttributeDatatypeMap(); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getClinicalDataCounts(StudyViewFilter studyViewFilter, List filteredAttributes) { - - var context = createContext(studyViewFilter); - - List involvedCancerStudies = context.involvedCancerStudies(); - - var result = studyViewRepository.getClinicalDataCounts(context, filteredAttributes); - - // normalize data counts so that values like TRUE, True, and true are all merged in one count - result.forEach(item -> item.setCounts(StudyViewColumnarServiceUtil.normalizeDataCounts(item.getCounts()))); - - // attributes may be missing in result set because they have been filtered out - // e.g. if the filtered samples happen to have no SEX data, they will not appear in the list - // even though the inferred value of those attributes is NA - // the following code restores these counts for missing attributes - if (result.size() != filteredAttributes.size()) { - var attributes = getClinicalAttributesForStudies(involvedCancerStudies) - .stream() - .filter(attribute -> filteredAttributes.contains(attribute.getAttrId())) - .toList(); - - Integer filteredSampleCount = studyViewRepository.getFilteredSamplesCount(createContext(studyViewFilter)); - Integer filteredPatientCount = studyViewRepository.getFilteredPatientCount(createContext(studyViewFilter)); - - result = StudyViewColumnarServiceUtil.addClinicalDataCountsForMissingAttributes( - result, - attributes, - filteredSampleCount, - filteredPatientCount - ); - } - - return StudyViewColumnarServiceUtil.mergeClinicalDataCounts(result); - - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse()" - ) - public List getClinicalAttributesForStudies(List studyIds) { - return studyViewRepository.getClinicalAttributesForStudies(studyIds).stream().toList(); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getCaseListDataCounts(StudyViewFilter studyViewFilter) { - // the study view merges case lists by type across studies - // type is determined by the suffix of case list name (after study name) - var caseListDataCountsPerStudy = studyViewRepository.getCaseListDataCountsPerStudy(createContext(studyViewFilter)); - return StudyViewColumnarServiceUtil.mergeCaseListCounts(caseListDataCountsPerStudy); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getPatientClinicalData(StudyViewFilter studyViewFilter, List attributeIds) { - return studyViewRepository.getPatientClinicalData(createContext(studyViewFilter), attributeIds); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getSampleClinicalData(StudyViewFilter studyViewFilter, List attributeIds) { - return studyViewRepository.getSampleClinicalData(createContext(studyViewFilter), attributeIds); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getCNACountsByGeneSpecific(StudyViewFilter studyViewFilter, List genomicDataFilters) { - return studyViewRepository.getCNACounts(createContext(studyViewFilter), genomicDataFilters); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getGenericAssayDataCounts(StudyViewFilter studyViewFilter, List genericAssayDataFilters) { - return studyViewRepository.getGenericAssayDataCounts(createContext(studyViewFilter), genericAssayDataFilters); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getMutationCountsByGeneSpecific(StudyViewFilter studyViewFilter, List genomicDataFilters) { - List genomicDataCountItemList = new ArrayList<>(); - for (GenomicDataFilter genomicDataFilter : genomicDataFilters) { - Map counts = studyViewRepository.getMutationCounts(createContext(studyViewFilter), genomicDataFilter); - genomicDataCountItemList.add(StudyViewColumnarServiceUtil.createGenomicDataCountItemFromMutationCounts(genomicDataFilter, counts)); - } - return genomicDataCountItemList; - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List getMutationTypeCountsByGeneSpecific(StudyViewFilter studyViewFilter, List genomicDataFilters) { - return studyViewRepository.getMutationCountsByType(createContext(studyViewFilter), genomicDataFilters); - } - - @Cacheable( - cacheResolver = "staticRepositoryCacheOneResolver", - condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" - ) - @Override - public List fetchClinicalDataForXyPlot( - StudyViewFilter studyViewFilter, - List attributeIds, - boolean shouldFilterNonEmptyClinicalData - ) { - List sampleClinicalDataList = this.getSampleClinicalData(studyViewFilter, attributeIds); - List patientClinicalDataList = this.getPatientClinicalData(studyViewFilter, attributeIds); - List samples = Collections.emptyList(); - - if (!patientClinicalDataList.isEmpty()) { - // fetch samples for the given study view filter. - // we need this to construct the complete patient to sample map. - samples = this.getFilteredSamples(studyViewFilter); - } - - return combineClinicalDataForXyPlot( - sampleClinicalDataList, - patientClinicalDataList, - samples, - shouldFilterNonEmptyClinicalData - ); - } - - private StudyViewFilterContext createContext(StudyViewFilter studyViewFilter) { - List customSampleIdentifiers = customDataFilterUtil.extractCustomDataSamples(studyViewFilter); - List involvedCancerStudies = customDataFilterUtil.extractInvolvedCancerStudies(studyViewFilter); - return new StudyViewFilterContext(studyViewFilter, customSampleIdentifiers, involvedCancerStudies); - } - - private List generateDataCountItemsFromDataCounts(List dataCounts) { - return dataCounts.stream().collect(Collectors.groupingBy(ClinicalDataCount::getAttributeId)) - .entrySet().parallelStream().map(e -> { - ClinicalDataCountItem item = new ClinicalDataCountItem(); - item.setAttributeId(e.getKey()); - item.setCounts(StudyViewColumnarServiceUtil.normalizeDataCounts(e.getValue())); - return item; - }).toList(); - } - - - -} diff --git a/src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportService.java b/src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportService.java deleted file mode 100644 index 82ca2829d96..00000000000 --- a/src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportService.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.cbioportal.legacy.service.treatment; - -import org.cbioportal.legacy.model.PatientTreatmentReport; -import org.cbioportal.legacy.model.SampleTreatmentReport; -import org.cbioportal.legacy.model.StudyViewFilterContext; -import org.cbioportal.legacy.web.parameter.CustomSampleIdentifier; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; - -import java.util.List; - -public interface TreatmentCountReportService { - PatientTreatmentReport getPatientTreatmentReport(StudyViewFilterContext studyViewFilterContext); - SampleTreatmentReport getSampleTreatmentReport(StudyViewFilterContext studyViewFilterContext); -} diff --git a/src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportServiceImpl.java b/src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportServiceImpl.java deleted file mode 100644 index 1cbdc366a29..00000000000 --- a/src/main/java/org/cbioportal/legacy/service/treatment/TreatmentCountReportServiceImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.cbioportal.legacy.service.treatment; - -import org.cbioportal.legacy.model.PatientTreatmentReport; -import org.cbioportal.legacy.model.SampleTreatmentReport; -import org.cbioportal.legacy.model.SampleTreatmentRow; -import org.cbioportal.legacy.model.StudyViewFilterContext; -import org.cbioportal.legacy.model.TemporalRelation; -import org.cbioportal.legacy.persistence.StudyViewRepository; -import org.cbioportal.legacy.utils.config.annotation.ConditionalOnProperty; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.Set; -import java.util.stream.Stream; - -@Service -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") -public class TreatmentCountReportServiceImpl implements TreatmentCountReportService { - - private final StudyViewRepository studyViewRepository; - - @Autowired - public TreatmentCountReportServiceImpl(StudyViewRepository studyViewRepository) { - this.studyViewRepository = studyViewRepository; - } - - @Override - public PatientTreatmentReport getPatientTreatmentReport(StudyViewFilterContext studyViewFilterContext) { - var patientTreatments = studyViewRepository.getPatientTreatments(studyViewFilterContext); - var totalPatientTreatmentCount = studyViewRepository.getTotalPatientTreatmentCount(studyViewFilterContext); - return new PatientTreatmentReport(totalPatientTreatmentCount, 0, patientTreatments); - } - - @Override - public SampleTreatmentReport getSampleTreatmentReport(StudyViewFilterContext studyViewFilterContext) { - var sampleTreatments = studyViewRepository.getSampleTreatments(studyViewFilterContext) - .stream() - .flatMap(sampleTreatment -> - Stream.of(new SampleTreatmentRow(TemporalRelation.Pre, sampleTreatment.treatment(), sampleTreatment.preSampleCount(), Set.of()), - new SampleTreatmentRow(TemporalRelation.Post, sampleTreatment.treatment(), sampleTreatment.postSampleCount(), Set.of() )) - ) - .filter(sampleTreatment -> sampleTreatment.getCount() > 0 ) - .toList(); - var totalSampleTreatmentCount = studyViewRepository.getTotalSampleTreatmentCount(studyViewFilterContext); - return new SampleTreatmentReport(totalSampleTreatmentCount, sampleTreatments); - } - -} diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java b/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java index 5f9755830b6..3a808266213 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java @@ -44,7 +44,8 @@ // but BasicDataBinner can support clinical data counts too // after we switched clinical data counts to use this, then We can remove ClinicalDataBinner @Component -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") +@Deprecated +@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "test") public class BasicDataBinner { private final StudyViewColumnarService studyViewColumnarService; private final DataBinner dataBinner; diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java b/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java index 2e8b9375b93..56a4f86d4fe 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java @@ -22,7 +22,8 @@ import java.util.stream.Collectors; @Component -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") +@Deprecated +@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "test") public class ClinicalDataBinner { private final StudyViewColumnarService studyViewColumnarService; private final DataBinner dataBinner; diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java b/src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java deleted file mode 100644 index 4750880ee2b..00000000000 --- a/src/main/java/org/cbioportal/legacy/web/columnar/StudyViewColumnStoreController.java +++ /dev/null @@ -1,688 +0,0 @@ -package org.cbioportal.legacy.web.columnar; - -import io.swagger.v3.oas.annotations.Hidden; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import jakarta.validation.Valid; -import org.cbioportal.legacy.model.AlterationCountByGene; -import org.cbioportal.legacy.model.AlterationFilter; -import org.cbioportal.legacy.model.CaseListDataCount; -import org.cbioportal.legacy.model.ClinicalData; -import org.cbioportal.legacy.model.ClinicalDataBin; -import org.cbioportal.legacy.model.ClinicalDataCountItem; -import org.cbioportal.legacy.model.ClinicalEventKeyCode; -import org.cbioportal.legacy.model.ClinicalEventTypeCount; -import org.cbioportal.legacy.model.ClinicalViolinPlotData; -import org.cbioportal.legacy.model.CopyNumberCountByGene; -import org.cbioportal.legacy.model.DensityPlotData; -import org.cbioportal.legacy.model.GenericAssayDataBin; -import org.cbioportal.legacy.model.GenericAssayDataCountItem; -import org.cbioportal.legacy.model.GenomicDataBin; -import org.cbioportal.legacy.model.GenomicDataCount; -import org.cbioportal.legacy.model.PatientTreatmentReport; -import org.cbioportal.legacy.model.Sample; -import org.cbioportal.legacy.model.SampleTreatmentReport; -import org.cbioportal.legacy.service.ClinicalDataDensityPlotService; -import org.cbioportal.legacy.model.GenomicDataCountItem; -import org.cbioportal.legacy.service.CustomDataService; -import org.cbioportal.legacy.service.StudyViewColumnarService; -import org.cbioportal.legacy.service.ViolinPlotService; -import org.cbioportal.legacy.service.exception.StudyNotFoundException; -import org.cbioportal.legacy.service.util.CustomDataSession; -import org.cbioportal.legacy.utils.config.annotation.ConditionalOnProperty; -import org.cbioportal.legacy.web.columnar.util.CustomDataFilterUtil; -import org.cbioportal.legacy.web.columnar.util.NewStudyViewFilterUtil; -import org.cbioportal.legacy.web.config.annotation.InternalApi; -import org.cbioportal.legacy.web.parameter.ClinicalDataBinCountFilter; -import org.cbioportal.legacy.web.parameter.ClinicalDataCountFilter; -import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; -import org.cbioportal.legacy.web.parameter.DataBinMethod; -import org.cbioportal.legacy.web.parameter.GenericAssayDataBinCountFilter; -import org.cbioportal.legacy.web.parameter.GenericAssayDataCountFilter; -import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; -import org.cbioportal.legacy.web.parameter.GenomicDataBinCountFilter; -import org.cbioportal.legacy.web.parameter.GenomicDataCountFilter; -import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.legacy.web.parameter.MutationOption; -import org.cbioportal.legacy.web.parameter.Projection; -import org.cbioportal.legacy.web.parameter.SampleIdentifier; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.cbioportal.legacy.web.util.DensityPlotParameters; -import org.cbioportal.legacy.web.util.StudyViewFilterUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.RequestAttribute; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static java.util.stream.Collectors.toSet; - -@InternalApi -@RestController() -@RequestMapping("/api") -@Validated -@ConditionalOnProperty(name = "clickhouse_mode", havingValue = "true") -public class StudyViewColumnStoreController { - - private final StudyViewColumnarService studyViewColumnarService; - private final ClinicalDataBinner clinicalDataBinner; - - private final BasicDataBinner basicDataBinner; - private final ClinicalDataDensityPlotService clinicalDataDensityPlotService; - private final ViolinPlotService violinPlotService; - private final CustomDataService customDataService; - private final StudyViewFilterUtil studyViewFilterUtil; - private final CustomDataFilterUtil customDataFilterUtil; - - @Autowired - public StudyViewColumnStoreController(StudyViewColumnarService studyViewColumnarService, - ClinicalDataBinner clinicalDataBinner, - BasicDataBinner basicDataBinner, - ClinicalDataDensityPlotService clinicalDataDensityPlotService, - ViolinPlotService violinPlotService, - CustomDataService customDataService, - StudyViewFilterUtil studyViewFilterUtil, - CustomDataFilterUtil customDataFilterUtil - ) { - this.studyViewColumnarService = studyViewColumnarService; - this.clinicalDataBinner = clinicalDataBinner; - this.basicDataBinner = basicDataBinner; - this.clinicalDataDensityPlotService = clinicalDataDensityPlotService; - this.violinPlotService = violinPlotService; - this.customDataService = customDataService; - this.studyViewFilterUtil = studyViewFilterUtil; - this.customDataFilterUtil = customDataFilterUtil; - } - - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/filtered-samples/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> fetchFilteredSamples( - @RequestParam(defaultValue = "false") Boolean negateFilters, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter, - @RequestBody(required = false) StudyViewFilter studyViewFilter) { - return new ResponseEntity<>( - studyViewColumnarService.getFilteredSamples(interceptedStudyViewFilter), - HttpStatus.OK - ); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/mutated-genes/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> fetchMutatedGenes( - @RequestBody(required = false) StudyViewFilter studyViewFilter, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter - ) throws StudyNotFoundException { - AlterationFilter annotationFilters = interceptedStudyViewFilter.getAlterationFilter(); - return new ResponseEntity<>( - studyViewColumnarService.getMutatedGenes(interceptedStudyViewFilter), - HttpStatus.OK - ); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/molecular-profile-sample-counts/fetch", method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch sample counts by study view filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataCount.class)))) - public ResponseEntity> fetchMolecularProfileSampleCounts( - @Parameter(required = true, description = "Study view filter") - @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter - ) - { - return new ResponseEntity>( - studyViewColumnarService.getMolecularProfileSampleCounts(interceptedStudyViewFilter) - , HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/column-store/cna-genes/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> fetchCnaGenes( - @RequestBody(required = false) StudyViewFilter studyViewFilter, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter - ) throws StudyNotFoundException { - return new ResponseEntity<>( - studyViewColumnarService.getCnaGenes(interceptedStudyViewFilter), - HttpStatus.OK - ); - } - - @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/column-store/structuralvariant-genes/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch structural variant genes by study view filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = AlterationCountByGene.class)))) - public ResponseEntity> fetchStructuralVariantGenes( - @Parameter(required = true, description = "Study view filter") - @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. This attribute is needed for the @PreAuthorize tag above. - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. - @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter - ) throws StudyNotFoundException { - return new ResponseEntity<>(studyViewColumnarService.getStructuralVariantGenes(interceptedStudyViewFilter), HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils" + - ".security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/clinical-data-counts/fetch", - method=RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> fetchClinicalDataCounts( - @RequestBody(required = false) ClinicalDataCountFilter clinicalDataCountFilter, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedClinicalDataCountFilter") ClinicalDataCountFilter interceptedClinicalDataCountFilter) { - - List attributes = interceptedClinicalDataCountFilter.getAttributes(); - StudyViewFilter studyViewFilter = interceptedClinicalDataCountFilter.getStudyViewFilter(); - - if (attributes.size() == 1) { - NewStudyViewFilterUtil.removeClinicalDataFilter(attributes.getFirst().getAttributeId(), studyViewFilter.getClinicalDataFilters()); - } - List result = studyViewColumnarService.getClinicalDataCounts( - studyViewFilter, - attributes.stream().map(ClinicalDataFilter::getAttributeId).collect(Collectors.toList())); - return new ResponseEntity<>(result, HttpStatus.OK); - - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/sample-lists-counts/fetch", method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch case list sample counts by study view filter") - public List fetchCaseListCounts( - @Parameter(required = true, description = "Study view filter") - @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter) { - - return studyViewColumnarService.getCaseListDataCounts(interceptedStudyViewFilter); - - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/clinical-data-bin-counts/fetch", method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> fetchClinicalDataBinCounts( - @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, - @RequestBody(required = false) ClinicalDataBinCountFilter clinicalDataBinCountFilter, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedClinicalDataBinCountFilter") ClinicalDataBinCountFilter interceptedClinicalDataBinCountFilter - ) { - List clinicalDataBins = clinicalDataBinner.fetchClinicalDataBinCounts( - dataBinMethod, - interceptedClinicalDataBinCountFilter, - true - ); - return new ResponseEntity<>(clinicalDataBins, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/clinical-data-density-plot/fetch", - method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch clinical data density plot bins by study view filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(schema = @Schema(implementation = DensityPlotData.class))) - @Validated - public ResponseEntity fetchClinicalDataDensityPlot( - @Parameter(required = true, description = "Clinical Attribute ID of the X axis") - @RequestParam String xAxisAttributeId, - @Parameter(description = "Number of the bins in X axis") - @RequestParam(defaultValue = "50") Integer xAxisBinCount, - @Parameter(description = "Starting point of the X axis, if different than smallest value") - @RequestParam(required = false) BigDecimal xAxisStart, - @Parameter(description = "Starting point of the X axis, if different than largest value") - @RequestParam(required = false) BigDecimal xAxisEnd, - @Parameter(required = true, description = "Clinical Attribute ID of the Y axis") - @RequestParam String yAxisAttributeId, - @Parameter(description = "Number of the bins in Y axis") - @RequestParam(defaultValue = "50") Integer yAxisBinCount, - @Parameter(description = "Starting point of the Y axis, if different than smallest value") - @RequestParam(required = false) BigDecimal yAxisStart, - @Parameter(description = "Starting point of the Y axis, if different than largest value") - @RequestParam(required = false) BigDecimal yAxisEnd, - @Parameter(description="Use log scale for X axis") - @RequestParam(required = false, defaultValue = "false") Boolean xAxisLogScale, - @Schema(defaultValue = "false") - @Parameter(description="Use log scale for Y axis") - @RequestParam(required = false, defaultValue = "false") Boolean yAxisLogScale, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter, - @Parameter(required = true, description = "Study view filter") - @RequestBody(required = false) StudyViewFilter studyViewFilter - ) { - DensityPlotParameters densityPlotParameters = - new DensityPlotParameters.Builder() - .xAxisAttributeId(xAxisAttributeId) - .yAxisAttributeId(yAxisAttributeId) - .xAxisBinCount(xAxisBinCount) - .yAxisBinCount(yAxisBinCount) - .xAxisStart(xAxisStart) - .yAxisStart(yAxisStart) - .xAxisEnd(xAxisEnd) - .yAxisEnd(yAxisEnd) - .xAxisLogScale(xAxisLogScale) - .yAxisLogScale(yAxisLogScale) - .build(); - - List combinedClinicalDataList = studyViewColumnarService.fetchClinicalDataForXyPlot( - interceptedStudyViewFilter, - List.of(xAxisAttributeId, yAxisAttributeId), - false - ); - - DensityPlotData result = clinicalDataDensityPlotService.getDensityPlotData( - combinedClinicalDataList, - densityPlotParameters, - interceptedStudyViewFilter - ); - - return new ResponseEntity<>(result, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/clinical-data-violin-plots/fetch", - method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch violin plot curves per categorical clinical data value, filtered by study view filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(schema = @Schema(implementation = ClinicalViolinPlotData.class))) - public ResponseEntity fetchClinicalDataViolinPlots( - @Parameter(required = true, description = "Clinical Attribute ID of the categorical attribute") - @RequestParam String categoricalAttributeId, - @Parameter(required = true, description = "Clinical Attribute ID of the numerical attribute") - @RequestParam String numericalAttributeId, - @Parameter(description = "Starting point of the violin plot axis, if different than smallest value") - @RequestParam(required = false) BigDecimal axisStart, - @Parameter(description = "Ending point of the violin plot axis, if different than largest value") - @RequestParam(required = false) BigDecimal axisEnd, - @Parameter(description = "Number of points in the curve") - @RequestParam(required = false, defaultValue = "100") BigDecimal numCurvePoints, - @Parameter(description="Use log scale for the numerical attribute") - @RequestParam(required = false, defaultValue = "false") Boolean logScale, - @Parameter(description="Sigma stepsize multiplier") - @RequestParam(required = false, defaultValue = "1") BigDecimal sigmaMultiplier, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter, - @Parameter(required = true, description = "Study view filter") - @Valid @RequestBody(required = false) StudyViewFilter studyViewFilter - ) { - // fetch the samples by using the provided study view filter - List filteredSamples = studyViewColumnarService.getFilteredSamples(interceptedStudyViewFilter); - - // remove the numerical clinical data filter from the study view filter. - // this new modified filter is used to fetch sample and patient clinical data. - // this is required to get the complete violin plot data. - // filteredSamples reflects only the original unmodified study view filter. - // we will need to fetch samples again to get the samples corresponding to this modified filter, - // otherwise patient to sample mapping may be incomplete. - if (interceptedStudyViewFilter.getClinicalDataFilters() != null) { - interceptedStudyViewFilter.getClinicalDataFilters().stream() - .filter(f->f.getAttributeId().equals(numericalAttributeId)) - .findAny() - .ifPresent(f->interceptedStudyViewFilter.getClinicalDataFilters().remove(f)); - } - - List combinedClinicalDataList = studyViewColumnarService.fetchClinicalDataForXyPlot( - interceptedStudyViewFilter, - List.of(numericalAttributeId, categoricalAttributeId), - true // filter out clinical data with empty attribute values due to Clickhouse migration - ); - - // Only mutation count can use log scale - boolean useLogScale = logScale && numericalAttributeId.equals("MUTATION_COUNT"); - - Set sampleIdsSet = filteredSamples - .stream() - .map(s -> s.getInternalId()) - .collect(toSet()); - - ClinicalViolinPlotData result = violinPlotService.getClinicalViolinPlotData( - combinedClinicalDataList, - sampleIdsSet, - axisStart, - axisEnd, - numCurvePoints, - useLogScale, - sigmaMultiplier, - interceptedStudyViewFilter - ); - - return new ResponseEntity<>(result, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/genomic-data-counts/fetch", - method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch genomic data counts by GenomicDataCountFilter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataCountItem.class)))) - public ResponseEntity> fetchGenomicDataCounts( - @Parameter(required = true, description = "Genomic data count filter") @Valid @RequestBody(required = false) GenomicDataCountFilter genomicDataCountFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(required = true, description = "Intercepted Genomic Data Count Filter") - @Valid @RequestAttribute(required = false, value = "interceptedGenomicDataCountFilter") GenomicDataCountFilter interceptedGenomicDataCountFilter - ) throws StudyNotFoundException { - List genomicDataFilters = interceptedGenomicDataCountFilter.getGenomicDataFilters(); - StudyViewFilter studyViewFilter = interceptedGenomicDataCountFilter.getStudyViewFilter(); - // when there is only one filter, it means study view is doing a single chart filter operation - // remove filter from studyViewFilter to return all data counts - // the reason we do this is to make sure after chart get filtered, user can still see unselected portion of the chart - if (genomicDataFilters.size() == 1) { - studyViewFilterUtil.removeSelfFromGenomicDataFilter( - genomicDataFilters.get(0).getHugoGeneSymbol(), - genomicDataFilters.get(0).getProfileType(), - studyViewFilter); - } - - // This endpoint is CNA specific. The name choice of "genomic data" does not imply it support other genomic data types - List result = studyViewColumnarService.getCNACountsByGeneSpecific(studyViewFilter, genomicDataFilters); - - return new ResponseEntity<>(result, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/generic-assay-data-counts/fetch", - method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch generic assay data counts by study view filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenericAssayDataCountItem.class)))) - public ResponseEntity> fetchGenericAssayDataCounts( - @Parameter(required = true, description = "Generic assay data count filter") @Valid @RequestBody(required = false) GenericAssayDataCountFilter genericAssayDataCountFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this - // attribute is needed for the @PreAuthorize tag above. - @Valid @RequestAttribute(required = false, value = "interceptedGenericAssayDataCountFilter") GenericAssayDataCountFilter interceptedGenericAssayDataCountFilter) { - - List gaFilters = interceptedGenericAssayDataCountFilter.getGenericAssayDataFilters(); - StudyViewFilter studyViewFilter = interceptedGenericAssayDataCountFilter.getStudyViewFilter(); - // when there is only one filter, it means study view is doing a single chart filter operation - // remove filter from studyViewFilter to return all data counts - // the reason we do this is to make sure after chart get filtered, user can still see unselected portion of the chart - - if (gaFilters.size() == 1) { - studyViewFilterUtil.removeSelfFromGenericAssayFilter(gaFilters.getFirst().getStableId(), studyViewFilter); - } - - return new ResponseEntity<>(studyViewColumnarService.getGenericAssayDataCounts(studyViewFilter, gaFilters), HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/mutation-data-counts/fetch", - method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch mutation data counts by GenomicDataCountFilter") - public ResponseEntity> fetchMutationDataCounts( - @Parameter(description = "Level of detail of the response") - @RequestParam(defaultValue = "SUMMARY") Projection projection, - @Parameter(required = true, description = "Genomic data count filter") - @Valid @RequestBody(required = false) GenomicDataCountFilter genomicDataCountFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @Valid @RequestAttribute(required = false, value = "interceptedGenomicDataCountFilter") GenomicDataCountFilter interceptedGenomicDataCountFilter - ) { - List genomicDataFilters = interceptedGenomicDataCountFilter.getGenomicDataFilters(); - StudyViewFilter studyViewFilter = interceptedGenomicDataCountFilter.getStudyViewFilter(); - // when there is only one filter, it means study view is doing a single chart filter operation - // remove filter from studyViewFilter to return all data counts - // the reason we do this is to make sure after chart get filtered, user can still see unselected portion of the chart - if (genomicDataFilters.size() == 1 && projection == Projection.SUMMARY) { - studyViewFilterUtil.removeSelfFromMutationDataFilter( - genomicDataFilters.get(0).getHugoGeneSymbol(), - genomicDataFilters.get(0).getProfileType(), - MutationOption.MUTATED, - studyViewFilter); - } - - List result = projection == Projection.SUMMARY ? - studyViewColumnarService.getMutationCountsByGeneSpecific(studyViewFilter, genomicDataFilters) : - studyViewColumnarService.getMutationTypeCountsByGeneSpecific(studyViewFilter, genomicDataFilters); - - return new ResponseEntity<>(result, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/clinical-event-type-counts/fetch", - method = RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Get Counts of Clinical Event Types by Study View Filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalEventTypeCount.class)))) - public ResponseEntity> getClinicalEventTypeCounts( - @Parameter(required = true, description = "Study view filter") - @Valid - @RequestBody(required = false) - StudyViewFilter studyViewFilter, - - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") - Collection involvedCancerStudies, - - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid - @RequestAttribute(required = false, value = "interceptedStudyViewFilter") - StudyViewFilter interceptedStudyViewFilter - ) { - return new ResponseEntity<>(studyViewColumnarService.getClinicalEventTypeCounts(interceptedStudyViewFilter), HttpStatus.OK); - } - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/treatments/patient-counts/fetch", - method = RequestMethod.POST, - produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Get all patient level treatments") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(schema = @Schema(implementation = PatientTreatmentReport.class))) - public ResponseEntity fetchPatientTreatmentCounts( - @Parameter(required = false ) - @RequestParam(name = "tier", required = false, defaultValue = "Agent") - ClinicalEventKeyCode tier, - - @Parameter(required = true, description = "Study view filter") - @Valid - @RequestBody(required = false) - StudyViewFilter studyViewFilter, - - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") - Collection involvedCancerStudies, - - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid - @RequestAttribute(required = false, value = "interceptedStudyViewFilter") - StudyViewFilter interceptedStudyViewFilter - ) { - return new ResponseEntity<>(studyViewColumnarService.getPatientTreatmentReport(interceptedStudyViewFilter), - HttpStatus.OK); - } - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/treatments/sample-counts/fetch", - method = RequestMethod.POST, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(schema = @Schema(implementation = SampleTreatmentReport.class))) - public ResponseEntity fetchSampleTreatmentCounts( - @Parameter(required = false ) - @RequestParam(name = "tier", required = false, defaultValue = "Agent") - ClinicalEventKeyCode tier, - - @Parameter(required = true, description = "Study view filter") - @Valid - @RequestBody(required = false) - StudyViewFilter studyViewFilter, - - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") - Collection involvedCancerStudies, - - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid - @RequestAttribute(required = false, value = "interceptedStudyViewFilter") - StudyViewFilter interceptedStudyViewFilter - ) { - return new ResponseEntity<>(studyViewColumnarService.getSampleTreatmentReport(interceptedStudyViewFilter), - HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/custom-data-counts/fetch", - method=RequestMethod.POST, - consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch custom data counts by study view filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalDataCountItem.class)))) - public ResponseEntity> fetchCustomDataCounts( - @Parameter(required = true, description = "Custom data count filter") @Valid @RequestBody(required = false) ClinicalDataCountFilter clinicalDataCountFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui - // interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui - // interface. this attribute is needed for the - // @PreAuthorize tag above. - @Valid @RequestAttribute(required = false, value = "interceptedClinicalDataCountFilter") ClinicalDataCountFilter interceptedClinicalDataCountFilter) { - - List attributes = interceptedClinicalDataCountFilter.getAttributes(); - StudyViewFilter studyViewFilter = interceptedClinicalDataCountFilter.getStudyViewFilter(); - if (attributes.size() == 1) { - NewStudyViewFilterUtil.removeClinicalDataFilter(attributes.getFirst().getAttributeId(), studyViewFilter.getCustomDataFilters()); - } - - List filteredSampleIdentifiers = studyViewColumnarService.getFilteredSamples(studyViewFilter).stream().map(sample -> studyViewFilterUtil.buildSampleIdentifier(sample.getCancerStudyIdentifier(), sample.getStableId())).toList(); - - if (filteredSampleIdentifiers.isEmpty()) { - return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK); - } - - final List attributeIds = attributes.stream().map(ClinicalDataFilter::getAttributeId).toList(); - Map customDataSessionsMap = customDataService.getCustomDataSessions(attributeIds); - - List result = customDataFilterUtil.getCustomDataCounts(filteredSampleIdentifiers, customDataSessionsMap); - - return new ResponseEntity<>(result, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/custom-data-bin-counts/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method= RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @Operation(description = "Fetch custom data bin counts by study view filter") - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalDataBin.class)))) - public ResponseEntity> fetchCustomDataBinCounts( - @Parameter(description = "Method for data binning") - @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, - @Parameter(required = true, description = "Clinical data bin count filter") - @Valid @RequestBody(required = false) ClinicalDataBinCountFilter clinicalDataBinCountFilter, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. this attribute is needed for the @PreAuthorize tag above. - @Valid @RequestAttribute(required = false, value = "interceptedClinicalDataBinCountFilter") ClinicalDataBinCountFilter interceptedClinicalDataBinCountFilter - ) { - List customDataBins = basicDataBinner.getDataBins( - dataBinMethod, - interceptedClinicalDataBinCountFilter, - true - ); - - return new ResponseEntity<>(customDataBins, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/genomic-data-bin-counts/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataBin.class)))) - public ResponseEntity> fetchGenomicDataBinCounts( - @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, - @RequestBody(required = false) GenomicDataBinCountFilter genomicDataBinCountFilter, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedGenomicDataBinCountFilter") GenomicDataBinCountFilter interceptedGenomicDataBinCountFilter - ) { - List genomicDataBins = basicDataBinner.getDataBins( - dataBinMethod, - interceptedGenomicDataBinCountFilter, - true - ); - return new ResponseEntity<>(genomicDataBins, HttpStatus.OK); - } - - @Hidden // should unhide when we remove legacy controller - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/column-store/generic-assay-data-bin-counts/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ApiResponse(responseCode = "200", description = "OK", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenericAssayDataBin.class)))) - public ResponseEntity> fetchGenericAssayDataBinCounts( - @RequestParam(defaultValue = "DYNAMIC") DataBinMethod dataBinMethod, - @RequestBody(required = false) GenericAssayDataBinCountFilter genericAssayDataBinCountFilter, - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @RequestAttribute(required = false, value = "interceptedGenericAssayDataBinCountFilter") GenericAssayDataBinCountFilter interceptedGenericAssayDataBinCountFilter - ) { - List genericAssayDataBins = basicDataBinner.getDataBins( - dataBinMethod, - interceptedGenericAssayDataBinCountFilter, - true - ); - return new ResponseEntity<>(genericAssayDataBins, HttpStatus.OK); - } -} diff --git a/src/main/java/org/cbioportal/legacy/web/parameter/StudyViewFilter.java b/src/main/java/org/cbioportal/legacy/web/parameter/StudyViewFilter.java index 61d3f7f5356..93d529b8d1c 100644 --- a/src/main/java/org/cbioportal/legacy/web/parameter/StudyViewFilter.java +++ b/src/main/java/org/cbioportal/legacy/web/parameter/StudyViewFilter.java @@ -1,8 +1,11 @@ package org.cbioportal.legacy.web.parameter; import java.io.Serializable; +import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -98,6 +101,17 @@ public void setStudyIds(List studyIds) { this.studyIds = studyIds; } + public Set getUniqueStudyIds() { + Set uniqueStudyIds = new HashSet<>(); + if (sampleIdentifiers != null && !sampleIdentifiers.isEmpty()) { + uniqueStudyIds.addAll(sampleIdentifiers.stream().map(SampleIdentifier::getStudyId).collect(Collectors.toSet())); + } + if (studyIds != null && !studyIds.isEmpty()) { + uniqueStudyIds.addAll(studyIds); + } + return uniqueStudyIds; + } + public List getClinicalDataFilters() { return clinicalDataFilters; } diff --git a/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml b/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml index e322525c28e..970196a7443 100644 --- a/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml +++ b/src/main/resources/mappers/clickhouse/cancerstudy/CancerStudyMapper.xml @@ -137,7 +137,7 @@ + type="org.cbioportal.domain.cancerstudy.CancerStudyMetadata"> @@ -164,12 +164,12 @@ - + + type="org.cbioportal.domain.cancerstudy.CancerStudyMetadata"> @@ -183,11 +183,11 @@ - + - + diff --git a/src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml b/src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml index b0ee0ba1fcb..2ff1ff4dc0b 100644 --- a/src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml +++ b/src/main/resources/mappers/clickhouse/sample/ClickhouseSampleMapper.xml @@ -18,7 +18,7 @@ + type="org.cbioportal.domain.sample.Sample"> diff --git a/src/test/java/org/cbioportal/cancerstudy/usecase/GetCancerStudyMetadataUseCaseTest.java b/src/test/java/org/cbioportal/cancerstudy/usecase/GetCancerStudyMetadataUseCaseTest.java index 771ae3b040e..86e8dfa8c86 100644 --- a/src/test/java/org/cbioportal/cancerstudy/usecase/GetCancerStudyMetadataUseCaseTest.java +++ b/src/test/java/org/cbioportal/cancerstudy/usecase/GetCancerStudyMetadataUseCaseTest.java @@ -1,6 +1,7 @@ package org.cbioportal.cancerstudy.usecase; -import org.cbioportal.cancerstudy.repository.CancerStudyRepository; +import org.cbioportal.domain.cancerstudy.repository.CancerStudyRepository; +import org.cbioportal.domain.cancerstudy.usecase.GetCancerStudyMetadataUseCase; import org.cbioportal.shared.SortAndSearchCriteria; import org.cbioportal.shared.enums.ProjectionType; import org.junit.Assert; From a640804d73312de592e31eb86840404faa2757da Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Tue, 18 Feb 2025 13:54:38 -0500 Subject: [PATCH 6/9] Extract UseCases --- .../AbstractAlterationCountByGeneUseCase.java | 108 +++++++++ .../usecase/AlterationCountByGeneUseCase.java | 215 ------------------ .../AlterationCountByGeneUseCases.java | 13 ++ .../GetAlterationCountByGeneUseCase.java | 144 ++++++++++++ .../GetCnaAlterationCountByGeneUseCase.java | 131 +++++++++++ .../studyview/StudyViewFilterFactory.java | 7 + .../domain/studyview/StudyViewService.java | 27 ++- .../GetPatientTreatmentReportUseCase.java | 36 +++ ...a => GetSampleTreatmentReportUseCase.java} | 24 +- .../usecase/TreatmentCountReportUseCases.java | 12 + 10 files changed, 477 insertions(+), 240 deletions(-) create mode 100644 src/main/java/org/cbioportal/domain/alteration/usecase/AbstractAlterationCountByGeneUseCase.java delete mode 100644 src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCase.java create mode 100644 src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCases.java create mode 100644 src/main/java/org/cbioportal/domain/alteration/usecase/GetAlterationCountByGeneUseCase.java create mode 100644 src/main/java/org/cbioportal/domain/alteration/usecase/GetCnaAlterationCountByGeneUseCase.java create mode 100644 src/main/java/org/cbioportal/domain/treatment/usecase/GetPatientTreatmentReportUseCase.java rename src/main/java/org/cbioportal/domain/treatment/usecase/{FilteredTreatmentCountReportUseCase.java => GetSampleTreatmentReportUseCase.java} (66%) create mode 100644 src/main/java/org/cbioportal/domain/treatment/usecase/TreatmentCountReportUseCases.java diff --git a/src/main/java/org/cbioportal/domain/alteration/usecase/AbstractAlterationCountByGeneUseCase.java b/src/main/java/org/cbioportal/domain/alteration/usecase/AbstractAlterationCountByGeneUseCase.java new file mode 100644 index 00000000000..89431068834 --- /dev/null +++ b/src/main/java/org/cbioportal/domain/alteration/usecase/AbstractAlterationCountByGeneUseCase.java @@ -0,0 +1,108 @@ +package org.cbioportal.domain.alteration.usecase; + +import org.cbioportal.domain.alteration.repository.AlterationRepository; +import org.cbioportal.domain.generic_assay.usecase.GetFilteredMolecularProfilesByAlterationType; +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.AlterationType; +import org.cbioportal.legacy.model.MolecularProfile; +import org.springframework.lang.NonNull; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +abstract class AbstractAlterationCountByGeneUseCase { + + private static final String WHOLE_EXOME_SEQUENCING = "WES"; + + private final AlterationRepository alterationRepository; + private final GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType; + + AbstractAlterationCountByGeneUseCase(AlterationRepository alterationRepository, GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType){ + this.alterationRepository = alterationRepository; + this.getFilteredMolecularProfilesByAlterationType = getFilteredMolecularProfilesByAlterationType; + } + + /** + * Populates alteration counts with profile data, including the total profiled count and matching gene panel IDs. + * + * @param alterationCounts List of alteration counts to enrich. + * @param studyViewFilterContext Context containing filter criteria. + * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). + * @param The type of alteration count. + * @return List of enriched alteration counts. + */ + List populateAlterationCounts(@NonNull List alterationCounts, + @NonNull StudyViewFilterContext studyViewFilterContext, + @NonNull AlterationType alterationType) { + final var firstMolecularProfileForEachStudy = getFirstMolecularProfileGroupedByStudy(studyViewFilterContext, + alterationType); + final int totalProfiledCount = alterationRepository.getTotalProfiledCountsByAlterationType(studyViewFilterContext, + alterationType.toString()); + var profiledCountsMap = alterationRepository.getTotalProfiledCounts(studyViewFilterContext, alterationType.toString(), + firstMolecularProfileForEachStudy); + final var matchingGenePanelIdsMap = alterationRepository.getMatchingGenePanelIds(studyViewFilterContext, + alterationType.toString()); + final int sampleProfileCountWithoutGenePanelData = + alterationRepository.getSampleProfileCountWithoutPanelData(studyViewFilterContext, alterationType.toString()); + + alterationCounts.parallelStream() + .forEach(alterationCountByGene -> { + String hugoGeneSymbol = alterationCountByGene.getHugoGeneSymbol(); + Set matchingGenePanelIds = matchingGenePanelIdsMap.get(hugoGeneSymbol) != null ? + matchingGenePanelIdsMap.get(hugoGeneSymbol) : Collections.emptySet(); + + int alterationTotalProfiledCount = computeTotalProfiledCount(hasGenePanelData(matchingGenePanelIds), + profiledCountsMap.getOrDefault(hugoGeneSymbol, 0), + sampleProfileCountWithoutGenePanelData, totalProfiledCount); + + alterationCountByGene.setNumberOfProfiledCases(alterationTotalProfiledCount); + + alterationCountByGene.setMatchingGenePanelIds(matchingGenePanelIds); + + }); + return alterationCounts; + } + + + private boolean hasGenePanelData(@NonNull Set matchingGenePanelIds) { + return matchingGenePanelIds.contains(WHOLE_EXOME_SEQUENCING) + && matchingGenePanelIds.size() > 1 || !matchingGenePanelIds.contains(WHOLE_EXOME_SEQUENCING) && !matchingGenePanelIds.isEmpty(); + } + + private int computeTotalProfiledCount(boolean hasGenePanelData, int alterationsProfiledCount, + int sampleProfileCountWithoutGenePanelData, int totalProfiledCount) { + int profiledCount = hasGenePanelData ? alterationsProfiledCount + sampleProfileCountWithoutGenePanelData + : sampleProfileCountWithoutGenePanelData; + return profiledCount == 0 ? totalProfiledCount : profiledCount; + } + + /** + * Retrieves the first molecular profile for each study based on the alteration type. + * + * @param studyViewFilterContext Context containing filter criteria. + * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). + * @return List of MolecularProfile objects representing the first profile for each study. + */ + private List getFirstMolecularProfileGroupedByStudy(StudyViewFilterContext studyViewFilterContext, AlterationType alterationType) { + final var molecularProfiles = + getFilteredMolecularProfilesByAlterationType.execute(studyViewFilterContext, alterationType.toString()); + return getFirstMolecularProfileGroupedByStudy(molecularProfiles); + } + + private List getFirstMolecularProfileGroupedByStudy(List molecularProfiles) { + return molecularProfiles.stream() + .collect(Collectors.toMap( + MolecularProfile::getCancerStudyIdentifier, + Function.identity(), + (existing, replacement) -> existing // Keep the first occurrence + )) + .values() + .stream() + .toList(); + } + +} diff --git a/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCase.java b/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCase.java deleted file mode 100644 index 6de30053676..00000000000 --- a/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCase.java +++ /dev/null @@ -1,215 +0,0 @@ -package org.cbioportal.domain.alteration.usecase; - -import org.apache.commons.math3.util.Pair; -import org.cbioportal.domain.alteration.repository.AlterationRepository; -import org.cbioportal.domain.cancerstudy.usecase.GetFilteredStudyIdsUseCase; -import org.cbioportal.domain.generic_assay.usecase.GetFilteredMolecularProfilesByAlterationType; -import org.cbioportal.legacy.model.AlterationCountByGene; -import org.cbioportal.legacy.model.AlterationType; -import org.cbioportal.legacy.model.CopyNumberCountByGene; -import org.cbioportal.legacy.model.Gistic; -import org.cbioportal.legacy.model.MolecularProfile; -import org.cbioportal.legacy.model.MutSig; -import org.cbioportal.legacy.service.SignificantCopyNumberRegionService; -import org.cbioportal.legacy.service.SignificantlyMutatedGeneService; -import org.cbioportal.legacy.service.exception.StudyNotFoundException; -import org.cbioportal.legacy.service.util.AlterationCountServiceUtil; -import org.cbioportal.legacy.web.parameter.Projection; -import org.cbioportal.domain.studyview.StudyViewFilterContext; -import org.springframework.context.annotation.Profile; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Service; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -@Service -@Profile("clickhouse") -public class AlterationCountByGeneUseCase { - - private final AlterationRepository alterationRepository; - private final GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType; - private final GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase; - private final SignificantlyMutatedGeneService significantlyMutatedGeneService; - private final SignificantCopyNumberRegionService significantCopyNumberRegionService; - - public AlterationCountByGeneUseCase(AlterationRepository alterationRepository, GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType, - GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase, - SignificantlyMutatedGeneService significantlyMutatedGeneService, - SignificantCopyNumberRegionService significantCopyNumberRegionService) { - this.alterationRepository = alterationRepository; - this.getFilteredMolecularProfilesByAlterationType = getFilteredMolecularProfilesByAlterationType; - this.getFilteredStudyIdsUseCase = getFilteredStudyIdsUseCase; - this.significantlyMutatedGeneService = significantlyMutatedGeneService; - this.significantCopyNumberRegionService = significantCopyNumberRegionService; - } - - public List getMutatedGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException{ - var alterationCountByGenes = - populateAlterationCounts(AlterationCountServiceUtil.combineAlterationCountsWithConflictingHugoSymbols(alterationRepository.getMutatedGenes(studyViewFilterContext)), - studyViewFilterContext, AlterationType.MUTATION_EXTENDED); - return populateAlterationCountsWithMutSigQValue(alterationCountByGenes, studyViewFilterContext); - } - - /** - * Retrieves a list of genes with copy number alterations (CNA) and their alteration counts for a given filter context. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return List of CopyNumberCountByGene objects representing genes with CNAs. - * @throws StudyNotFoundException if the specified study is not found. - */ - public List getCnaGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var copyNumberAlterationCounts = - populateAlterationCounts(AlterationCountServiceUtil.combineCopyNumberCountsWithConflictingHugoSymbols(alterationRepository.getCnaGenes(studyViewFilterContext)), studyViewFilterContext, AlterationType.COPY_NUMBER_ALTERATION); - return populateAlterationCountsWithCNASigQValue(copyNumberAlterationCounts, studyViewFilterContext); - } - - /** - * Retrieves a list of structural variant genes and their alteration counts for a given filter context. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return List of AlterationCountByGene objects representing structural variant genes. - * @throws StudyNotFoundException if the specified study is not found. - */ - public List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var alterationCountByGenes = - populateAlterationCounts(AlterationCountServiceUtil.combineAlterationCountsWithConflictingHugoSymbols(alterationRepository.getStructuralVariantGenes(studyViewFilterContext)), - studyViewFilterContext, AlterationType.STRUCTURAL_VARIANT); - return populateAlterationCountsWithMutSigQValue(alterationCountByGenes, studyViewFilterContext); - } - - /** - * Populates alteration counts with profile data, including the total profiled count and matching gene panel IDs. - * - * @param alterationCounts List of alteration counts to enrich. - * @param studyViewFilterContext Context containing filter criteria. - * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). - * @param The type of alteration count. - * @return List of enriched alteration counts. - */ - private List populateAlterationCounts(@NonNull List alterationCounts, - @NonNull StudyViewFilterContext studyViewFilterContext, - @NonNull AlterationType alterationType) { - final var firstMolecularProfileForEachStudy = getFirstMolecularProfileGroupedByStudy(studyViewFilterContext, - alterationType); - final int totalProfiledCount = alterationRepository.getTotalProfiledCountsByAlterationType(studyViewFilterContext, - alterationType.toString()); - var profiledCountsMap = alterationRepository.getTotalProfiledCounts(studyViewFilterContext, alterationType.toString(), - firstMolecularProfileForEachStudy); - final var matchingGenePanelIdsMap = alterationRepository.getMatchingGenePanelIds(studyViewFilterContext, - alterationType.toString()); - final int sampleProfileCountWithoutGenePanelData = - alterationRepository.getSampleProfileCountWithoutPanelData(studyViewFilterContext, alterationType.toString()); - - alterationCounts.parallelStream() - .forEach(alterationCountByGene -> { - String hugoGeneSymbol = alterationCountByGene.getHugoGeneSymbol(); - Set matchingGenePanelIds = matchingGenePanelIdsMap.get(hugoGeneSymbol) != null ? - matchingGenePanelIdsMap.get(hugoGeneSymbol) : Collections.emptySet(); - - int alterationTotalProfiledCount = AlterationCountServiceUtil.computeTotalProfiledCount(AlterationCountServiceUtil.hasGenePanelData(matchingGenePanelIds), - profiledCountsMap.getOrDefault(hugoGeneSymbol, 0), - sampleProfileCountWithoutGenePanelData, totalProfiledCount); - - alterationCountByGene.setNumberOfProfiledCases(alterationTotalProfiledCount); - - alterationCountByGene.setMatchingGenePanelIds(matchingGenePanelIds); - - }); - return alterationCounts; - } - - /** - * Updates alteration counts with MutSig Q-value data for significance. - * - * @param alterationCountByGenes List of alteration counts to update. - * @param studyViewFilterContext Context containing filter criteria. - * @return List of alteration counts updated with MutSig Q-value. - * @throws StudyNotFoundException if the specified study is not found. - */ - private List populateAlterationCountsWithMutSigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - final var mutSigs = getMutSigs(studyViewFilterContext); - // If MutSig is not empty update Mutated Genes - return AlterationCountServiceUtil.updateAlterationCountsWithMutSigQValue(alterationCountByGenes, mutSigs); - } - - /** - * Updates copy number alteration counts with GISTIC significance data. - * - * @param alterationCountByGenes List of alteration counts to update. - * @param studyViewFilterContext Context containing filter criteria. - * @return List of alteration counts updated with GISTIC significance data. - * @throws StudyNotFoundException if the specified study is not found. - */ - private List populateAlterationCountsWithCNASigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - final var gisticMap = getGisticMap(studyViewFilterContext); - return AlterationCountServiceUtil.updateAlterationCountsWithCNASigQValue(alterationCountByGenes, gisticMap); - } - - /** - * Retrieves the first molecular profile for each study based on the alteration type. - * - * @param studyViewFilterContext Context containing filter criteria. - * @param alterationType Type of alteration (e.g., mutation, CNA, structural variant). - * @return List of MolecularProfile objects representing the first profile for each study. - */ - private List getFirstMolecularProfileGroupedByStudy(StudyViewFilterContext studyViewFilterContext, AlterationType alterationType) { - final var molecularProfiles = - getFilteredMolecularProfilesByAlterationType.execute(studyViewFilterContext, alterationType.toString()); - return AlterationCountServiceUtil.getFirstMolecularProfileGroupedByStudy(molecularProfiles); - } - - /** - * Retrieves MutSig data for significantly mutated genes in the specified studies. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return Map of MutSig objects keyed by Hugo gene symbol. - * @throws StudyNotFoundException if the specified study is not found. - */ - private Map getMutSigs(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var distinctStudyIds = getFilteredStudyIdsUseCase.execute(studyViewFilterContext); - Map mutSigs = new HashMap<>(); - if (distinctStudyIds.size() == 1) { - var studyId = distinctStudyIds.getFirst(); - mutSigs = significantlyMutatedGeneService.getSignificantlyMutatedGenes( - studyId, - Projection.SUMMARY.name(), - null, - null, - null, - null) - .stream() - .collect(Collectors.toMap(MutSig::getHugoGeneSymbol, Function.identity())); - } - return mutSigs; - } - - /** - * Retrieves GISTIC data for significant copy number alterations in the specified studies. - * - * @param studyViewFilterContext Context containing filter criteria. - * @return Map of GISTIC objects keyed by gene and G-score rank. - * @throws StudyNotFoundException if the specified study is not found. - */ - private Map, Gistic> getGisticMap(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { - var distinctStudyIds = getFilteredStudyIdsUseCase.execute(studyViewFilterContext); - Map, Gistic> gisticMap = new HashMap<>(); - if (distinctStudyIds.size() == 1) { - var studyId = distinctStudyIds.getFirst(); - List gisticList = significantCopyNumberRegionService.getSignificantCopyNumberRegions( - studyId, - Projection.SUMMARY.name(), - null, - null, - null, - null); - AlterationCountServiceUtil.setupGisticMap(gisticList, gisticMap); - } - return gisticMap; - } -} diff --git a/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCases.java b/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCases.java new file mode 100644 index 00000000000..a865aebbd6c --- /dev/null +++ b/src/main/java/org/cbioportal/domain/alteration/usecase/AlterationCountByGeneUseCases.java @@ -0,0 +1,13 @@ +package org.cbioportal.domain.alteration.usecase; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +@Service +@Profile("clickhouse") +public record AlterationCountByGeneUseCases( + GetAlterationCountByGeneUseCase getAlterationCountByGeneUseCase, + GetCnaAlterationCountByGeneUseCase getCnaAlterationCountByGeneUseCase) { + + +} diff --git a/src/main/java/org/cbioportal/domain/alteration/usecase/GetAlterationCountByGeneUseCase.java b/src/main/java/org/cbioportal/domain/alteration/usecase/GetAlterationCountByGeneUseCase.java new file mode 100644 index 00000000000..526ca2452df --- /dev/null +++ b/src/main/java/org/cbioportal/domain/alteration/usecase/GetAlterationCountByGeneUseCase.java @@ -0,0 +1,144 @@ +package org.cbioportal.domain.alteration.usecase; + +import org.cbioportal.domain.alteration.repository.AlterationRepository; +import org.cbioportal.domain.cancerstudy.usecase.GetFilteredStudyIdsUseCase; +import org.cbioportal.domain.generic_assay.usecase.GetFilteredMolecularProfilesByAlterationType; +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.AlterationType; +import org.cbioportal.legacy.model.MutSig; +import org.cbioportal.legacy.service.SignificantlyMutatedGeneService; +import org.cbioportal.legacy.service.exception.StudyNotFoundException; +import org.cbioportal.legacy.web.parameter.Projection; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +@Profile("clickhouse") +public class GetAlterationCountByGeneUseCase extends AbstractAlterationCountByGeneUseCase { + private final AlterationRepository alterationRepository; + private final GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase; + private final SignificantlyMutatedGeneService significantlyMutatedGeneService; + public GetAlterationCountByGeneUseCase(AlterationRepository alterationRepository, GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType, GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase, SignificantlyMutatedGeneService significantlyMutatedGeneService) { + super(alterationRepository, getFilteredMolecularProfilesByAlterationType); + + this.alterationRepository = alterationRepository; + this.getFilteredStudyIdsUseCase = getFilteredStudyIdsUseCase; + this.significantlyMutatedGeneService = significantlyMutatedGeneService; + } + + /** + * Retrieves alteration counts by gene based on the given {@link AlterationType} and study filter context. + * Supports {@code MUTATION_EXTENDED} and {@code STRUCTURAL_VARIANT} alteration types. + * + * @param studyViewFilterContext the context containing study view filters + * @param alterationType the type of alteration to retrieve (must be either {@code MUTATION_EXTENDED} or {@code STRUCTURAL_VARIANT}) + * @return a list of {@link AlterationCountByGene} objects containing alteration counts + * @throws StudyNotFoundException if the study is not found + * @throws UnsupportedOperationException if the given {@code alterationType} is not supported + */ + public List execute(StudyViewFilterContext studyViewFilterContext, + AlterationType alterationType) throws StudyNotFoundException { + + final List alterationCountByGenes = switch (alterationType) { + case MUTATION_EXTENDED -> alterationRepository.getMutatedGenes(studyViewFilterContext); + case STRUCTURAL_VARIANT -> alterationRepository.getStructuralVariantGenes(studyViewFilterContext); + default -> throw new UnsupportedOperationException("AlterationType " + alterationType + " not supported.." + + ". For cna... use GetCnaAlterationCountByGeneUseCase"); + }; + + var combinedAlterationCountByGenes = + combineAlterationCountsWithConflictingHugoSymbols(alterationCountByGenes); + + return populateAlterationCountsWithMutSigQValue( + populateAlterationCounts( + combinedAlterationCountByGenes, + studyViewFilterContext, alterationType), + studyViewFilterContext); + } + + /** + * Combines alteration counts by Hugo gene symbols. If multiple entries exist for the same + * gene symbol, their number of altered cases and total counts are summed up. Returns a + * list of unique AlterationCountByGene objects where each gene symbol is represented only once. + * + * This appears in the Data where Genes have similar Hugo Gene Symbols but different Entrez Ids + * + * @param alterationCounts List of AlterationCountByGene objects, potentially with duplicate gene symbols + * @return List of AlterationCountByGene objects with unique gene symbols and combined counts + */ + private List combineAlterationCountsWithConflictingHugoSymbols(List alterationCounts) { + Map alterationCountByGeneMap = new HashMap<>(); + for (var alterationCount : alterationCounts) { + if (alterationCountByGeneMap.containsKey(alterationCount.getHugoGeneSymbol())){ + AlterationCountByGene toUpdate = alterationCountByGeneMap.get(alterationCount.getHugoGeneSymbol()); + toUpdate.setNumberOfAlteredCases(toUpdate.getNumberOfAlteredCases() + alterationCount.getNumberOfAlteredCases()); + toUpdate.setTotalCount(toUpdate.getTotalCount() + alterationCount.getTotalCount()); + } else { + alterationCountByGeneMap.put(alterationCount.getHugoGeneSymbol(), alterationCount); + } + } + return alterationCountByGeneMap.values().stream().toList(); + } + + /** + * Updates alteration counts with MutSig Q-value data for significance. + * + * @param alterationCountByGenes List of alteration counts to update. + * @param studyViewFilterContext Context containing filter criteria. + * @return List of alteration counts updated with MutSig Q-value. + * @throws StudyNotFoundException if the specified study is not found. + */ + private List populateAlterationCountsWithMutSigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + final var mutSigs = getMutSigs(studyViewFilterContext); + // If MutSig is not empty update Mutated Genes + return updateAlterationCountsWithMutSigQValue(alterationCountByGenes, mutSigs); + } + + /** + * Retrieves MutSig data for significantly mutated genes in the specified studies. + * + * @param studyViewFilterContext Context containing filter criteria. + * @return Map of MutSig objects keyed by Hugo gene symbol. + * @throws StudyNotFoundException if the specified study is not found. + */ + private Map getMutSigs(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + var distinctStudyIds = getFilteredStudyIdsUseCase.execute(studyViewFilterContext); + Map mutSigs = new HashMap<>(); + if (distinctStudyIds.size() == 1) { + var studyId = distinctStudyIds.getFirst(); + mutSigs = significantlyMutatedGeneService.getSignificantlyMutatedGenes( + studyId, + Projection.SUMMARY.name(), + null, + null, + null, + null) + .stream() + .collect(Collectors.toMap(MutSig::getHugoGeneSymbol, Function.identity())); + } + return mutSigs; + } + + private List updateAlterationCountsWithMutSigQValue( + List alterationCountByGenes, + Map mutSigs) { + + if (!mutSigs.isEmpty()) { + alterationCountByGenes.parallelStream() + .filter(alterationCount -> mutSigs.containsKey(alterationCount.getHugoGeneSymbol())) + .forEach(alterationCount -> + alterationCount.setqValue(mutSigs.get(alterationCount.getHugoGeneSymbol()).getqValue()) + ); + } + return alterationCountByGenes; + } + + +} diff --git a/src/main/java/org/cbioportal/domain/alteration/usecase/GetCnaAlterationCountByGeneUseCase.java b/src/main/java/org/cbioportal/domain/alteration/usecase/GetCnaAlterationCountByGeneUseCase.java new file mode 100644 index 00000000000..318a50c90d0 --- /dev/null +++ b/src/main/java/org/cbioportal/domain/alteration/usecase/GetCnaAlterationCountByGeneUseCase.java @@ -0,0 +1,131 @@ +package org.cbioportal.domain.alteration.usecase; + +import org.apache.commons.math3.util.Pair; +import org.cbioportal.domain.alteration.repository.AlterationRepository; +import org.cbioportal.domain.cancerstudy.usecase.GetFilteredStudyIdsUseCase; +import org.cbioportal.domain.generic_assay.usecase.GetFilteredMolecularProfilesByAlterationType; +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.legacy.model.AlterationType; +import org.cbioportal.legacy.model.CopyNumberCountByGene; +import org.cbioportal.legacy.model.Gistic; +import org.cbioportal.legacy.service.SignificantCopyNumberRegionService; +import org.cbioportal.legacy.service.exception.StudyNotFoundException; +import org.cbioportal.legacy.service.util.AlterationCountServiceUtil; +import org.cbioportal.legacy.web.parameter.Projection; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +@Profile("clickhouse") +public class GetCnaAlterationCountByGeneUseCase extends AbstractAlterationCountByGeneUseCase{ + + private final AlterationRepository alterationRepository; + private final GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase; + private final SignificantCopyNumberRegionService significantCopyNumberRegionService; + + public GetCnaAlterationCountByGeneUseCase(AlterationRepository alterationRepository, + GetFilteredMolecularProfilesByAlterationType getFilteredMolecularProfilesByAlterationType, GetFilteredStudyIdsUseCase getFilteredStudyIdsUseCase, SignificantCopyNumberRegionService significantCopyNumberRegionService){ + super(alterationRepository,getFilteredMolecularProfilesByAlterationType); + + this.alterationRepository = alterationRepository; + this.getFilteredStudyIdsUseCase = getFilteredStudyIdsUseCase; + this.significantCopyNumberRegionService = significantCopyNumberRegionService; + } + + /** + * Retrieves a list of genes with copy number alterations (CNA) and their alteration counts for a given filter context. + * + * @param studyViewFilterContext Context containing filter criteria. + * @return List of CopyNumberCountByGene objects representing genes with CNAs. + * @throws StudyNotFoundException if the specified study is not found. + */ + public List execute(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + var combinedCopyNumberCountByGene = + combineCopyNumberCountsWithConflictingHugoSymbols(alterationRepository.getCnaGenes(studyViewFilterContext)); + return populateAlterationCountsWithCNASigQValue( + populateAlterationCounts(combinedCopyNumberCountByGene,studyViewFilterContext, + AlterationType.COPY_NUMBER_ALTERATION), + studyViewFilterContext); + } + + /** + * Combines alteration counts by Hugo gene symbols. If multiple entries exist for the same + * gene symbol, their number of altered cases and total counts are summed up. Returns a + * list of unique AlterationCountByGene objects where each gene symbol is represented only once. + * + * This appears in the Data where Genes have similar Hugo Gene Symbols but different Entrez Ids. + * This is a special case to handle Copy Number Mutations where the Alteration type should be a part of the key + * + * @param alterationCounts List of CopyNumberCountByGene objects, potentially with duplicate gene symbols + * @return List of AlterationCountByGene objects with unique gene symbols and combined counts + */ + private List combineCopyNumberCountsWithConflictingHugoSymbols(List alterationCounts) { + Map, CopyNumberCountByGene> alterationCountByGeneMap = new HashMap<>(); + for (var alterationCount : alterationCounts) { + var copyNumberKey = Pair.create(alterationCount.getHugoGeneSymbol(), alterationCount.getAlteration()); + if (alterationCountByGeneMap.containsKey(copyNumberKey)) { + CopyNumberCountByGene toUpdate = alterationCountByGeneMap.get(copyNumberKey); + toUpdate.setNumberOfAlteredCases(toUpdate.getNumberOfAlteredCases() + alterationCount.getNumberOfAlteredCases()); + toUpdate.setTotalCount(toUpdate.getTotalCount() + alterationCount.getTotalCount()); + } else { + alterationCountByGeneMap.put(copyNumberKey, alterationCount); + } + } + return alterationCountByGeneMap.values().stream().toList(); + } + + /** + * Updates copy number alteration counts with GISTIC significance data. + * + * @param alterationCountByGenes List of alteration counts to update. + * @param studyViewFilterContext Context containing filter criteria. + * @return List of alteration counts updated with GISTIC significance data. + * @throws StudyNotFoundException if the specified study is not found. + */ + private List populateAlterationCountsWithCNASigQValue(List alterationCountByGenes, StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + final var gisticMap = getGisticMap(studyViewFilterContext); + return updateAlterationCountsWithCNASigQValue(alterationCountByGenes, gisticMap); + } + + /** + * Retrieves GISTIC data for significant copy number alterations in the specified studies. + * + * @param studyViewFilterContext Context containing filter criteria. + * @return Map of GISTIC objects keyed by gene and G-score rank. + * @throws StudyNotFoundException if the specified study is not found. + */ + private Map, Gistic> getGisticMap(StudyViewFilterContext studyViewFilterContext) throws StudyNotFoundException { + var distinctStudyIds = getFilteredStudyIdsUseCase.execute(studyViewFilterContext); + Map, Gistic> gisticMap = new HashMap<>(); + if (distinctStudyIds.size() == 1) { + var studyId = distinctStudyIds.getFirst(); + List gisticList = significantCopyNumberRegionService.getSignificantCopyNumberRegions( + studyId, + Projection.SUMMARY.name(), + null, + null, + null, + null); + AlterationCountServiceUtil.setupGisticMap(gisticList, gisticMap); + } + return gisticMap; + } + + private List updateAlterationCountsWithCNASigQValue( + List alterationCountByGenes, + Map, Gistic> gisticMap) { + + if (!gisticMap.isEmpty()) { + alterationCountByGenes.parallelStream() + .filter(alterationCount -> gisticMap.containsKey(Pair.create(alterationCount.getHugoGeneSymbol(), alterationCount.getAlteration()))) + .forEach(alterationCount -> + alterationCount.setqValue(gisticMap.get(Pair.create(alterationCount.getHugoGeneSymbol(), alterationCount.getAlteration())).getqValue()) + ); + } + return alterationCountByGenes; + } +} diff --git a/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterFactory.java b/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterFactory.java index 451f3db39be..d7455517ec7 100644 --- a/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterFactory.java +++ b/src/main/java/org/cbioportal/domain/studyview/StudyViewFilterFactory.java @@ -43,6 +43,13 @@ public static StudyViewFilterContext make(StudyViewFilter base, base.setGenericAssayDataFilters(mergedGenericAssayDataFilters); } + return make(base, customSampleIdentifiers, involvedCancerStudies, categorizedGenericAssayDataCountFilter); + } + + public static StudyViewFilterContext make(StudyViewFilter base, + List customSampleIdentifiers, + List involvedCancerStudies, + CategorizedGenericAssayDataCountFilter categorizedGenericAssayDataCountFilter){ return new StudyViewFilterContext(base.getSampleIdentifiers(), base.getStudyIds(), base.getClinicalDataFilters(), base.getGeneFilters(), base.getStructuralVariantFilters(), base.getSampleTreatmentFilters(), base.getSampleTreatmentGroupFilters(), diff --git a/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java b/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java index 2ef208abe58..cb2097fa3bf 100644 --- a/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java +++ b/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java @@ -1,6 +1,6 @@ package org.cbioportal.domain.studyview; -import org.cbioportal.domain.alteration.usecase.AlterationCountByGeneUseCase; +import org.cbioportal.domain.alteration.usecase.AlterationCountByGeneUseCases; import org.cbioportal.domain.clinical_attributes.usecase.GetClinicalAttributesDataTypeMapUseCase; import org.cbioportal.domain.clinical_attributes.usecase.GetClinicalAttributesForStudiesUseCase; import org.cbioportal.domain.clinical_data.usecase.ClinicalDataUseCases; @@ -8,6 +8,7 @@ import org.cbioportal.domain.generic_assay.usecase.GenericAssayUseCases; import org.cbioportal.domain.genomic_data.usecase.GenomicDataUseCases; import org.cbioportal.legacy.model.AlterationCountByGene; +import org.cbioportal.legacy.model.AlterationType; import org.cbioportal.legacy.model.CaseListDataCount; import org.cbioportal.legacy.model.ClinicalAttribute; import org.cbioportal.legacy.model.ClinicalData; @@ -34,7 +35,7 @@ import org.cbioportal.domain.sample.Sample; import org.cbioportal.domain.sample.usecase.GetFilteredSamplesUseCase; import org.cbioportal.shared.util.ClinicalDataCountItemUtil; -import org.cbioportal.domain.treatment.usecase.FilteredTreatmentCountReportUseCase; +import org.cbioportal.domain.treatment.usecase.TreatmentCountReportUseCases; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @@ -53,9 +54,9 @@ public class StudyViewService { private final GetFilteredSamplesUseCase getFilteredSamplesUseCase; - private final AlterationCountByGeneUseCase alterationCountByGeneUseCase; + private final AlterationCountByGeneUseCases alterationCountByGeneUseCase; private final GetClinicalEventTypeCountsUseCase getClinicalEventTypeCountsUseCase; - private final FilteredTreatmentCountReportUseCase filteredTreatmentCountReportUseCase; + private final TreatmentCountReportUseCases treatmentCountReportUseCases; private final GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase; private final GetCaseListDataCountsUseCase getCaseListDataCountsUseCase; private final GetClinicalAttributesDataTypeMapUseCase getClinicalAttributesDataTypeMapUseCase; @@ -68,9 +69,9 @@ public class StudyViewService { public StudyViewService(GetFilteredSamplesUseCase getFilteredSamplesUseCase, - AlterationCountByGeneUseCase alterationCountByGeneUseCase, + AlterationCountByGeneUseCases alterationCountByGeneUseCase, GetClinicalEventTypeCountsUseCase getClinicalEventTypeCountsUseCase, - FilteredTreatmentCountReportUseCase filteredTreatmentCountReportUseCase, + TreatmentCountReportUseCases treatmentCountReportUseCases, GetClinicalAttributesForStudiesUseCase getClinicalAttributesForStudiesUseCase, GetCaseListDataCountsUseCase getCaseListDataCountsUseCase, GetClinicalAttributesDataTypeMapUseCase getClinicalAttributesDataTypeMapUseCase, @@ -82,7 +83,7 @@ public StudyViewService(GetFilteredSamplesUseCase getFilteredSamplesUseCase, this.clinicalDataUseCases = clinicalDataUseCases; this.genomicDataUseCases = genomicDataUseCases; this.getClinicalEventTypeCountsUseCase = getClinicalEventTypeCountsUseCase; - this.filteredTreatmentCountReportUseCase = filteredTreatmentCountReportUseCase; + this.treatmentCountReportUseCases = treatmentCountReportUseCases; this.getClinicalAttributesForStudiesUseCase = getClinicalAttributesForStudiesUseCase; this.getCaseListDataCountsUseCase = getCaseListDataCountsUseCase; this.getClinicalAttributesDataTypeMapUseCase = getClinicalAttributesDataTypeMapUseCase; @@ -103,7 +104,8 @@ public List getFilteredSamples(StudyViewFilter studyViewFilter){ condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" ) public List getMutatedGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { - return alterationCountByGeneUseCase.getMutatedGenes(buildStudyViewFilterContext(studyViewFilter)); + return alterationCountByGeneUseCase.getAlterationCountByGeneUseCase() + .execute(buildStudyViewFilterContext(studyViewFilter), AlterationType.MUTATION_EXTENDED); } @Cacheable( @@ -111,7 +113,7 @@ public List getMutatedGenes(StudyViewFilter studyViewFilt condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" ) public List getCnaGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { - return alterationCountByGeneUseCase.getCnaGenes(buildStudyViewFilterContext(studyViewFilter)); + return alterationCountByGeneUseCase.getCnaAlterationCountByGeneUseCase().execute(buildStudyViewFilterContext(studyViewFilter)); } @Cacheable( @@ -119,7 +121,8 @@ public List getCnaGenes(StudyViewFilter studyViewFilter) condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" ) public List getStructuralVariantGenes(StudyViewFilter studyViewFilter) throws StudyNotFoundException { - return alterationCountByGeneUseCase.getStructuralVariantGenes(buildStudyViewFilterContext(studyViewFilter)); + return alterationCountByGeneUseCase.getAlterationCountByGeneUseCase() + .execute(buildStudyViewFilterContext(studyViewFilter), AlterationType.STRUCTURAL_VARIANT); } @Cacheable( @@ -143,7 +146,7 @@ public List getClinicalEventTypeCounts(StudyViewFilter s condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" ) public PatientTreatmentReport getPatientTreatmentReport(StudyViewFilter studyViewFilter) { - return filteredTreatmentCountReportUseCase.getFilteredPatientTreatmentReport(buildStudyViewFilterContext(studyViewFilter)); + return treatmentCountReportUseCases.getPatientTreatmentReportUseCase().execute(buildStudyViewFilterContext(studyViewFilter)); } @Cacheable( @@ -151,7 +154,7 @@ public PatientTreatmentReport getPatientTreatmentReport(StudyViewFilter studyVie condition = "@cacheEnabledConfig.getEnabledClickhouse() && @studyViewFilterUtil.isUnfilteredQuery(#studyViewFilter)" ) public SampleTreatmentReport getSampleTreatmentReport(StudyViewFilter studyViewFilter) { - return filteredTreatmentCountReportUseCase.getFilteredSampleTreatmentReport(buildStudyViewFilterContext(studyViewFilter)); + return treatmentCountReportUseCases.getSampleTreatmentReportUseCase().execute(buildStudyViewFilterContext(studyViewFilter)); } @Cacheable( diff --git a/src/main/java/org/cbioportal/domain/treatment/usecase/GetPatientTreatmentReportUseCase.java b/src/main/java/org/cbioportal/domain/treatment/usecase/GetPatientTreatmentReportUseCase.java new file mode 100644 index 00000000000..d2853435c43 --- /dev/null +++ b/src/main/java/org/cbioportal/domain/treatment/usecase/GetPatientTreatmentReportUseCase.java @@ -0,0 +1,36 @@ +package org.cbioportal.domain.treatment.usecase; + +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.domain.treatment.repository.TreatmentRepository; +import org.cbioportal.legacy.model.PatientTreatmentReport; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +@Service +@Profile("clickhouse") +public class GetPatientTreatmentReportUseCase { + private final TreatmentRepository treatmentRepository; + + + /** + * Constructs a new use case with the given treatment repository. + * + * @param treatmentRepository the repository used to fetch treatment data + */ + public GetPatientTreatmentReportUseCase(TreatmentRepository treatmentRepository) { + this.treatmentRepository = treatmentRepository; + } + + + /** + * Executes the use case to retrieve a patient treatment report based on the given filter context. + * + * @param studyViewFilterContext the filtering criteria for retrieving patient treatments + * @return a {@link PatientTreatmentReport} containing treatment data for patients + */ + public PatientTreatmentReport execute(StudyViewFilterContext studyViewFilterContext){ + var patientTreatments = treatmentRepository.getPatientTreatments(studyViewFilterContext); + var totalPatientTreatmentCount = treatmentRepository.getTotalPatientTreatmentCount(studyViewFilterContext); + return new PatientTreatmentReport(totalPatientTreatmentCount, 0, patientTreatments); + } +} diff --git a/src/main/java/org/cbioportal/domain/treatment/usecase/FilteredTreatmentCountReportUseCase.java b/src/main/java/org/cbioportal/domain/treatment/usecase/GetSampleTreatmentReportUseCase.java similarity index 66% rename from src/main/java/org/cbioportal/domain/treatment/usecase/FilteredTreatmentCountReportUseCase.java rename to src/main/java/org/cbioportal/domain/treatment/usecase/GetSampleTreatmentReportUseCase.java index 9fb9a43f83b..5237f04b880 100644 --- a/src/main/java/org/cbioportal/domain/treatment/usecase/FilteredTreatmentCountReportUseCase.java +++ b/src/main/java/org/cbioportal/domain/treatment/usecase/GetSampleTreatmentReportUseCase.java @@ -1,11 +1,10 @@ package org.cbioportal.domain.treatment.usecase; -import org.cbioportal.legacy.model.PatientTreatmentReport; +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.domain.treatment.repository.TreatmentRepository; import org.cbioportal.legacy.model.SampleTreatmentReport; import org.cbioportal.legacy.model.SampleTreatmentRow; import org.cbioportal.legacy.model.TemporalRelation; -import org.cbioportal.domain.studyview.StudyViewFilterContext; -import org.cbioportal.domain.treatment.repository.TreatmentRepository; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @@ -14,21 +13,20 @@ @Service @Profile("clickhouse") -public class FilteredTreatmentCountReportUseCase { - +public class GetSampleTreatmentReportUseCase { private final TreatmentRepository treatmentRepository; - public FilteredTreatmentCountReportUseCase(TreatmentRepository treatmentRepository) { + public GetSampleTreatmentReportUseCase(TreatmentRepository treatmentRepository) { this.treatmentRepository = treatmentRepository; } - public PatientTreatmentReport getFilteredPatientTreatmentReport(StudyViewFilterContext studyViewFilterContext){ - var patientTreatments = treatmentRepository.getPatientTreatments(studyViewFilterContext); - var totalPatientTreatmentCount = treatmentRepository.getTotalPatientTreatmentCount(studyViewFilterContext); - return new PatientTreatmentReport(totalPatientTreatmentCount, 0, patientTreatments); - } - - public SampleTreatmentReport getFilteredSampleTreatmentReport(StudyViewFilterContext studyViewFilterContext){ + /** + * Executes the use case to retrieve a sample treatment report based on the given filter context. + * + * @param studyViewFilterContext the filtering criteria for retrieving sample treatments + * @return a {@link SampleTreatmentReport} containing treatment data for samples + */ + public SampleTreatmentReport execute(StudyViewFilterContext studyViewFilterContext){ var sampleTreatments = treatmentRepository.getSampleTreatments(studyViewFilterContext) .stream() .flatMap(sampleTreatment -> diff --git a/src/main/java/org/cbioportal/domain/treatment/usecase/TreatmentCountReportUseCases.java b/src/main/java/org/cbioportal/domain/treatment/usecase/TreatmentCountReportUseCases.java new file mode 100644 index 00000000000..bcfb4685199 --- /dev/null +++ b/src/main/java/org/cbioportal/domain/treatment/usecase/TreatmentCountReportUseCases.java @@ -0,0 +1,12 @@ +package org.cbioportal.domain.treatment.usecase; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +@Service +@Profile("clickhouse") +public record TreatmentCountReportUseCases( + GetPatientTreatmentReportUseCase getPatientTreatmentReportUseCase, + GetSampleTreatmentReportUseCase getSampleTreatmentReportUseCase) { + +} From 8dc093b33dd0fb742ec029f2e1ff168365d7e4a3 Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Tue, 18 Feb 2025 13:55:02 -0500 Subject: [PATCH 7/9] Move tests for domain specific Repositories --- .../clickhouse}/AbstractTestcontainers.java | 4 +- .../ClickhouseAlterationMapperTest.java | 265 +++++++++++++++++ .../ClickhouseClinicalDataMapperTest.java} | 147 +++++----- .../ClickhouseClinicalEventMapperTest.java} | 34 +-- .../clickhouse}/config/MyBatisConfig.java | 26 +- .../ClickhouseGenericAssayMapperTest.java} | 61 ++-- .../ClickhouseGenomicDataMapperTest.java | 267 ++++++++++++++++++ .../patient/ClickhousePatientMapperTest.java} | 50 ++-- .../sample/ClickhouseSampleMapperTest.java} | 140 ++++----- .../ClickhouseTreatmentMapperTest.java | 106 +++++++ .../mybatisclickhouse/CNAGenesTest.java | 76 ----- .../GenomicDataCountsTest.java | 73 ----- .../MolecularProfileCountTest.java | 119 -------- .../mybatisclickhouse/MutatedGenesTest.java | 89 ------ .../MutationDataCountsTest.java | 72 ----- .../PatientTreatmentCountsTest.java | 67 ----- .../mybatisclickhouse/ProfiledCountsTest.java | 145 ---------- .../ProteinExpressionCountsTest.java | 99 ------- .../SampleTreatmentCountsTest.java | 71 ----- .../StructuralVariantGenesTest.java | 56 ---- 20 files changed, 874 insertions(+), 1093 deletions(-) rename src/test/java/org/cbioportal/{legacy/persistence/mybatisclickhouse => infrastructure/repository/clickhouse}/AbstractTestcontainers.java (95%) create mode 100644 src/test/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationMapperTest.java rename src/test/java/org/cbioportal/{legacy/persistence/mybatisclickhouse/StudyViewMapperClinicalDataCountTest.java => infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapperTest.java} (76%) rename src/test/java/org/cbioportal/{legacy/persistence/mybatisclickhouse/ClinicalEventTypeCountsTest.java => infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapperTest.java} (67%) rename src/test/java/org/cbioportal/{legacy/persistence/mybatisclickhouse => infrastructure/repository/clickhouse}/config/MyBatisConfig.java (54%) rename src/test/java/org/cbioportal/{legacy/persistence/mybatisclickhouse/GenericAssayDataCountsTest.java => infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapperTest.java} (53%) create mode 100644 src/test/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapperTest.java rename src/test/java/org/cbioportal/{legacy/persistence/mybatisclickhouse/StudyViewCaseListSamplesCountsTest.java => infrastructure/repository/clickhouse/patient/ClickhousePatientMapperTest.java} (70%) rename src/test/java/org/cbioportal/{legacy/persistence/mybatisclickhouse/FilteredSamplesTest.java => infrastructure/repository/clickhouse/sample/ClickhouseSampleMapperTest.java} (54%) create mode 100644 src/test/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapperTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/CNAGenesTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/GenomicDataCountsTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MolecularProfileCountTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutatedGenesTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutationDataCountsTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/PatientTreatmentCountsTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProfiledCountsTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProteinExpressionCountsTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/SampleTreatmentCountsTest.java delete mode 100644 src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StructuralVariantGenesTest.java diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/AbstractTestcontainers.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/AbstractTestcontainers.java similarity index 95% rename from src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/AbstractTestcontainers.java rename to src/test/java/org/cbioportal/infrastructure/repository/clickhouse/AbstractTestcontainers.java index fb1d8117aff..2b05d1282ea 100644 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/AbstractTestcontainers.java +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/AbstractTestcontainers.java @@ -1,7 +1,6 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; +package org.cbioportal.infrastructure.repository.clickhouse; import org.junit.BeforeClass; - import org.junit.ClassRule; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; @@ -32,6 +31,7 @@ public static class Initializer implements ApplicationContextInitializer Objects.equals(a.getHugoGeneSymbol(), "BRCA1")).findFirst(); + assert (testBrca1AlterationCount.isPresent()); + assertEquals(Integer.valueOf(5), testBrca1AlterationCount.get().getTotalCount()); + } + + @Test + public void getMutatedGenesWithAlterationFilter() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + // Create AlterationFilter + AlterationFilter alterationFilter = new AlterationFilter(); + Map mutationEventTypeFilterMap = new HashMap<>(); + mutationEventTypeFilterMap.put(MutationEventType.nonsense_mutation, Boolean.TRUE); + mutationEventTypeFilterMap.put(MutationEventType.other, Boolean.FALSE); + alterationFilter.setMutationEventTypes(mutationEventTypeFilterMap); + + var alterationCountByGenes = mapper.getMutatedGenes(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + AlterationFilterHelper.build(alterationFilter)); + assertEquals(2, alterationCountByGenes.size()); + + AlterationFilter onlyMutationStatusFilter = new AlterationFilter(); + onlyMutationStatusFilter.setMutationEventTypes(new HashMap<>()); + onlyMutationStatusFilter.setIncludeGermline(false); + onlyMutationStatusFilter.setIncludeSomatic(false); + onlyMutationStatusFilter.setIncludeUnknownStatus(true); + + var alterationCountByGenes1 = mapper.getMutatedGenes(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + AlterationFilterHelper.build(onlyMutationStatusFilter)); + assertEquals(1, alterationCountByGenes1.size()); + + AlterationFilter mutationTypeAndStatusFilter = new AlterationFilter(); + mutationTypeAndStatusFilter.setMutationEventTypes(mutationEventTypeFilterMap); + mutationTypeAndStatusFilter.setMutationEventTypes(new HashMap<>()); + mutationTypeAndStatusFilter.setIncludeGermline(false); + mutationTypeAndStatusFilter.setIncludeSomatic(false); + mutationTypeAndStatusFilter.setIncludeUnknownStatus(true); + + var alterationCountByGenes2 = mapper.getMutatedGenes(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + AlterationFilterHelper.build(onlyMutationStatusFilter)); + assertEquals(1, alterationCountByGenes2.size()); + } + + @Test + public void getCnaGenes() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + var alterationCountByGenes = mapper.getCnaGenes(StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null), + AlterationFilterHelper.build(studyViewFilter.getAlterationFilter())); + assertEquals(3, alterationCountByGenes.size()); + + // Test cna count for akt1 + var testAKT1AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "AKT1")) + .mapToInt(c -> c.getTotalCount().intValue()) + .sum(); + assertEquals(3, testAKT1AlterationCount); + } + + @Test + public void getCnaGenesWithAlterationFilter() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + // Create AlterationFilter + AlterationFilter alterationFilter = new AlterationFilter(); + Map cnaEventTypeFilterMap = new HashMap<>(); + cnaEventTypeFilterMap.put(CNA.HOMDEL, false); + cnaEventTypeFilterMap.put(CNA.AMP, true); + alterationFilter.setCopyNumberAlterationEventTypes(cnaEventTypeFilterMap); + + var alterationCountByGenes = mapper.getCnaGenes(StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null), + AlterationFilterHelper.build(alterationFilter)); + assertEquals(2, alterationCountByGenes.size()); + + // Test cna count for akt1 filtering for AMP + var testAKT1AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "AKT1")) + .mapToInt(c -> c.getTotalCount().intValue()) + .sum(); + assertEquals(2, testAKT1AlterationCount); + } + + @Test + public void getStructuralVariantGenes() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_ACC_TCGA)); + var alterationCountByGenes = mapper.getStructuralVariantGenes(StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null), + AlterationFilterHelper.build(studyViewFilter.getAlterationFilter())); + assertEquals(8, alterationCountByGenes.size()); + + // Test sv count for eml4 which is in one study + var testeml4AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "eml4")) + .mapToInt(c -> c.getTotalCount().intValue()) + .sum(); + assertEquals(1, testeml4AlterationCount); + + // Test sv count for ncoa4 which is in both studies + var testncoa4AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "ncoa4")) + .mapToInt(c -> c.getTotalCount().intValue()) + .sum(); + assertEquals(3, testncoa4AlterationCount); + } + + @Test + public void getTotalProfiledCountsByGene() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + // Testing profiled counts on samples with gene panel data and WES for one study + var totalProfiledCountsForMutationsMap = mapper.getTotalProfiledCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "MUTATION_EXTENDED", List.of()); + var totalProfiledCountsForCnaMap = mapper.getTotalProfiledCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "COPY_NUMBER_ALTERATION", List.of()); + var sampleProfiledCountsForMutationsWithoutPanelDataMap = mapper.getSampleProfileCountWithoutPanelData(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "MUTATION_EXTENDED"); + var sampleProfiledCountsForCnaWithoutPanelDataMap = mapper.getSampleProfileCountWithoutPanelData(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "COPY_NUMBER_ALTERATION"); + + // Assert the count of genes with profiled cases for mutations + assertEquals(5, totalProfiledCountsForMutationsMap.size()); + // Assert the count of genes with profiled cases for CNA + assertEquals(5, totalProfiledCountsForCnaMap.size()); + // Assert the profiled counts for mutations without panel data (WES) + assertEquals(6, sampleProfiledCountsForMutationsWithoutPanelDataMap); + // Assert the profiled counts for CNA without panel data (WES) + assertEquals(11, sampleProfiledCountsForCnaWithoutPanelDataMap); + + // Assert the profiled counts for AKT2 mutations + // AKT2 is on testpanel2 in STUDY_TCGA_PUB + var akt2TotalProfiledCountsForMutations = totalProfiledCountsForMutationsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); + assertTrue(akt2TotalProfiledCountsForMutations.isPresent()); + assertEquals(4, akt2TotalProfiledCountsForMutations.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for BRCA1 mutations + // BRCA1 is on testpanel1 in STUDY_TCGA_PUB + var brca1TotalProfiledCountsForMutations = totalProfiledCountsForMutationsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); + assertTrue(brca1TotalProfiledCountsForMutations.isPresent()); + assertEquals(1, brca1TotalProfiledCountsForMutations.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for AKT1 mutations + // AKT1 is on both testpanel1 and testpanel2 in STUDY_TCGA_PUB + var akt1TotalProfiledCountsForMutations = totalProfiledCountsForMutationsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT1")).findFirst(); + assertTrue(akt1TotalProfiledCountsForMutations.isPresent()); + assertEquals(5, akt1TotalProfiledCountsForMutations.get().getNumberOfProfiledCases().intValue()); + + // Assert the profiled counts for AKT2 CNA + // AKT2 is on testpanel2 in STUDY_TCGA_PUB + var akt2TotalProfiledCountsForCna = totalProfiledCountsForCnaMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); + assertTrue(akt2TotalProfiledCountsForCna.isPresent()); + assertEquals(6, akt2TotalProfiledCountsForCna.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for BRCA1 CNA + // BRCA1 is on testpanel1 in STUDY_TCGA_PUB + var brca1TotalProfiledCountsForCna = totalProfiledCountsForCnaMap.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); + assertTrue(brca1TotalProfiledCountsForCna.isPresent()); + assertEquals(2, brca1TotalProfiledCountsForCna.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for AKT1 CNA + // AKT1 is on both testpanel1 and testpanel2 in STUDY_TCGA_PUB + var akt1TotalProfiledCountsForCna = totalProfiledCountsForCnaMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT1")).findFirst(); + assertTrue(akt1TotalProfiledCountsForCna.isPresent()); + assertEquals(8, akt1TotalProfiledCountsForCna.get().getNumberOfProfiledCases().intValue()); + + // Testing profiled counts on combined studies + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_GENIE_PUB)); + + // Testing profiled counts on samples with gene panel data and WES for a combined study + var totalProfiledCountsForMutationsMap1 = mapper.getTotalProfiledCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "MUTATION_EXTENDED", List.of()); + var totalProfiledCountsForCnaMap1 = mapper.getTotalProfiledCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "COPY_NUMBER_ALTERATION", List.of()); + var sampleProfiledCountsForMutationsWithoutPanelDataMap1 = mapper.getSampleProfileCountWithoutPanelData(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "MUTATION_EXTENDED"); + var sampleProfiledCountsForCnaWithoutPanelDataMap1 = mapper.getSampleProfileCountWithoutPanelData(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + "COPY_NUMBER_ALTERATION"); + + // Assert the count of genes with profiled cases for mutations in a combined study + assertEquals(8, totalProfiledCountsForMutationsMap1.size()); + // Assert the count of genes with profiled cases for CNA in a combined study + assertEquals(8, totalProfiledCountsForCnaMap1.size()); + // Assert the profiled counts for mutations without panel data (WES) in a combined study + assertEquals(8, sampleProfiledCountsForMutationsWithoutPanelDataMap1); + // Assert the profiled counts for CNA without panel data (WES) in a combined study + assertEquals(12, sampleProfiledCountsForCnaWithoutPanelDataMap1); + + // Assert the profiled counts for BRCA1 mutations + // BRCA1 is on testpanel1 in STUDY_TCGA_PUB + var brca1TotalProfiledCountsForMutations1 = totalProfiledCountsForMutationsMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); + assertTrue(brca1TotalProfiledCountsForMutations1.isPresent()); + assertEquals(1, brca1TotalProfiledCountsForMutations1.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for BRCA2 mutations + // BRCA2 is on testpanel3 and testpanel4 in STUDY_GENIE_PUB + var brca2TotalProfiledCountsForMutations1 = totalProfiledCountsForMutationsMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA2")).findFirst(); + assertTrue(brca2TotalProfiledCountsForMutations1.isPresent()); + assertEquals(2, brca2TotalProfiledCountsForMutations1.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for AKT2 mutations + // AKT2 is on testpanel2 in STUDY_TCGA_PUB and testpanel4 in STUDY_GENIE_PUB + var akt2TotalProfiledCountsForMutations1 = totalProfiledCountsForMutationsMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); + assertTrue(akt2TotalProfiledCountsForMutations1.isPresent()); + assertEquals(4, akt2TotalProfiledCountsForMutations1.get().getNumberOfProfiledCases().intValue()); + + // Assert the profiled counts for BRCA1 CNA + // BRCA1 is on testpanel1 in STUDY_TCGA_PUB + var brca1TotalProfiledCountsForCna1 = totalProfiledCountsForCnaMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); + assertTrue(brca1TotalProfiledCountsForCna1.isPresent()); + assertEquals(2, brca1TotalProfiledCountsForCna1.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for BRCA2 CNA + // BRCA2 is on testpanel3 and testpanel4 in STUDY_GENIE_PUB + var brca2TotalProfiledCountsForCna1 = totalProfiledCountsForCnaMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA2")).findFirst(); + assertTrue(brca2TotalProfiledCountsForCna1.isPresent()); + assertEquals(3, brca2TotalProfiledCountsForCna1.get().getNumberOfProfiledCases().intValue()); + // Assert the profiled counts for AKT2 CNA + // AKT2 is on testpanel2 in STUDY_TCGA_PUB and testpanel4 in STUDY_GENIE_PUB + var akt2TotalProfiledCountsForCna1 = totalProfiledCountsForCnaMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); + assertTrue(akt2TotalProfiledCountsForCna1.isPresent()); + assertEquals(7, akt2TotalProfiledCountsForCna1.get().getNumberOfProfiledCases().intValue()); + } +} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapperClinicalDataCountTest.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapperTest.java similarity index 76% rename from src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapperClinicalDataCountTest.java rename to src/test/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapperTest.java index a7d74ae3b3d..a0cc83be843 100644 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapperClinicalDataCountTest.java +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataMapperTest.java @@ -1,8 +1,9 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; +package org.cbioportal.infrastructure.repository.clickhouse.clinical_data; +import org.cbioportal.domain.studyview.StudyViewFilterFactory; +import org.cbioportal.infrastructure.repository.clickhouse.AbstractTestcontainers; +import org.cbioportal.infrastructure.repository.clickhouse.config.MyBatisConfig; import org.cbioportal.legacy.model.ClinicalDataCount; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; import org.cbioportal.legacy.web.parameter.DataFilterValue; import org.cbioportal.legacy.web.parameter.StudyViewFilter; @@ -20,39 +21,38 @@ import java.util.Collections; import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; @RunWith(SpringRunner.class) @Import(MyBatisConfig.class) @DataJpaTest @DirtiesContext -@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class StudyViewMapperClinicalDataCountTest extends AbstractTestcontainers { +public class ClickhouseClinicalDataMapperTest { private static final String STUDY_ACC_TCGA = "acc_tcga"; - private static final String STUDY_GENIE_PUB = "study_genie_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; + private static final String STUDY_GENIE_PUB = "study_genie_pub"; + @Autowired + private ClickhouseClinicalDataMapper mapper; + @Test public void getMutationCounts() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB)); - var clinicalDataCountItems = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("mutation_count"), - Collections.emptyList() + var clinicalDataCountItems = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("mutation_count"), + Collections.emptyList() ); - + var mutationsCountsOptional = clinicalDataCountItems.stream() - .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); - + .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); + assertTrue(mutationsCountsOptional.isPresent()); var mutationsCounts = mutationsCountsOptional.get().getCounts(); - + assertEquals(6, mutationsCounts.size()); assertEquals(1, findClinicaDataCount(mutationsCounts, "11")); assertEquals(1, findClinicaDataCount(mutationsCounts, "6")); @@ -62,20 +62,20 @@ public void getMutationCounts() { // 1 empty string + 1 'NAN' + 15 samples with no data assertEquals(17, findClinicaDataCount(mutationsCounts, "NA")); } - + @Test public void getCenterCounts() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB)); - var clinicalDataCounts = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("center"), - Collections.emptyList() + var clinicalDataCounts = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("center"), + Collections.emptyList() ); var categoricalClinicalDataCountsOptional = clinicalDataCounts.stream() - .filter(c -> c.getAttributeId().equals("center")).findFirst(); + .filter(c -> c.getAttributeId().equals("center")).findFirst(); assertTrue(categoricalClinicalDataCountsOptional.isPresent()); var categoricalClinicalDataCounts = categoricalClinicalDataCountsOptional.get().getCounts(); @@ -96,14 +96,14 @@ public void getDeadCounts() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB)); - var clinicalDataCounts = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("dead"), - Collections.emptyList() + var clinicalDataCounts = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("dead"), + Collections.emptyList() ); var categoricalClinicalDataCountsOptional = clinicalDataCounts.stream() - .filter(c -> c.getAttributeId().equals("dead")).findFirst(); + .filter(c -> c.getAttributeId().equals("dead")).findFirst(); assertTrue(categoricalClinicalDataCountsOptional.isPresent()); var categoricalClinicalDataCounts = categoricalClinicalDataCountsOptional.get().getCounts(); @@ -127,10 +127,10 @@ public void getMutationAndCenterCounts() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB)); - var combinedClinicalDataCounts = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("mutation_count", "center"), - Collections.emptyList() + var combinedClinicalDataCounts = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("mutation_count", "center"), + Collections.emptyList() ); assertEquals(2, combinedClinicalDataCounts.size()); @@ -141,20 +141,20 @@ public void getAgeCounts() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB)); - var clinicalDataCountItems = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("age"), - Collections.emptyList() + var clinicalDataCountItems = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("age"), + Collections.emptyList() ); var ageCountsOptional = clinicalDataCountItems.stream() - .filter(c -> c.getAttributeId().equals("age")).findFirst(); + .filter(c -> c.getAttributeId().equals("age")).findFirst(); assertTrue(ageCountsOptional.isPresent()); - var ageCounts = ageCountsOptional.get().getCounts(); + var ageCounts = ageCountsOptional.get().getCounts(); assertAgeCounts(ageCounts); - + // 1 empty string + 1 'NAN' + 1 'N/A' + 1 patient without data assertEquals(4, findClinicaDataCount(ageCounts, "NA")); } @@ -164,18 +164,18 @@ public void getAgeCountsForMultipleStudies() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB, STUDY_ACC_TCGA)); - var clinicalDataCountItems = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("age"), - Collections.emptyList() + var clinicalDataCountItems = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("age"), + Collections.emptyList() ); var ageCountsOptional = clinicalDataCountItems.stream() - .filter(c -> c.getAttributeId().equals("age")).findFirst(); + .filter(c -> c.getAttributeId().equals("age")).findFirst(); assertTrue(ageCountsOptional.isPresent()); var ageCounts = ageCountsOptional.get().getCounts(); - + // everything should be exactly the same as single study (STUDY_GENIE_PUB) filter // except NA counts assertAgeCounts(ageCounts); @@ -183,10 +183,10 @@ public void getAgeCountsForMultipleStudies() { // 1 empty string + 1 'NAN' + 1 'N/A' + 1 GENIE_PUB patient without data + 4 ACC_TCGA data without data assertEquals(8, findClinicaDataCount(ageCounts, "NA")); } - + private void assertAgeCounts(List ageCounts) { assertEquals(15, ageCounts.size()); - + assertEquals(3, findClinicaDataCount(ageCounts, "<18")); assertEquals(1, findClinicaDataCount(ageCounts, "18")); assertEquals(1, findClinicaDataCount(ageCounts, "22")); @@ -203,25 +203,25 @@ private void assertAgeCounts(List ageCounts) { assertEquals(2, findClinicaDataCount(ageCounts, ">89")); assertEquals(1, findClinicaDataCount(ageCounts, "UNKNOWN")); } - + @Test public void getMutationCountsFilteredByAge() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB)); - + // filter patients with age between 20 and 70 // (there are 5 patients within this range, which are 307..311) ClinicalDataFilter filter = buildClinicalDataFilter("age", 20, 70); studyViewFilter.setClinicalDataFilters(List.of(filter)); - - var clinicalDataCountItems = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("mutation_count"), - Collections.emptyList() + + var clinicalDataCountItems = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("mutation_count"), + Collections.emptyList() ); var mutationsCountsOptional = clinicalDataCountItems.stream() - .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); + .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); assertTrue(mutationsCountsOptional.isPresent()); var mutationCountsFiltered = mutationsCountsOptional.get().getCounts(); @@ -242,18 +242,18 @@ public void getMutationCountsFilteredByAgeWithOpenStartValues() { ClinicalDataFilter filter = buildClinicalDataFilter("age", null, 20); studyViewFilter.setClinicalDataFilters(List.of(filter)); - var clinicalDataCountItems = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("mutation_count"), - Collections.emptyList() + var clinicalDataCountItems = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("mutation_count"), + Collections.emptyList() ); var mutationsCountsOptional = clinicalDataCountItems.stream() - .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); + .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); assertTrue(mutationsCountsOptional.isPresent()); var mutationCountsFiltered = mutationsCountsOptional.get().getCounts(); - + assertEquals(4, mutationCountsFiltered.size()); assertEquals(1, findClinicaDataCount(mutationCountsFiltered, "11")); // patient 301 assertEquals(1, findClinicaDataCount(mutationCountsFiltered, "6")); // patient 302 @@ -261,7 +261,7 @@ public void getMutationCountsFilteredByAgeWithOpenStartValues() { assertEquals(1, findClinicaDataCount(mutationCountsFiltered, "2")); // patient 306 // no patients/samples with NA - assertEquals(0, findClinicaDataCount(mutationCountsFiltered, "NA")); + assertEquals(0, findClinicaDataCount(mutationCountsFiltered, "NA")); } @Test @@ -274,14 +274,14 @@ public void getMutationCountsFilteredByAgeWithOpenEndValues() { ClinicalDataFilter filter = buildClinicalDataFilter("age", 80, null); studyViewFilter.setClinicalDataFilters(List.of(filter)); - var clinicalDataCountItems = studyViewMapper.getClinicalDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of("mutation_count"), - Collections.emptyList() + var clinicalDataCountItems = mapper.getClinicalDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of("mutation_count"), + Collections.emptyList() ); var mutationsCountsOptional = clinicalDataCountItems.stream() - .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); + .filter(c -> c.getAttributeId().equals("mutation_count")).findFirst(); assertTrue(mutationsCountsOptional.isPresent()); var mutationCountsFiltered = mutationsCountsOptional.get().getCounts(); @@ -293,7 +293,7 @@ public void getMutationCountsFilteredByAgeWithOpenEndValues() { // patients/samples with NA data: 317, 318, and 319 assertEquals(3, findClinicaDataCount(mutationCountsFiltered, "NA")); } - + private ClinicalDataFilter buildClinicalDataFilter(String attributeId, Integer start, Integer end) { DataFilterValue value = new DataFilterValue(); if (start != null) { @@ -306,13 +306,14 @@ private ClinicalDataFilter buildClinicalDataFilter(String attributeId, Integer s ClinicalDataFilter filter = new ClinicalDataFilter(); filter.setAttributeId(attributeId); filter.setValues(List.of(value)); - + return filter; } - + private int findClinicaDataCount(List counts, String attrValue) { var count = counts.stream().filter(c -> c.getValue().equals(attrValue)).findAny().orElse(null); return count == null ? 0 : count.getCount(); } -} + +} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ClinicalEventTypeCountsTest.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapperTest.java similarity index 67% rename from src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ClinicalEventTypeCountsTest.java rename to src/test/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapperTest.java index 24684b768dc..10773030c07 100644 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ClinicalEventTypeCountsTest.java +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventMapperTest.java @@ -1,7 +1,9 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; +package org.cbioportal.infrastructure.repository.clickhouse.clinical_event; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; +import org.cbioportal.domain.studyview.StudyViewFilterContext; +import org.cbioportal.domain.studyview.StudyViewFilterFactory; +import org.cbioportal.infrastructure.repository.clickhouse.AbstractTestcontainers; +import org.cbioportal.infrastructure.repository.clickhouse.config.MyBatisConfig; import org.cbioportal.legacy.web.parameter.DataFilter; import org.cbioportal.legacy.web.parameter.DataFilterValue; import org.cbioportal.legacy.web.parameter.StudyViewFilter; @@ -13,39 +15,37 @@ import org.springframework.context.annotation.Import; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - +import static org.junit.Assert.*; @RunWith(SpringRunner.class) @Import(MyBatisConfig.class) @DataJpaTest @DirtiesContext @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class ClinicalEventTypeCountsTest extends AbstractTestcontainers { - +public class ClickhouseClinicalEventMapperTest { private static final String STUDY_TCGA_PUB = "study_tcga_pub"; @Autowired - private StudyViewMapper studyViewMapper; + private ClickhouseClinicalEventMapper mapper; @Test public void getClinicalEventTypeCounts() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - var clinicalEventTypeCounts = studyViewMapper.getClinicalEventTypeCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); + StudyViewFilterContext studyViewFilterContext = StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null ); + + var clinicalEventTypeCounts = mapper.getClinicalEventTypeCounts(studyViewFilterContext); assertEquals(4, clinicalEventTypeCounts.size()); var clinicalEventTypeCountOptional = clinicalEventTypeCounts.stream().filter(ce -> ce.getEventType().equals("Treatment")) - .findFirst(); + .findFirst(); assertTrue(clinicalEventTypeCountOptional.isPresent()); assertEquals(1, clinicalEventTypeCountOptional.get().getCount().intValue()); @@ -56,13 +56,15 @@ public void getClinicalEventTypeCounts() { dataFilter.setValues(List.of(dataFilterValue)); studyViewFilter.setClinicalEventFilters(List.of(dataFilter)); - clinicalEventTypeCounts = studyViewMapper.getClinicalEventTypeCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); + clinicalEventTypeCounts = mapper.getClinicalEventTypeCounts( + StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null )); assertEquals(3, clinicalEventTypeCounts.size()); clinicalEventTypeCountOptional = clinicalEventTypeCounts.stream().filter(ce -> ce.getEventType().equals("status")) - .findFirst(); + .findFirst(); assertFalse(clinicalEventTypeCountOptional.isPresent()); } -} +} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/config/MyBatisConfig.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/config/MyBatisConfig.java similarity index 54% rename from src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/config/MyBatisConfig.java rename to src/test/java/org/cbioportal/infrastructure/repository/clickhouse/config/MyBatisConfig.java index 174c55207ff..6eaf0973089 100644 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/config/MyBatisConfig.java +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/config/MyBatisConfig.java @@ -1,10 +1,11 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse.config; +package org.cbioportal.infrastructure.repository.clickhouse.config; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.core.io.ResourceLoader; @@ -12,7 +13,7 @@ import java.io.IOException; @TestConfiguration -@MapperScan("org.cbioportal.legacy.persistence.mybatisclickhouse") +@MapperScan(value= "org.cbioportal.infrastructure.repository.clickhouse") public class MyBatisConfig { @Bean @@ -24,25 +25,18 @@ public DataSourceProperties clickhouseDatSourceProperties() { @Bean public DataSource dataSource() { return clickhouseDatSourceProperties() - .initializeDataSourceBuilder() - .build(); + .initializeDataSourceBuilder() + .build(); } @Bean - public SqlSessionFactoryBean sqlColumnarSessionFactory(ResourceLoader resourceLoader, DataSource dataSource) throws IOException { + public SqlSessionFactoryBean sqlColumnarSessionFactory(ResourceLoader resourceLoader, DataSource dataSource, + ApplicationContext context) throws IOException { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); - var studyViewMapperResource = resourceLoader.getResource("classpath:org/cbioportal/persistence/mybatisclickhouse/StudyViewMapper.xml") ; - var studyViewFilterMapperResource = resourceLoader.getResource("classpath:org/cbioportal/persistence/mybatisclickhouse/StudyViewFilterMapper.xml"); - var alterationFilterMapperResource = resourceLoader.getResource("classpath:org/cbioportal/persistence/mybatisclickhouse/StudyViewAlterationFilterMapper.xml"); - sessionFactory.setMapperLocations( - studyViewMapperResource,studyViewFilterMapperResource, alterationFilterMapperResource - ); + sessionFactory.addMapperLocations( + context.getResources("classpath:mappers/clickhouse/**/*.xml")); return sessionFactory; } - - - - - } + diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/GenericAssayDataCountsTest.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapperTest.java similarity index 53% rename from src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/GenericAssayDataCountsTest.java rename to src/test/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapperTest.java index d1e5165ab86..2468cfb37e0 100644 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/GenericAssayDataCountsTest.java +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayMapperTest.java @@ -1,9 +1,10 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; +package org.cbioportal.infrastructure.repository.clickhouse.generic_assay; +import org.cbioportal.domain.studyview.StudyViewFilterFactory; +import org.cbioportal.infrastructure.repository.clickhouse.AbstractTestcontainers; +import org.cbioportal.infrastructure.repository.clickhouse.config.MyBatisConfig; import org.cbioportal.legacy.model.GenericAssayDataCount; import org.cbioportal.legacy.model.GenericAssayDataCountItem; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; import org.cbioportal.legacy.web.parameter.GenericAssayDataFilter; import org.cbioportal.legacy.web.parameter.StudyViewFilter; import org.junit.Test; @@ -24,15 +25,16 @@ @Import(MyBatisConfig.class) @DataJpaTest @DirtiesContext -@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class GenericAssayDataCountsTest extends AbstractTestcontainers { +public class ClickhouseGenericAssayMapperTest { + private static final String ACC_TCGA = "acc_tcga"; private static final String STUDY_GENIE_PUB = "study_genie_pub"; @Autowired - private StudyViewMapper studyViewMapper; + private ClickhouseGenericAssayMapper mapper; @Test public void getSampleCategoricalGenericAssayDataCounts() { @@ -40,24 +42,24 @@ public void getSampleCategoricalGenericAssayDataCounts() { studyViewFilter.setStudyIds(List.of(ACC_TCGA)); GenericAssayDataFilter genericAssayDataFilter = new GenericAssayDataFilter("1p_status", "armlevel_cna"); - List actualCounts = studyViewMapper.getGenericAssayDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of(genericAssayDataFilter) + List actualCounts = mapper.getGenericAssayDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of(genericAssayDataFilter) ); List expectedCounts = List.of( - new GenericAssayDataCountItem("1p_status", List.of( - new GenericAssayDataCount("Loss", 1), - new GenericAssayDataCount("Gain", 1), - new GenericAssayDataCount("Unchanged", 1), - new GenericAssayDataCount("NA", 1) - )) + new GenericAssayDataCountItem("1p_status", List.of( + new GenericAssayDataCount("Loss", 1), + new GenericAssayDataCount("Gain", 1), + new GenericAssayDataCount("Unchanged", 1), + new GenericAssayDataCount("NA", 1) + )) ); assertThat(actualCounts) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedCounts); + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedCounts); } @Test @@ -66,22 +68,23 @@ public void getPatientCategoricalGenericAssayDataCounts() { studyViewFilter.setStudyIds(List.of(STUDY_GENIE_PUB)); GenericAssayDataFilter genericAssayDataFilter = new GenericAssayDataFilter("DMETS_DX_ADRENAL", "distant_mets"); - List actualCounts = studyViewMapper.getGenericAssayDataCounts( - StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - List.of(genericAssayDataFilter) + List actualCounts = mapper.getGenericAssayDataCounts( + StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), + List.of(genericAssayDataFilter) ); List expectedCounts = List.of( - new GenericAssayDataCountItem("DMETS_DX_ADRENAL", List.of( - new GenericAssayDataCount("No", 9), - new GenericAssayDataCount("Yes", 1), - new GenericAssayDataCount("NA", 14) - )) + new GenericAssayDataCountItem("DMETS_DX_ADRENAL", List.of( + new GenericAssayDataCount("No", 9), + new GenericAssayDataCount("Yes", 1), + new GenericAssayDataCount("NA", 14) + )) ); assertThat(actualCounts) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedCounts); + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedCounts); } + } \ No newline at end of file diff --git a/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapperTest.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapperTest.java new file mode 100644 index 00000000000..ffc3e72ced0 --- /dev/null +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataMapperTest.java @@ -0,0 +1,267 @@ +package org.cbioportal.infrastructure.repository.clickhouse.genomic_data; + +import org.cbioportal.domain.studyview.StudyViewFilterFactory; +import org.cbioportal.infrastructure.repository.clickhouse.AbstractTestcontainers; +import org.cbioportal.infrastructure.repository.clickhouse.config.MyBatisConfig; +import org.cbioportal.legacy.model.ClinicalDataCount; +import org.cbioportal.legacy.model.GenomicDataCount; +import org.cbioportal.legacy.model.GenomicDataCountItem; +import org.cbioportal.legacy.web.parameter.DataFilterValue; +import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; +import org.cbioportal.legacy.web.parameter.GenomicDataFilter; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@Import(MyBatisConfig.class) +@DataJpaTest +@DirtiesContext +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) +public class ClickhouseGenomicDataMapperTest { + private static final String STUDY_TCGA_PUB = "study_tcga_pub"; + private static final String STUDY_ACC_TCGA = "acc_tcga"; + + @Autowired + private ClickhouseGenomicDataMapper mapper; + + @Test + public void getCNACounts() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + GenomicDataFilter genomicDataFilterCNA = new GenomicDataFilter("AKT1", "cna"); + List actualCountsCNA = mapper.getCNACounts(StudyViewFilterFactory.make(studyViewFilter, + null, studyViewFilter.getStudyIds(),null), List.of(genomicDataFilterCNA)); + List expectedCountsCNA = List.of( + new GenomicDataCountItem("AKT1", "cna", List.of( + new GenomicDataCount("Homozygously deleted", "-2", 2), + new GenomicDataCount("Heterozygously deleted", "-1", 2), + new GenomicDataCount("Diploid", "0", 2), + new GenomicDataCount("Gained", "1", 2), + new GenomicDataCount("Amplified", "2", 2), + new GenomicDataCount("NA", "NA", 5) + ))); + assertThat(actualCountsCNA) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedCountsCNA); + + GenomicDataFilter genomicDataFilterGISTIC = new GenomicDataFilter("AKT1", "gistic"); + List actualCountsGISTIC = + mapper.getCNACounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds() + , null), List.of(genomicDataFilterGISTIC)); + List expectedCountsGISTIC = List.of( + new GenomicDataCountItem("AKT1", "gistic", List.of( + new GenomicDataCount("Homozygously deleted", "-2", 2), + new GenomicDataCount("Heterozygously deleted", "-1", 3), + new GenomicDataCount("Diploid", "0", 3), + new GenomicDataCount("Gained", "1", 3), + new GenomicDataCount("Amplified", "2", 3), + new GenomicDataCount("NA", "NA", 1) + ))); + assertThat(actualCountsGISTIC) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedCountsGISTIC); + } + + @Test + public void getMutationCounts() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + GenomicDataFilter genomicDataFilterMutation = new GenomicDataFilter("AKT1", "cna"); + Map actualMutationCounts = mapper.getMutationCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), genomicDataFilterMutation); + Map expectedMutationCounts = new HashMap<>(); + expectedMutationCounts.put("mutatedCount", 2); + expectedMutationCounts.put("notMutatedCount", 8); + expectedMutationCounts.put("notProfiledCount", 5); + assertThat(actualMutationCounts) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedMutationCounts); + } + + @Test + public void getMutationCountsByType() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + GenomicDataFilter genomicDataFilterMutation = new GenomicDataFilter("AKT1", "mutation"); + List actualMutationCountsByType = mapper.getMutationCountsByType(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null), List.of(genomicDataFilterMutation)); + List expectedMutationCountsByType = List.of( + new GenomicDataCountItem("AKT1", "mutations", List.of( + new GenomicDataCount("nonsense mutation", "nonsense_mutation", 2, 1), + new GenomicDataCount("missense mutation", "missense_mutation", 1, 1) + ))); + assertThat(actualMutationCountsByType) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedMutationCountsByType); + } + + @Test + public void getProteinExpressionCounts() { + // Testing combined study missing samples when one lacks a relevant genomic profile + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_ACC_TCGA)); + + GenomicDataBinFilter genomicDataBinFilterRPPA = new GenomicDataBinFilter(); + genomicDataBinFilterRPPA.setHugoGeneSymbol("AKT1"); + genomicDataBinFilterRPPA.setProfileType("rppa"); + + List actualRPPACounts1 = + mapper.getGenomicDataBinCounts(StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null), List.of(genomicDataBinFilterRPPA)); + + ClinicalDataCount expectedRPPACount1 = new ClinicalDataCount(); + expectedRPPACount1.setAttributeId("AKT1rppa"); + expectedRPPACount1.setValue("0.7360"); + expectedRPPACount1.setCount(1); + ClinicalDataCount expectedRPPACount2 = new ClinicalDataCount(); + expectedRPPACount2.setAttributeId("AKT1rppa"); + expectedRPPACount2.setValue("-0.8097"); + expectedRPPACount2.setCount(1); + ClinicalDataCount expectedRPPACount3 = new ClinicalDataCount(); + expectedRPPACount3.setAttributeId("AKT1rppa"); + expectedRPPACount3.setValue("-0.1260"); + expectedRPPACount3.setCount(1); + ClinicalDataCount expectedRPPACountNA = new ClinicalDataCount(); + expectedRPPACountNA.setAttributeId("AKT1rppa"); + expectedRPPACountNA.setValue("NA"); + expectedRPPACountNA.setCount(16); + + List expectedRPPACounts1 = List.of( + expectedRPPACount1, expectedRPPACount2, expectedRPPACount3, expectedRPPACountNA + ); + assertThat(actualRPPACounts1) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedRPPACounts1); + + + // Testing NA filtering on combined study missing samples when one lacks a relevant genomic profile + // Make genomic data filter to put in study view filter + GenomicDataFilter genomicDataFilterRPPA = new GenomicDataFilter("AKT1", "rppa"); + DataFilterValue dataFilterValue = new DataFilterValue(); + dataFilterValue.setValue("NA"); + genomicDataFilterRPPA.setValues(List.of(dataFilterValue)); + studyViewFilter.setGenomicDataFilters(List.of(genomicDataFilterRPPA)); + + List actualRPPACounts2 = + mapper.getGenomicDataBinCounts(StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null), List.of(genomicDataBinFilterRPPA)); + + ClinicalDataCount expectedRPPACount = new ClinicalDataCount(); + expectedRPPACount.setAttributeId("AKT1rppa"); + expectedRPPACount.setValue("NA"); + expectedRPPACount.setCount(16); + + List expectedRPPACounts2 = List.of( + expectedRPPACount + ); + assertThat(actualRPPACounts2) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(expectedRPPACounts2); + } + + @Test + public void getMolecularProfileCounts() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + var profiles = new ArrayList(Arrays.asList("mutations")); + var profileGroups = new ArrayList>(Arrays.asList(profiles)); + + studyViewFilter.setGenomicProfiles(profileGroups); + + var molecularProfileCounts = + mapper.getMolecularProfileSampleCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + var size = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) + .findFirst().get().getCount().intValue(); + assertEquals(11, size); + + } + + @Test + public void getMolecularProfileCountsMultipleStudies() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_ACC_TCGA)); + + var profiles = new ArrayList(Arrays.asList("mutations")); + var profileGroups = new ArrayList>(Arrays.asList(profiles)); + + studyViewFilter.setGenomicProfiles(profileGroups); + + var molecularProfileCounts = + mapper.getMolecularProfileSampleCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + var size = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) + .findFirst().get().getCount().intValue(); + assertEquals(11, size); + + } + + @Test + public void getMolecularProfileCountsMultipleProfilesUnion() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + var profiles = new ArrayList(Arrays.asList("mutations","mrna")); + var profileGroups = new ArrayList>(Arrays.asList(profiles)); + + studyViewFilter.setGenomicProfiles(profileGroups); + + var molecularProfileCounts = + mapper.getMolecularProfileSampleCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + var sizeMutations = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) + .findFirst().get().getCount().intValue(); + assertEquals(11, sizeMutations); + + var sizeMrna = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mrna")) + .findFirst().get().getCount().intValue(); + assertEquals(9, sizeMrna); + + } + + @Test + public void getMolecularProfileCountsMultipleProfilesIntersect() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + var profile1 = new ArrayList(Arrays.asList("mutations")); + var profile2 = new ArrayList(Arrays.asList("mrna")); + var profileGroups = new ArrayList>(Arrays.asList(profile1, profile2)); + + studyViewFilter.setGenomicProfiles(profileGroups); + + var molecularProfileCounts = + mapper.getMolecularProfileSampleCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + var sizeMutations = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) + .findFirst().get().getCount().intValue(); + assertEquals(10, sizeMutations); + + } +} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewCaseListSamplesCountsTest.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapperTest.java similarity index 70% rename from src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewCaseListSamplesCountsTest.java rename to src/test/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapperTest.java index 4ec4993d5e2..3abe20fee9c 100644 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewCaseListSamplesCountsTest.java +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientMapperTest.java @@ -1,8 +1,8 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; +package org.cbioportal.infrastructure.repository.clickhouse.patient; +import org.cbioportal.domain.studyview.StudyViewFilterFactory; +import org.cbioportal.infrastructure.repository.clickhouse.AbstractTestcontainers; +import org.cbioportal.infrastructure.repository.clickhouse.config.MyBatisConfig; import org.cbioportal.legacy.service.util.StudyViewColumnarServiceUtil; import org.cbioportal.legacy.web.parameter.StudyViewFilter; import org.junit.Test; @@ -19,22 +19,23 @@ import java.util.Arrays; import java.util.List; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; @RunWith(SpringRunner.class) @Import(MyBatisConfig.class) @DataJpaTest @DirtiesContext -@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class StudyViewCaseListSamplesCountsTest extends AbstractTestcontainers { - +public class ClickhousePatientMapperTest { + private static final String STUDY_TCGA_PUB = "study_tcga_pub"; private static final String STUDY_ACC_TCGA = "acc_tcga"; - @Autowired - private StudyViewMapper studyViewMapper; + @Autowired + private ClickhousePatientMapper mapper; + @Test public void getMolecularProfileCounts() { StudyViewFilter studyViewFilter = new StudyViewFilter(); @@ -44,13 +45,13 @@ public void getMolecularProfileCounts() { var caseListGroups = new ArrayList(Arrays.asList(caseList)); studyViewFilter.setCaseLists(caseListGroups); - - var sampleListCounts = studyViewMapper.getCaseListDataCountsPerStudy(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()) ); + + var sampleListCounts = mapper.getCaseListDataCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null) ); var size = sampleListCounts.stream().filter(gc->gc.getValue().equals("mrna")) - .findFirst().get().getCount().intValue(); + .findFirst().get().getCount().intValue(); assertEquals(7, size); - + } @Test @@ -63,10 +64,10 @@ public void getMolecularProfileCountsMultipleListsOr() { studyViewFilter.setCaseLists(caseListGroups); - var sampleListCounts = studyViewMapper.getCaseListDataCountsPerStudy(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()) ); + var sampleListCounts = mapper.getCaseListDataCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null) ); var size = sampleListCounts.stream().filter(gc->gc.getValue().equals("mrna")) - .findFirst().get().getCount().intValue(); + .findFirst().get().getCount().intValue(); assertEquals(8, size); } @@ -82,10 +83,10 @@ public void getMolecularProfileCountsMultipleListsAnd() { studyViewFilter.setCaseLists(caseListGroups); - var sampleListCounts = studyViewMapper.getCaseListDataCountsPerStudy(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()) ); + var sampleListCounts = mapper.getCaseListDataCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null) ); var size = sampleListCounts.stream().filter(gc->gc.getValue().equals("mrna")) - .findFirst().get().getCount().intValue(); + .findFirst().get().getCount().intValue(); assertEquals(7, size); } @@ -100,21 +101,20 @@ public void getMolecularProfileCountsAcrossStudies() { studyViewFilter.setCaseLists(caseListGroups); - var unMergedCounts = studyViewMapper.getCaseListDataCountsPerStudy(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()) ); - + var unMergedCounts = mapper.getCaseListDataCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null) ); + var caseListCountsMerged = StudyViewColumnarServiceUtil.mergeCaseListCounts( - unMergedCounts + unMergedCounts ); var sizeUnmerged = unMergedCounts.stream().filter(gc->gc.getValue().equals("all")) - .findFirst().get().getCount().intValue(); + .findFirst().get().getCount().intValue(); assertEquals(14, sizeUnmerged); - + // now we've combined the "all" from the two studies var sizeMerged = caseListCountsMerged.stream().filter(gc->gc.getValue().equals("all")) - .findFirst().get().getCount().intValue(); + .findFirst().get().getCount().intValue(); assertEquals(15, sizeMerged); } - } \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/FilteredSamplesTest.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapperTest.java similarity index 54% rename from src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/FilteredSamplesTest.java rename to src/test/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapperTest.java index 6d95950fafc..f4c609b0c2c 100644 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/FilteredSamplesTest.java +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleMapperTest.java @@ -1,7 +1,9 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; +package org.cbioportal.infrastructure.repository.clickhouse.sample; +import org.cbioportal.domain.studyview.StudyViewFilterFactory; +import org.cbioportal.infrastructure.repository.clickhouse.AbstractTestcontainers; +import org.cbioportal.infrastructure.repository.clickhouse.config.MyBatisConfig; import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; import org.cbioportal.legacy.web.parameter.ClinicalDataFilter; import org.cbioportal.legacy.web.parameter.CustomSampleIdentifier; import org.cbioportal.legacy.web.parameter.DataFilterValue; @@ -21,7 +23,7 @@ import java.util.Arrays; import java.util.List; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; @RunWith(SpringRunner.class) @Import(MyBatisConfig.class) @@ -29,20 +31,21 @@ @DirtiesContext @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class FilteredSamplesTest extends AbstractTestcontainers { - +public class ClickhouseSampleMapperTest { private static final String STUDY_TCGA_PUB = "study_tcga_pub"; private static final String STUDY_ACC_TCGA = "acc_tcga"; private static final String STUDY_GENIE_PUB = "study_genie_pub"; - @Autowired - private StudyViewMapper studyViewMapper; + @Autowired + private ClickhouseSampleMapper mapper; + @Test public void getFilteredSamples() { StudyViewFilter studyViewFilter = new StudyViewFilter(); studyViewFilter.setStudyIds(Arrays.asList(STUDY_TCGA_PUB, STUDY_ACC_TCGA)); - var filteredSamples = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); + var filteredSamples = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, null, + studyViewFilter.getStudyIds(), null )); assertEquals(19, filteredSamples.size()); ClinicalDataFilter customDataFilter = new ClinicalDataFilter(); @@ -50,16 +53,17 @@ public void getFilteredSamples() { DataFilterValue value = new DataFilterValue(); customDataFilter.setValues(List.of(value)); studyViewFilter.setCustomDataFilters(List.of(customDataFilter)); - var filteredSamples1 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, new ArrayList<>(), studyViewFilter.getStudyIds())); + var filteredSamples1 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, List.of(), + studyViewFilter.getStudyIds(), null )); assertEquals(0, filteredSamples1.size()); CustomSampleIdentifier customSampleIdentifier = new CustomSampleIdentifier(); customSampleIdentifier.setStudyId("acc_tcga"); customSampleIdentifier.setSampleId("tcga-a1-a0sb-01"); - var filteredSamples2 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, Arrays.asList(customSampleIdentifier), studyViewFilter.getStudyIds())); + var filteredSamples2 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, + List.of(customSampleIdentifier), studyViewFilter.getStudyIds(), null )); assertEquals(1, filteredSamples2.size()); } - @Test public void getSamplesFilteredByClinicalData() { StudyViewFilter studyViewFilter = new StudyViewFilter(); @@ -67,106 +71,112 @@ public void getSamplesFilteredByClinicalData() { // samples of patients with AGE <= 20.0 studyViewFilter.setClinicalDataFilters( - List.of( - newClinicalDataFilter( - "age", List.of( - newDataFilterValue(null, 20.0, null) - ) + List.of( + newClinicalDataFilter( + "age", List.of( + newDataFilterValue(null, 20.0, null) + ) + ) ) - ) ); - var filteredSamples1 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, new ArrayList<>(), studyViewFilter.getStudyIds())); + var filteredSamples1 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, + List.of(),studyViewFilter.getStudyIds(), null)); assertEquals(4, filteredSamples1.size()); // samples of patients with AGE <= 20.0 or (80.0, 82.0] studyViewFilter.setClinicalDataFilters( - List.of( - newClinicalDataFilter( - "age", List.of( - newDataFilterValue(null, 20.0, null), - newDataFilterValue(80.0, 82.0, null) - ) + List.of( + newClinicalDataFilter( + "age", List.of( + newDataFilterValue(null, 20.0, null), + newDataFilterValue(80.0, 82.0, null) + ) + ) ) - ) ); - var filteredSamples2 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, new ArrayList<>(), studyViewFilter.getStudyIds())); + var filteredSamples2 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, + List.of(), studyViewFilter.getStudyIds(), null)); assertEquals(6, filteredSamples2.size()); // samples of patients with UNKNOWN AGE studyViewFilter.setClinicalDataFilters( - List.of( - newClinicalDataFilter( - "age", List.of( - newDataFilterValue(null, null, "Unknown") - ) + List.of( + newClinicalDataFilter( + "age", List.of( + newDataFilterValue(null, null, "Unknown") + ) + ) ) - ) ); - var filteredSamples3 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, new ArrayList<>(), studyViewFilter.getStudyIds())); + var filteredSamples3 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, + List.of(), studyViewFilter.getStudyIds(), null)); assertEquals(1, filteredSamples3.size()); // samples of patients with AGE <= 20.0 or (80.0, 82.0] or UNKNOWN // this is a mixed list of filters of both numerical and non-numerical values studyViewFilter.setClinicalDataFilters( - List.of( - newClinicalDataFilter( - "age", List.of( - newDataFilterValue(null, 20.0, null), - newDataFilterValue(80.0, 82.0, null), - newDataFilterValue(null, null, "unknown") - ) + List.of( + newClinicalDataFilter( + "age", List.of( + newDataFilterValue(null, 20.0, null), + newDataFilterValue(80.0, 82.0, null), + newDataFilterValue(null, null, "unknown") + ) + ) ) - ) ); - var filteredSamples4 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, new ArrayList<>(), studyViewFilter.getStudyIds())); + var filteredSamples4 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, + List.of(), studyViewFilter.getStudyIds(),null)); assertEquals(7, filteredSamples4.size()); - + // NA filter studyViewFilter.setClinicalDataFilters( - List.of( - newClinicalDataFilter( - "age", List.of( - newDataFilterValue(null, null, "NA") - ) + List.of( + newClinicalDataFilter( + "age", List.of( + newDataFilterValue(null, null, "NA") + ) + ) ) - ) ); - var filteredSamples5 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, new ArrayList<>(), studyViewFilter.getStudyIds())); + var filteredSamples5 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, + List.of(), studyViewFilter.getStudyIds(), null)); // 4 acc_tcga + 7 study_genie_pub samples with "NA" AGE data or no AGE data assertEquals(11, filteredSamples5.size()); - + // NA + UNKNOWN studyViewFilter.setClinicalDataFilters( - List.of( - newClinicalDataFilter( - "age", List.of( - newDataFilterValue(null, null, "NA"), - newDataFilterValue(null, null, "UNKNOWN") - ) + List.of( + newClinicalDataFilter( + "age", List.of( + newDataFilterValue(null, null, "NA"), + newDataFilterValue(null, null, "UNKNOWN") + ) + ) ) - ) ); - var filteredSamples6 = studyViewMapper.getFilteredSamples(StudyViewFilterHelper.build(studyViewFilter, null, new ArrayList<>(), studyViewFilter.getStudyIds())); + var filteredSamples6 = mapper.getFilteredSamples(StudyViewFilterFactory.make(studyViewFilter, + List.of(), studyViewFilter.getStudyIds(), null)); // 11 NA + 1 UNKNOWN assertEquals(12, filteredSamples6.size()); } - + private DataFilterValue newDataFilterValue(Double start, Double end, String value) { DataFilterValue dataFilterValue = new DataFilterValue(); - + dataFilterValue.setStart(start == null ? null : new BigDecimal(start)); dataFilterValue.setEnd(end == null ? null: new BigDecimal(end)); dataFilterValue.setValue(value); - + return dataFilterValue; } private ClinicalDataFilter newClinicalDataFilter(String attributeId, List values) { ClinicalDataFilter clinicalDataFilter = new ClinicalDataFilter(); - + clinicalDataFilter.setAttributeId(attributeId); clinicalDataFilter.setValues(values); - + return clinicalDataFilter; } -} +} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapperTest.java b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapperTest.java new file mode 100644 index 00000000000..1ba97f1c0ed --- /dev/null +++ b/src/test/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentMapperTest.java @@ -0,0 +1,106 @@ +package org.cbioportal.infrastructure.repository.clickhouse.treatment; + +import org.cbioportal.domain.studyview.StudyViewFilterFactory; +import org.cbioportal.infrastructure.repository.clickhouse.AbstractTestcontainers; +import org.cbioportal.infrastructure.repository.clickhouse.config.MyBatisConfig; +import org.cbioportal.legacy.model.TemporalRelation; +import org.cbioportal.legacy.web.parameter.StudyViewFilter; +import org.cbioportal.legacy.web.parameter.filter.AndedPatientTreatmentFilters; +import org.cbioportal.legacy.web.parameter.filter.AndedSampleTreatmentFilters; +import org.cbioportal.legacy.web.parameter.filter.OredPatientTreatmentFilters; +import org.cbioportal.legacy.web.parameter.filter.OredSampleTreatmentFilters; +import org.cbioportal.legacy.web.parameter.filter.PatientTreatmentFilter; +import org.cbioportal.legacy.web.parameter.filter.SampleTreatmentFilter; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@Import(MyBatisConfig.class) +@DataJpaTest +@DirtiesContext +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) +public class ClickhouseTreatmentMapperTest { + private static final String STUDY_TCGA_PUB = "study_tcga_pub"; + + @Autowired + private ClickhouseTreatmentMapper mapper; + + @Test + public void getPatientTreatments() { + + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + + var patientTreatmentCounts = mapper.getPatientTreatmentCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + var patientTreatments = mapper.getPatientTreatments(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + assertEquals(1, patientTreatmentCounts); + assertEquals("madeupanib", patientTreatments.getFirst().treatment()); + + PatientTreatmentFilter filter = new PatientTreatmentFilter(); + filter.setTreatment("madeupanib"); + + OredPatientTreatmentFilters oredPatientTreatmentFilters = new OredPatientTreatmentFilters(); + oredPatientTreatmentFilters.setFilters(List.of(filter)); + + AndedPatientTreatmentFilters andedPatientTreatmentFilters = new AndedPatientTreatmentFilters(); + andedPatientTreatmentFilters.setFilters(List.of(oredPatientTreatmentFilters)); + studyViewFilter.setPatientTreatmentFilters(andedPatientTreatmentFilters); + + patientTreatmentCounts = mapper.getPatientTreatmentCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + patientTreatments = mapper.getPatientTreatments(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + assertEquals(1, patientTreatmentCounts); + assertEquals("madeupanib", patientTreatments.getFirst().treatment()); + + } + + @Test + public void getTotalSampleTreatmentCounts() { + StudyViewFilter studyViewFilter = new StudyViewFilter(); + studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); + + + var totalSampleTreatmentCount = mapper.getTotalSampleTreatmentCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + var sampleTreatmentCounts = mapper.getSampleTreatmentCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + assertEquals(1, totalSampleTreatmentCount); + assertEquals("madeupanib", sampleTreatmentCounts.getFirst().treatment()); + assertEquals(1, sampleTreatmentCounts.getFirst().postSampleCount()); + assertEquals(0, sampleTreatmentCounts.getFirst().preSampleCount()); + + SampleTreatmentFilter filter = new SampleTreatmentFilter(); + filter.setTreatment("madeupanib"); + filter.setTime(TemporalRelation.Pre); + + OredSampleTreatmentFilters oredSampleTreatmentFilters = new OredSampleTreatmentFilters(); + oredSampleTreatmentFilters.setFilters(List.of(filter)); + + AndedSampleTreatmentFilters andedSampleTreatmentFilters = new AndedSampleTreatmentFilters(); + andedSampleTreatmentFilters.setFilters(List.of(oredSampleTreatmentFilters)); + studyViewFilter.setSampleTreatmentFilters(andedSampleTreatmentFilters); + + totalSampleTreatmentCount = mapper.getTotalSampleTreatmentCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + sampleTreatmentCounts = mapper.getSampleTreatmentCounts(StudyViewFilterFactory.make(studyViewFilter, null, studyViewFilter.getStudyIds(), null)); + + assertEquals(0, totalSampleTreatmentCount); + assertEquals(0, sampleTreatmentCounts.size()); + } +} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/CNAGenesTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/CNAGenesTest.java deleted file mode 100644 index 210d448534c..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/CNAGenesTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.model.AlterationFilter; -import org.cbioportal.legacy.model.CNA; -import org.cbioportal.legacy.persistence.helper.AlterationFilterHelper; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class CNAGenesTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getCnaGenes() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - var alterationCountByGenes = studyViewMapper.getCnaGenes(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - AlterationFilterHelper.build(studyViewFilter.getAlterationFilter())); - assertEquals(3, alterationCountByGenes.size()); - - // Test cna count for akt1 - var testAKT1AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "AKT1")) - .mapToInt(c -> c.getTotalCount().intValue()) - .sum(); - assertEquals(3, testAKT1AlterationCount); - } - - @Test - public void getCnaGenesWithAlterationFilter() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - // Create AlterationFilter - AlterationFilter alterationFilter = new AlterationFilter(); - Map cnaEventTypeFilterMap = new HashMap<>(); - cnaEventTypeFilterMap.put(CNA.HOMDEL, false); - cnaEventTypeFilterMap.put(CNA.AMP, true); - alterationFilter.setCopyNumberAlterationEventTypes(cnaEventTypeFilterMap); - - var alterationCountByGenes = studyViewMapper.getCnaGenes(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - AlterationFilterHelper.build(alterationFilter)); - assertEquals(2, alterationCountByGenes.size()); - - // Test cna count for akt1 filtering for AMP - var testAKT1AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "AKT1")) - .mapToInt(c -> c.getTotalCount().intValue()) - .sum(); - assertEquals(2, testAKT1AlterationCount); - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/GenomicDataCountsTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/GenomicDataCountsTest.java deleted file mode 100644 index c2594b589a9..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/GenomicDataCountsTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.model.GenomicDataCount; -import org.cbioportal.legacy.model.GenomicDataCountItem; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class GenomicDataCountsTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getCNACounts() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - GenomicDataFilter genomicDataFilterCNA = new GenomicDataFilter("AKT1", "cna"); - List actualCountsCNA = studyViewMapper.getCNACounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), List.of(genomicDataFilterCNA)); - List expectedCountsCNA = List.of( - new GenomicDataCountItem("AKT1", "cna", List.of( - new GenomicDataCount("Homozygously deleted", "-2", 2), - new GenomicDataCount("Heterozygously deleted", "-1", 2), - new GenomicDataCount("Diploid", "0", 2), - new GenomicDataCount("Gained", "1", 2), - new GenomicDataCount("Amplified", "2", 2), - new GenomicDataCount("NA", "NA", 5) - ))); - assertThat(actualCountsCNA) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedCountsCNA); - - GenomicDataFilter genomicDataFilterGISTIC = new GenomicDataFilter("AKT1", "gistic"); - List actualCountsGISTIC = studyViewMapper.getCNACounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), List.of(genomicDataFilterGISTIC)); - List expectedCountsGISTIC = List.of( - new GenomicDataCountItem("AKT1", "gistic", List.of( - new GenomicDataCount("Homozygously deleted", "-2", 2), - new GenomicDataCount("Heterozygously deleted", "-1", 3), - new GenomicDataCount("Diploid", "0", 3), - new GenomicDataCount("Gained", "1", 3), - new GenomicDataCount("Amplified", "2", 3), - new GenomicDataCount("NA", "NA", 1) - ))); - assertThat(actualCountsGISTIC) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedCountsGISTIC); - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MolecularProfileCountTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MolecularProfileCountTest.java deleted file mode 100644 index b46492bf09a..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MolecularProfileCountTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; - -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class MolecularProfileCountTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - private static final String STUDY_ACC_TCGA = "acc_tcga"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getMolecularProfileCounts() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - var profiles = new ArrayList(Arrays.asList("mutations")); - var profileGroups = new ArrayList>(Arrays.asList(profiles)); - - studyViewFilter.setGenomicProfiles(profileGroups); - - var molecularProfileCounts = studyViewMapper.getMolecularProfileSampleCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - var size = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) - .findFirst().get().getCount().intValue(); - assertEquals(11, size); - - } - - @Test - public void getMolecularProfileCountsMultipleStudies() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_ACC_TCGA)); - - var profiles = new ArrayList(Arrays.asList("mutations")); - var profileGroups = new ArrayList>(Arrays.asList(profiles)); - - studyViewFilter.setGenomicProfiles(profileGroups); - - var molecularProfileCounts = studyViewMapper.getMolecularProfileSampleCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - var size = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) - .findFirst().get().getCount().intValue(); - assertEquals(11, size); - - } - - @Test - public void getMolecularProfileCountsMultipleProfilesUnion() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - var profiles = new ArrayList(Arrays.asList("mutations","mrna")); - var profileGroups = new ArrayList>(Arrays.asList(profiles)); - - studyViewFilter.setGenomicProfiles(profileGroups); - - var molecularProfileCounts = studyViewMapper.getMolecularProfileSampleCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - var sizeMutations = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) - .findFirst().get().getCount().intValue(); - assertEquals(11, sizeMutations); - - var sizeMrna = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mrna")) - .findFirst().get().getCount().intValue(); - assertEquals(9, sizeMrna); - - } - - @Test - public void getMolecularProfileCountsMultipleProfilesIntersect() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - var profile1 = new ArrayList(Arrays.asList("mutations")); - var profile2 = new ArrayList(Arrays.asList("mrna")); - var profileGroups = new ArrayList>(Arrays.asList(profile1, profile2)); - - studyViewFilter.setGenomicProfiles(profileGroups); - - var molecularProfileCounts = studyViewMapper.getMolecularProfileSampleCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - var sizeMutations = molecularProfileCounts.stream().filter(gc->gc.getValue().equals("mutations")) - .findFirst().get().getCount().intValue(); - assertEquals(10, sizeMutations); - - - - } - - - - -} \ No newline at end of file diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutatedGenesTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutatedGenesTest.java deleted file mode 100644 index 86658bc8dfb..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutatedGenesTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.model.AlterationFilter; -import org.cbioportal.legacy.model.MutationEventType; -import org.cbioportal.legacy.persistence.helper.AlterationFilterHelper; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class MutatedGenesTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getMutatedGenes() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - var alterationCountByGenes = studyViewMapper.getMutatedGenes(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - AlterationFilterHelper.build(studyViewFilter.getAlterationFilter())); - assertEquals(3, alterationCountByGenes.size()); - - var testBrca1AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "BRCA1")).findFirst(); - assert (testBrca1AlterationCount.isPresent()); - assertEquals(Integer.valueOf(5), testBrca1AlterationCount.get().getTotalCount()); - } - - @Test - public void getMutatedGenesWithAlterationFilter() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - // Create AlterationFilter - AlterationFilter alterationFilter = new AlterationFilter(); - Map mutationEventTypeFilterMap = new HashMap<>(); - mutationEventTypeFilterMap.put(MutationEventType.nonsense_mutation, Boolean.TRUE); - mutationEventTypeFilterMap.put(MutationEventType.other, Boolean.FALSE); - alterationFilter.setMutationEventTypes(mutationEventTypeFilterMap); - - var alterationCountByGenes = studyViewMapper.getMutatedGenes(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - AlterationFilterHelper.build(alterationFilter)); - assertEquals(2, alterationCountByGenes.size()); - - AlterationFilter onlyMutationStatusFilter = new AlterationFilter(); - onlyMutationStatusFilter.setMutationEventTypes(new HashMap<>()); - onlyMutationStatusFilter.setIncludeGermline(false); - onlyMutationStatusFilter.setIncludeSomatic(false); - onlyMutationStatusFilter.setIncludeUnknownStatus(true); - - var alterationCountByGenes1 = studyViewMapper.getMutatedGenes(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - AlterationFilterHelper.build(onlyMutationStatusFilter)); - assertEquals(1, alterationCountByGenes1.size()); - - AlterationFilter mutationTypeAndStatusFilter = new AlterationFilter(); - mutationTypeAndStatusFilter.setMutationEventTypes(mutationEventTypeFilterMap); - mutationTypeAndStatusFilter.setMutationEventTypes(new HashMap<>()); - mutationTypeAndStatusFilter.setIncludeGermline(false); - mutationTypeAndStatusFilter.setIncludeSomatic(false); - mutationTypeAndStatusFilter.setIncludeUnknownStatus(true); - - var alterationCountByGenes2 = studyViewMapper.getMutatedGenes(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - AlterationFilterHelper.build(onlyMutationStatusFilter)); - assertEquals(1, alterationCountByGenes2.size()); - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutationDataCountsTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutationDataCountsTest.java deleted file mode 100644 index a7c7959a0b4..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/MutationDataCountsTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.model.GenomicDataCount; -import org.cbioportal.legacy.model.GenomicDataCountItem; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class MutationDataCountsTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getMutationCounts() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - GenomicDataFilter genomicDataFilterMutation = new GenomicDataFilter("AKT1", "cna"); - Map actualMutationCounts = studyViewMapper.getMutationCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), genomicDataFilterMutation); - Map expectedMutationCounts = new HashMap<>(); - expectedMutationCounts.put("mutatedCount", 2); - expectedMutationCounts.put("notMutatedCount", 8); - expectedMutationCounts.put("notProfiledCount", 5); - assertThat(actualMutationCounts) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedMutationCounts); - } - - @Test - public void getMutationCountsByType() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - GenomicDataFilter genomicDataFilterMutation = new GenomicDataFilter("AKT1", "mutation"); - List actualMutationCountsByType = studyViewMapper.getMutationCountsByType(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), List.of(genomicDataFilterMutation)); - List expectedMutationCountsByType = List.of( - new GenomicDataCountItem("AKT1", "mutations", List.of( - new GenomicDataCount("nonsense mutation", "nonsense_mutation", 2, 1), - new GenomicDataCount("missense mutation", "missense_mutation", 1, 1) - ))); - assertThat(actualMutationCountsByType) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedMutationCountsByType); - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/PatientTreatmentCountsTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/PatientTreatmentCountsTest.java deleted file mode 100644 index f83ea3f263a..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/PatientTreatmentCountsTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.cbioportal.legacy.web.parameter.filter.AndedPatientTreatmentFilters; -import org.cbioportal.legacy.web.parameter.filter.OredPatientTreatmentFilters; -import org.cbioportal.legacy.web.parameter.filter.PatientTreatmentFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.List; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class PatientTreatmentCountsTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getPatientTreatmentReportCounts() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - - var patientTreatmentCounts = studyViewMapper.getPatientTreatmentCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - var patientTreatments = studyViewMapper.getPatientTreatments(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - assertEquals(1, patientTreatmentCounts); - assertEquals("madeupanib", patientTreatments.getFirst().treatment()); - - PatientTreatmentFilter filter = new PatientTreatmentFilter(); - filter.setTreatment("madeupanib"); - - OredPatientTreatmentFilters oredPatientTreatmentFilters = new OredPatientTreatmentFilters(); - oredPatientTreatmentFilters.setFilters(List.of(filter)); - - AndedPatientTreatmentFilters andedPatientTreatmentFilters = new AndedPatientTreatmentFilters(); - andedPatientTreatmentFilters.setFilters(List.of(oredPatientTreatmentFilters)); - studyViewFilter.setPatientTreatmentFilters(andedPatientTreatmentFilters); - - patientTreatmentCounts = studyViewMapper.getPatientTreatmentCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - patientTreatments = studyViewMapper.getPatientTreatments(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - assertEquals(1, patientTreatmentCounts); - assertEquals("madeupanib", patientTreatments.getFirst().treatment()); - - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProfiledCountsTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProfiledCountsTest.java deleted file mode 100644 index 6edfada6bec..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProfiledCountsTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class ProfiledCountsTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - private static final String STUDY_GENIE_PUB = "study_genie_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getTotalProfiledCountsByGene() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - // Testing profiled counts on samples with gene panel data and WES for one study - var totalProfiledCountsForMutationsMap = studyViewMapper.getTotalProfiledCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "MUTATION_EXTENDED", List.of()); - var totalProfiledCountsForCnaMap = studyViewMapper.getTotalProfiledCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "COPY_NUMBER_ALTERATION", List.of()); - var sampleProfiledCountsForMutationsWithoutPanelDataMap = studyViewMapper.getSampleProfileCountWithoutPanelData(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "MUTATION_EXTENDED"); - var sampleProfiledCountsForCnaWithoutPanelDataMap = studyViewMapper.getSampleProfileCountWithoutPanelData(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "COPY_NUMBER_ALTERATION"); - - // Assert the count of genes with profiled cases for mutations - assertEquals(5, totalProfiledCountsForMutationsMap.size()); - // Assert the count of genes with profiled cases for CNA - assertEquals(5, totalProfiledCountsForCnaMap.size()); - // Assert the profiled counts for mutations without panel data (WES) - assertEquals(6, sampleProfiledCountsForMutationsWithoutPanelDataMap); - // Assert the profiled counts for CNA without panel data (WES) - assertEquals(11, sampleProfiledCountsForCnaWithoutPanelDataMap); - - // Assert the profiled counts for AKT2 mutations - // AKT2 is on testpanel2 in STUDY_TCGA_PUB - var akt2TotalProfiledCountsForMutations = totalProfiledCountsForMutationsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); - assertTrue(akt2TotalProfiledCountsForMutations.isPresent()); - assertEquals(4, akt2TotalProfiledCountsForMutations.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for BRCA1 mutations - // BRCA1 is on testpanel1 in STUDY_TCGA_PUB - var brca1TotalProfiledCountsForMutations = totalProfiledCountsForMutationsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); - assertTrue(brca1TotalProfiledCountsForMutations.isPresent()); - assertEquals(1, brca1TotalProfiledCountsForMutations.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for AKT1 mutations - // AKT1 is on both testpanel1 and testpanel2 in STUDY_TCGA_PUB - var akt1TotalProfiledCountsForMutations = totalProfiledCountsForMutationsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT1")).findFirst(); - assertTrue(akt1TotalProfiledCountsForMutations.isPresent()); - assertEquals(5, akt1TotalProfiledCountsForMutations.get().getNumberOfProfiledCases().intValue()); - - // Assert the profiled counts for AKT2 CNA - // AKT2 is on testpanel2 in STUDY_TCGA_PUB - var akt2TotalProfiledCountsForCna = totalProfiledCountsForCnaMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); - assertTrue(akt2TotalProfiledCountsForCna.isPresent()); - assertEquals(6, akt2TotalProfiledCountsForCna.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for BRCA1 CNA - // BRCA1 is on testpanel1 in STUDY_TCGA_PUB - var brca1TotalProfiledCountsForCna = totalProfiledCountsForCnaMap.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); - assertTrue(brca1TotalProfiledCountsForCna.isPresent()); - assertEquals(2, brca1TotalProfiledCountsForCna.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for AKT1 CNA - // AKT1 is on both testpanel1 and testpanel2 in STUDY_TCGA_PUB - var akt1TotalProfiledCountsForCna = totalProfiledCountsForCnaMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT1")).findFirst(); - assertTrue(akt1TotalProfiledCountsForCna.isPresent()); - assertEquals(8, akt1TotalProfiledCountsForCna.get().getNumberOfProfiledCases().intValue()); - - // Testing profiled counts on combined studies - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_GENIE_PUB)); - - // Testing profiled counts on samples with gene panel data and WES for a combined study - var totalProfiledCountsForMutationsMap1 = studyViewMapper.getTotalProfiledCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "MUTATION_EXTENDED", List.of()); - var totalProfiledCountsForCnaMap1 = studyViewMapper.getTotalProfiledCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "COPY_NUMBER_ALTERATION", List.of()); - var sampleProfiledCountsForMutationsWithoutPanelDataMap1 = studyViewMapper.getSampleProfileCountWithoutPanelData(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "MUTATION_EXTENDED"); - var sampleProfiledCountsForCnaWithoutPanelDataMap1 = studyViewMapper.getSampleProfileCountWithoutPanelData(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - "COPY_NUMBER_ALTERATION"); - - // Assert the count of genes with profiled cases for mutations in a combined study - assertEquals(8, totalProfiledCountsForMutationsMap1.size()); - // Assert the count of genes with profiled cases for CNA in a combined study - assertEquals(8, totalProfiledCountsForCnaMap1.size()); - // Assert the profiled counts for mutations without panel data (WES) in a combined study - assertEquals(8, sampleProfiledCountsForMutationsWithoutPanelDataMap1); - // Assert the profiled counts for CNA without panel data (WES) in a combined study - assertEquals(12, sampleProfiledCountsForCnaWithoutPanelDataMap1); - - // Assert the profiled counts for BRCA1 mutations - // BRCA1 is on testpanel1 in STUDY_TCGA_PUB - var brca1TotalProfiledCountsForMutations1 = totalProfiledCountsForMutationsMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); - assertTrue(brca1TotalProfiledCountsForMutations1.isPresent()); - assertEquals(1, brca1TotalProfiledCountsForMutations1.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for BRCA2 mutations - // BRCA2 is on testpanel3 and testpanel4 in STUDY_GENIE_PUB - var brca2TotalProfiledCountsForMutations1 = totalProfiledCountsForMutationsMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA2")).findFirst(); - assertTrue(brca2TotalProfiledCountsForMutations1.isPresent()); - assertEquals(2, brca2TotalProfiledCountsForMutations1.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for AKT2 mutations - // AKT2 is on testpanel2 in STUDY_TCGA_PUB and testpanel4 in STUDY_GENIE_PUB - var akt2TotalProfiledCountsForMutations1 = totalProfiledCountsForMutationsMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); - assertTrue(akt2TotalProfiledCountsForMutations1.isPresent()); - assertEquals(4, akt2TotalProfiledCountsForMutations1.get().getNumberOfProfiledCases().intValue()); - - // Assert the profiled counts for BRCA1 CNA - // BRCA1 is on testpanel1 in STUDY_TCGA_PUB - var brca1TotalProfiledCountsForCna1 = totalProfiledCountsForCnaMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA1")).findFirst(); - assertTrue(brca1TotalProfiledCountsForCna1.isPresent()); - assertEquals(2, brca1TotalProfiledCountsForCna1.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for BRCA2 CNA - // BRCA2 is on testpanel3 and testpanel4 in STUDY_GENIE_PUB - var brca2TotalProfiledCountsForCna1 = totalProfiledCountsForCnaMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("BRCA2")).findFirst(); - assertTrue(brca2TotalProfiledCountsForCna1.isPresent()); - assertEquals(3, brca2TotalProfiledCountsForCna1.get().getNumberOfProfiledCases().intValue()); - // Assert the profiled counts for AKT2 CNA - // AKT2 is on testpanel2 in STUDY_TCGA_PUB and testpanel4 in STUDY_GENIE_PUB - var akt2TotalProfiledCountsForCna1 = totalProfiledCountsForCnaMap1.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst(); - assertTrue(akt2TotalProfiledCountsForCna1.isPresent()); - assertEquals(7, akt2TotalProfiledCountsForCna1.get().getNumberOfProfiledCases().intValue()); - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProteinExpressionCountsTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProteinExpressionCountsTest.java deleted file mode 100644 index 9d352d15b0e..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/ProteinExpressionCountsTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.model.ClinicalDataCount; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.DataFilterValue; -import org.cbioportal.legacy.web.parameter.GenomicDataBinFilter; -import org.cbioportal.legacy.web.parameter.GenomicDataFilter; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class ProteinExpressionCountsTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - private static final String STUDY_ACC_TCGA = "acc_tcga"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getProteinExpressionCounts() { - // Testing combined study missing samples when one lacks a relevant genomic profile - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_ACC_TCGA)); - - GenomicDataBinFilter genomicDataBinFilterRPPA = new GenomicDataBinFilter(); - genomicDataBinFilterRPPA.setHugoGeneSymbol("AKT1"); - genomicDataBinFilterRPPA.setProfileType("rppa"); - - List actualRPPACounts1 = studyViewMapper.getGenomicDataBinCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), List.of(genomicDataBinFilterRPPA)); - - ClinicalDataCount expectedRPPACount1 = new ClinicalDataCount(); - expectedRPPACount1.setAttributeId("AKT1rppa"); - expectedRPPACount1.setValue("0.7360"); - expectedRPPACount1.setCount(1); - ClinicalDataCount expectedRPPACount2 = new ClinicalDataCount(); - expectedRPPACount2.setAttributeId("AKT1rppa"); - expectedRPPACount2.setValue("-0.8097"); - expectedRPPACount2.setCount(1); - ClinicalDataCount expectedRPPACount3 = new ClinicalDataCount(); - expectedRPPACount3.setAttributeId("AKT1rppa"); - expectedRPPACount3.setValue("-0.1260"); - expectedRPPACount3.setCount(1); - ClinicalDataCount expectedRPPACountNA = new ClinicalDataCount(); - expectedRPPACountNA.setAttributeId("AKT1rppa"); - expectedRPPACountNA.setValue("NA"); - expectedRPPACountNA.setCount(16); - - List expectedRPPACounts1 = List.of( - expectedRPPACount1, expectedRPPACount2, expectedRPPACount3, expectedRPPACountNA - ); - assertThat(actualRPPACounts1) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedRPPACounts1); - - - // Testing NA filtering on combined study missing samples when one lacks a relevant genomic profile - // Make genomic data filter to put in study view filter - GenomicDataFilter genomicDataFilterRPPA = new GenomicDataFilter("AKT1", "rppa"); - DataFilterValue dataFilterValue = new DataFilterValue(); - dataFilterValue.setValue("NA"); - genomicDataFilterRPPA.setValues(List.of(dataFilterValue)); - studyViewFilter.setGenomicDataFilters(List.of(genomicDataFilterRPPA)); - - List actualRPPACounts2 = studyViewMapper.getGenomicDataBinCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), List.of(genomicDataBinFilterRPPA)); - - ClinicalDataCount expectedRPPACount = new ClinicalDataCount(); - expectedRPPACount.setAttributeId("AKT1rppa"); - expectedRPPACount.setValue("NA"); - expectedRPPACount.setCount(16); - - List expectedRPPACounts2 = List.of( - expectedRPPACount - ); - assertThat(actualRPPACounts2) - .usingRecursiveComparison() - .ignoringCollectionOrder() - .isEqualTo(expectedRPPACounts2); - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/SampleTreatmentCountsTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/SampleTreatmentCountsTest.java deleted file mode 100644 index 8cfd8977da4..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/SampleTreatmentCountsTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.model.TemporalRelation; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.cbioportal.legacy.web.parameter.filter.AndedSampleTreatmentFilters; -import org.cbioportal.legacy.web.parameter.filter.OredSampleTreatmentFilters; -import org.cbioportal.legacy.web.parameter.filter.SampleTreatmentFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.List; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class SampleTreatmentCountsTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getSampleTreatmentCounts() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB)); - - - var totalSampleTreatmentCount = studyViewMapper.getTotalSampleTreatmentCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - var sampleTreatmentCounts = studyViewMapper.getSampleTreatmentCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - assertEquals(1, totalSampleTreatmentCount); - assertEquals("madeupanib", sampleTreatmentCounts.getFirst().treatment()); - assertEquals(1, sampleTreatmentCounts.getFirst().postSampleCount()); - assertEquals(0, sampleTreatmentCounts.getFirst().preSampleCount()); - - SampleTreatmentFilter filter = new SampleTreatmentFilter(); - filter.setTreatment("madeupanib"); - filter.setTime(TemporalRelation.Pre); - - OredSampleTreatmentFilters oredSampleTreatmentFilters = new OredSampleTreatmentFilters(); - oredSampleTreatmentFilters.setFilters(List.of(filter)); - - AndedSampleTreatmentFilters andedSampleTreatmentFilters = new AndedSampleTreatmentFilters(); - andedSampleTreatmentFilters.setFilters(List.of(oredSampleTreatmentFilters)); - studyViewFilter.setSampleTreatmentFilters(andedSampleTreatmentFilters); - - totalSampleTreatmentCount = studyViewMapper.getTotalSampleTreatmentCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - sampleTreatmentCounts = studyViewMapper.getSampleTreatmentCounts(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds())); - - assertEquals(0, totalSampleTreatmentCount); - assertEquals(0, sampleTreatmentCounts.size()); - - } -} diff --git a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StructuralVariantGenesTest.java b/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StructuralVariantGenesTest.java deleted file mode 100644 index f5abdcb578f..00000000000 --- a/src/test/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StructuralVariantGenesTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.cbioportal.legacy.persistence.mybatisclickhouse; - -import org.cbioportal.legacy.persistence.helper.AlterationFilterHelper; -import org.cbioportal.legacy.persistence.helper.StudyViewFilterHelper; -import org.cbioportal.legacy.persistence.mybatisclickhouse.config.MyBatisConfig; -import org.cbioportal.legacy.web.parameter.StudyViewFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.List; -import java.util.Objects; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@Import(MyBatisConfig.class) -@DataJpaTest -@DirtiesContext -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class) -public class StructuralVariantGenesTest extends AbstractTestcontainers { - - private static final String STUDY_TCGA_PUB = "study_tcga_pub"; - private static final String STUDY_ACC_TCGA = "acc_tcga"; - - @Autowired - private StudyViewMapper studyViewMapper; - - @Test - public void getStructuralVariantGenes() { - StudyViewFilter studyViewFilter = new StudyViewFilter(); - studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB, STUDY_ACC_TCGA)); - var alterationCountByGenes = studyViewMapper.getStructuralVariantGenes(StudyViewFilterHelper.build(studyViewFilter, null, null, studyViewFilter.getStudyIds()), - AlterationFilterHelper.build(studyViewFilter.getAlterationFilter())); - assertEquals(8, alterationCountByGenes.size()); - - // Test sv count for eml4 which is in one study - var testeml4AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "eml4")) - .mapToInt(c -> c.getTotalCount().intValue()) - .sum(); - assertEquals(1, testeml4AlterationCount); - - // Test sv count for ncoa4 which is in both studies - var testncoa4AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "ncoa4")) - .mapToInt(c -> c.getTotalCount().intValue()) - .sum(); - assertEquals(3, testncoa4AlterationCount); - } -} From 0566711f49756ab847c0673650764189f049c40e Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Tue, 18 Feb 2025 14:43:21 -0500 Subject: [PATCH 8/9] Make sonar fixes --- .../ColumnarStoreStudyViewController.java | 62 ++++++++----------- .../domain/studyview/StudyViewService.java | 2 + .../service/BasicDataBinner.java | 1 + .../service/ClinicalDataBinner.java | 3 +- .../mybatisclickhouse/StudyViewMapper.java | 2 +- .../StudyViewMyBatisRepository.java | 2 +- .../legacy/web/columnar/BasicDataBinner.java | 2 +- .../web/columnar/ClinicalDataBinner.java | 2 +- .../columnar/util/ClinicalDataXyPlotUtil.java | 2 +- .../columnar/util/CustomDataFilterUtil.java | 2 +- .../columnar/util/NewClinicalDataBinUtil.java | 2 +- .../columnar/util/NewStudyViewFilterUtil.java | 2 +- 12 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java index 5856a48f452..e6bcbed4afd 100644 --- a/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java +++ b/src/main/java/org/cbioportal/application/rest/vcolumnstore/ColumnarStoreStudyViewController.java @@ -71,7 +71,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import static java.util.stream.Collectors.toSet; @@ -137,8 +136,8 @@ public ResponseEntity> fetchMolecularProfileSampleCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/cna-genes/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "/cna-genes/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchCnaGenes( @RequestBody(required = false) StudyViewFilter studyViewFilter @@ -147,8 +146,8 @@ public ResponseEntity> fetchCnaGenes( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/structuralvariant-genes/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "/structuralvariant-genes/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch structural variant genes by study view filter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = AlterationCountByGene.class)))) @@ -161,8 +160,7 @@ public ResponseEntity> fetchStructuralVariantGenes( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/clinical-data-counts/fetch", - method=RequestMethod.POST, + @PostMapping(value = "/clinical-data-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasPermission(#clinicalDataCountFilter, 'ClinicalDataCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchClinicalDataCounts( @@ -177,12 +175,12 @@ public ResponseEntity> fetchClinicalDataCounts( } List result = studyViewService.getClinicalDataCounts( studyViewFilter, - attributes.stream().map(ClinicalDataFilter::getAttributeId).collect(Collectors.toList())); + attributes.stream().map(ClinicalDataFilter::getAttributeId).toList()); return ResponseEntity.ok(result); } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/sample-lists-counts/fetch", method = RequestMethod.POST, + @PostMapping(value = "/sample-lists-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch case list sample counts by study view filter") @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") @@ -194,7 +192,7 @@ public List fetchCaseListCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/clinical-data-bin-counts/fetch", method = RequestMethod.POST, + @PostMapping(value = "/clinical-data-bin-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasPermission(#clinicalDataBinCountFilter, 'DataBinCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") public ResponseEntity> fetchClinicalDataBinCounts( @@ -209,8 +207,7 @@ public ResponseEntity> fetchClinicalDataBinCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/clinical-data-density-plot/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/clinical-data-density-plot/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch clinical data density plot bins by study view filter") @@ -274,8 +271,7 @@ public ResponseEntity fetchClinicalDataDensityPlot( @Hidden // should unhide when we remove legacy controller @PreAuthorize("hasPermission(#studyViewFilter, 'StudyViewFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/clinical-data-violin-plots/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/clinical-data-violin-plots/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch violin plot curves per categorical clinical data value, filtered by study view filter") @ApiResponse(responseCode = "200", description = "OK", @@ -325,7 +321,7 @@ public ResponseEntity fetchClinicalDataViolinPlots( Set sampleIdsSet = filteredSamples .stream() - .map(s -> s.internalId()) + .map(Sample::internalId) .collect(toSet()); ClinicalViolinPlotData result = violinPlotService.getClinicalViolinPlotData( @@ -343,8 +339,7 @@ public ResponseEntity fetchClinicalDataViolinPlots( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/genomic-data-counts/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/genomic-data-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch genomic data counts by GenomicDataCountFilter") @ApiResponse(responseCode = "200", description = "OK", @@ -373,8 +368,7 @@ public ResponseEntity> fetchGenomicDataCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/generic-assay-data-counts/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/generic-assay-data-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch generic assay data counts by study view filter") @ApiResponse(responseCode = "200", description = "OK", @@ -399,8 +393,7 @@ public ResponseEntity> fetchGenericAssayDataCoun } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/mutation-data-counts/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/mutation-data-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch mutation data counts by GenomicDataCountFilter") @PreAuthorize("hasPermission(#genomicDataCountFilter, 'GenomicDataCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") @@ -431,8 +424,8 @@ public ResponseEntity> fetchMutationDataCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/clinical-event-type-counts/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/clinical-event-type-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Get Counts of Clinical Event Types by Study View Filter") @@ -447,8 +440,8 @@ public ResponseEntity> getClinicalEventTypeCounts( return ResponseEntity.ok(studyViewService.getClinicalEventTypeCounts(studyViewFilter)); } - @RequestMapping(value = "/treatments/patient-counts/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/treatments/patient-counts/fetch", + produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Get all patient level treatments") @ApiResponse(responseCode = "200", description = "OK", @@ -466,8 +459,8 @@ public ResponseEntity fetchPatientTreatmentCounts( return ResponseEntity.ok(studyViewService.getPatientTreatmentReport(studyViewFilter)); } - @RequestMapping(value = "/treatments/sample-counts/fetch", - method = RequestMethod.POST, + @PostMapping(value = "/treatments/sample-counts/fetch", + produces = MediaType.APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SampleTreatmentReport.class))) @@ -485,8 +478,7 @@ public ResponseEntity fetchSampleTreatmentCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/custom-data-counts/fetch", - method=RequestMethod.POST, + @PostMapping(value = "/custom-data-counts/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch custom data counts by study view filter") @ApiResponse(responseCode = "200", description = "OK", @@ -521,8 +513,8 @@ public ResponseEntity> fetchCustomDataCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/custom-data-bin-counts/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method= RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "/custom-data-bin-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(description = "Fetch custom data bin counts by study view filter") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ClinicalDataBin.class)))) @@ -541,8 +533,8 @@ public ResponseEntity> fetchCustomDataBinCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/genomic-data-bin-counts/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "/genomic-data-bin-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenomicDataBin.class)))) @PreAuthorize("hasPermission(#genomicDataBinCountFilter, 'DataBinCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") @@ -558,8 +550,8 @@ public ResponseEntity> fetchGenomicDataBinCounts( } @Hidden // should unhide when we remove legacy controller - @RequestMapping(value = "/generic-assay-data-bin-counts/fetch", - consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "/generic-assay-data-bin-counts/fetch", + consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = GenericAssayDataBin.class)))) @PreAuthorize("hasPermission(#genericAssayDataBinCountFilter, 'DataBinCountFilter', T(org.cbioportal.legacy.utils.security.AccessLevel).READ)") diff --git a/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java b/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java index cb2097fa3bf..90dc15d631f 100644 --- a/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java +++ b/src/main/java/org/cbioportal/domain/studyview/StudyViewService.java @@ -37,6 +37,7 @@ import org.cbioportal.shared.util.ClinicalDataCountItemUtil; import org.cbioportal.domain.treatment.usecase.TreatmentCountReportUseCases; import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -46,6 +47,7 @@ import java.util.stream.Collectors; @Service +@Profile("clickhouse") /** * A service class responsible for handling study view-related operations, including retrieving filtered samples, * genomic data counts, clinical data, and other study-specific information. This class acts as a central hub diff --git a/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java b/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java index bd46c43914f..8e6ece160be 100644 --- a/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java +++ b/src/main/java/org/cbioportal/infrastructure/service/BasicDataBinner.java @@ -47,6 +47,7 @@ // we are using BasicDataBinner for genomic data, generic assay, and custom data bin counts now // but BasicDataBinner can support clinical data counts too // after we switched clinical data counts to use this, then We can remove ClinicalDataBinner +@Deprecated(forRemoval = true) @Component @Profile("clickhouse") public class BasicDataBinner { diff --git a/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java b/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java index 814fec1d30c..8e4577022f3 100644 --- a/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java +++ b/src/main/java/org/cbioportal/infrastructure/service/ClinicalDataBinner.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.stream.Collectors; +@Deprecated(forRemoval = true) @Component @Profile("clickhouse") public class ClinicalDataBinner { @@ -64,7 +65,7 @@ public List fetchClinicalDataBinCounts( studyViewFilter = NewClinicalDataBinUtil.removeSelfFromFilter(dataBinCountFilter); } - List attributeIds = attributes.stream().map(ClinicalDataBinFilter::getAttributeId).collect(Collectors.toList()); + List attributeIds = attributes.stream().map(ClinicalDataBinFilter::getAttributeId).toList(); // a new StudyView filter to partially filter by study and sample ids only // we need this additional partial filter because we always need to know the bins generated for the initial state diff --git a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java index 9004df6139d..4baa6fb333e 100644 --- a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java +++ b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMapper.java @@ -28,7 +28,7 @@ import java.util.Map; -@Deprecated +@Deprecated(forRemoval = true) public interface StudyViewMapper { List getFilteredSamples(@Param("studyViewFilterHelper") StudyViewFilterHelper studyViewFilterHelper); diff --git a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java index 2a04ec8e3e5..3b22731953c 100644 --- a/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java +++ b/src/main/java/org/cbioportal/legacy/persistence/mybatisclickhouse/StudyViewMyBatisRepository.java @@ -39,7 +39,7 @@ import java.util.stream.Collectors; @Repository -@Deprecated +@Deprecated(forRemoval = true) @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "test") public class StudyViewMyBatisRepository implements StudyViewRepository { diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java b/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java index 3a808266213..869d5cbaf74 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/BasicDataBinner.java @@ -44,7 +44,7 @@ // but BasicDataBinner can support clinical data counts too // after we switched clinical data counts to use this, then We can remove ClinicalDataBinner @Component -@Deprecated +@Deprecated(forRemoval = true) @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "test") public class BasicDataBinner { private final StudyViewColumnarService studyViewColumnarService; diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java b/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java index 56a4f86d4fe..9da46656c0a 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/ClinicalDataBinner.java @@ -22,7 +22,7 @@ import java.util.stream.Collectors; @Component -@Deprecated +@Deprecated(forRemoval = true) @ConditionalOnProperty(name = "clickhouse_mode", havingValue = "test") public class ClinicalDataBinner { private final StudyViewColumnarService studyViewColumnarService; diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/util/ClinicalDataXyPlotUtil.java b/src/main/java/org/cbioportal/legacy/web/columnar/util/ClinicalDataXyPlotUtil.java index 5c75cf806a6..a0dd1d7bf00 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/util/ClinicalDataXyPlotUtil.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/util/ClinicalDataXyPlotUtil.java @@ -8,7 +8,7 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; - +@Deprecated(forRemoval = true) public class ClinicalDataXyPlotUtil { public static List combineClinicalDataForXyPlot( List sampleClinicalDataList, diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/util/CustomDataFilterUtil.java b/src/main/java/org/cbioportal/legacy/web/columnar/util/CustomDataFilterUtil.java index 786c695e5f3..cf00524afa9 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/util/CustomDataFilterUtil.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/util/CustomDataFilterUtil.java @@ -24,7 +24,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; - +@Deprecated(forRemoval = true) @Component public class CustomDataFilterUtil { private final StudyViewFilterUtil studyViewFilterUtil; diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/util/NewClinicalDataBinUtil.java b/src/main/java/org/cbioportal/legacy/web/columnar/util/NewClinicalDataBinUtil.java index 8ea39ca19da..7d63bc4c931 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/util/NewClinicalDataBinUtil.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/util/NewClinicalDataBinUtil.java @@ -18,7 +18,7 @@ import java.util.Map; import static java.util.Collections.emptyList; - +@Deprecated(forRemoval = true) public class NewClinicalDataBinUtil { public static StudyViewFilter removeSelfFromFilter(ClinicalDataBinCountFilter dataBinCountFilter) { List attributes = dataBinCountFilter.getAttributes(); diff --git a/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java b/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java index 778f5dd0da7..8edd9e8d359 100644 --- a/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java +++ b/src/main/java/org/cbioportal/legacy/web/columnar/util/NewStudyViewFilterUtil.java @@ -7,7 +7,7 @@ import org.cbioportal.legacy.web.parameter.StudyViewFilter; import java.util.List; - +@Deprecated(forRemoval = true) public abstract class NewStudyViewFilterUtil { private NewStudyViewFilterUtil() {} From 45fdafcab5d757cbfac2dc6379271946f0857683 Mon Sep 17 00:00:00 2001 From: Charles Haynes Date: Wed, 19 Feb 2025 14:28:28 -0500 Subject: [PATCH 9/9] Remove docs --- .../ClickhouseAlterationRepository.java | 33 ------------------- ...lickhouseClinicalAttributesRepository.java | 7 ---- .../ClickhouseClinicalDataRepository.java | 15 --------- .../ClickhouseClinicalEventRepository.java | 4 --- .../ClickhouseGenericAssayRepository.java | 18 ---------- .../ClickhouseGenomicDataRepository.java | 24 -------------- .../patient/ClickhousePatientRepository.java | 8 ----- .../sample/ClickhouseSampleRepository.java | 8 ----- .../ClickhouseTreatmentRepository.java | 16 --------- 9 files changed, 133 deletions(-) diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java index 6fa2dd2316a..7aef74b9c1f 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/alteration/ClickhouseAlterationRepository.java @@ -25,50 +25,27 @@ public ClickhouseAlterationRepository(ClickhouseAlterationMapper mapper) { this.mapper = mapper; } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getMutatedGenes(StudyViewFilterContext studyViewFilterContext) { return mapper.getMutatedGenes(studyViewFilterContext, AlterationFilterHelper.build(studyViewFilterContext.alterationFilter())); } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getStructuralVariantGenes(StudyViewFilterContext studyViewFilterContext) { return mapper.getStructuralVariantGenes(studyViewFilterContext, AlterationFilterHelper.build(studyViewFilterContext.alterationFilter())); } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getCnaGenes(StudyViewFilterContext studyViewFilterContext) { return mapper.getCnaGenes(studyViewFilterContext, AlterationFilterHelper.build(studyViewFilterContext.alterationFilter())); } - /** - * @param studyViewFilterContext - * @param alterationType - * @return - */ @Override public int getTotalProfiledCountsByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType) { return mapper.getTotalProfiledCountByAlterationType(studyViewFilterContext, alterationType); } - /** - * @param studyViewFilterContext - * @param alterationType - * @param molecularProfiles - * @return - */ @Override public Map getTotalProfiledCounts(StudyViewFilterContext studyViewFilterContext, String alterationType, List molecularProfiles) { return mapper.getTotalProfiledCounts(studyViewFilterContext,alterationType,molecularProfiles) @@ -77,11 +54,6 @@ public Map getTotalProfiledCounts(StudyViewFilterContext studyV Collectors.mapping(AlterationCountByGene::getNumberOfProfiledCases, Collectors.summingInt(Integer::intValue)))); } - /** - * @param studyViewFilterContext - * @param alterationType - * @return - */ @Override public Map> getMatchingGenePanelIds(StudyViewFilterContext studyViewFilterContext, String alterationType) { return mapper.getMatchingGenePanelIds(studyViewFilterContext, alterationType) @@ -90,11 +62,6 @@ public Map> getMatchingGenePanelIds(StudyViewFilterContext s Collectors.mapping(GenePanelToGene::getGenePanelId, Collectors.toSet()))); } - /** - * @param studyViewFilterContext - * @param alterationType - * @return - */ @Override public int getSampleProfileCountWithoutPanelData(StudyViewFilterContext studyViewFilterContext, String alterationType) { return mapper.getSampleProfileCountWithoutPanelData(studyViewFilterContext, alterationType); diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java index 043adc7591c..f520e920a6b 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_attributes/ClickhouseClinicalAttributesRepository.java @@ -25,18 +25,11 @@ public ClickhouseClinicalAttributesRepository(ClickhouseClinicalAttributesMapper this.mapper = mapper; } - /** - * @param studyIds - * @return - */ @Override public List getClinicalAttributesForStudies(List studyIds) { return mapper.getClinicalAttributesForStudies(studyIds); } - /** - * @return - */ @Override public Map getClinicalAttributeDatatypeMap() { if (clinicalAttributesMap.isEmpty()) { diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java index 980bd427a68..67129d04e54 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_data/ClickhouseClinicalDataRepository.java @@ -23,31 +23,16 @@ public ClickhouseClinicalDataRepository(ClickhouseClinicalDataMapper mapper) { } - /** - * @param studyViewFilterContext - * @param filteredAttributes - * @return - */ @Override public List getPatientClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { return mapper.getPatientClinicalDataFromStudyViewFilter(studyViewFilterContext, filteredAttributes); } - /** - * @param studyViewFilterContext - * @param filteredAttributes - * @return - */ @Override public List getSampleClinicalData(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { return mapper.getSampleClinicalDataFromStudyViewFilter(studyViewFilterContext, filteredAttributes); } - /** - * @param studyViewFilterContext - * @param filteredAttributes - * @return - */ @Override public List getClinicalDataCounts(StudyViewFilterContext studyViewFilterContext, List filteredAttributes) { return mapper.getClinicalDataCounts(studyViewFilterContext, filteredAttributes, FILTERED_CLINICAL_ATTR_VALUES); diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java index d709b3d4e9b..ac4e4a73dd5 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/clinical_event/ClickhouseClinicalEventRepository.java @@ -18,10 +18,6 @@ public ClickhouseClinicalEventRepository(ClickhouseClinicalEventMapper mapper) { this.mapper = mapper; } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getClinicalEventTypeCounts(StudyViewFilterContext studyViewFilterContext) { return mapper.getClinicalEventTypeCounts(studyViewFilterContext); diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java index 7c5d54efac1..12d697380df 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/generic_assay/ClickhouseGenericAssayRepository.java @@ -22,39 +22,21 @@ public ClickhouseGenericAssayRepository(ClickhouseGenericAssayMapper mapper) { this.mapper = mapper; } - /** - * @return - */ @Override public List getGenericAssayProfiles() { return mapper.getGenericAssayProfiles(); } - /** - * @param studyViewFilterContext - * @param alterationType - * @return - */ @Override public List getFilteredMolecularProfilesByAlterationType(StudyViewFilterContext studyViewFilterContext, String alterationType) { return mapper.getFilteredMolecularProfilesByAlterationType(studyViewFilterContext, alterationType); } - /** - * @param studyViewFilterContext - * @param genericAssayDataBinFilters - * @return - */ @Override public List getGenericAssayDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataBinFilters) { return mapper.getGenericAssayDataBinCounts(studyViewFilterContext, genericAssayDataBinFilters); } - /** - * @param studyViewFilterContext - * @param genericAssayDataFilters - * @return - */ @Override public List getGenericAssayDataCounts(StudyViewFilterContext studyViewFilterContext, List genericAssayDataFilters) { return mapper.getGenericAssayDataCounts(studyViewFilterContext, genericAssayDataFilters); diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java index 1da746c4889..7cae3cd2fe7 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/genomic_data/ClickhouseGenomicDataRepository.java @@ -23,51 +23,27 @@ public ClickhouseGenomicDataRepository(ClickhouseGenomicDataMapper mapper) { this.mapper = mapper; } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getMolecularProfileSampleCounts(StudyViewFilterContext studyViewFilterContext) { return mapper.getMolecularProfileSampleCounts(studyViewFilterContext); } - /** - * @param studyViewFilterContext - * @param genomicDataBinFilters - * @return - */ @Override public List getGenomicDataBinCounts(StudyViewFilterContext studyViewFilterContext, List genomicDataBinFilters) { return mapper.getGenomicDataBinCounts(studyViewFilterContext, genomicDataBinFilters); } - /** - * @param studyViewFilterContext - * @param genomicDataFilters - * @return - */ @Override public List getCNACounts(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters) { return mapper.getCNACounts(studyViewFilterContext, genomicDataFilters); } - /** - * @param studyViewFilterContext - * @param genomicDataFilter - * @return - */ @Override public Map getMutationCounts(StudyViewFilterContext studyViewFilterContext, GenomicDataFilter genomicDataFilter) { return mapper.getMutationCounts(studyViewFilterContext, genomicDataFilter); } - /** - * @param studyViewFilterContext - * @param genomicDataFilters - * @return - */ @Override public List getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List genomicDataFilters) { return mapper.getMutationCountsByType(studyViewFilterContext, genomicDataFilters); diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java index 1df361db7e6..35b620aa035 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/patient/ClickhousePatientRepository.java @@ -18,19 +18,11 @@ public ClickhousePatientRepository(ClickhousePatientMapper mapper) { this.mapper = mapper; } - /** - * @param studyViewFilterContext - * @return - */ @Override public int getFilteredPatientCount(StudyViewFilterContext studyViewFilterContext) { return mapper.getPatientCount(studyViewFilterContext); } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getCaseListDataCounts(StudyViewFilterContext studyViewFilterContext) { return mapper.getCaseListDataCounts(studyViewFilterContext); diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java index bbf87770516..12d25cd5889 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/sample/ClickhouseSampleRepository.java @@ -18,19 +18,11 @@ public ClickhouseSampleRepository(ClickhouseSampleMapper clickhouseSampleMapper) this.mapper = clickhouseSampleMapper; } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getFilteredSamples(StudyViewFilterContext studyViewFilterContext) { return mapper.getFilteredSamples(studyViewFilterContext); } - /** - * @param studyViewFilterContext - * @return - */ @Override public int getFilteredSamplesCount(StudyViewFilterContext studyViewFilterContext) { return mapper.getSampleCount(studyViewFilterContext); diff --git a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java index 97fb4051550..583a0a3cf25 100644 --- a/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java +++ b/src/main/java/org/cbioportal/infrastructure/repository/clickhouse/treatment/ClickhouseTreatmentRepository.java @@ -18,37 +18,21 @@ public ClickhouseTreatmentRepository(ClickhouseTreatmentMapper mapper) { this.mapper = mapper; } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getPatientTreatments(StudyViewFilterContext studyViewFilterContext) { return mapper.getPatientTreatments(studyViewFilterContext); } - /** - * @param studyViewFilterContext - * @return - */ @Override public int getTotalPatientTreatmentCount(StudyViewFilterContext studyViewFilterContext) { return mapper.getPatientTreatmentCounts(studyViewFilterContext); } - /** - * @param studyViewFilterContext - * @return - */ @Override public List getSampleTreatments(StudyViewFilterContext studyViewFilterContext) { return mapper.getSampleTreatmentCounts(studyViewFilterContext); } - /** - * @param studyViewFilterContext - * @return - */ @Override public int getTotalSampleTreatmentCount(StudyViewFilterContext studyViewFilterContext) { return mapper.getTotalSampleTreatmentCounts(studyViewFilterContext);