From c84238a010b8372b6bc0faf15cc9c13adf577970 Mon Sep 17 00:00:00 2001 From: Neel Kuila Date: Fri, 14 Jun 2024 16:38:07 -0400 Subject: [PATCH 1/5] working poc --- .../StudyViewColumnStoreController.java | 218 +++++++++++++++++- 1 file changed, 216 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java index cf65ed4cc78..639b305fa47 100644 --- a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java +++ b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java @@ -1,20 +1,47 @@ package org.cbioportal.web.columnar; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +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.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.commons.math3.stat.correlation.PearsonsCorrelation; +import org.apache.commons.math3.stat.correlation.SpearmansCorrelation; import org.cbioportal.model.AlterationCountByGene; import org.cbioportal.model.AlterationFilter; +import org.cbioportal.model.ClinicalAttribute; +import org.cbioportal.model.ClinicalData; import org.cbioportal.model.ClinicalDataBin; import org.cbioportal.model.ClinicalDataCountItem; +import org.cbioportal.model.DensityPlotBin; +import org.cbioportal.model.DensityPlotData; +import org.cbioportal.model.Patient; import org.cbioportal.model.Sample; +import org.cbioportal.persistence.mybatisclickhouse.StudyViewMapper; +import org.cbioportal.service.ClinicalAttributeService; import org.cbioportal.service.StudyViewColumnarService; import org.cbioportal.service.StudyViewService; import org.cbioportal.service.exception.StudyNotFoundException; +import org.cbioportal.service.impl.ClinicalAttributeServiceImpl; +import org.cbioportal.service.impl.PatientServiceImpl; +import org.cbioportal.service.impl.SampleServiceImpl; +import org.cbioportal.service.util.ClinicalAttributeUtil; +import org.cbioportal.web.StudyViewController; import org.cbioportal.web.columnar.util.NewStudyViewFilterUtil; import org.cbioportal.web.config.annotation.InternalApi; import org.cbioportal.web.parameter.ClinicalDataBinCountFilter; import org.cbioportal.web.parameter.ClinicalDataCountFilter; import org.cbioportal.web.parameter.ClinicalDataFilter; import org.cbioportal.web.parameter.DataBinMethod; +import org.cbioportal.web.parameter.Projection; import org.cbioportal.web.parameter.StudyViewFilter; +import org.cbioportal.web.util.ClinicalDataBinUtil; +import org.cbioportal.web.util.ClinicalDataFetcher; +import org.cbioportal.web.util.StudyViewFilterApplier; +import org.cbioportal.web.util.StudyViewFilterUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -29,9 +56,12 @@ 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.Arrays; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @InternalApi @@ -41,16 +71,33 @@ public class StudyViewColumnStoreController { private final StudyViewColumnarService studyViewColumnarService; - private final StudyViewService studyViewService; private final ClinicalDataBinner clinicalDataBinner; + private final StudyViewService studyViewService; + @Autowired + private final ClinicalAttributeService clinicalAttributeService; + @Autowired + private ClinicalAttributeUtil clinicalAttributeUtil; + @Autowired + private PatientServiceImpl patientService; + @Autowired + private StudyViewFilterApplier studyViewFilterApplier; + @Autowired + private StudyViewFilterUtil studyViewFilterUtil; + @Autowired + private SampleServiceImpl sampleService; + @Autowired + private ClinicalDataFetcher clinicalDataFetcher; @Autowired - public StudyViewColumnStoreController(StudyViewColumnarService studyViewColumnarService, StudyViewService studyViewService, ClinicalDataBinner clinicalDataBinner) { + public StudyViewColumnStoreController(StudyViewColumnarService studyViewColumnarService, StudyViewService studyViewService, ClinicalDataBinner clinicalDataBinner, ClinicalAttributeService clinicalAttributeService) { this.studyViewColumnarService = studyViewColumnarService; this.studyViewService = studyViewService; this.clinicalDataBinner = clinicalDataBinner; + this.clinicalAttributeService = clinicalAttributeService; } + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") @PostMapping(value = "/column-store/filtered-samples/fetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @@ -118,4 +165,171 @@ public ResponseEntity> fetchClinicalDataBinCounts( ); return new ResponseEntity<>(clinicalDataBins, HttpStatus.OK); } + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.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) { + + DensityPlotData result = new DensityPlotData(); + result.setBins(new ArrayList<>()); + + List xyAttributeId = new ArrayList<>(Arrays.asList(xAxisAttributeId, yAxisAttributeId)); + List sampleClinicalDataList = studyViewColumnarService.getSampleClinicalData(interceptedStudyViewFilter, xyAttributeId); + + Map> smallerClinicalDataMap = sampleClinicalDataList.stream().collect(Collectors.groupingBy(ClinicalData::getSampleId)); + List filteredClinicalDataList = new ArrayList<>(); + smallerClinicalDataMap.forEach((sampleId, clinDataList) -> { + if (clinDataList.size() == 2 && + NumberUtils.isCreatable(clinDataList.get(0).getAttrValue()) && + NumberUtils.isCreatable(clinDataList.get(1).getAttrValue())) { + filteredClinicalDataList.addAll(clinDataList); + } + }); + + if (filteredClinicalDataList.isEmpty()) { + return new ResponseEntity<>(result, HttpStatus.OK); + } + + Map> partition = filteredClinicalDataList.stream().collect( + Collectors.partitioningBy(c -> c.getAttrId().equals(xAxisAttributeId))); + + boolean useXLogScale = xAxisLogScale && StudyViewColumnStoreController.isLogScalePossibleForAttribute(xAxisAttributeId); + boolean useYLogScale = yAxisLogScale && StudyViewColumnStoreController.isLogScalePossibleForAttribute(yAxisAttributeId); + + double[] xValues = partition.get(true).stream().mapToDouble( + useXLogScale ? StudyViewColumnStoreController::parseValueLog : StudyViewColumnStoreController::parseValueLinear + ).toArray(); + double[] yValues = partition.get(false).stream().mapToDouble( + useYLogScale ? StudyViewColumnStoreController::parseValueLog : StudyViewColumnStoreController::parseValueLinear + ).toArray(); + double[] xValuesCopy = Arrays.copyOf(xValues, xValues.length); + double[] yValuesCopy = Arrays.copyOf(yValues, yValues.length); // Why copy these? + Arrays.sort(xValuesCopy); + Arrays.sort(yValuesCopy); + + double xAxisStartValue = xAxisStart == null ? xValuesCopy[0] : + (useXLogScale ? StudyViewColumnStoreController.logScale(xAxisStart.doubleValue()) : xAxisStart.doubleValue()); + double xAxisEndValue = xAxisEnd == null ? xValuesCopy[xValuesCopy.length - 1] : + (useXLogScale ? StudyViewColumnStoreController.logScale(xAxisEnd.doubleValue()) : xAxisEnd.doubleValue()); + double yAxisStartValue = yAxisStart == null ? yValuesCopy[0] : + (useYLogScale ? StudyViewColumnStoreController.logScale(yAxisStart.doubleValue()) : yAxisStart.doubleValue()); + double yAxisEndValue = yAxisEnd == null ? yValuesCopy[yValuesCopy.length - 1] : + (useYLogScale ? StudyViewColumnStoreController.logScale(yAxisEnd.doubleValue()) : yAxisEnd.doubleValue()); + double xAxisBinInterval = (xAxisEndValue - xAxisStartValue) / xAxisBinCount; + double yAxisBinInterval = (yAxisEndValue - yAxisStartValue) / yAxisBinCount; + List bins = result.getBins(); + for (int i = 0; i < xAxisBinCount; i++) { + for (int j = 0; j < yAxisBinCount; j++) { + DensityPlotBin densityPlotBin = new DensityPlotBin(); + densityPlotBin.setBinX(BigDecimal.valueOf(xAxisStartValue + (i * xAxisBinInterval))); + densityPlotBin.setBinY(BigDecimal.valueOf(yAxisStartValue + (j * yAxisBinInterval))); + densityPlotBin.setCount(0); + bins.add(densityPlotBin); + } + } + + for (int i = 0; i < xValues.length; i++) { + double xValue = xValues[i]; + double yValue = yValues[i]; + int xBinIndex = (int) ((xValue - xAxisStartValue) / xAxisBinInterval); + int yBinIndex = (int) ((yValue - yAxisStartValue) / yAxisBinInterval); + int index = (int) (((xBinIndex - (xBinIndex == xAxisBinCount ? 1 : 0)) * yAxisBinCount) + + (yBinIndex - (yBinIndex == yAxisBinCount ? 1 : 0))); + DensityPlotBin densityPlotBin = bins.get(index); + densityPlotBin.setCount(densityPlotBin.getCount() + 1); + BigDecimal xValueBigDecimal = BigDecimal.valueOf(xValue); + BigDecimal yValueBigDecimal = BigDecimal.valueOf(yValue); + if (densityPlotBin.getMinX() != null) { + if (densityPlotBin.getMinX().compareTo(xValueBigDecimal) > 0) { + densityPlotBin.setMinX(xValueBigDecimal); + } + } else { + densityPlotBin.setMinX(xValueBigDecimal); + } + if (densityPlotBin.getMaxX() != null) { + if (densityPlotBin.getMaxX().compareTo(xValueBigDecimal) < 0) { + densityPlotBin.setMaxX(xValueBigDecimal); + } + } else { + densityPlotBin.setMaxX(xValueBigDecimal); + } + if (densityPlotBin.getMinY() != null) { + if (densityPlotBin.getMinY().compareTo(yValueBigDecimal) > 0) { + densityPlotBin.setMinY(yValueBigDecimal); + } + } else { + densityPlotBin.setMinY(yValueBigDecimal); + } + if (densityPlotBin.getMaxY() != null) { + if (densityPlotBin.getMaxY().compareTo(yValueBigDecimal) < 0) { + densityPlotBin.setMaxY(yValueBigDecimal); + } + } else { + densityPlotBin.setMaxY(yValueBigDecimal); + } + } + + if (xValues.length > 1) { + // need at least 2 entries in each to compute correlation + result.setPearsonCorr(new PearsonsCorrelation().correlation(xValues, yValues)); + result.setSpearmanCorr(new SpearmansCorrelation().correlation(xValues, yValues)); + } else { + // if less than 1 entry, just set 0 correlation + result.setSpearmanCorr(0.0); + result.setPearsonCorr(0.0); + } + + // filter out empty bins + result.setBins(result.getBins().stream().filter((bin)->(bin.getCount() > 0)).collect(Collectors.toList())); + + return new ResponseEntity<>(result, HttpStatus.OK); + } + + private static boolean isLogScalePossibleForAttribute(String clinicalAttributeId) { + return clinicalAttributeId.equals("MUTATION_COUNT"); + } + + private static double logScale(double val) { + return Math.log(1+val); + } + + private static double parseValueLog(ClinicalData c) { + return StudyViewColumnStoreController.logScale(Double.parseDouble(c.getAttrValue())); + } + + private static double parseValueLinear(ClinicalData c) { + return Double.parseDouble(c.getAttrValue()); + } } From 1e08295e4721bd7b5886fce033bfc4f080d475e2 Mon Sep 17 00:00:00 2001 From: Neel Kuila Date: Mon, 17 Jun 2024 10:58:34 -0400 Subject: [PATCH 2/5] refactor logic into service, so clean --- .../ClinicalDataDensityPlotService.java | 23 +++ .../ClinicalDataDensityPlotServiceImpl.java | 163 ++++++++++++++++++ .../StudyViewColumnStoreController.java | 136 ++------------- 3 files changed, 197 insertions(+), 125 deletions(-) create mode 100644 src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java create mode 100644 src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java diff --git a/src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java b/src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java new file mode 100644 index 00000000000..8382567975c --- /dev/null +++ b/src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java @@ -0,0 +1,23 @@ +package org.cbioportal.service; + +import org.cbioportal.model.ClinicalData; +import org.cbioportal.model.DensityPlotData; + +import java.math.BigDecimal; +import java.util.List; + +public interface ClinicalDataDensityPlotService { + DensityPlotData getDensityPlotData(List filteredClinicalData, + String xAxisAttributeId, + String yAxisAttributeId, + Boolean xAxisLogScale, + Boolean yAxisLogScale, + Integer xAxisBinCount, + Integer yAxisBinCount, + BigDecimal xAxisStart, + BigDecimal yAxisStart, + BigDecimal xAxisEnd, + BigDecimal yAxisEnd); + + List filterClinicalData(List clinicalDataList); +} diff --git a/src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java b/src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java new file mode 100644 index 00000000000..c316b7a59ff --- /dev/null +++ b/src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java @@ -0,0 +1,163 @@ +package org.cbioportal.service.impl; + +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.commons.math3.stat.correlation.PearsonsCorrelation; +import org.apache.commons.math3.stat.correlation.SpearmansCorrelation; +import org.cbioportal.model.ClinicalData; +import org.cbioportal.model.DensityPlotBin; +import org.cbioportal.model.DensityPlotData; +import org.cbioportal.service.ClinicalDataDensityPlotService; +import org.cbioportal.web.columnar.StudyViewColumnStoreController; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class ClinicalDataDensityPlotServiceImpl implements ClinicalDataDensityPlotService { + @Override + public DensityPlotData getDensityPlotData(List filteredClinicalData, + String xAxisAttributeId, + String yAxisAttributeId, + Boolean xAxisLogScale, + Boolean yAxisLogScale, + Integer xAxisBinCount, + Integer yAxisBinCount, + BigDecimal xAxisStart, + BigDecimal yAxisStart, + BigDecimal xAxisEnd, + BigDecimal yAxisEnd) { + DensityPlotData result = new DensityPlotData(); + result.setBins(new ArrayList<>()); + + if (filteredClinicalData.isEmpty()) { + return result; + } + + Map> partition = filteredClinicalData.stream().collect( + Collectors.partitioningBy(c -> c.getAttrId().equals(xAxisAttributeId))); + + boolean useXLogScale = xAxisLogScale && ClinicalDataDensityPlotServiceImpl.isLogScalePossibleForAttribute(xAxisAttributeId); + boolean useYLogScale = yAxisLogScale && ClinicalDataDensityPlotServiceImpl.isLogScalePossibleForAttribute(yAxisAttributeId); + + double[] xValues = partition.get(true).stream().mapToDouble( + useXLogScale ? ClinicalDataDensityPlotServiceImpl::parseValueLog : ClinicalDataDensityPlotServiceImpl::parseValueLinear + ).toArray(); + double[] yValues = partition.get(false).stream().mapToDouble( + useYLogScale ? ClinicalDataDensityPlotServiceImpl::parseValueLog : ClinicalDataDensityPlotServiceImpl::parseValueLinear + ).toArray(); + double[] xValuesCopy = Arrays.copyOf(xValues, xValues.length); + double[] yValuesCopy = Arrays.copyOf(yValues, yValues.length); // Why copy these? + Arrays.sort(xValuesCopy); + Arrays.sort(yValuesCopy); + + double xAxisStartValue = xAxisStart == null ? xValuesCopy[0] : + (useXLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(xAxisStart.doubleValue()) : xAxisStart.doubleValue()); + double xAxisEndValue = xAxisEnd == null ? xValuesCopy[xValuesCopy.length - 1] : + (useXLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(xAxisEnd.doubleValue()) : xAxisEnd.doubleValue()); + double yAxisStartValue = yAxisStart == null ? yValuesCopy[0] : + (useYLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(yAxisStart.doubleValue()) : yAxisStart.doubleValue()); + double yAxisEndValue = yAxisEnd == null ? yValuesCopy[yValuesCopy.length - 1] : + (useYLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(yAxisEnd.doubleValue()) : yAxisEnd.doubleValue()); + double xAxisBinInterval = (xAxisEndValue - xAxisStartValue) / xAxisBinCount; + double yAxisBinInterval = (yAxisEndValue - yAxisStartValue) / yAxisBinCount; + List bins = result.getBins(); + for (int i = 0; i < xAxisBinCount; i++) { + for (int j = 0; j < yAxisBinCount; j++) { + DensityPlotBin densityPlotBin = new DensityPlotBin(); + densityPlotBin.setBinX(BigDecimal.valueOf(xAxisStartValue + (i * xAxisBinInterval))); + densityPlotBin.setBinY(BigDecimal.valueOf(yAxisStartValue + (j * yAxisBinInterval))); + densityPlotBin.setCount(0); + bins.add(densityPlotBin); + } + } + + for (int i = 0; i < xValues.length; i++) { + double xValue = xValues[i]; + double yValue = yValues[i]; + int xBinIndex = (int) ((xValue - xAxisStartValue) / xAxisBinInterval); + int yBinIndex = (int) ((yValue - yAxisStartValue) / yAxisBinInterval); + int index = (int) (((xBinIndex - (xBinIndex == xAxisBinCount ? 1 : 0)) * yAxisBinCount) + + (yBinIndex - (yBinIndex == yAxisBinCount ? 1 : 0))); + DensityPlotBin densityPlotBin = bins.get(index); + densityPlotBin.setCount(densityPlotBin.getCount() + 1); + BigDecimal xValueBigDecimal = BigDecimal.valueOf(xValue); + BigDecimal yValueBigDecimal = BigDecimal.valueOf(yValue); + if (densityPlotBin.getMinX() != null) { + if (densityPlotBin.getMinX().compareTo(xValueBigDecimal) > 0) { + densityPlotBin.setMinX(xValueBigDecimal); + } + } else { + densityPlotBin.setMinX(xValueBigDecimal); + } + if (densityPlotBin.getMaxX() != null) { + if (densityPlotBin.getMaxX().compareTo(xValueBigDecimal) < 0) { + densityPlotBin.setMaxX(xValueBigDecimal); + } + } else { + densityPlotBin.setMaxX(xValueBigDecimal); + } + if (densityPlotBin.getMinY() != null) { + if (densityPlotBin.getMinY().compareTo(yValueBigDecimal) > 0) { + densityPlotBin.setMinY(yValueBigDecimal); + } + } else { + densityPlotBin.setMinY(yValueBigDecimal); + } + if (densityPlotBin.getMaxY() != null) { + if (densityPlotBin.getMaxY().compareTo(yValueBigDecimal) < 0) { + densityPlotBin.setMaxY(yValueBigDecimal); + } + } else { + densityPlotBin.setMaxY(yValueBigDecimal); + } + } + + if (xValues.length > 1) { + // need at least 2 entries in each to compute correlation + result.setPearsonCorr(new PearsonsCorrelation().correlation(xValues, yValues)); + result.setSpearmanCorr(new SpearmansCorrelation().correlation(xValues, yValues)); + } else { + // if less than 1 entry, just set 0 correlation + result.setSpearmanCorr(0.0); + result.setPearsonCorr(0.0); + } + + // filter out empty bins + result.setBins(result.getBins().stream().filter((bin)->(bin.getCount() > 0)).collect(Collectors.toList())); + return result; + } + + @Override + public List filterClinicalData(List clinicalDataList) { + Map> clinicalDataGroupedBySampleId = clinicalDataList.stream(). + collect(Collectors.groupingBy(ClinicalData::getSampleId)); + + return clinicalDataGroupedBySampleId.entrySet().stream() + .filter(entry -> entry.getValue().size() == 2 && + NumberUtils.isCreatable(entry.getValue().get(0).getAttrValue()) && + NumberUtils.isCreatable(entry.getValue().get(1).getAttrValue()) + ).flatMap(entry -> entry.getValue().stream()) + .toList(); + } + + private static boolean isLogScalePossibleForAttribute(String clinicalAttributeId) { + return clinicalAttributeId.equals("MUTATION_COUNT"); + } + + private static double logScale(double val) { + return Math.log(1+val); + } + + private static double parseValueLog(ClinicalData c) { + return ClinicalDataDensityPlotServiceImpl.logScale(Double.parseDouble(c.getAttrValue())); + } + + private static double parseValueLinear(ClinicalData c) { + return Double.parseDouble(c.getAttrValue()); + } +} diff --git a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java index 639b305fa47..98761acc191 100644 --- a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java +++ b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java @@ -22,6 +22,7 @@ import org.cbioportal.model.Sample; import org.cbioportal.persistence.mybatisclickhouse.StudyViewMapper; import org.cbioportal.service.ClinicalAttributeService; +import org.cbioportal.service.ClinicalDataDensityPlotService; import org.cbioportal.service.StudyViewColumnarService; import org.cbioportal.service.StudyViewService; import org.cbioportal.service.exception.StudyNotFoundException; @@ -87,13 +88,19 @@ public class StudyViewColumnStoreController { private SampleServiceImpl sampleService; @Autowired private ClinicalDataFetcher clinicalDataFetcher; + @Autowired + private ClinicalDataDensityPlotService clinicalDataDensityPlotService; @Autowired - public StudyViewColumnStoreController(StudyViewColumnarService studyViewColumnarService, StudyViewService studyViewService, ClinicalDataBinner clinicalDataBinner, ClinicalAttributeService clinicalAttributeService) { + public StudyViewColumnStoreController(StudyViewColumnarService studyViewColumnarService, StudyViewService studyViewService, + ClinicalDataBinner clinicalDataBinner, ClinicalAttributeService clinicalAttributeService, + ClinicalDataDensityPlotService clinicalDataDensityPlotService + ) { this.studyViewColumnarService = studyViewColumnarService; this.studyViewService = studyViewService; this.clinicalDataBinner = clinicalDataBinner; this.clinicalAttributeService = clinicalAttributeService; + this.clinicalDataDensityPlotService = clinicalDataDensityPlotService; } @@ -201,135 +208,14 @@ public ResponseEntity fetchClinicalDataDensityPlot( @Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter, @Parameter(required = true, description = "Study view filter") @RequestBody(required = false) StudyViewFilter studyViewFilter) { - - DensityPlotData result = new DensityPlotData(); - result.setBins(new ArrayList<>()); List xyAttributeId = new ArrayList<>(Arrays.asList(xAxisAttributeId, yAxisAttributeId)); List sampleClinicalDataList = studyViewColumnarService.getSampleClinicalData(interceptedStudyViewFilter, xyAttributeId); - - Map> smallerClinicalDataMap = sampleClinicalDataList.stream().collect(Collectors.groupingBy(ClinicalData::getSampleId)); - List filteredClinicalDataList = new ArrayList<>(); - smallerClinicalDataMap.forEach((sampleId, clinDataList) -> { - if (clinDataList.size() == 2 && - NumberUtils.isCreatable(clinDataList.get(0).getAttrValue()) && - NumberUtils.isCreatable(clinDataList.get(1).getAttrValue())) { - filteredClinicalDataList.addAll(clinDataList); - } - }); - if (filteredClinicalDataList.isEmpty()) { - return new ResponseEntity<>(result, HttpStatus.OK); - } - - Map> partition = filteredClinicalDataList.stream().collect( - Collectors.partitioningBy(c -> c.getAttrId().equals(xAxisAttributeId))); - - boolean useXLogScale = xAxisLogScale && StudyViewColumnStoreController.isLogScalePossibleForAttribute(xAxisAttributeId); - boolean useYLogScale = yAxisLogScale && StudyViewColumnStoreController.isLogScalePossibleForAttribute(yAxisAttributeId); - - double[] xValues = partition.get(true).stream().mapToDouble( - useXLogScale ? StudyViewColumnStoreController::parseValueLog : StudyViewColumnStoreController::parseValueLinear - ).toArray(); - double[] yValues = partition.get(false).stream().mapToDouble( - useYLogScale ? StudyViewColumnStoreController::parseValueLog : StudyViewColumnStoreController::parseValueLinear - ).toArray(); - double[] xValuesCopy = Arrays.copyOf(xValues, xValues.length); - double[] yValuesCopy = Arrays.copyOf(yValues, yValues.length); // Why copy these? - Arrays.sort(xValuesCopy); - Arrays.sort(yValuesCopy); - - double xAxisStartValue = xAxisStart == null ? xValuesCopy[0] : - (useXLogScale ? StudyViewColumnStoreController.logScale(xAxisStart.doubleValue()) : xAxisStart.doubleValue()); - double xAxisEndValue = xAxisEnd == null ? xValuesCopy[xValuesCopy.length - 1] : - (useXLogScale ? StudyViewColumnStoreController.logScale(xAxisEnd.doubleValue()) : xAxisEnd.doubleValue()); - double yAxisStartValue = yAxisStart == null ? yValuesCopy[0] : - (useYLogScale ? StudyViewColumnStoreController.logScale(yAxisStart.doubleValue()) : yAxisStart.doubleValue()); - double yAxisEndValue = yAxisEnd == null ? yValuesCopy[yValuesCopy.length - 1] : - (useYLogScale ? StudyViewColumnStoreController.logScale(yAxisEnd.doubleValue()) : yAxisEnd.doubleValue()); - double xAxisBinInterval = (xAxisEndValue - xAxisStartValue) / xAxisBinCount; - double yAxisBinInterval = (yAxisEndValue - yAxisStartValue) / yAxisBinCount; - List bins = result.getBins(); - for (int i = 0; i < xAxisBinCount; i++) { - for (int j = 0; j < yAxisBinCount; j++) { - DensityPlotBin densityPlotBin = new DensityPlotBin(); - densityPlotBin.setBinX(BigDecimal.valueOf(xAxisStartValue + (i * xAxisBinInterval))); - densityPlotBin.setBinY(BigDecimal.valueOf(yAxisStartValue + (j * yAxisBinInterval))); - densityPlotBin.setCount(0); - bins.add(densityPlotBin); - } - } - - for (int i = 0; i < xValues.length; i++) { - double xValue = xValues[i]; - double yValue = yValues[i]; - int xBinIndex = (int) ((xValue - xAxisStartValue) / xAxisBinInterval); - int yBinIndex = (int) ((yValue - yAxisStartValue) / yAxisBinInterval); - int index = (int) (((xBinIndex - (xBinIndex == xAxisBinCount ? 1 : 0)) * yAxisBinCount) + - (yBinIndex - (yBinIndex == yAxisBinCount ? 1 : 0))); - DensityPlotBin densityPlotBin = bins.get(index); - densityPlotBin.setCount(densityPlotBin.getCount() + 1); - BigDecimal xValueBigDecimal = BigDecimal.valueOf(xValue); - BigDecimal yValueBigDecimal = BigDecimal.valueOf(yValue); - if (densityPlotBin.getMinX() != null) { - if (densityPlotBin.getMinX().compareTo(xValueBigDecimal) > 0) { - densityPlotBin.setMinX(xValueBigDecimal); - } - } else { - densityPlotBin.setMinX(xValueBigDecimal); - } - if (densityPlotBin.getMaxX() != null) { - if (densityPlotBin.getMaxX().compareTo(xValueBigDecimal) < 0) { - densityPlotBin.setMaxX(xValueBigDecimal); - } - } else { - densityPlotBin.setMaxX(xValueBigDecimal); - } - if (densityPlotBin.getMinY() != null) { - if (densityPlotBin.getMinY().compareTo(yValueBigDecimal) > 0) { - densityPlotBin.setMinY(yValueBigDecimal); - } - } else { - densityPlotBin.setMinY(yValueBigDecimal); - } - if (densityPlotBin.getMaxY() != null) { - if (densityPlotBin.getMaxY().compareTo(yValueBigDecimal) < 0) { - densityPlotBin.setMaxY(yValueBigDecimal); - } - } else { - densityPlotBin.setMaxY(yValueBigDecimal); - } - } - - if (xValues.length > 1) { - // need at least 2 entries in each to compute correlation - result.setPearsonCorr(new PearsonsCorrelation().correlation(xValues, yValues)); - result.setSpearmanCorr(new SpearmansCorrelation().correlation(xValues, yValues)); - } else { - // if less than 1 entry, just set 0 correlation - result.setSpearmanCorr(0.0); - result.setPearsonCorr(0.0); - } - - // filter out empty bins - result.setBins(result.getBins().stream().filter((bin)->(bin.getCount() > 0)).collect(Collectors.toList())); + List filteredClinicalDataList = clinicalDataDensityPlotService.filterClinicalData(sampleClinicalDataList); + DensityPlotData result = clinicalDataDensityPlotService.getDensityPlotData(filteredClinicalDataList, xAxisAttributeId, + yAxisAttributeId, xAxisLogScale, yAxisLogScale, xAxisBinCount, yAxisBinCount, xAxisStart, yAxisStart, xAxisEnd, yAxisEnd); return new ResponseEntity<>(result, HttpStatus.OK); } - - private static boolean isLogScalePossibleForAttribute(String clinicalAttributeId) { - return clinicalAttributeId.equals("MUTATION_COUNT"); - } - - private static double logScale(double val) { - return Math.log(1+val); - } - - private static double parseValueLog(ClinicalData c) { - return StudyViewColumnStoreController.logScale(Double.parseDouble(c.getAttrValue())); - } - - private static double parseValueLinear(ClinicalData c) { - return Double.parseDouble(c.getAttrValue()); - } } From 3f0907fcffcd1411909570bb14b884666eeb0a33 Mon Sep 17 00:00:00 2001 From: Neel Kuila Date: Tue, 18 Jun 2024 12:07:16 -0400 Subject: [PATCH 3/5] refactor for parameters builder, simplify min max logic, streamline service call --- .../ClinicalDataDensityPlotService.java | 15 +-- .../ClinicalDataDensityPlotServiceImpl.java | 99 ++++++--------- .../StudyViewColumnStoreController.java | 20 ++- .../web/util/DensityPlotParameters.java | 118 ++++++++++++++++++ 4 files changed, 173 insertions(+), 79 deletions(-) create mode 100644 src/main/java/org/cbioportal/web/util/DensityPlotParameters.java diff --git a/src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java b/src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java index 8382567975c..641ea3dbeb4 100644 --- a/src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java +++ b/src/main/java/org/cbioportal/service/ClinicalDataDensityPlotService.java @@ -2,22 +2,11 @@ import org.cbioportal.model.ClinicalData; import org.cbioportal.model.DensityPlotData; +import org.cbioportal.web.util.DensityPlotParameters; import java.math.BigDecimal; import java.util.List; public interface ClinicalDataDensityPlotService { - DensityPlotData getDensityPlotData(List filteredClinicalData, - String xAxisAttributeId, - String yAxisAttributeId, - Boolean xAxisLogScale, - Boolean yAxisLogScale, - Integer xAxisBinCount, - Integer yAxisBinCount, - BigDecimal xAxisStart, - BigDecimal yAxisStart, - BigDecimal xAxisEnd, - BigDecimal yAxisEnd); - - List filterClinicalData(List clinicalDataList); + DensityPlotData getDensityPlotData(List filteredClinicalData, DensityPlotParameters densityPlotParameters); } diff --git a/src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java b/src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java index c316b7a59ff..cfbb8c5fdd0 100644 --- a/src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java +++ b/src/main/java/org/cbioportal/service/impl/ClinicalDataDensityPlotServiceImpl.java @@ -8,6 +8,7 @@ import org.cbioportal.model.DensityPlotData; import org.cbioportal.service.ClinicalDataDensityPlotService; import org.cbioportal.web.columnar.StudyViewColumnStoreController; +import org.cbioportal.web.util.DensityPlotParameters; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -20,29 +21,29 @@ @Service public class ClinicalDataDensityPlotServiceImpl implements ClinicalDataDensityPlotService { @Override - public DensityPlotData getDensityPlotData(List filteredClinicalData, - String xAxisAttributeId, - String yAxisAttributeId, - Boolean xAxisLogScale, - Boolean yAxisLogScale, - Integer xAxisBinCount, - Integer yAxisBinCount, - BigDecimal xAxisStart, - BigDecimal yAxisStart, - BigDecimal xAxisEnd, - BigDecimal yAxisEnd) { + public DensityPlotData getDensityPlotData(List sampleClinicalData, DensityPlotParameters densityPlotParameters) { DensityPlotData result = new DensityPlotData(); result.setBins(new ArrayList<>()); + + Map> clinicalDataGroupedBySampleId = sampleClinicalData.stream(). + collect(Collectors.groupingBy(ClinicalData::getSampleId)); + + List extractedXYClinicalData = clinicalDataGroupedBySampleId.entrySet().stream() + .filter(entry -> entry.getValue().size() == 2 && + NumberUtils.isCreatable(entry.getValue().get(0).getAttrValue()) && + NumberUtils.isCreatable(entry.getValue().get(1).getAttrValue()) + ).flatMap(entry -> entry.getValue().stream()) + .toList(); - if (filteredClinicalData.isEmpty()) { + if (extractedXYClinicalData.isEmpty()) { return result; } - Map> partition = filteredClinicalData.stream().collect( - Collectors.partitioningBy(c -> c.getAttrId().equals(xAxisAttributeId))); + Map> partition = extractedXYClinicalData.stream().collect( + Collectors.partitioningBy(c -> c.getAttrId().equals(densityPlotParameters.getXAxisAttributeId()))); - boolean useXLogScale = xAxisLogScale && ClinicalDataDensityPlotServiceImpl.isLogScalePossibleForAttribute(xAxisAttributeId); - boolean useYLogScale = yAxisLogScale && ClinicalDataDensityPlotServiceImpl.isLogScalePossibleForAttribute(yAxisAttributeId); + boolean useXLogScale = densityPlotParameters.getXAxisLogScale() && ClinicalDataDensityPlotServiceImpl.isLogScalePossibleForAttribute(densityPlotParameters.getXAxisAttributeId()); + boolean useYLogScale = densityPlotParameters.getYAxisLogScale() && ClinicalDataDensityPlotServiceImpl.isLogScalePossibleForAttribute(densityPlotParameters.getYAxisAttributeId()); double[] xValues = partition.get(true).stream().mapToDouble( useXLogScale ? ClinicalDataDensityPlotServiceImpl::parseValueLog : ClinicalDataDensityPlotServiceImpl::parseValueLinear @@ -55,19 +56,19 @@ public DensityPlotData getDensityPlotData(List filteredClinicalDat Arrays.sort(xValuesCopy); Arrays.sort(yValuesCopy); - double xAxisStartValue = xAxisStart == null ? xValuesCopy[0] : - (useXLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(xAxisStart.doubleValue()) : xAxisStart.doubleValue()); - double xAxisEndValue = xAxisEnd == null ? xValuesCopy[xValuesCopy.length - 1] : - (useXLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(xAxisEnd.doubleValue()) : xAxisEnd.doubleValue()); - double yAxisStartValue = yAxisStart == null ? yValuesCopy[0] : - (useYLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(yAxisStart.doubleValue()) : yAxisStart.doubleValue()); - double yAxisEndValue = yAxisEnd == null ? yValuesCopy[yValuesCopy.length - 1] : - (useYLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(yAxisEnd.doubleValue()) : yAxisEnd.doubleValue()); - double xAxisBinInterval = (xAxisEndValue - xAxisStartValue) / xAxisBinCount; - double yAxisBinInterval = (yAxisEndValue - yAxisStartValue) / yAxisBinCount; + double xAxisStartValue = densityPlotParameters.getXAxisStart() == null ? xValuesCopy[0] : + (useXLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(densityPlotParameters.getXAxisStart().doubleValue()) : densityPlotParameters.getXAxisStart().doubleValue()); + double xAxisEndValue = densityPlotParameters.getXAxisEnd() == null ? xValuesCopy[xValuesCopy.length - 1] : + (useXLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(densityPlotParameters.getXAxisEnd().doubleValue()) : densityPlotParameters.getXAxisEnd().doubleValue()); + double yAxisStartValue = densityPlotParameters.getYAxisStart() == null ? yValuesCopy[0] : + (useYLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(densityPlotParameters.getYAxisStart().doubleValue()) : densityPlotParameters.getYAxisStart().doubleValue()); + double yAxisEndValue = densityPlotParameters.getYAxisEnd() == null ? yValuesCopy[yValuesCopy.length - 1] : + (useYLogScale ? ClinicalDataDensityPlotServiceImpl.logScale(densityPlotParameters.getYAxisEnd().doubleValue()) : densityPlotParameters.getYAxisEnd().doubleValue()); + double xAxisBinInterval = (xAxisEndValue - xAxisStartValue) / densityPlotParameters.getXAxisBinCount(); + double yAxisBinInterval = (yAxisEndValue - yAxisStartValue) / densityPlotParameters.getYAxisBinCount(); List bins = result.getBins(); - for (int i = 0; i < xAxisBinCount; i++) { - for (int j = 0; j < yAxisBinCount; j++) { + for (int i = 0; i < densityPlotParameters.getXAxisBinCount(); i++) { + for (int j = 0; j < densityPlotParameters.getYAxisBinCount(); j++) { DensityPlotBin densityPlotBin = new DensityPlotBin(); densityPlotBin.setBinX(BigDecimal.valueOf(xAxisStartValue + (i * xAxisBinInterval))); densityPlotBin.setBinY(BigDecimal.valueOf(yAxisStartValue + (j * yAxisBinInterval))); @@ -81,38 +82,24 @@ public DensityPlotData getDensityPlotData(List filteredClinicalDat double yValue = yValues[i]; int xBinIndex = (int) ((xValue - xAxisStartValue) / xAxisBinInterval); int yBinIndex = (int) ((yValue - yAxisStartValue) / yAxisBinInterval); - int index = (int) (((xBinIndex - (xBinIndex == xAxisBinCount ? 1 : 0)) * yAxisBinCount) + - (yBinIndex - (yBinIndex == yAxisBinCount ? 1 : 0))); + int index = (int) (((xBinIndex - (xBinIndex == densityPlotParameters.getXAxisBinCount() ? 1 : 0)) * densityPlotParameters.getYAxisBinCount()) + + (yBinIndex - (yBinIndex == densityPlotParameters.getYAxisBinCount() ? 1 : 0))); DensityPlotBin densityPlotBin = bins.get(index); densityPlotBin.setCount(densityPlotBin.getCount() + 1); BigDecimal xValueBigDecimal = BigDecimal.valueOf(xValue); BigDecimal yValueBigDecimal = BigDecimal.valueOf(yValue); - if (densityPlotBin.getMinX() != null) { - if (densityPlotBin.getMinX().compareTo(xValueBigDecimal) > 0) { - densityPlotBin.setMinX(xValueBigDecimal); - } - } else { + + // Set new min and max as needed + if (densityPlotBin.getMinX() == null || densityPlotBin.getMinX().compareTo(xValueBigDecimal) > 0){ densityPlotBin.setMinX(xValueBigDecimal); } - if (densityPlotBin.getMaxX() != null) { - if (densityPlotBin.getMaxX().compareTo(xValueBigDecimal) < 0) { - densityPlotBin.setMaxX(xValueBigDecimal); - } - } else { + if (densityPlotBin.getMaxX() == null || densityPlotBin.getMaxX().compareTo(xValueBigDecimal) < 0){ densityPlotBin.setMaxX(xValueBigDecimal); } - if (densityPlotBin.getMinY() != null) { - if (densityPlotBin.getMinY().compareTo(yValueBigDecimal) > 0) { - densityPlotBin.setMinY(yValueBigDecimal); - } - } else { + if (densityPlotBin.getMinY() == null || densityPlotBin.getMinY().compareTo(yValueBigDecimal) > 0){ densityPlotBin.setMinY(yValueBigDecimal); } - if (densityPlotBin.getMaxY() != null) { - if (densityPlotBin.getMaxY().compareTo(yValueBigDecimal) < 0) { - densityPlotBin.setMaxY(yValueBigDecimal); - } - } else { + if (densityPlotBin.getMaxY() == null || densityPlotBin.getMaxY().compareTo(yValueBigDecimal) < 0){ densityPlotBin.setMaxY(yValueBigDecimal); } } @@ -132,18 +119,6 @@ public DensityPlotData getDensityPlotData(List filteredClinicalDat return result; } - @Override - public List filterClinicalData(List clinicalDataList) { - Map> clinicalDataGroupedBySampleId = clinicalDataList.stream(). - collect(Collectors.groupingBy(ClinicalData::getSampleId)); - - return clinicalDataGroupedBySampleId.entrySet().stream() - .filter(entry -> entry.getValue().size() == 2 && - NumberUtils.isCreatable(entry.getValue().get(0).getAttrValue()) && - NumberUtils.isCreatable(entry.getValue().get(1).getAttrValue()) - ).flatMap(entry -> entry.getValue().stream()) - .toList(); - } private static boolean isLogScalePossibleForAttribute(String clinicalAttributeId) { return clinicalAttributeId.equals("MUTATION_COUNT"); diff --git a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java index 98761acc191..9923ee06c10 100644 --- a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java +++ b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java @@ -41,6 +41,7 @@ import org.cbioportal.web.parameter.StudyViewFilter; import org.cbioportal.web.util.ClinicalDataBinUtil; import org.cbioportal.web.util.ClinicalDataFetcher; +import org.cbioportal.web.util.DensityPlotParameters; import org.cbioportal.web.util.StudyViewFilterApplier; import org.cbioportal.web.util.StudyViewFilterUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -210,11 +211,22 @@ public ResponseEntity fetchClinicalDataDensityPlot( @RequestBody(required = false) StudyViewFilter studyViewFilter) { List xyAttributeId = new ArrayList<>(Arrays.asList(xAxisAttributeId, yAxisAttributeId)); - List sampleClinicalDataList = studyViewColumnarService.getSampleClinicalData(interceptedStudyViewFilter, xyAttributeId); + 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 filteredClinicalDataList = clinicalDataDensityPlotService.filterClinicalData(sampleClinicalDataList); - DensityPlotData result = clinicalDataDensityPlotService.getDensityPlotData(filteredClinicalDataList, xAxisAttributeId, - yAxisAttributeId, xAxisLogScale, yAxisLogScale, xAxisBinCount, yAxisBinCount, xAxisStart, yAxisStart, xAxisEnd, yAxisEnd); + List sampleClinicalDataList = studyViewColumnarService.getSampleClinicalData(interceptedStudyViewFilter, xyAttributeId); + DensityPlotData result = clinicalDataDensityPlotService.getDensityPlotData(sampleClinicalDataList, densityPlotParameters); return new ResponseEntity<>(result, HttpStatus.OK); } diff --git a/src/main/java/org/cbioportal/web/util/DensityPlotParameters.java b/src/main/java/org/cbioportal/web/util/DensityPlotParameters.java new file mode 100644 index 00000000000..47e65543680 --- /dev/null +++ b/src/main/java/org/cbioportal/web/util/DensityPlotParameters.java @@ -0,0 +1,118 @@ +package org.cbioportal.web.util; + +import java.math.BigDecimal; + +public class DensityPlotParameters { + private final Integer xAxisBinCount; + private final Integer yAxisBinCount; + private final BigDecimal xAxisStart; + private final BigDecimal xAxisEnd; + private final BigDecimal yAxisStart; + private final BigDecimal yAxisEnd; + private final Boolean xAxisLogScale; + private final Boolean yAxisLogScale; + private final String xAxisAttributeId; + private final String yAxisAttributeId; + + DensityPlotParameters(Builder builder) { + this.xAxisBinCount = builder.xAxisBinCount; + this.yAxisBinCount = builder.yAxisBinCount; + this.xAxisStart = builder.xAxisStart; + this.xAxisEnd = builder.xAxisEnd; + this.yAxisStart = builder.yAxisStart; + this.yAxisEnd = builder.yAxisEnd; + this.xAxisAttributeId = builder.xAxisAttributeId; + this.yAxisAttributeId = builder.yAxisAttributeId; + this.xAxisLogScale = builder.xAxisLogScale; + this.yAxisLogScale = builder.yAxisLogScale; + } + + public Integer getXAxisBinCount() { + return xAxisBinCount; + } + public Integer getYAxisBinCount() { + return yAxisBinCount; + } + public BigDecimal getXAxisStart() { + return xAxisStart; + } + public BigDecimal getXAxisEnd() { + return xAxisEnd; + } + public BigDecimal getYAxisStart() { + return yAxisStart; + } + public BigDecimal getYAxisEnd() { + return yAxisEnd; + } + public Boolean getXAxisLogScale() { + return xAxisLogScale; + } + public Boolean getYAxisLogScale() { + return yAxisLogScale; + } + public String getXAxisAttributeId() { + return xAxisAttributeId; + } + public String getYAxisAttributeId() { + return yAxisAttributeId; + } + + public static class Builder { + private Integer xAxisBinCount; + private Integer yAxisBinCount; + private BigDecimal xAxisStart; + private BigDecimal xAxisEnd; + private BigDecimal yAxisStart; + private BigDecimal yAxisEnd; + private Boolean xAxisLogScale; + private Boolean yAxisLogScale; + private String xAxisAttributeId; + private String yAxisAttributeId; + + public Builder xAxisBinCount(Integer xAxisBinCount) { + this.xAxisBinCount = xAxisBinCount; + return this; + } + public Builder yAxisBinCount(Integer yAxisBinCount) { + this.yAxisBinCount = yAxisBinCount; + return this; + } + public Builder xAxisStart(BigDecimal xAxisStart) { + this.xAxisStart = xAxisStart; + return this; + } + public Builder xAxisEnd(BigDecimal xAxisEnd) { + this.xAxisEnd = xAxisEnd; + return this; + } + public Builder yAxisStart(BigDecimal yAxisStart) { + this.yAxisStart = yAxisStart; + return this; + } + public Builder yAxisEnd(BigDecimal yAxisEnd) { + this.yAxisEnd = yAxisEnd; + return this; + } + public Builder xAxisLogScale(Boolean xAxisLogScale) { + this.xAxisLogScale = xAxisLogScale; + return this; + } + public Builder yAxisLogScale(Boolean yAxisLogScale) { + this.yAxisLogScale = yAxisLogScale; + return this; + } + public Builder xAxisAttributeId(String xAxisAttributeId) { + this.xAxisAttributeId = xAxisAttributeId; + return this; + } + public Builder yAxisAttributeId(String yAxisAttributeId) { + this.yAxisAttributeId = yAxisAttributeId; + return this; + } + public DensityPlotParameters build() { + return new DensityPlotParameters(this); + + } + } +} From 2567fc1110ab1e69a32cb55cb869fa4a24624c1f Mon Sep 17 00:00:00 2001 From: Neel Kuila Date: Tue, 18 Jun 2024 16:06:04 -0400 Subject: [PATCH 4/5] remove unused services and imports --- .../StudyViewColumnStoreController.java | 37 ++----------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java index 9923ee06c10..8b0af114112 100644 --- a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java +++ b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java @@ -6,40 +6,28 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.validation.Valid; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.math.NumberUtils; -import org.apache.commons.math3.stat.correlation.PearsonsCorrelation; -import org.apache.commons.math3.stat.correlation.SpearmansCorrelation; import org.cbioportal.model.AlterationCountByGene; import org.cbioportal.model.AlterationFilter; -import org.cbioportal.model.ClinicalAttribute; import org.cbioportal.model.ClinicalData; import org.cbioportal.model.ClinicalDataBin; import org.cbioportal.model.ClinicalDataCountItem; -import org.cbioportal.model.DensityPlotBin; import org.cbioportal.model.DensityPlotData; -import org.cbioportal.model.Patient; import org.cbioportal.model.Sample; -import org.cbioportal.persistence.mybatisclickhouse.StudyViewMapper; import org.cbioportal.service.ClinicalAttributeService; import org.cbioportal.service.ClinicalDataDensityPlotService; import org.cbioportal.service.StudyViewColumnarService; import org.cbioportal.service.StudyViewService; import org.cbioportal.service.exception.StudyNotFoundException; -import org.cbioportal.service.impl.ClinicalAttributeServiceImpl; import org.cbioportal.service.impl.PatientServiceImpl; import org.cbioportal.service.impl.SampleServiceImpl; import org.cbioportal.service.util.ClinicalAttributeUtil; -import org.cbioportal.web.StudyViewController; import org.cbioportal.web.columnar.util.NewStudyViewFilterUtil; import org.cbioportal.web.config.annotation.InternalApi; import org.cbioportal.web.parameter.ClinicalDataBinCountFilter; import org.cbioportal.web.parameter.ClinicalDataCountFilter; import org.cbioportal.web.parameter.ClinicalDataFilter; import org.cbioportal.web.parameter.DataBinMethod; -import org.cbioportal.web.parameter.Projection; import org.cbioportal.web.parameter.StudyViewFilter; -import org.cbioportal.web.util.ClinicalDataBinUtil; import org.cbioportal.web.util.ClinicalDataFetcher; import org.cbioportal.web.util.DensityPlotParameters; import org.cbioportal.web.util.StudyViewFilterApplier; @@ -63,7 +51,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; @InternalApi @@ -74,33 +61,15 @@ public class StudyViewColumnStoreController { private final StudyViewColumnarService studyViewColumnarService; private final ClinicalDataBinner clinicalDataBinner; - private final StudyViewService studyViewService; - @Autowired - private final ClinicalAttributeService clinicalAttributeService; - @Autowired - private ClinicalAttributeUtil clinicalAttributeUtil; - @Autowired - private PatientServiceImpl patientService; - @Autowired - private StudyViewFilterApplier studyViewFilterApplier; - @Autowired - private StudyViewFilterUtil studyViewFilterUtil; - @Autowired - private SampleServiceImpl sampleService; - @Autowired - private ClinicalDataFetcher clinicalDataFetcher; - @Autowired - private ClinicalDataDensityPlotService clinicalDataDensityPlotService; + private final ClinicalDataDensityPlotService clinicalDataDensityPlotService; @Autowired - public StudyViewColumnStoreController(StudyViewColumnarService studyViewColumnarService, StudyViewService studyViewService, - ClinicalDataBinner clinicalDataBinner, ClinicalAttributeService clinicalAttributeService, + public StudyViewColumnStoreController(StudyViewColumnarService studyViewColumnarService, + ClinicalDataBinner clinicalDataBinner, ClinicalDataDensityPlotService clinicalDataDensityPlotService ) { this.studyViewColumnarService = studyViewColumnarService; - this.studyViewService = studyViewService; this.clinicalDataBinner = clinicalDataBinner; - this.clinicalAttributeService = clinicalAttributeService; this.clinicalDataDensityPlotService = clinicalDataDensityPlotService; } From d369b6a40b6f67e4f96f31c3c60bce4563eb2302 Mon Sep 17 00:00:00 2001 From: Neel Kuila Date: Tue, 18 Jun 2024 16:13:08 -0400 Subject: [PATCH 5/5] remove more unused imports --- .../web/columnar/StudyViewColumnStoreController.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java index 8b0af114112..dffc99a9797 100644 --- a/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java +++ b/src/main/java/org/cbioportal/web/columnar/StudyViewColumnStoreController.java @@ -13,14 +13,9 @@ import org.cbioportal.model.ClinicalDataCountItem; import org.cbioportal.model.DensityPlotData; import org.cbioportal.model.Sample; -import org.cbioportal.service.ClinicalAttributeService; import org.cbioportal.service.ClinicalDataDensityPlotService; import org.cbioportal.service.StudyViewColumnarService; -import org.cbioportal.service.StudyViewService; import org.cbioportal.service.exception.StudyNotFoundException; -import org.cbioportal.service.impl.PatientServiceImpl; -import org.cbioportal.service.impl.SampleServiceImpl; -import org.cbioportal.service.util.ClinicalAttributeUtil; import org.cbioportal.web.columnar.util.NewStudyViewFilterUtil; import org.cbioportal.web.config.annotation.InternalApi; import org.cbioportal.web.parameter.ClinicalDataBinCountFilter; @@ -28,10 +23,7 @@ import org.cbioportal.web.parameter.ClinicalDataFilter; import org.cbioportal.web.parameter.DataBinMethod; import org.cbioportal.web.parameter.StudyViewFilter; -import org.cbioportal.web.util.ClinicalDataFetcher; import org.cbioportal.web.util.DensityPlotParameters; -import org.cbioportal.web.util.StudyViewFilterApplier; -import org.cbioportal.web.util.StudyViewFilterUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType;