From f4b15fb61d6727d0388019620299f69bf31f26b5 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 28 Jun 2023 10:30:46 -0400 Subject: [PATCH 01/40] update backend --- .../model/GenericAssayBinaryEnrichment.java | 28 +++ .../GenericAssayCategoricalEnrichment.java | 18 ++ .../model/GenericAssayCountSummary.java | 38 ++++ .../GenericAssayBinaryDataService.java | 18 ++ .../GenericAssayCategoricalDataService.java | 16 ++ .../GenericAssayBinaryDataServiceImpl.java | 126 +++++++++++ ...enericAssayCategoricalDataServiceImpl.java | 121 ++++++++++ .../util/ExpressionEnrichmentUtil.java | 204 +++++++++++++++-- .../util/FisherExactTestCalculator.java | 45 +++- ...GenericAssayBinaryDataServiceImplTest.java | 207 ++++++++++++++++++ ...icAssayCategoricalDataServiceImplTest.java | 194 ++++++++++++++++ .../web/GenericAssayBinaryDataController.java | 74 +++++++ ...GenericAssayCategoricalDataController.java | 79 +++++++ 13 files changed, 1144 insertions(+), 24 deletions(-) create mode 100644 model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java create mode 100644 model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java create mode 100644 model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java create mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java create mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java create mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java create mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java create mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java create mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java new file mode 100644 index 00000000000..f16a7015db6 --- /dev/null +++ b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java @@ -0,0 +1,28 @@ +package org.cbioportal.model; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.List; + +public class GenericAssayBinaryEnrichment extends GenericAssayEnrichment { + @NotNull + private List counts; + @NotNull + private BigDecimal qValue; + + public List getCounts() { + return counts; + } + + public void setCounts(List counts) { + this.counts = counts; + } + + public BigDecimal getqValue() { + return qValue; + } + + public void setqValue(BigDecimal qValue) { + this.qValue = qValue; + } +} diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java new file mode 100644 index 00000000000..1632f3718c4 --- /dev/null +++ b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java @@ -0,0 +1,18 @@ +package org.cbioportal.model; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.Comparator; + +public class GenericAssayCategoricalEnrichment extends GenericAssayEnrichment { + @NotNull + private BigDecimal qValue; + + public BigDecimal getqValue() { + return qValue; + } + + public void setqValue(BigDecimal qValue) { + this.qValue = qValue; + } +} diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java b/model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java new file mode 100644 index 00000000000..2f24ed760ba --- /dev/null +++ b/model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java @@ -0,0 +1,38 @@ +package org.cbioportal.model; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +public class GenericAssayCountSummary implements Serializable { + + @NotNull + private String name; + @NotNull + private Integer count; + @NotNull + private Integer totalCount; + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getTotalCount() { + return totalCount; + } + + public void setTotalCount(Integer totalCount) { + this.totalCount = totalCount; + } +} diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java new file mode 100644 index 00000000000..91d6f4df92c --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java @@ -0,0 +1,18 @@ +package org.cbioportal.service; + +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; + +import java.util.List; +import java.util.Map; + +public interface GenericAssayBinaryDataService { + List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; + +} diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java new file mode 100644 index 00000000000..ceace7ff351 --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java @@ -0,0 +1,16 @@ +package org.cbioportal.service; + +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import java.util.List; +import java.util.Map; + +public interface GenericAssayCategoricalDataService { + List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; + +} diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java new file mode 100644 index 00000000000..55233c81a29 --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -0,0 +1,126 @@ +package org.cbioportal.service.impl; + +import org.apache.commons.lang3.BooleanUtils; +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.persistence.SampleListRepository; +import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryDataService { + + @Autowired + private MolecularDataRepository molecularDataRepository; + + @Autowired + private SampleService sampleService; + + @Autowired + private MolecularProfileService molecularProfileService; + + @Autowired + private FisherExactTestCalculator fisherExactTestCalculator; + + @Autowired + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Autowired + private GenericAssayService genericAssayService; + + @Override + public List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); + + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + + if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); + List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + filteredMolecularProfileCaseSets = new HashMap<>(); + for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { + Set patientSet = new HashSet(); + List identifierListUniqueByPatientId = new ArrayList<>(); + for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { + if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { + identifierListUniqueByPatientId.add(caseIdentifier); + patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); + } + } + filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); + } + } else { + filteredMolecularProfileCaseSets = molecularProfileCaseSets; + } + + List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + // Sort the list based on pValue. + Collections.sort(genericAssayBinaryEnrichments, new Comparator() { + @Override + public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment c2) { + return c1.getpValue().compareTo(c2.getpValue()); + } + }); + + // Extract pValues and calculate qValues. + BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); + + // Assign qValues back to the objects. + for (int i = 0; i < genericAssayBinaryEnrichments.size(); i++) { + genericAssayBinaryEnrichments.get(i).setqValue(qValues[i]); + } + + List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + Map genericAssayMetaByStableId = genericAssayService + .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, + getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) + .collect(Collectors.toList()), + "SUMMARY") + .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + + return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + + } + + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + +} diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java new file mode 100644 index 00000000000..b81c06118b4 --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -0,0 +1,121 @@ +package org.cbioportal.service.impl; + +import org.apache.commons.lang3.BooleanUtils; +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.GenericAssayRepository; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.persistence.SampleListRepository; +import org.cbioportal.service.*; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class GenericAssayCategoricalDataServiceImpl implements GenericAssayCategoricalDataService { + + @Autowired + private MolecularDataRepository molecularDataRepository; + + @Autowired + private SampleService sampleService; + + @Autowired + private MolecularProfileService molecularProfileService; + + @Autowired + private FisherExactTestCalculator fisherExactTestCalculator; + + @Autowired + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Autowired + private GenericAssayService genericAssayService; + + @Override + public List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); + + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); + List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + filteredMolecularProfileCaseSets = new HashMap<>(); + for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { + Set patientSet = new HashSet(); + List identifierListUniqueByPatientId = new ArrayList<>(); + for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { + if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { + identifierListUniqueByPatientId.add(caseIdentifier); + patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); + } + } + filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); + } + } else { + filteredMolecularProfileCaseSets = molecularProfileCaseSets; + } + + List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + // Sort the list based on pValue. + Collections.sort(genericAssayCategoricalEnrichments, new Comparator() { + @Override + public int compare(GenericAssayCategoricalEnrichment c1, GenericAssayCategoricalEnrichment c2) { + return c1.getpValue().compareTo(c2.getpValue()); + } + }); + + // Extract pValues and calculate qValues. + BigDecimal[] pValues = genericAssayCategoricalEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); + + // Assign qValues back to the objects. + for (int i = 0; i < genericAssayCategoricalEnrichments.size(); i++) { + genericAssayCategoricalEnrichments.get(i).setqValue(qValues[i]); + } + + List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + Map genericAssayMetaByStableId = genericAssayService + .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, + getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) + .collect(Collectors.toList()), + "SUMMARY") + .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + + return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + +} diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index a147e0065fc..9b3c5b45678 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -1,31 +1,20 @@ package org.cbioportal.service.util; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.math3.stat.StatUtils; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; +import org.apache.commons.math3.stat.inference.ChiSquareTest; import org.apache.commons.math3.stat.inference.OneWayAnova; import org.apache.commons.math3.stat.inference.TestUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.ExpressionEnrichment; -import org.cbioportal.model.GenericAssayEnrichment; -import org.cbioportal.model.GenericAssayMolecularAlteration; -import org.cbioportal.model.GenomicEnrichment; -import org.cbioportal.model.GroupStatistics; -import org.cbioportal.model.MolecularAlteration; -import org.cbioportal.model.MolecularProfile; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.model.MolecularProfileSamples; -import org.cbioportal.model.Sample; +import org.cbioportal.model.*; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.SampleService; import org.springframework.beans.factory.annotation.Autowired; @@ -41,7 +30,10 @@ public class ExpressionEnrichmentUtil { private static final double LOG2 = Math.log(2); private static final String RNA_SEQ = "rna_seq"; - + private static final String POS = "true"; + private static final String NEG = "false"; + private static final String ALTERED = "1"; + private static final String UNALTERED = "0"; public List getEnrichments( MolecularProfile molecularProfile, Map> molecularProfileCaseSets, EnrichmentType enrichmentType, @@ -63,12 +55,12 @@ public List g .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) .filter(a -> NumberUtils.isNumber(a)) .collect(Collectors.toList()); - + // ignore group if there are less than 2 values if (molecularDataValues.size() < 2) { continue; } - + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); GroupStatistics groupStatistics = new GroupStatistics(); @@ -111,7 +103,144 @@ public List g return expressionEnrichments; } - private double[] getAlterationValues(List molecularDataValues, String molecularProfileId) { + public List getGenericAssayCategoricalEnrichments( + MolecularProfile molecularProfile, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + Iterable maItr) { + + List expressionEnrichments = new ArrayList<>(); + Map> groupCategoryStatistics = new HashMap<>(); + Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, + molecularProfile); + + for (MolecularAlteration ma : maItr) { + List groupsStatistics = new ArrayList(); + for (Entry> group : groupIndicesMap.entrySet()) { + // Get the corresponding split values for the group + List groupValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .collect(Collectors.toList()); + // Group and count the split values + Map groupedSplitValues = groupValues.stream() + .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); + + // ignore group if there are less than 2 values + if (groupValues.size() < 2) { + continue; + } + + GroupStatistics groupStatistics = new GroupStatistics(); + groupStatistics.setName(group.getKey()); + groupsStatistics.add(groupStatistics); + groupCategoryStatistics.put(group.getKey(), groupedSplitValues); + } + + // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { + long[][] array = getCategoricalValues(groupCategoryStatistics); + double pValue; + + ChiSquareTest chiSquareTest = new ChiSquareTest(); + pValue = chiSquareTest.chiSquareTest(array); + + // set p-value to 1 when the cases in all groups are altered + if (Double.isNaN(pValue)) { + pValue = 1; + } + + S expressionEnrichment = null; + GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = new GenericAssayCategoricalEnrichment(); + genericAssayCategoricalEnrichment.setStableId(ma.getStableId()); + expressionEnrichment = (S) genericAssayCategoricalEnrichment; + + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); + expressionEnrichment.setGroupsStatistics(groupsStatistics); + expressionEnrichments.add(expressionEnrichment); + } + } + return expressionEnrichments; + } + + public List getGenericAssayBinaryEnrichments( + MolecularProfile molecularProfile, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + Iterable maItr) { + List expressionEnrichments = new ArrayList<>(); + + Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, + molecularProfile); + // unaltered: 34 altered 12 1: tttf 2:ffft + for (MolecularAlteration ma : maItr) { + List genericAssayCountSummaries = new ArrayList<>(); + List groupsStatistics = new ArrayList(); + // used for p-value calculation + List groupedValues = new ArrayList(); + + for (Entry> group : groupIndicesMap.entrySet()) { + GenericAssayCountSummary genericAssayCountSummary = new GenericAssayCountSummary(); + genericAssayCountSummary.setName(group.getKey()); + // Get the corresponding split values for the group + List groupValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .collect(Collectors.toList()); + // Group and count the split values + Map groupedSplitValues = groupValues.stream() + .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); + + // get expression values to all the indices in the group, filter NA and map binary values + //unaltered:1:1,0 2:0,1 altered:1:1,1 2:0,0 + List molecularDataValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .filter(StringUtils::isNotEmpty) + .map(a -> a.equals(POS) ? ALTERED : UNALTERED) + .collect(Collectors.toList()); + + // ignore group if there are less than 2 values + if (molecularDataValues.size() < 2) { + continue; + } + + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); + + GroupStatistics groupStatistics = new GroupStatistics(); + double alteredMean = StatUtils.mean(values); + double alteredStandardDeviation = calculateStandardDeviation(values); + + // ignore if mean or standard deviation are not numbers + if (Double.isNaN(alteredMean) || Double.isNaN(alteredStandardDeviation)) { + continue; + } + + groupedValues.add(values); + groupStatistics.setName(group.getKey()); + groupStatistics.setMeanExpression(BigDecimal.valueOf(alteredMean)); + groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); + groupsStatistics.add(groupStatistics); + genericAssayCountSummaries.add(genericAssayCountSummary); + + } + + // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { + double pValue = calculatePValue(groupedValues); + if (Double.isNaN(pValue)) { + continue; + } + S expressionEnrichment = null; + GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = new GenericAssayBinaryEnrichment(); + genericAssayBinaryEnrichment.setStableId(ma.getStableId()); + genericAssayBinaryEnrichment.setCounts(genericAssayCountSummaries); + expressionEnrichment = (S) genericAssayBinaryEnrichment; + + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); + expressionEnrichment.setGroupsStatistics(groupsStatistics); + expressionEnrichments.add(expressionEnrichment); + } + } + return expressionEnrichments; + } + + private double[] getAlterationValues(List molecularDataValues, String molecularProfileId) { if (molecularProfileId.contains(RNA_SEQ)) { return molecularDataValues.stream().mapToDouble(d -> { @@ -123,6 +252,36 @@ private double[] getAlterationValues(List molecularDataValues, String mo return molecularDataValues.stream().mapToDouble(g -> Double.parseDouble(g)).toArray(); } } + + private long[][] getCategoricalValues(Map> groupCategoryStatistics) { + // Determine the number of rows and columns + int numRows = groupCategoryStatistics.size(); + Set allCategories = groupCategoryStatistics.values().stream() + .flatMap(innerMap -> innerMap.keySet().stream()) + .collect(Collectors.toSet()); + int numCols = allCategories.size(); + + // Create the 2-dimensional long array + long[][] array = new long[numRows][numCols]; + + // Iterate over the outer map (group -> categories) + List groupKeys = new ArrayList<>(groupCategoryStatistics.keySet()); + for (int row = 0; row < numRows; row++) { + String groupKey = groupKeys.get(row); + Map innerMap = groupCategoryStatistics.get(groupKey); + + // Iterate over all categories + List categoryKeys = new ArrayList<>(allCategories); + for (int col = 0; col < numCols; col++) { + String categoryKey = categoryKeys.get(col); + + // Get the count from the inner map, or set as zero if the category doesn't exist + int count = innerMap.getOrDefault(categoryKey, 0); + array[row][col] = count; + } + } + return array; + } private double calculatePValue(List alteredValues) { @@ -229,4 +388,11 @@ private Map> getCaseIdToInternalIdsMap( .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); } } + public static void main(String[] args) { + List alteredValues = null; + alteredValues.add(new double[]{0, 0}); + alteredValues.add(new double[]{0, 1}); + double pValue = TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); + System.out.println("Calculated p-value: " + pValue); + } } diff --git a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java index ed94cad2b5b..6ac8cac1047 100644 --- a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java +++ b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java @@ -2,6 +2,8 @@ import org.springframework.stereotype.Component; +import java.math.BigDecimal; + @Component public class FisherExactTestCalculator { @@ -40,9 +42,9 @@ public double getCumulativePValue(int a, int b, int c, int d) { } return p; } - + public double getTwoTailedPValue(int a, int b, int c, int d) { - + int min, i; int n = a + b + c + d; double p = 0; @@ -60,10 +62,10 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { // frequencies, of obtaining exactly the frequencies observed and any configuration more extreme. // By "more extreme," we mean any configuration (given observed marginals) with a smaller probability of // occurrence in the same direction (one-tailed) or in both directions (two-tailed). - + int initialA = a, initialB = b, initialC = c, initialD = d; p += baseP; - + min = (c < b) ? c : b; for (i = 0; i < min; i++) { double tempP = getPValue(++a, --b, --c, ++d, f); @@ -77,7 +79,7 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { b = initialB; c = initialC; d = initialD; - + min = (a < d) ? a : d; for (i = 0; i < min; i++) { double pTemp = getPValue(--a, ++b, ++c, --d, f); @@ -86,5 +88,38 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { } } return p; + } + public BigDecimal[] calcqValue(BigDecimal[] pValuesInIncreasingOrder) { + BigDecimal cachedElement = BigDecimal.valueOf(0.0); + int dataLength = pValuesInIncreasingOrder.length; + BigDecimal[] reversedQValues = new BigDecimal[dataLength]; + + reverseValues(dataLength, pValuesInIncreasingOrder); + + for (int i = 0; i < dataLength; i++) { + if (i > 0) { + BigDecimal calculatedValue = cachedElement.min( + (pValuesInIncreasingOrder[i].multiply(new BigDecimal(dataLength))).divide(new BigDecimal(dataLength - i)) + ); + cachedElement = calculatedValue; + reversedQValues[i] = calculatedValue; + } else { + cachedElement = pValuesInIncreasingOrder[i]; + reversedQValues[i] = pValuesInIncreasingOrder[i]; + } + } + + reverseValues(dataLength, reversedQValues); + + return reversedQValues; + } + + private void reverseValues(int dataLength, BigDecimal[] reversedQValues) { + for (int i = 0; i < dataLength / 2; i++) { + BigDecimal temp = reversedQValues[i]; + reversedQValues[i] = reversedQValues[dataLength - i - 1]; + reversedQValues[dataLength - i - 1] = temp; + } + } } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java new file mode 100644 index 00000000000..bfbc841a352 --- /dev/null +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java @@ -0,0 +1,207 @@ +package org.cbioportal.service.impl; + +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.service.GeneService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import java.math.BigDecimal; +import java.util.*; + +import static org.junit.Assert.*; + + +@RunWith(MockitoJUnitRunner.class) +public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ + + @InjectMocks + private GenericAssayBinaryDataServiceImpl genericAssayBinaryDataServiceImpl; + @Mock + private SampleService sampleService; + @Mock + private MolecularProfileService molecularProfileService; + @Mock + private MolecularDataRepository molecularDataRepository; + @Mock + private GeneService geneService; + @Spy + @InjectMocks + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Mock + private GenericAssayService genericAssayService; + + CancerStudy cancerStudy = new CancerStudy(); + MolecularProfile geneMolecularProfile = new MolecularProfile(); + MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); + List samples = new ArrayList<>(); + Map> molecularProfileCaseSets = new HashMap<>(); + Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + // patient level only data + public static final String SAMPLE_ID5 = "sample_id5"; + + + @Before + public void setup() throws MolecularProfileNotFoundException { + cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); + cancerStudy.setCancerStudyIdentifier(STUDY_ID); + + geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); + geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); + + geneMolecularProfile.setCancerStudy(cancerStudy); + + molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); + molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); + + Sample sample1 = new Sample(); + sample1.setStableId(SAMPLE_ID1); + sample1.setInternalId(1); + sample1.setCancerStudyIdentifier(STUDY_ID); + sample1.setPatientId(1); + samples.add(sample1); + Sample sample2 = new Sample(); + sample2.setStableId(SAMPLE_ID2); + sample2.setInternalId(2); + sample2.setCancerStudyIdentifier(STUDY_ID); + sample2.setPatientId(2); + samples.add(sample2); + Sample sample3 = new Sample(); + sample3.setStableId(SAMPLE_ID3); + sample3.setInternalId(3); + sample3.setCancerStudyIdentifier(STUDY_ID); + sample3.setPatientId(3); + samples.add(sample3); + Sample sample4 = new Sample(); + sample4.setStableId(SAMPLE_ID4); + sample4.setInternalId(4); + sample4.setCancerStudyIdentifier(STUDY_ID); + sample4.setPatientId(4); + samples.add(sample4); + + List alteredSampleIdentifieres = new ArrayList<>(); + List unalteredSampleIdentifieres = new ArrayList<>(); + List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); + + MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); + caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier1.setCaseId(SAMPLE_ID1); + alteredSampleIdentifieres.add(caseIdentifier1); + + MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); + caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier2.setCaseId(SAMPLE_ID2); + alteredSampleIdentifieres.add(caseIdentifier2); + + MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); + caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier3.setCaseId(SAMPLE_ID3); + unalteredSampleIdentifieres.add(caseIdentifier3); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); + + MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); + caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier4.setCaseId(SAMPLE_ID4); + unalteredSampleIdentifieres.add(caseIdentifier4); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); + + // patient level only data + MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); + caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier5.setCaseId(SAMPLE_ID5); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); + + molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); + + Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(geneMolecularProfile); + + Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfileSamples); + + Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), + Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); + } + + @Test + public void getGenericAssayBinaryEnrichments() throws Exception { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + + // here are 2 groups + genericAssayMolecularAlteration1.setValues("true,true,true,false"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("true,false,false,true"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayBinaryDataServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + + GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("1"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("0.0416666666666667"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.0833333333333334"), genericAssayBinaryEnrichment.getqValue()); + + genericAssayBinaryEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + + alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.707106781186548"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getqValue()); + } + + +} \ No newline at end of file diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java new file mode 100644 index 00000000000..dcd0e9bfaed --- /dev/null +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java @@ -0,0 +1,194 @@ +package org.cbioportal.service.impl; + +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.service.GeneService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import java.math.BigDecimal; +import java.util.*; + +@RunWith(MockitoJUnitRunner.class) +public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplTest{ + @InjectMocks + private ExpressionEnrichmentServiceImpl enrichmentServiceImpl; + @InjectMocks + private GenericAssayCategoricalDataServiceImpl genericAssayCategoricalDataServiceImpl; + @Mock + private SampleService sampleService; + @Mock + private MolecularProfileService molecularProfileService; + @Mock + private MolecularDataRepository molecularDataRepository; + @Mock + private GeneService geneService; + @Spy + @InjectMocks + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Mock + private GenericAssayService genericAssayService; + + CancerStudy cancerStudy = new CancerStudy(); + MolecularProfile geneMolecularProfile = new MolecularProfile(); + MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); + List samples = new ArrayList<>(); + Map> molecularProfileCaseSets = new HashMap<>(); + Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + // patient level only data + public static final String SAMPLE_ID5 = "sample_id5"; + + + @Before + public void setup() throws MolecularProfileNotFoundException { + cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); + cancerStudy.setCancerStudyIdentifier(STUDY_ID); + + geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); + geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); + + geneMolecularProfile.setCancerStudy(cancerStudy); + + molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); + molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); + + Sample sample1 = new Sample(); + sample1.setStableId(SAMPLE_ID1); + sample1.setInternalId(1); + sample1.setCancerStudyIdentifier(STUDY_ID); + sample1.setPatientId(1); + samples.add(sample1); + Sample sample2 = new Sample(); + sample2.setStableId(SAMPLE_ID2); + sample2.setInternalId(2); + sample2.setCancerStudyIdentifier(STUDY_ID); + sample2.setPatientId(2); + samples.add(sample2); + Sample sample3 = new Sample(); + sample3.setStableId(SAMPLE_ID3); + sample3.setInternalId(3); + sample3.setCancerStudyIdentifier(STUDY_ID); + sample3.setPatientId(3); + samples.add(sample3); + Sample sample4 = new Sample(); + sample4.setStableId(SAMPLE_ID4); + sample4.setInternalId(4); + sample4.setCancerStudyIdentifier(STUDY_ID); + sample4.setPatientId(4); + samples.add(sample4); + + List alteredSampleIdentifieres = new ArrayList<>(); + List unalteredSampleIdentifieres = new ArrayList<>(); + List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); + + MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); + caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier1.setCaseId(SAMPLE_ID1); + alteredSampleIdentifieres.add(caseIdentifier1); + + MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); + caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier2.setCaseId(SAMPLE_ID2); + alteredSampleIdentifieres.add(caseIdentifier2); + + MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); + caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier3.setCaseId(SAMPLE_ID3); + unalteredSampleIdentifieres.add(caseIdentifier3); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); + + MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); + caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier4.setCaseId(SAMPLE_ID4); + unalteredSampleIdentifieres.add(caseIdentifier4); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); + + // patient level only data + MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); + caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier5.setCaseId(SAMPLE_ID5); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); + + molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); + + Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(geneMolecularProfile); + + Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfileSamples); + + Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), + Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); + } + + @Test + public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFoundException { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + genericAssayMolecularAlteration1.setValues("category1,category1,category2,category2"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("category2,category2,category1,category1"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayCategoricalDataServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + + genericAssayCategoricalEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + } + +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java new file mode 100644 index 00000000000..5d16690163a --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -0,0 +1,74 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Binary Data", description = " ") +public class GenericAssayBinaryDataController { + @Autowired + private GenericAssayBinaryDataService genericAssayBinaryDataService; + + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java new file mode 100644 index 00000000000..976a8076c3b --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -0,0 +1,79 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.commons.lang3.StringUtils; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayData; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayCategoricalDataService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.GenericAssayNotFoundException; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.GenericAssayFilter; +import org.cbioportal.web.parameter.HeaderKeyConstants; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +import org.cbioportal.web.parameter.Projection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.*; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Categorical Data", description = " ") +public class GenericAssayCategoricalDataController { + + @Autowired + private GenericAssayCategoricalDataService genericAssayCategoricalDataService; + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} From 06d269927a23eab5d41bbcce0481de72ccd6b80a Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 26 Jul 2023 14:17:22 -0400 Subject: [PATCH 02/40] finish tests --- .../GenericAssayBinaryDataServiceImpl.java | 5 ++- ...enericAssayCategoricalDataServiceImpl.java | 11 ++++-- .../util/ExpressionEnrichmentUtil.java | 39 ++++++++----------- .../util/FisherExactTestCalculator.java | 2 +- ...GenericAssayBinaryDataServiceImplTest.java | 24 ++++++------ ...icAssayCategoricalDataServiceImplTest.java | 13 +++---- .../web/GenericAssayBinaryDataController.java | 2 +- ...GenericAssayCategoricalDataController.java | 27 ++++++------- ...volvedCancerStudyExtractorInterceptor.java | 6 ++- 9 files changed, 66 insertions(+), 63 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 55233c81a29..7ffc558f0ea 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -14,6 +14,7 @@ import org.cbioportal.service.util.FisherExactTestCalculator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; @@ -33,7 +34,7 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData private MolecularProfileService molecularProfileService; @Autowired - private FisherExactTestCalculator fisherExactTestCalculator; + private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); @Autowired private ExpressionEnrichmentUtil expressionEnrichmentUtil; @@ -41,6 +42,7 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData private GenericAssayService genericAssayService; @Override + @Transactional(readOnly = true) public List getGenericAssayBinaryEnrichments( String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) @@ -90,6 +92,7 @@ public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment // Extract pValues and calculate qValues. BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); // Assign qValues back to the objects. diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index b81c06118b4..99b1c6e91f5 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -32,20 +32,20 @@ public class GenericAssayCategoricalDataServiceImpl implements GenericAssayCateg private MolecularProfileService molecularProfileService; @Autowired - private FisherExactTestCalculator fisherExactTestCalculator; + private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); @Autowired - private ExpressionEnrichmentUtil expressionEnrichmentUtil; + private ExpressionEnrichmentUtil expressionEnrichmentUtil = new ExpressionEnrichmentUtil(); @Autowired private GenericAssayService genericAssayService; @Override + @Transactional(readOnly = true) public List getGenericAssayCategoricalEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); Iterable maItr = molecularDataRepository @@ -56,7 +56,10 @@ public List getGenericAssayCategoricalEnrichm List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + Map sampleIdToPatientIdMap = samples.stream() + .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) + .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); filteredMolecularProfileCaseSets = new HashMap<>(); for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index 9b3c5b45678..a07454a4b5f 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -7,6 +7,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import io.swagger.models.auth.In; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.math3.stat.StatUtils; @@ -43,7 +44,6 @@ public List g Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, molecularProfile); for (MolecularAlteration ma : maItr) { - List groupsStatistics = new ArrayList(); // used for p-value calculation List groupedValues = new ArrayList(); @@ -112,7 +112,7 @@ public List g Map> groupCategoryStatistics = new HashMap<>(); Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, molecularProfile); - + for (MolecularAlteration ma : maItr) { List groupsStatistics = new ArrayList(); for (Entry> group : groupIndicesMap.entrySet()) { @@ -136,12 +136,16 @@ public List g } // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { long[][] array = getCategoricalValues(groupCategoryStatistics); double pValue; - - ChiSquareTest chiSquareTest = new ChiSquareTest(); - pValue = chiSquareTest.chiSquareTest(array); + if(array[0].length <= 1) { + pValue = 1; + } else { + ChiSquareTest chiSquareTest = new ChiSquareTest(); + pValue = chiSquareTest.chiSquareTest(array); + } // set p-value to 1 when the cases in all groups are altered if (Double.isNaN(pValue)) { @@ -179,16 +183,8 @@ public List g for (Entry> group : groupIndicesMap.entrySet()) { GenericAssayCountSummary genericAssayCountSummary = new GenericAssayCountSummary(); genericAssayCountSummary.setName(group.getKey()); - // Get the corresponding split values for the group - List groupValues = group.getValue().stream() - .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) - .collect(Collectors.toList()); - // Group and count the split values - Map groupedSplitValues = groupValues.stream() - .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); // get expression values to all the indices in the group, filter NA and map binary values - //unaltered:1:1,0 2:0,1 altered:1:1,1 2:0,0 List molecularDataValues = group.getValue().stream() .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) .filter(StringUtils::isNotEmpty) @@ -199,9 +195,12 @@ public List g if (molecularDataValues.size() < 2) { continue; } - + genericAssayCountSummary.setTotalCount(molecularDataValues.size()); + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); - + genericAssayCountSummary.setCount((int) Arrays.stream(values) + .filter(num -> num == 1) + .count()); GroupStatistics groupStatistics = new GroupStatistics(); double alteredMean = StatUtils.mean(values); double alteredStandardDeviation = calculateStandardDeviation(values); @@ -217,11 +216,11 @@ public List g groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); groupsStatistics.add(groupStatistics); genericAssayCountSummaries.add(genericAssayCountSummary); - } // calculate p-value and add enrichment if atleast 2 groups have data if (groupsStatistics.size() > 1) { + double pValue = calculatePValue(groupedValues); if (Double.isNaN(pValue)) { continue; @@ -388,11 +387,5 @@ private Map> getCaseIdToInternalIdsMap( .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); } } - public static void main(String[] args) { - List alteredValues = null; - alteredValues.add(new double[]{0, 0}); - alteredValues.add(new double[]{0, 1}); - double pValue = TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); - System.out.println("Calculated p-value: " + pValue); - } + } diff --git a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java index 6ac8cac1047..4584341e2e2 100644 --- a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java +++ b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java @@ -99,7 +99,7 @@ public BigDecimal[] calcqValue(BigDecimal[] pValuesInIncreasingOrder) { for (int i = 0; i < dataLength; i++) { if (i > 0) { BigDecimal calculatedValue = cachedElement.min( - (pValuesInIncreasingOrder[i].multiply(new BigDecimal(dataLength))).divide(new BigDecimal(dataLength - i)) + (pValuesInIncreasingOrder[i].multiply(new BigDecimal(dataLength))).divide(new BigDecimal(dataLength - i), BigDecimal.ROUND_HALF_UP) ); cachedElement = calculatedValue; reversedQValues[i] = calculatedValue; diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java index bfbc841a352..f7f423f6cda 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java @@ -9,6 +9,7 @@ import org.cbioportal.service.SampleService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -36,8 +37,7 @@ public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ private MolecularProfileService molecularProfileService; @Mock private MolecularDataRepository molecularDataRepository; - @Mock - private GeneService geneService; + @Spy @InjectMocks private ExpressionEnrichmentUtil expressionEnrichmentUtil; @@ -50,6 +50,8 @@ public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ List samples = new ArrayList<>(); Map> molecularProfileCaseSets = new HashMap<>(); Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + private FisherExactTestCalculator fisherExactTestCalculator; + // patient level only data public static final String SAMPLE_ID5 = "sample_id5"; @@ -175,15 +177,15 @@ public void getGenericAssayBinaryEnrichments() throws Exception { GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("1"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0"), alteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("1.0"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.0"), alteredGroupStats.getStandardDeviation()); - Assert.assertEquals(new BigDecimal("0.0416666666666667"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.0833333333333334"), genericAssayBinaryEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("0.49999999999999983"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.99999999999999966"), genericAssayBinaryEnrichment.getqValue()); genericAssayBinaryEnrichment = result.get(1); Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); @@ -192,15 +194,15 @@ public void getGenericAssayBinaryEnrichments() throws Exception { unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.707106781186548"), alteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), alteredGroupStats.getStandardDeviation()); - Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getqValue()); } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java index dcd0e9bfaed..405641dfc92 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java @@ -24,8 +24,6 @@ @RunWith(MockitoJUnitRunner.class) public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplTest{ - @InjectMocks - private ExpressionEnrichmentServiceImpl enrichmentServiceImpl; @InjectMocks private GenericAssayCategoricalDataServiceImpl genericAssayCategoricalDataServiceImpl; @Mock @@ -34,8 +32,7 @@ public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplT private MolecularProfileService molecularProfileService; @Mock private MolecularDataRepository molecularDataRepository; - @Mock - private GeneService geneService; + @Spy @InjectMocks private ExpressionEnrichmentUtil expressionEnrichmentUtil; @@ -174,8 +171,8 @@ public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFo GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); genericAssayCategoricalEnrichment = result.get(1); Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); @@ -187,8 +184,8 @@ public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFo alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); } } diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java index 5d16690163a..60a7fddc58d 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -41,7 +41,7 @@ public class GenericAssayBinaryDataController { method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + public ResponseEntity> fetchGenericAssayBinaryDataEnrichmentInMultipleMolecularProfiles( @ApiIgnore @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java index 976a8076c3b..c3344ce94e9 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -4,10 +4,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayData; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.*; import org.cbioportal.service.GenericAssayCategoricalDataService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.SampleService; @@ -56,7 +53,13 @@ public ResponseEntity> fetchGenericAssay @ApiIgnore @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) throws MolecularProfileNotFoundException, UnsupportedOperationException { - + + return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), + HttpStatus.OK); + } + private List fetchExpressionEnrichments(EnrichmentType enrichmentType, + List interceptedMolecularProfileCasesGroupFilters + ) throws MolecularProfileNotFoundException { Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); @@ -65,15 +68,13 @@ public ResponseEntity> fetchGenericAssay .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) .collect(Collectors.toSet()); - + if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - - return new ResponseEntity<>( - genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), - HttpStatus.OK); + return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } - } + + diff --git a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java index f56a51727b0..dc81162be46 100644 --- a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java +++ b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java @@ -102,6 +102,8 @@ public class InvolvedCancerStudyExtractorInterceptor extends HandlerInterceptorA public static final String TREATMENTS_PATIENT_PATH = "/treatments/patient"; public static final String TREATMENTS_SAMPLE_PATH = "/treatments/sample"; public static final String GENERIC_ASSAY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/fetch"; + public static final String GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/categorical/fetch"; + public static final String GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/binary/fetch"; public static final String CLINICAL_EVENT_TYPE_COUNT_FETCH_PATH = "/clinical-event-type-counts/fetch"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { @@ -151,7 +153,9 @@ public class InvolvedCancerStudyExtractorInterceptor extends HandlerInterceptorA } else if (requestPathInfo.equals(MUTATION_ENRICHMENT_FETCH_PATH) || requestPathInfo.equals(COPY_NUMBER_ENRICHMENT_FETCH_PATH) || requestPathInfo.equals(EXPRESSION_ENRICHMENT_FETCH_PATH) || - requestPathInfo.equals(GENERIC_ASSAY_ENRICHMENT_FETCH_PATH)) { + requestPathInfo.equals(GENERIC_ASSAY_ENRICHMENT_FETCH_PATH) || + requestPathInfo.equals(GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH) || + requestPathInfo.equals(GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH)) { return extractAttributesFromMolecularProfileCasesGroups(request); } else if (requestPathInfo.equals(ALTERATION_ENRICHMENT_FETCH_PATH)) { return extractAttributesFromMolecularProfileCasesGroupsAndAlterationTypes(request); From f46960b7db554d7e58c2b86801805c2d7b731974 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:04:39 -0400 Subject: [PATCH 03/40] modify controller file structure --- ...GenericAssayCategoricalDataController.java | 80 ------------------- ... => GenericAssayEnrichmentController.java} | 47 ++++++++++- ...volvedCancerStudyExtractorInterceptor.java | 4 +- 3 files changed, 46 insertions(+), 85 deletions(-) delete mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java rename web/src/main/java/org/cbioportal/web/{GenericAssayBinaryDataController.java => GenericAssayEnrichmentController.java} (53%) diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java deleted file mode 100644 index c3344ce94e9..00000000000 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.cbioportal.web; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.*; -import org.cbioportal.service.GenericAssayCategoricalDataService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.GenericAssayNotFoundException; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.web.config.annotation.InternalApi; -import org.cbioportal.web.parameter.GenericAssayFilter; -import org.cbioportal.web.parameter.HeaderKeyConstants; -import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; -import org.cbioportal.web.parameter.Projection; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -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.*; -import springfox.documentation.annotations.ApiIgnore; - -import javax.validation.Valid; -import java.util.*; -import java.util.stream.Collectors; - -@InternalApi -@RestController -@Validated -@Api(tags = "Generic Assay Categorical Data", description = " ") -public class GenericAssayCategoricalDataController { - - @Autowired - private GenericAssayCategoricalDataService genericAssayCategoricalDataService; - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", - method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( - @ApiIgnore - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") - @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, - @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") - @Valid @RequestBody(required = false) List groups, - @ApiIgnore - @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) - throws MolecularProfileNotFoundException, UnsupportedOperationException { - - return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), - HttpStatus.OK); - } - private List fetchExpressionEnrichments(EnrichmentType enrichmentType, - List interceptedMolecularProfileCasesGroupFilters - ) throws MolecularProfileNotFoundException { - Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters - .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, - MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); - - Set molecularProfileIds = groupCaseIdentifierSet.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) - .collect(Collectors.toSet()); - - if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); - } - return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); - } -} - - diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java similarity index 53% rename from web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java rename to web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java index 60a7fddc58d..bac54097958 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java @@ -5,8 +5,10 @@ import io.swagger.annotations.ApiParam; import org.cbioportal.model.EnrichmentType; import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.GenericAssayCategoricalDataService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; import org.cbioportal.web.config.annotation.InternalApi; @@ -30,14 +32,35 @@ @InternalApi @RestController @Validated -@Api(tags = "Generic Assay Binary Data", description = " ") -public class GenericAssayBinaryDataController { +@Api(tags = "Generic Assay Enrichment Data", description = " ") +public class GenericAssayEnrichmentController { + @Autowired + private GenericAssayCategoricalDataService genericAssayCategoricalDataService; @Autowired private GenericAssayBinaryDataService genericAssayBinaryDataService; + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-categorical-enrichments/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), + HttpStatus.OK); + } @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", + @RequestMapping(value = "/generic-assay-binary-enrichments/fetch", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") @@ -71,4 +94,22 @@ public ResponseEntity> fetchGenericAssayBinar HttpStatus.OK); } + private List fetchExpressionEnrichments(EnrichmentType enrichmentType, + List interceptedMolecularProfileCasesGroupFilters + ) throws MolecularProfileNotFoundException { + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); + } + return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); + } } diff --git a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java index dc81162be46..91720ee1f81 100644 --- a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java +++ b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java @@ -102,8 +102,8 @@ public class InvolvedCancerStudyExtractorInterceptor extends HandlerInterceptorA public static final String TREATMENTS_PATIENT_PATH = "/treatments/patient"; public static final String TREATMENTS_SAMPLE_PATH = "/treatments/sample"; public static final String GENERIC_ASSAY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/fetch"; - public static final String GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/categorical/fetch"; - public static final String GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/binary/fetch"; + public static final String GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH = "/generic-assay-categorical-enrichments/fetch"; + public static final String GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH = "/generic-assay-binary-enrichments/fetch"; public static final String CLINICAL_EVENT_TYPE_COUNT_FETCH_PATH = "/clinical-event-type-counts/fetch"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { From 79e44b4c83a417783c564ef1488a95c1317ee5c7 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:15:34 -0400 Subject: [PATCH 04/40] modify import --- .../impl/GenericAssayBinaryDataServiceImpl.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 7ffc558f0ea..2958530d8ba 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -4,7 +4,6 @@ import org.cbioportal.model.*; import org.cbioportal.model.meta.GenericAssayMeta; import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.persistence.SampleListRepository; import org.cbioportal.service.GenericAssayBinaryDataService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.MolecularProfileService; @@ -17,7 +16,16 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; -import java.util.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; From 99357cb691c771d8ea82c36b329d1ff695a650c7 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 28 Jun 2023 10:30:46 -0400 Subject: [PATCH 05/40] update backend --- .../GenericAssayBinaryDataServiceImpl.java | 13 +- ...enericAssayCategoricalDataServiceImpl.java | 2 + .../util/ExpressionEnrichmentUtil.java | 448 +++++++++--------- .../util/FisherExactTestCalculator.java | 3 +- ...GenericAssayBinaryDataServiceImplTest.java | 209 -------- ...icAssayCategoricalDataServiceImplTest.java | 191 -------- .../web/GenericAssayBinaryDataController.java | 74 +++ ...GenericAssayCategoricalDataController.java | 79 +++ 8 files changed, 382 insertions(+), 637 deletions(-) delete mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java delete mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 2958530d8ba..c02c725fbb0 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -14,18 +14,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - import java.math.BigDecimal; -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.Map; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -44,6 +34,7 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData @Autowired private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); + @Autowired private ExpressionEnrichmentUtil expressionEnrichmentUtil; @Autowired diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index 99b1c6e91f5..9d6ab72ff84 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -46,6 +46,7 @@ public List getGenericAssayCategoricalEnrichm throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); Iterable maItr = molecularDataRepository @@ -57,6 +58,7 @@ public List getGenericAssayCategoricalEnrichm List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream() .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index a07454a4b5f..71e7ef8e09d 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -24,90 +24,90 @@ @Component public class ExpressionEnrichmentUtil { - @Autowired - private SampleService sampleService; - @Autowired - private MolecularDataRepository molecularDataRepository; + @Autowired + private SampleService sampleService; + @Autowired + private MolecularDataRepository molecularDataRepository; - private static final double LOG2 = Math.log(2); - private static final String RNA_SEQ = "rna_seq"; + private static final double LOG2 = Math.log(2); + private static final String RNA_SEQ = "rna_seq"; private static final String POS = "true"; private static final String NEG = "false"; private static final String ALTERED = "1"; private static final String UNALTERED = "0"; - public List getEnrichments( - MolecularProfile molecularProfile, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType, - Iterable maItr) { - List expressionEnrichments = new ArrayList<>(); - - Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, - molecularProfile); - for (MolecularAlteration ma : maItr) { - List groupsStatistics = new ArrayList(); - // used for p-value calculation - List groupedValues = new ArrayList(); - - for (Entry> group : groupIndicesMap.entrySet()) { - - // get expression values to all the indices in the group - List molecularDataValues = group.getValue().stream() - .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) - .filter(a -> NumberUtils.isNumber(a)) - .collect(Collectors.toList()); - - // ignore group if there are less than 2 values - if (molecularDataValues.size() < 2) { - continue; - } - - double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); - - GroupStatistics groupStatistics = new GroupStatistics(); - double alteredMean = StatUtils.mean(values); - double alteredStandardDeviation = calculateStandardDeviation(values); - - // ignore if mean or standard deviation are not numbers - if (Double.isNaN(alteredMean) || Double.isNaN(alteredStandardDeviation)) { - continue; - } - - groupedValues.add(values); - groupStatistics.setName(group.getKey()); - groupStatistics.setMeanExpression(BigDecimal.valueOf(alteredMean)); - groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); - groupsStatistics.add(groupStatistics); - } - - // calculate p-value and add enrichment if atleast 2 groups have data - if (groupsStatistics.size() > 1) { - double pValue = calculatePValue(groupedValues); - if (Double.isNaN(pValue)) { - continue; - } - S expressionEnrichment = null; - if (ma instanceof GenericAssayMolecularAlteration) { - GenericAssayEnrichment genericAssayEnrichment = new GenericAssayEnrichment(); - genericAssayEnrichment.setStableId(ma.getStableId()); - expressionEnrichment = (S) genericAssayEnrichment; - } else { - GenomicEnrichment genomicEnrichment = new GenomicEnrichment(); - genomicEnrichment.setEntrezGeneId(Integer.valueOf(ma.getStableId())); - expressionEnrichment = (S) genomicEnrichment; - } - expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); - expressionEnrichment.setGroupsStatistics(groupsStatistics); - expressionEnrichments.add(expressionEnrichment); - } - } - return expressionEnrichments; - } + public List getEnrichments( + MolecularProfile molecularProfile, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + Iterable maItr) { + List expressionEnrichments = new ArrayList<>(); + + Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, + molecularProfile); + for (MolecularAlteration ma : maItr) { + List groupsStatistics = new ArrayList(); + // used for p-value calculation + List groupedValues = new ArrayList(); + + for (Entry> group : groupIndicesMap.entrySet()) { + + // get expression values to all the indices in the group + List molecularDataValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .filter(a -> NumberUtils.isNumber(a)) + .collect(Collectors.toList()); + + // ignore group if there are less than 2 values + if (molecularDataValues.size() < 2) { + continue; + } + + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); + + GroupStatistics groupStatistics = new GroupStatistics(); + double alteredMean = StatUtils.mean(values); + double alteredStandardDeviation = calculateStandardDeviation(values); + + // ignore if mean or standard deviation are not numbers + if (Double.isNaN(alteredMean) || Double.isNaN(alteredStandardDeviation)) { + continue; + } + + groupedValues.add(values); + groupStatistics.setName(group.getKey()); + groupStatistics.setMeanExpression(BigDecimal.valueOf(alteredMean)); + groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); + groupsStatistics.add(groupStatistics); + } + + // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { + double pValue = calculatePValue(groupedValues); + if (Double.isNaN(pValue)) { + continue; + } + S expressionEnrichment = null; + if (ma instanceof GenericAssayMolecularAlteration) { + GenericAssayEnrichment genericAssayEnrichment = new GenericAssayEnrichment(); + genericAssayEnrichment.setStableId(ma.getStableId()); + expressionEnrichment = (S) genericAssayEnrichment; + } else { + GenomicEnrichment genomicEnrichment = new GenomicEnrichment(); + genomicEnrichment.setEntrezGeneId(Integer.valueOf(ma.getStableId())); + expressionEnrichment = (S) genomicEnrichment; + } + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); + expressionEnrichment.setGroupsStatistics(groupsStatistics); + expressionEnrichments.add(expressionEnrichment); + } + } + return expressionEnrichments; + } public List getGenericAssayCategoricalEnrichments( MolecularProfile molecularProfile, Map> molecularProfileCaseSets, EnrichmentType enrichmentType, Iterable maItr) { - + List expressionEnrichments = new ArrayList<>(); Map> groupCategoryStatistics = new HashMap<>(); Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, @@ -123,12 +123,12 @@ public List g // Group and count the split values Map groupedSplitValues = groupValues.stream() .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); - + // ignore group if there are less than 2 values if (groupValues.size() < 2) { continue; } - + GroupStatistics groupStatistics = new GroupStatistics(); groupStatistics.setName(group.getKey()); groupsStatistics.add(groupStatistics); @@ -151,7 +151,7 @@ public List g if (Double.isNaN(pValue)) { pValue = 1; } - + S expressionEnrichment = null; GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = new GenericAssayCategoricalEnrichment(); genericAssayCategoricalEnrichment.setStableId(ma.getStableId()); @@ -173,7 +173,7 @@ public List g Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, molecularProfile); - // unaltered: 34 altered 12 1: tttf 2:ffft + for (MolecularAlteration ma : maItr) { List genericAssayCountSummaries = new ArrayList<>(); List groupsStatistics = new ArrayList(); @@ -196,7 +196,7 @@ public List g continue; } genericAssayCountSummary.setTotalCount(molecularDataValues.size()); - + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); genericAssayCountSummary.setCount((int) Arrays.stream(values) .filter(num -> num == 1) @@ -230,7 +230,7 @@ public List g genericAssayBinaryEnrichment.setStableId(ma.getStableId()); genericAssayBinaryEnrichment.setCounts(genericAssayCountSummaries); expressionEnrichment = (S) genericAssayBinaryEnrichment; - + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); expressionEnrichment.setGroupsStatistics(groupsStatistics); expressionEnrichments.add(expressionEnrichment); @@ -241,151 +241,151 @@ public List g private double[] getAlterationValues(List molecularDataValues, String molecularProfileId) { - if (molecularProfileId.contains(RNA_SEQ)) { - return molecularDataValues.stream().mapToDouble(d -> { - double datum = Double.parseDouble(d); - // reset to 0 if there are any negative values and then do log1p - return Math.log1p(datum < 0 ? 0 : datum) / LOG2; - }).toArray(); - } else { - return molecularDataValues.stream().mapToDouble(g -> Double.parseDouble(g)).toArray(); - } - } - + if (molecularProfileId.contains(RNA_SEQ)) { + return molecularDataValues.stream().mapToDouble(d -> { + double datum = Double.parseDouble(d); + // reset to 0 if there are any negative values and then do log1p + return Math.log1p(datum < 0 ? 0 : datum) / LOG2; + }).toArray(); + } else { + return molecularDataValues.stream().mapToDouble(g -> Double.parseDouble(g)).toArray(); + } + } + private long[][] getCategoricalValues(Map> groupCategoryStatistics) { - // Determine the number of rows and columns - int numRows = groupCategoryStatistics.size(); - Set allCategories = groupCategoryStatistics.values().stream() - .flatMap(innerMap -> innerMap.keySet().stream()) - .collect(Collectors.toSet()); - int numCols = allCategories.size(); - - // Create the 2-dimensional long array - long[][] array = new long[numRows][numCols]; - - // Iterate over the outer map (group -> categories) - List groupKeys = new ArrayList<>(groupCategoryStatistics.keySet()); - for (int row = 0; row < numRows; row++) { - String groupKey = groupKeys.get(row); - Map innerMap = groupCategoryStatistics.get(groupKey); - - // Iterate over all categories - List categoryKeys = new ArrayList<>(allCategories); - for (int col = 0; col < numCols; col++) { - String categoryKey = categoryKeys.get(col); - - // Get the count from the inner map, or set as zero if the category doesn't exist - int count = innerMap.getOrDefault(categoryKey, 0); - array[row][col] = count; - } + // Determine the number of rows and columns + int numRows = groupCategoryStatistics.size(); + Set allCategories = groupCategoryStatistics.values().stream() + .flatMap(innerMap -> innerMap.keySet().stream()) + .collect(Collectors.toSet()); + int numCols = allCategories.size(); + + // Create the 2-dimensional long array + long[][] array = new long[numRows][numCols]; + + // Iterate over the outer map (group -> categories) + List groupKeys = new ArrayList<>(groupCategoryStatistics.keySet()); + for (int row = 0; row < numRows; row++) { + String groupKey = groupKeys.get(row); + Map innerMap = groupCategoryStatistics.get(groupKey); + + // Iterate over all categories + List categoryKeys = new ArrayList<>(allCategories); + for (int col = 0; col < numCols; col++) { + String categoryKey = categoryKeys.get(col); + + // Get the count from the inner map, or set as zero if the category doesn't exist + int count = innerMap.getOrDefault(categoryKey, 0); + array[row][col] = count; } - return array; + } + return array; + } + + private double calculatePValue(List alteredValues) { + + if (alteredValues.size() == 2) { + return TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); + } else { + // calculate Anova statisitcs if there are more than 2 groups + OneWayAnova oneWayAnova = new OneWayAnova(); + return oneWayAnova.anovaPValue(alteredValues); + } + } + + private double calculateStandardDeviation(double[] values) { + + DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(); + for (double value : values) { + descriptiveStatistics.addValue(value); + } + return descriptiveStatistics.getStandardDeviation(); + } + + /** + * + * This method maps valid samples in molecularProfileCaseSets to indices in + * genetic_alteration.VALUES column. Recall this column of the + * genetic_alteration table is a comma separated list of scalar values. Each + * value in this list is associated with a sample at the same position found in + * the genetic_profile_samples.ORDERED_SAMPLE_LIST column. + * + * @param molecularProfileCaseSets + * @param enrichmentType + * @param molecularProfile + * @return + */ + private Map> getGroupIndicesMap( + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + MolecularProfile molecularProfile) { + + MolecularProfileSamples commaSeparatedSampleIdsOfMolecularProfile = molecularDataRepository + .getCommaSeparatedSampleIdsOfMolecularProfile(molecularProfile.getStableId()); + + List internalSampleIds = Arrays.stream(commaSeparatedSampleIdsOfMolecularProfile.getSplitSampleIds()) + .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); + + Map internalSampleIdToIndexMap = IntStream.range(0, internalSampleIds.size()).boxed() + .collect(Collectors.toMap(internalSampleIds::get, Function.identity())); + + Map> selectedCaseIdToInternalIdsMap = getCaseIdToInternalIdsMap(molecularProfileCaseSets, + enrichmentType, molecularProfile); + + // this block map caseIds(sampleIds or patientids) to sampleIndices which + // represents the position fount in the + // genetic_profile_samples.ORDERED_SAMPLE_LIST column + Map> groupIndicesMap = molecularProfileCaseSets.entrySet().stream() + .collect(Collectors.toMap(entity -> entity.getKey(), entity -> { + List sampleIndices = new ArrayList<>(); + entity.getValue().forEach(molecularProfileCaseIdentifier -> { + // consider only valid samples + if (selectedCaseIdToInternalIdsMap.containsKey(molecularProfileCaseIdentifier.getCaseId())) { + List sampleInternalIds = selectedCaseIdToInternalIdsMap + .get(molecularProfileCaseIdentifier.getCaseId()); + + // only consider samples which are profiled for the give molecular profile id + sampleInternalIds.forEach(sampleInternalId -> { + if (internalSampleIdToIndexMap.containsKey(sampleInternalId)) { + sampleIndices.add(internalSampleIdToIndexMap.get(sampleInternalId)); + } + }); + } + }); + return sampleIndices; + })); + return groupIndicesMap; + } + + private Map> getCaseIdToInternalIdsMap( + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + MolecularProfile molecularProfile) { + + if (enrichmentType.equals(EnrichmentType.PATIENT)) { + List patientIds = molecularProfileCaseSets.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getCaseId)) + .collect(Collectors.toList()); + + List samples = sampleService + .getAllSamplesOfPatientsInStudy(molecularProfile.getCancerStudyIdentifier(), patientIds, "SUMMARY"); + + return samples.stream().collect(Collectors.groupingBy(Sample::getPatientStableId, + Collectors.mapping(Sample::getInternalId, Collectors.toList()))); + } else { + List sampleIds = new ArrayList<>(); + List studyIds = new ArrayList<>(); + + molecularProfileCaseSets.values().forEach(molecularProfileCaseIdentifiers -> { + molecularProfileCaseIdentifiers.forEach(molecularProfileCaseIdentifier -> { + sampleIds.add(molecularProfileCaseIdentifier.getCaseId()); + studyIds.add(molecularProfile.getCancerStudyIdentifier()); + }); + }); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + + return samples.stream() + .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); + } } - private double calculatePValue(List alteredValues) { - - if (alteredValues.size() == 2) { - return TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); - } else { - // calculate Anova statisitcs if there are more than 2 groups - OneWayAnova oneWayAnova = new OneWayAnova(); - return oneWayAnova.anovaPValue(alteredValues); - } - } - - private double calculateStandardDeviation(double[] values) { - - DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(); - for (double value : values) { - descriptiveStatistics.addValue(value); - } - return descriptiveStatistics.getStandardDeviation(); - } - - /** - * - * This method maps valid samples in molecularProfileCaseSets to indices in - * genetic_alteration.VALUES column. Recall this column of the - * genetic_alteration table is a comma separated list of scalar values. Each - * value in this list is associated with a sample at the same position found in - * the genetic_profile_samples.ORDERED_SAMPLE_LIST column. - * - * @param molecularProfileCaseSets - * @param enrichmentType - * @param molecularProfile - * @return - */ - private Map> getGroupIndicesMap( - Map> molecularProfileCaseSets, EnrichmentType enrichmentType, - MolecularProfile molecularProfile) { - - MolecularProfileSamples commaSeparatedSampleIdsOfMolecularProfile = molecularDataRepository - .getCommaSeparatedSampleIdsOfMolecularProfile(molecularProfile.getStableId()); - - List internalSampleIds = Arrays.stream(commaSeparatedSampleIdsOfMolecularProfile.getSplitSampleIds()) - .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); - - Map internalSampleIdToIndexMap = IntStream.range(0, internalSampleIds.size()).boxed() - .collect(Collectors.toMap(internalSampleIds::get, Function.identity())); - - Map> selectedCaseIdToInternalIdsMap = getCaseIdToInternalIdsMap(molecularProfileCaseSets, - enrichmentType, molecularProfile); - - // this block map caseIds(sampleIds or patientids) to sampleIndices which - // represents the position fount in the - // genetic_profile_samples.ORDERED_SAMPLE_LIST column - Map> groupIndicesMap = molecularProfileCaseSets.entrySet().stream() - .collect(Collectors.toMap(entity -> entity.getKey(), entity -> { - List sampleIndices = new ArrayList<>(); - entity.getValue().forEach(molecularProfileCaseIdentifier -> { - // consider only valid samples - if (selectedCaseIdToInternalIdsMap.containsKey(molecularProfileCaseIdentifier.getCaseId())) { - List sampleInternalIds = selectedCaseIdToInternalIdsMap - .get(molecularProfileCaseIdentifier.getCaseId()); - - // only consider samples which are profiled for the give molecular profile id - sampleInternalIds.forEach(sampleInternalId -> { - if (internalSampleIdToIndexMap.containsKey(sampleInternalId)) { - sampleIndices.add(internalSampleIdToIndexMap.get(sampleInternalId)); - } - }); - } - }); - return sampleIndices; - })); - return groupIndicesMap; - } - - private Map> getCaseIdToInternalIdsMap( - Map> molecularProfileCaseSets, EnrichmentType enrichmentType, - MolecularProfile molecularProfile) { - - if (enrichmentType.equals(EnrichmentType.PATIENT)) { - List patientIds = molecularProfileCaseSets.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getCaseId)) - .collect(Collectors.toList()); - - List samples = sampleService - .getAllSamplesOfPatientsInStudy(molecularProfile.getCancerStudyIdentifier(), patientIds, "SUMMARY"); - - return samples.stream().collect(Collectors.groupingBy(Sample::getPatientStableId, - Collectors.mapping(Sample::getInternalId, Collectors.toList()))); - } else { - List sampleIds = new ArrayList<>(); - List studyIds = new ArrayList<>(); - - molecularProfileCaseSets.values().forEach(molecularProfileCaseIdentifiers -> { - molecularProfileCaseIdentifiers.forEach(molecularProfileCaseIdentifier -> { - sampleIds.add(molecularProfileCaseIdentifier.getCaseId()); - studyIds.add(molecularProfile.getCancerStudyIdentifier()); - }); - }); - List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - - return samples.stream() - .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); - } - } - -} +} \ No newline at end of file diff --git a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java index 4584341e2e2..150fb370178 100644 --- a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java +++ b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java @@ -88,7 +88,7 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { } } return p; - } + } public BigDecimal[] calcqValue(BigDecimal[] pValuesInIncreasingOrder) { BigDecimal cachedElement = BigDecimal.valueOf(0.0); int dataLength = pValuesInIncreasingOrder.length; @@ -120,6 +120,5 @@ private void reverseValues(int dataLength, BigDecimal[] reversedQValues) { reversedQValues[i] = reversedQValues[dataLength - i - 1]; reversedQValues[dataLength - i - 1] = temp; } - } } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java deleted file mode 100644 index f7f423f6cda..00000000000 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.cbioportal.service.impl; - -import org.cbioportal.model.*; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GeneService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.MolecularProfileService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.cbioportal.service.util.FisherExactTestCalculator; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import java.math.BigDecimal; -import java.util.*; - -import static org.junit.Assert.*; - - -@RunWith(MockitoJUnitRunner.class) -public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ - - @InjectMocks - private GenericAssayBinaryDataServiceImpl genericAssayBinaryDataServiceImpl; - @Mock - private SampleService sampleService; - @Mock - private MolecularProfileService molecularProfileService; - @Mock - private MolecularDataRepository molecularDataRepository; - - @Spy - @InjectMocks - private ExpressionEnrichmentUtil expressionEnrichmentUtil; - @Mock - private GenericAssayService genericAssayService; - - CancerStudy cancerStudy = new CancerStudy(); - MolecularProfile geneMolecularProfile = new MolecularProfile(); - MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); - List samples = new ArrayList<>(); - Map> molecularProfileCaseSets = new HashMap<>(); - Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); - private FisherExactTestCalculator fisherExactTestCalculator; - - // patient level only data - public static final String SAMPLE_ID5 = "sample_id5"; - - - @Before - public void setup() throws MolecularProfileNotFoundException { - cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); - cancerStudy.setCancerStudyIdentifier(STUDY_ID); - - geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); - geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); - - geneMolecularProfile.setCancerStudy(cancerStudy); - - molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); - molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); - - Sample sample1 = new Sample(); - sample1.setStableId(SAMPLE_ID1); - sample1.setInternalId(1); - sample1.setCancerStudyIdentifier(STUDY_ID); - sample1.setPatientId(1); - samples.add(sample1); - Sample sample2 = new Sample(); - sample2.setStableId(SAMPLE_ID2); - sample2.setInternalId(2); - sample2.setCancerStudyIdentifier(STUDY_ID); - sample2.setPatientId(2); - samples.add(sample2); - Sample sample3 = new Sample(); - sample3.setStableId(SAMPLE_ID3); - sample3.setInternalId(3); - sample3.setCancerStudyIdentifier(STUDY_ID); - sample3.setPatientId(3); - samples.add(sample3); - Sample sample4 = new Sample(); - sample4.setStableId(SAMPLE_ID4); - sample4.setInternalId(4); - sample4.setCancerStudyIdentifier(STUDY_ID); - sample4.setPatientId(4); - samples.add(sample4); - - List alteredSampleIdentifieres = new ArrayList<>(); - List unalteredSampleIdentifieres = new ArrayList<>(); - List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); - - MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); - caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier1.setCaseId(SAMPLE_ID1); - alteredSampleIdentifieres.add(caseIdentifier1); - - MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); - caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier2.setCaseId(SAMPLE_ID2); - alteredSampleIdentifieres.add(caseIdentifier2); - - MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); - caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier3.setCaseId(SAMPLE_ID3); - unalteredSampleIdentifieres.add(caseIdentifier3); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); - - MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); - caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier4.setCaseId(SAMPLE_ID4); - unalteredSampleIdentifieres.add(caseIdentifier4); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); - - // patient level only data - MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); - caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier5.setCaseId(SAMPLE_ID5); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); - - molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); - - Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(geneMolecularProfile); - - Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(molecularProfileSamples); - - Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), - Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); - } - - @Test - public void getGenericAssayBinaryEnrichments() throws Exception { - geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); - - List molecularDataList = new ArrayList(); - GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); - - // here are 2 groups - genericAssayMolecularAlteration1.setValues("true,true,true,false"); - molecularDataList.add(genericAssayMolecularAlteration1); - - GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); - genericAssayMolecularAlteration2.setValues("true,false,false,true"); - molecularDataList.add(genericAssayMolecularAlteration2); - Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, - "SUMMARY")).thenReturn(molecularDataList); - - Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( - Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), - Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) - .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), - new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - - List result = genericAssayBinaryDataServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, - molecularProfileCaseSets, EnrichmentType.SAMPLE); - - Assert.assertEquals(2, result.size()); - GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = result.get(0); - Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayBinaryEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); - - GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); - - GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("1.0"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.0"), alteredGroupStats.getStandardDeviation()); - - Assert.assertEquals(new BigDecimal("0.49999999999999983"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.99999999999999966"), genericAssayBinaryEnrichment.getqValue()); - - genericAssayBinaryEnrichment = result.get(1); - Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); - - unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); - - alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.7071067811865476"), alteredGroupStats.getStandardDeviation()); - - Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getqValue()); - } - - -} \ No newline at end of file diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java deleted file mode 100644 index 405641dfc92..00000000000 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java +++ /dev/null @@ -1,191 +0,0 @@ -package org.cbioportal.service.impl; - -import org.cbioportal.model.*; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GeneService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.MolecularProfileService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import java.math.BigDecimal; -import java.util.*; - -@RunWith(MockitoJUnitRunner.class) -public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplTest{ - @InjectMocks - private GenericAssayCategoricalDataServiceImpl genericAssayCategoricalDataServiceImpl; - @Mock - private SampleService sampleService; - @Mock - private MolecularProfileService molecularProfileService; - @Mock - private MolecularDataRepository molecularDataRepository; - - @Spy - @InjectMocks - private ExpressionEnrichmentUtil expressionEnrichmentUtil; - @Mock - private GenericAssayService genericAssayService; - - CancerStudy cancerStudy = new CancerStudy(); - MolecularProfile geneMolecularProfile = new MolecularProfile(); - MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); - List samples = new ArrayList<>(); - Map> molecularProfileCaseSets = new HashMap<>(); - Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); - // patient level only data - public static final String SAMPLE_ID5 = "sample_id5"; - - - @Before - public void setup() throws MolecularProfileNotFoundException { - cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); - cancerStudy.setCancerStudyIdentifier(STUDY_ID); - - geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); - geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); - - geneMolecularProfile.setCancerStudy(cancerStudy); - - molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); - molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); - - Sample sample1 = new Sample(); - sample1.setStableId(SAMPLE_ID1); - sample1.setInternalId(1); - sample1.setCancerStudyIdentifier(STUDY_ID); - sample1.setPatientId(1); - samples.add(sample1); - Sample sample2 = new Sample(); - sample2.setStableId(SAMPLE_ID2); - sample2.setInternalId(2); - sample2.setCancerStudyIdentifier(STUDY_ID); - sample2.setPatientId(2); - samples.add(sample2); - Sample sample3 = new Sample(); - sample3.setStableId(SAMPLE_ID3); - sample3.setInternalId(3); - sample3.setCancerStudyIdentifier(STUDY_ID); - sample3.setPatientId(3); - samples.add(sample3); - Sample sample4 = new Sample(); - sample4.setStableId(SAMPLE_ID4); - sample4.setInternalId(4); - sample4.setCancerStudyIdentifier(STUDY_ID); - sample4.setPatientId(4); - samples.add(sample4); - - List alteredSampleIdentifieres = new ArrayList<>(); - List unalteredSampleIdentifieres = new ArrayList<>(); - List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); - - MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); - caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier1.setCaseId(SAMPLE_ID1); - alteredSampleIdentifieres.add(caseIdentifier1); - - MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); - caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier2.setCaseId(SAMPLE_ID2); - alteredSampleIdentifieres.add(caseIdentifier2); - - MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); - caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier3.setCaseId(SAMPLE_ID3); - unalteredSampleIdentifieres.add(caseIdentifier3); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); - - MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); - caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier4.setCaseId(SAMPLE_ID4); - unalteredSampleIdentifieres.add(caseIdentifier4); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); - - // patient level only data - MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); - caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier5.setCaseId(SAMPLE_ID5); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); - - molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); - - Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(geneMolecularProfile); - - Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(molecularProfileSamples); - - Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), - Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); - } - - @Test - public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFoundException { - geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); - - List molecularDataList = new ArrayList(); - GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); - genericAssayMolecularAlteration1.setValues("category1,category1,category2,category2"); - molecularDataList.add(genericAssayMolecularAlteration1); - - GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); - genericAssayMolecularAlteration2.setValues("category2,category2,category1,category1"); - molecularDataList.add(genericAssayMolecularAlteration2); - Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, - "SUMMARY")).thenReturn(molecularDataList); - - Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( - Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), - Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) - .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), - new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - - List result = genericAssayCategoricalDataServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, - molecularProfileCaseSets, EnrichmentType.SAMPLE); - - Assert.assertEquals(2, result.size()); - GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = result.get(0); - Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayCategoricalEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); - - GroupStatistics unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - - GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); - - genericAssayCategoricalEnrichment = result.get(1); - Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); - - unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - - alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); - } - -} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java new file mode 100644 index 00000000000..5d16690163a --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -0,0 +1,74 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Binary Data", description = " ") +public class GenericAssayBinaryDataController { + @Autowired + private GenericAssayBinaryDataService genericAssayBinaryDataService; + + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java new file mode 100644 index 00000000000..976a8076c3b --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -0,0 +1,79 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.commons.lang3.StringUtils; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayData; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayCategoricalDataService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.GenericAssayNotFoundException; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.GenericAssayFilter; +import org.cbioportal.web.parameter.HeaderKeyConstants; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +import org.cbioportal.web.parameter.Projection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.*; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Categorical Data", description = " ") +public class GenericAssayCategoricalDataController { + + @Autowired + private GenericAssayCategoricalDataService genericAssayCategoricalDataService; + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} From e1166ea83b3f2ad8d9cb6c4c91f68532cd79a507 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 26 Jul 2023 14:17:22 -0400 Subject: [PATCH 06/40] finish tests --- .../GenericAssayBinaryDataServiceImpl.java | 1 - ...enericAssayCategoricalDataServiceImpl.java | 4 +-- .../web/GenericAssayBinaryDataController.java | 2 +- ...GenericAssayCategoricalDataController.java | 27 ++++++++++--------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index c02c725fbb0..38f208200af 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -34,7 +34,6 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData @Autowired private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); - @Autowired private ExpressionEnrichmentUtil expressionEnrichmentUtil; @Autowired diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index 9d6ab72ff84..c66650cdef4 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -46,7 +46,6 @@ public List getGenericAssayCategoricalEnrichm throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); Iterable maItr = molecularDataRepository @@ -57,8 +56,7 @@ public List getGenericAssayCategoricalEnrichm List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - - + Map sampleIdToPatientIdMap = samples.stream() .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java index 5d16690163a..60a7fddc58d 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -41,7 +41,7 @@ public class GenericAssayBinaryDataController { method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + public ResponseEntity> fetchGenericAssayBinaryDataEnrichmentInMultipleMolecularProfiles( @ApiIgnore @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java index 976a8076c3b..c3344ce94e9 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -4,10 +4,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayData; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.*; import org.cbioportal.service.GenericAssayCategoricalDataService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.SampleService; @@ -56,7 +53,13 @@ public ResponseEntity> fetchGenericAssay @ApiIgnore @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) throws MolecularProfileNotFoundException, UnsupportedOperationException { - + + return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), + HttpStatus.OK); + } + private List fetchExpressionEnrichments(EnrichmentType enrichmentType, + List interceptedMolecularProfileCasesGroupFilters + ) throws MolecularProfileNotFoundException { Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); @@ -65,15 +68,13 @@ public ResponseEntity> fetchGenericAssay .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) .collect(Collectors.toSet()); - + if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - - return new ResponseEntity<>( - genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), - HttpStatus.OK); + return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } - } + + From 93f4fc369600366521c43673423923670b4a13b5 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:04:39 -0400 Subject: [PATCH 07/40] modify controller file structure --- .../web/GenericAssayBinaryDataController.java | 74 ----------------- ...GenericAssayCategoricalDataController.java | 80 ------------------- 2 files changed, 154 deletions(-) delete mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java delete mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java deleted file mode 100644 index 60a7fddc58d..00000000000 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.cbioportal.web; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.GenericAssayBinaryDataService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; -import org.cbioportal.web.config.annotation.InternalApi; -import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; -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.*; -import springfox.documentation.annotations.ApiIgnore; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -@InternalApi -@RestController -@Validated -@Api(tags = "Generic Assay Binary Data", description = " ") -public class GenericAssayBinaryDataController { - @Autowired - private GenericAssayBinaryDataService genericAssayBinaryDataService; - - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", - method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayBinaryDataEnrichmentInMultipleMolecularProfiles( - @ApiIgnore - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") - @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, - @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") - @Valid @RequestBody(required = false) List groups, - @ApiIgnore - @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) - throws MolecularProfileNotFoundException, UnsupportedOperationException { - - Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters - .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, - MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); - - Set molecularProfileIds = groupCaseIdentifierSet.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) - .collect(Collectors.toSet()); - - if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); - } - - return new ResponseEntity<>( - genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), - HttpStatus.OK); - } - -} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java deleted file mode 100644 index c3344ce94e9..00000000000 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.cbioportal.web; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.*; -import org.cbioportal.service.GenericAssayCategoricalDataService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.GenericAssayNotFoundException; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.web.config.annotation.InternalApi; -import org.cbioportal.web.parameter.GenericAssayFilter; -import org.cbioportal.web.parameter.HeaderKeyConstants; -import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; -import org.cbioportal.web.parameter.Projection; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -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.*; -import springfox.documentation.annotations.ApiIgnore; - -import javax.validation.Valid; -import java.util.*; -import java.util.stream.Collectors; - -@InternalApi -@RestController -@Validated -@Api(tags = "Generic Assay Categorical Data", description = " ") -public class GenericAssayCategoricalDataController { - - @Autowired - private GenericAssayCategoricalDataService genericAssayCategoricalDataService; - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", - method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( - @ApiIgnore - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") - @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, - @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") - @Valid @RequestBody(required = false) List groups, - @ApiIgnore - @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) - throws MolecularProfileNotFoundException, UnsupportedOperationException { - - return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), - HttpStatus.OK); - } - private List fetchExpressionEnrichments(EnrichmentType enrichmentType, - List interceptedMolecularProfileCasesGroupFilters - ) throws MolecularProfileNotFoundException { - Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters - .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, - MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); - - Set molecularProfileIds = groupCaseIdentifierSet.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) - .collect(Collectors.toSet()); - - if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); - } - return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); - } -} - - From 0ab23a682dbf633593e9c6043e32dacd66a5c738 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:19:31 -0400 Subject: [PATCH 08/40] refactor some variables --- .../service/impl/GenericAssayBinaryDataServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 38f208200af..4a6e820e8a8 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -89,8 +89,7 @@ public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment }); // Extract pValues and calculate qValues. - BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); - + BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(GenericAssayBinaryEnrichment ::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); // Assign qValues back to the objects. From 7b94ec3c3adc1ae4cbd68047c2f691df12b414f8 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 00:13:11 -0400 Subject: [PATCH 09/40] modify enrichment compare and validate issue --- .../org/cbioportal/model/ExpressionEnrichment.java | 2 +- .../model/GenericAssayCategoricalEnrichment.java | 2 +- .../cbioportal/model/GenericAssayEnrichment.java | 5 ++++- .../impl/GenericAssayBinaryDataServiceImpl.java | 13 +++++-------- .../GenericAssayCategoricalDataServiceImpl.java | 10 ++++------ 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java index 57e6df2a5db..40ee2d11107 100644 --- a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java @@ -6,7 +6,7 @@ import javax.validation.constraints.NotNull; -public class ExpressionEnrichment implements Serializable { +public abstract class ExpressionEnrichment implements Serializable { @NotNull private List groupsStatistics; diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java index 1632f3718c4..2fdb661cf38 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java @@ -2,7 +2,6 @@ import javax.validation.constraints.NotNull; import java.math.BigDecimal; -import java.util.Comparator; public class GenericAssayCategoricalEnrichment extends GenericAssayEnrichment { @NotNull @@ -15,4 +14,5 @@ public BigDecimal getqValue() { public void setqValue(BigDecimal qValue) { this.qValue = qValue; } + } diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java index 8278694f9be..371032595cf 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java @@ -5,7 +5,7 @@ import javax.validation.constraints.NotNull; -public class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { +public abstract class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { @NotNull private String stableId; @@ -38,4 +38,7 @@ public void setGenericEntityMetaProperties(HashMap genericEntity this.genericEntityMetaProperties = genericEntityMetaProperties; } + public static int compare(GenericAssayEnrichment c1, GenericAssayEnrichment c2) { + return c1.getpValue().compareTo(c2.getpValue()); + } } diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 4a6e820e8a8..73566b87561 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -80,14 +80,7 @@ public List getGenericAssayBinaryEnrichments( List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); - // Sort the list based on pValue. - Collections.sort(genericAssayBinaryEnrichments, new Comparator() { - @Override - public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment c2) { - return c1.getpValue().compareTo(c2.getpValue()); - } - }); - + Collections.sort(genericAssayBinaryEnrichments, GenericAssayEnrichment::compare); // Extract pValues and calculate qValues. BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(GenericAssayBinaryEnrichment ::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); @@ -121,6 +114,10 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } + System.out.println(molecularProfile.getGenericAssayType()); + if(!molecularProfile.getGenericAssayType().equals("BINARY")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } } } diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index c66650cdef4..cacaa1ca0cc 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -81,12 +81,7 @@ public List getGenericAssayCategoricalEnrichm filteredMolecularProfileCaseSets, enrichmentType, maItr); // Sort the list based on pValue. - Collections.sort(genericAssayCategoricalEnrichments, new Comparator() { - @Override - public int compare(GenericAssayCategoricalEnrichment c1, GenericAssayCategoricalEnrichment c2) { - return c1.getpValue().compareTo(c2.getpValue()); - } - }); + Collections.sort(genericAssayCategoricalEnrichments, GenericAssayEnrichment::compare); // Extract pValues and calculate qValues. BigDecimal[] pValues = genericAssayCategoricalEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); @@ -119,6 +114,9 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } + if(!molecularProfile.getGenericAssayType().equals("CATEGORICAL")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } } } From 63e9f994c63fa7c74d2e8c64d0ca752b614bc951 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:44:33 -0400 Subject: [PATCH 10/40] refactor the controllers and services --- .../model/GenericAssayBinaryEnrichment.java | 11 +- .../model/GenericAssayEnrichment.java | 12 +- .../GenericAssayCategoricalDataService.java | 16 -- ...ava => GenericAssayEnrichmentService.java} | 7 +- ...enericAssayCategoricalDataServiceImpl.java | 122 ---------------- ...=> GenericAssayEnrichmentServiceImpl.java} | 137 ++++++++++++------ ...GenericAssayEnrichmentServiceImplTest.java | 4 + .../web/GenericAssayEnrichmentController.java | 12 +- 8 files changed, 117 insertions(+), 204 deletions(-) delete mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java rename service/src/main/java/org/cbioportal/service/{GenericAssayBinaryDataService.java => GenericAssayEnrichmentService.java} (52%) delete mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java rename service/src/main/java/org/cbioportal/service/impl/{GenericAssayBinaryDataServiceImpl.java => GenericAssayEnrichmentServiceImpl.java} (51%) create mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java index f16a7015db6..f7ccbc7c3b5 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java @@ -7,8 +7,6 @@ public class GenericAssayBinaryEnrichment extends GenericAssayEnrichment { @NotNull private List counts; - @NotNull - private BigDecimal qValue; public List getCounts() { return counts; @@ -17,12 +15,5 @@ public List getCounts() { public void setCounts(List counts) { this.counts = counts; } - - public BigDecimal getqValue() { - return qValue; - } - - public void setqValue(BigDecimal qValue) { - this.qValue = qValue; - } + } diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java index 371032595cf..074aa8926d9 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java @@ -1,16 +1,19 @@ package org.cbioportal.model; import java.io.Serializable; +import java.math.BigDecimal; import java.util.HashMap; import javax.validation.constraints.NotNull; -public abstract class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { +public class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { @NotNull private String stableId; @NotNull private String name; + @NotNull + private BigDecimal qValue; @NotNull private HashMap genericEntityMetaProperties; @@ -41,4 +44,11 @@ public void setGenericEntityMetaProperties(HashMap genericEntity public static int compare(GenericAssayEnrichment c1, GenericAssayEnrichment c2) { return c1.getpValue().compareTo(c2.getpValue()); } + public BigDecimal getqValue() { + return qValue; + } + + public void setqValue(BigDecimal qValue) { + this.qValue = qValue; + } } diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java deleted file mode 100644 index ceace7ff351..00000000000 --- a/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.cbioportal.service; - -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import java.util.List; -import java.util.Map; - -public interface GenericAssayCategoricalDataService { - List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, - EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException; - -} diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java similarity index 52% rename from service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java rename to service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java index 91d6f4df92c..80451d6e7e9 100644 --- a/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java +++ b/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java @@ -2,17 +2,22 @@ import org.cbioportal.model.EnrichmentType; import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import java.util.List; import java.util.Map; -public interface GenericAssayBinaryDataService { +public interface GenericAssayEnrichmentService { List getGenericAssayBinaryEnrichments( String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; + List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; } diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java deleted file mode 100644 index cacaa1ca0cc..00000000000 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.cbioportal.service.impl; - -import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.*; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.persistence.GenericAssayRepository; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.persistence.SampleListRepository; -import org.cbioportal.service.*; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.cbioportal.service.util.FisherExactTestCalculator; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -@Service -public class GenericAssayCategoricalDataServiceImpl implements GenericAssayCategoricalDataService { - - @Autowired - private MolecularDataRepository molecularDataRepository; - - @Autowired - private SampleService sampleService; - - @Autowired - private MolecularProfileService molecularProfileService; - - @Autowired - private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); - - @Autowired - private ExpressionEnrichmentUtil expressionEnrichmentUtil = new ExpressionEnrichmentUtil(); - @Autowired - private GenericAssayService genericAssayService; - - @Override - @Transactional(readOnly = true) - public List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - - MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); - - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - - Map> filteredMolecularProfileCaseSets; - if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { - List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); - List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); - List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - - Map sampleIdToPatientIdMap = samples.stream() - .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) - .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); - - filteredMolecularProfileCaseSets = new HashMap<>(); - for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { - Set patientSet = new HashSet(); - List identifierListUniqueByPatientId = new ArrayList<>(); - for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { - if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { - identifierListUniqueByPatientId.add(caseIdentifier); - patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); - } - } - filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); - } - } else { - filteredMolecularProfileCaseSets = molecularProfileCaseSets; - } - - List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); - - // Sort the list based on pValue. - Collections.sort(genericAssayCategoricalEnrichments, GenericAssayEnrichment::compare); - - // Extract pValues and calculate qValues. - BigDecimal[] pValues = genericAssayCategoricalEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); - BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - - // Assign qValues back to the objects. - for (int i = 0; i < genericAssayCategoricalEnrichments.size(); i++) { - genericAssayCategoricalEnrichments.get(i).setqValue(qValues[i]); - } - - List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - - Map genericAssayMetaByStableId = genericAssayService - .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, - getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) - .collect(Collectors.toList()), - "SUMMARY") - .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); - - return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - } - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - if(!molecularProfile.getGenericAssayType().equals("CATEGORICAL")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } - -} diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java similarity index 51% rename from service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java rename to service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index 73566b87561..336519ab893 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -4,7 +4,7 @@ import org.cbioportal.model.*; import org.cbioportal.model.meta.GenericAssayMeta; import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.GenericAssayEnrichmentService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.MolecularProfileService; import org.cbioportal.service.SampleService; @@ -19,8 +19,9 @@ import java.util.function.Function; import java.util.stream.Collectors; + @Service -public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryDataService { +public class GenericAssayEnrichmentServiceImpl implements GenericAssayEnrichmentService { @Autowired private MolecularDataRepository molecularDataRepository; @@ -43,25 +44,95 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData @Transactional(readOnly = true) public List getGenericAssayBinaryEnrichments( String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { - MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + + filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); + calcQValues(genericAssayBinaryEnrichments); + + List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + + } + + @Override + @Transactional(readOnly = true) + public List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); Map> filteredMolecularProfileCaseSets; - + filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + calcQValues(genericAssayCategoricalEnrichments); + + List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); + return molecularProfile; + } + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes, boolean isBinary) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + if(isBinary) { + if(!molecularProfile.getDatatype().equals("BINARY")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } else { + if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + } + + private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); - filteredMolecularProfileCaseSets = new HashMap<>(); + Map> filteredMolecularProfileCaseSets = new HashMap<>(); for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { Set patientSet = new HashSet(); List identifierListUniqueByPatientId = new ArrayList<>(); @@ -73,51 +144,25 @@ public List getGenericAssayBinaryEnrichments( } filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); } + return filteredMolecularProfileCaseSets; } else { - filteredMolecularProfileCaseSets = molecularProfileCaseSets; + return molecularProfileCaseSets; } + } - List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); + private Map getGenericAssayMetaByStableId(List stableIds, String molecularProfileId) { + return genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds(stableIds, stableIds.stream().map(sid -> molecularProfileId) + .collect(Collectors.toList()), "SUMMARY").stream() + .collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + } - Collections.sort(genericAssayBinaryEnrichments, GenericAssayEnrichment::compare); - // Extract pValues and calculate qValues. - BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(GenericAssayBinaryEnrichment ::getpValue).toArray(BigDecimal[]::new); + private void calcQValues(List enrichments) { + Collections.sort(enrichments, GenericAssayEnrichment::compare); + BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - // Assign qValues back to the objects. - for (int i = 0; i < genericAssayBinaryEnrichments.size(); i++) { - genericAssayBinaryEnrichments.get(i).setqValue(qValues[i]); - } - - List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - - Map genericAssayMetaByStableId = genericAssayService - .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, - getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) - .collect(Collectors.toList()), - "SUMMARY") - .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); - - return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - - } - - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - System.out.println(molecularProfile.getGenericAssayType()); - if(!molecularProfile.getGenericAssayType().equals("BINARY")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + for (int i = 0; i < enrichments.size(); i++) { + enrichments.get(i).setqValue(qValues[i]); } } - } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java new file mode 100644 index 00000000000..e0f6127b3a1 --- /dev/null +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java @@ -0,0 +1,4 @@ +package org.cbioportal.service.impl; + +public class GenericAssayEnrichmentServiceImplTest { +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java index bac54097958..569996ddcf1 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java @@ -7,10 +7,8 @@ import org.cbioportal.model.GenericAssayBinaryEnrichment; import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.GenericAssayBinaryDataService; -import org.cbioportal.service.GenericAssayCategoricalDataService; +import org.cbioportal.service.GenericAssayEnrichmentService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; import org.cbioportal.web.config.annotation.InternalApi; import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; import org.springframework.beans.factory.annotation.Autowired; @@ -35,9 +33,7 @@ @Api(tags = "Generic Assay Enrichment Data", description = " ") public class GenericAssayEnrichmentController { @Autowired - private GenericAssayCategoricalDataService genericAssayCategoricalDataService; - @Autowired - private GenericAssayBinaryDataService genericAssayBinaryDataService; + private GenericAssayEnrichmentService genericAssayEnrichmentService; @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") @RequestMapping(value = "/generic-assay-categorical-enrichments/fetch", @@ -89,7 +85,7 @@ public ResponseEntity> fetchGenericAssayBinar } return new ResponseEntity<>( - genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( + genericAssayEnrichmentService.getGenericAssayBinaryEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), HttpStatus.OK); } @@ -109,7 +105,7 @@ private List fetchExpressionEnrichments(Enric if (molecularProfileIds.size() > 1) { throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + return genericAssayEnrichmentService.getGenericAssayCategoricalEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } } From aa229fcea20e3e2f687a6f4d8f265b28821b5fe3 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 13:32:00 -0400 Subject: [PATCH 11/40] refactor test --- ...GenericAssayEnrichmentServiceImplTest.java | 259 +++++++++++++++++- 1 file changed, 258 insertions(+), 1 deletion(-) diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java index e0f6127b3a1..b92b629caee 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java @@ -1,4 +1,261 @@ package org.cbioportal.service.impl; -public class GenericAssayEnrichmentServiceImplTest { +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import java.math.BigDecimal; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + + +@RunWith(MockitoJUnitRunner.class) +public class GenericAssayEnrichmentServiceImplTest extends BaseServiceImplTest{ + @InjectMocks + private GenericAssayEnrichmentServiceImpl genericAssayEnrichmentServiceImpl; + @Mock + private SampleService sampleService; + @Mock + private MolecularProfileService molecularProfileService; + @Mock + private MolecularDataRepository molecularDataRepository; + + @Mock + private GenericAssayService genericAssayService; + + @Spy + @InjectMocks + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + + CancerStudy cancerStudy = new CancerStudy(); + MolecularProfile geneMolecularProfile = new MolecularProfile(); + MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); + List samples = new ArrayList<>(); + Map> molecularProfileCaseSets = new HashMap<>(); + Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + // patient level only data + public static final String SAMPLE_ID5 = "sample_id5"; + + + @Before + public void setup() throws MolecularProfileNotFoundException { + cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); + cancerStudy.setCancerStudyIdentifier(STUDY_ID); + + geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); + geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); + + geneMolecularProfile.setCancerStudy(cancerStudy); + + molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); + molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); + + Sample sample1 = new Sample(); + sample1.setStableId(SAMPLE_ID1); + sample1.setInternalId(1); + sample1.setCancerStudyIdentifier(STUDY_ID); + sample1.setPatientId(1); + samples.add(sample1); + Sample sample2 = new Sample(); + sample2.setStableId(SAMPLE_ID2); + sample2.setInternalId(2); + sample2.setCancerStudyIdentifier(STUDY_ID); + sample2.setPatientId(2); + samples.add(sample2); + Sample sample3 = new Sample(); + sample3.setStableId(SAMPLE_ID3); + sample3.setInternalId(3); + sample3.setCancerStudyIdentifier(STUDY_ID); + sample3.setPatientId(3); + samples.add(sample3); + Sample sample4 = new Sample(); + sample4.setStableId(SAMPLE_ID4); + sample4.setInternalId(4); + sample4.setCancerStudyIdentifier(STUDY_ID); + sample4.setPatientId(4); + samples.add(sample4); + + List alteredSampleIdentifieres = new ArrayList<>(); + List unalteredSampleIdentifieres = new ArrayList<>(); + List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); + + MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); + caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier1.setCaseId(SAMPLE_ID1); + alteredSampleIdentifieres.add(caseIdentifier1); + + MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); + caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier2.setCaseId(SAMPLE_ID2); + alteredSampleIdentifieres.add(caseIdentifier2); + + MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); + caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier3.setCaseId(SAMPLE_ID3); + unalteredSampleIdentifieres.add(caseIdentifier3); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); + + MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); + caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier4.setCaseId(SAMPLE_ID4); + unalteredSampleIdentifieres.add(caseIdentifier4); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); + + // patient level only data + MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); + caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier5.setCaseId(SAMPLE_ID5); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); + + molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); + + Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(geneMolecularProfile); + + Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfileSamples); + + Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), + Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); + } + + @Test + public void getGenericAssayBinaryEnrichments() throws Exception { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + geneMolecularProfile.setDatatype("BINARY"); + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + + // here are 2 groups + genericAssayMolecularAlteration1.setValues("true,true,true,false"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("true,false,false,true"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayEnrichmentServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); + + GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("1.0"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.0"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("0.49999999999999983"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.99999999999999966"), genericAssayBinaryEnrichment.getqValue()); + + genericAssayBinaryEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); + + alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getqValue()); + } + + + @Test + public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFoundException { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + geneMolecularProfile.setDatatype("CATEGORICAL"); + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + genericAssayMolecularAlteration1.setValues("category1,category1,category2,category2"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("category2,category2,category1,category1"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayEnrichmentServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); + + genericAssayCategoricalEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); + } + } From 8569262b431b480169446714f734cfaa9f1a2a41 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:03:53 -0400 Subject: [PATCH 12/40] Update GenericAssayEnrichmentServiceImpl.java --- .../service/impl/GenericAssayEnrichmentServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index 336519ab893..a8bceceae2d 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -110,7 +110,8 @@ private MolecularProfile getAndValidateMolecularProfile(String molecularProfileI } private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes, boolean isBinary) throws MolecularProfileNotFoundException { + List validMolecularAlterationTypes, + boolean isBinary) throws MolecularProfileNotFoundException { if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } From 34635ec82174f30878f602bfa8be94546168e85f Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 10:46:11 -0400 Subject: [PATCH 13/40] fixed simplification issues --- .../main/java/org/cbioportal/model/ExpressionEnrichment.java | 2 +- .../service/impl/GenericAssayEnrichmentServiceImpl.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java index 40ee2d11107..57e6df2a5db 100644 --- a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java @@ -6,7 +6,7 @@ import javax.validation.constraints.NotNull; -public abstract class ExpressionEnrichment implements Serializable { +public class ExpressionEnrichment implements Serializable { @NotNull private List groupsStatistics; diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index a8bceceae2d..d49876b0dbc 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -51,9 +51,7 @@ public List getGenericAssayBinaryEnrichments( Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - Map> filteredMolecularProfileCaseSets; - - filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); From 36a28428f9c79f79d1ee2b6e8ee115fb6cf1ed6f Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 11:05:28 -0400 Subject: [PATCH 14/40] add inline comments --- .../impl/GenericAssayEnrichmentServiceImpl.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index d49876b0dbc..948f54df1cf 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -47,28 +47,36 @@ public List getGenericAssayBinaryEnrichments( Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { + // Validate and fetch molecular profile MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + + // Get the molecular alterations for the provided profile Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + // Filter the case sets based on molecular profile Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + // Obtain binary enrichments from the utility List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); + // Calculate q-values for enrichments calcQValues(genericAssayBinaryEnrichments); + // Extract stable IDs from binary enrichments List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + // Fetch metadata of generic assays by their stable IDs Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + // Assign meta properties to each enrichment return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { enrichmentDatum.setGenericEntityMetaProperties( genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); return enrichmentDatum; }).collect(Collectors.toList()); - } @Override @@ -111,8 +119,10 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, List validMolecularAlterationTypes, boolean isBinary) throws MolecularProfileNotFoundException { if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + // Check alteration type throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } + // Check datatype for binary or categorical if(isBinary) { if(!molecularProfile.getDatatype().equals("BINARY")) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); @@ -126,6 +136,8 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + // If patient level, filter duplicates by patient id + // For now we only support sample level for samples List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); @@ -156,10 +168,11 @@ private Map getGenericAssayMetaByStableId(List } private void calcQValues(List enrichments) { + // Sort enrichments by pValue Collections.sort(enrichments, GenericAssayEnrichment::compare); BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - + // Assign q-values to enrichments for (int i = 0; i < enrichments.size(); i++) { enrichments.get(i).setqValue(qValues[i]); } From fa6e739560cd9d3fd85d84baf869aa17d1a17788 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 11:28:01 -0400 Subject: [PATCH 15/40] modify import --- .../service/impl/GenericAssayEnrichmentServiceImpl.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index 948f54df1cf..424ae1a44ef 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -1,8 +1,15 @@ package org.cbioportal.service.impl; import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.*; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.GenericAssayMolecularAlteration; +import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.Sample; +import org.cbioportal.model.GenericAssayEnrichment; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.GenericAssayEnrichmentService; import org.cbioportal.service.GenericAssayService; From 46344b02e2d26302d57249f95b10889558dd49ad Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 13:40:38 -0400 Subject: [PATCH 16/40] solve core test issue --- .../service/ExpressionEnrichmentService.java | 17 +- .../impl/ExpressionEnrichmentServiceImpl.java | 154 ++++++++++++++++-- .../web/GenericAssayEnrichmentController.java | 8 +- 3 files changed, 163 insertions(+), 16 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java index ae602d46b35..04295d959b8 100644 --- a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java +++ b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java @@ -3,20 +3,33 @@ import java.util.List; import java.util.Map; -import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.GenericAssayEnrichment; import org.cbioportal.model.GenomicEnrichment; +import org.cbioportal.model.EnrichmentType; + import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.service.exception.MolecularProfileNotFoundException; public interface ExpressionEnrichmentService { List getGenomicEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; List getGenericAssayEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; + List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; + + List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; } diff --git a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java index fb8fe8ef62a..aeb5f65818e 100644 --- a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java @@ -1,19 +1,12 @@ package org.cbioportal.service.impl; +import java.math.BigDecimal; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.Gene; -import org.cbioportal.model.GeneMolecularAlteration; -import org.cbioportal.model.GenericAssayEnrichment; -import org.cbioportal.model.GenericAssayMolecularAlteration; -import org.cbioportal.model.GenomicEnrichment; -import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.*; import org.cbioportal.model.MolecularProfile.MolecularAlterationType; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.model.Sample; import org.cbioportal.model.meta.GenericAssayMeta; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.ExpressionEnrichmentService; @@ -23,6 +16,7 @@ import org.cbioportal.service.SampleService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -42,7 +36,8 @@ public class ExpressionEnrichmentServiceImpl implements ExpressionEnrichmentServ private GenericAssayService genericAssayService; @Autowired private SampleService sampleService; - + @Autowired + private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); @Override // transaction needs to be setup here in order to return Iterable from // molecularDataService in fetchCoExpressions @@ -152,4 +147,143 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, } } + + @Override + @Transactional(readOnly = true) + public List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + // Validate and fetch molecular profile + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + + // Get the molecular alterations for the provided profile + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + // Filter the case sets based on molecular profile + Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + // Obtain binary enrichments from the utility + List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + // Calculate q-values for enrichments + calcQValues(genericAssayBinaryEnrichments); + + // Extract stable IDs from binary enrichments + List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + // Fetch metadata of generic assays by their stable IDs + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + // Assign meta properties to each enrichment + return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + @Override + @Transactional(readOnly = true) + public List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); + + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + calcQValues(genericAssayCategoricalEnrichments); + + List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); + return molecularProfile; + } + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes, + boolean isBinary) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + // Check alteration type + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + // Check datatype for binary or categorical + if(isBinary) { + if(!molecularProfile.getDatatype().equals("BINARY")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } else { + if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + } + + private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { + if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + // If patient level, filter duplicates by patient id + // For now we only support sample level for samples + List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); + List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + Map> filteredMolecularProfileCaseSets = new HashMap<>(); + for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { + Set patientSet = new HashSet(); + List identifierListUniqueByPatientId = new ArrayList<>(); + for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { + if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { + identifierListUniqueByPatientId.add(caseIdentifier); + patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); + } + } + filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); + } + return filteredMolecularProfileCaseSets; + } else { + return molecularProfileCaseSets; + } + } + + private Map getGenericAssayMetaByStableId(List stableIds, String molecularProfileId) { + return genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds(stableIds, stableIds.stream().map(sid -> molecularProfileId) + .collect(Collectors.toList()), "SUMMARY").stream() + .collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + } + + private void calcQValues(List enrichments) { + // Sort enrichments by pValue + Collections.sort(enrichments, GenericAssayEnrichment::compare); + BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); + // Assign q-values to enrichments + for (int i = 0; i < enrichments.size(); i++) { + enrichments.get(i).setqValue(qValues[i]); + } + } + } diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java index 569996ddcf1..5e864bdbbd0 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java @@ -7,7 +7,7 @@ import org.cbioportal.model.GenericAssayBinaryEnrichment; import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.GenericAssayEnrichmentService; +import org.cbioportal.service.ExpressionEnrichmentService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.web.config.annotation.InternalApi; import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; @@ -33,7 +33,7 @@ @Api(tags = "Generic Assay Enrichment Data", description = " ") public class GenericAssayEnrichmentController { @Autowired - private GenericAssayEnrichmentService genericAssayEnrichmentService; + private ExpressionEnrichmentService expressionEnrichmentService; @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") @RequestMapping(value = "/generic-assay-categorical-enrichments/fetch", @@ -85,7 +85,7 @@ public ResponseEntity> fetchGenericAssayBinar } return new ResponseEntity<>( - genericAssayEnrichmentService.getGenericAssayBinaryEnrichments( + expressionEnrichmentService.getGenericAssayBinaryEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), HttpStatus.OK); } @@ -105,7 +105,7 @@ private List fetchExpressionEnrichments(Enric if (molecularProfileIds.size() > 1) { throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - return genericAssayEnrichmentService.getGenericAssayCategoricalEnrichments( + return expressionEnrichmentService.getGenericAssayCategoricalEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } } From 6bccdb96143f3a4f522b5a687f14c6df5505e2da Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Sun, 13 Aug 2023 16:53:16 -0400 Subject: [PATCH 17/40] test check --- .../service/ExpressionEnrichmentService.java | 2 +- .../GenericAssayEnrichmentService.java | 23 --- .../impl/ExpressionEnrichmentServiceImpl.java | 131 ++++++------ .../GenericAssayEnrichmentServiceImpl.java | 187 ------------------ .../ExpressionEnrichmentServiceImplTest.java | 6 +- ...GenericAssayEnrichmentServiceImplTest.java | 6 +- .../web/ExpressionEnrichmentController.java | 2 +- .../ExpressionEnrichmentControllerTest.java | 2 +- 8 files changed, 65 insertions(+), 294 deletions(-) delete mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java delete mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java diff --git a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java index 04295d959b8..51d28da2b77 100644 --- a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java +++ b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java @@ -18,7 +18,7 @@ List getGenomicEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; - List getGenericAssayEnrichments(String molecularProfileId, + List getGenericAssayNumericalEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; List getGenericAssayBinaryEnrichments( diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java b/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java deleted file mode 100644 index 80451d6e7e9..00000000000 --- a/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.cbioportal.service; - -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; - -import java.util.List; -import java.util.Map; - -public interface GenericAssayEnrichmentService { - List getGenericAssayBinaryEnrichments( - String molecularProfileId, - Map> molecularProfileCaseSets, - EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException; - - List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, - EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException; -} diff --git a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java index aeb5f65818e..94dc510ecca 100644 --- a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java @@ -5,9 +5,19 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.*; import org.cbioportal.model.MolecularProfile.MolecularAlterationType; import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.GenericAssayMolecularAlteration; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.Sample; +import org.cbioportal.model.GenericAssayEnrichment; +import org.cbioportal.model.GenomicEnrichment; +import org.cbioportal.model.Gene; +import org.cbioportal.model.GeneMolecularAlteration; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.ExpressionEnrichmentService; import org.cbioportal.service.GeneService; @@ -43,62 +53,49 @@ public class ExpressionEnrichmentServiceImpl implements ExpressionEnrichmentServ // molecularDataService in fetchCoExpressions @Transactional(readOnly = true) public List getGenomicEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - List validGenomicMolecularAlterationTypes = Arrays.asList( - MolecularAlterationType.MICRO_RNA_EXPRESSION, MolecularAlterationType.MRNA_EXPRESSION, - MolecularAlterationType.MRNA_EXPRESSION_NORMALS, MolecularAlterationType.RNA_EXPRESSION, - MolecularAlterationType.METHYLATION, MolecularAlterationType.METHYLATION_BINARY, - MolecularAlterationType.PHOSPHORYLATION, MolecularAlterationType.PROTEIN_LEVEL, - MolecularAlterationType.PROTEIN_ARRAY_PROTEIN_LEVEL, - MolecularAlterationType.PROTEIN_ARRAY_PHOSPHORYLATION); - + MolecularAlterationType.MICRO_RNA_EXPRESSION, MolecularAlterationType.MRNA_EXPRESSION, + MolecularAlterationType.MRNA_EXPRESSION_NORMALS, MolecularAlterationType.RNA_EXPRESSION, + MolecularAlterationType.METHYLATION, MolecularAlterationType.METHYLATION_BINARY, + MolecularAlterationType.PHOSPHORYLATION, MolecularAlterationType.PROTEIN_LEVEL, + MolecularAlterationType.PROTEIN_ARRAY_PROTEIN_LEVEL, + MolecularAlterationType.PROTEIN_ARRAY_PHOSPHORYLATION); validateMolecularProfile(molecularProfile, validGenomicMolecularAlterationTypes); - Iterable maItr = molecularDataRepository - .getGeneMolecularAlterationsIterableFast(molecularProfile.getStableId()); - + .getGeneMolecularAlterationsIterableFast(molecularProfile.getStableId()); List expressionEnrichments = expressionEnrichmentUtil.getEnrichments(molecularProfile, - molecularProfileCaseSets, enrichmentType, maItr); - + molecularProfileCaseSets, enrichmentType, maItr); List entrezGeneIds = expressionEnrichments.stream().map(GenomicEnrichment::getEntrezGeneId) - .collect(Collectors.toList()); - + .collect(Collectors.toList()); Map> geneMapByEntrezId = geneService - .fetchGenes(entrezGeneIds.stream().map(Object::toString).collect(Collectors.toList()), "ENTREZ_GENE_ID", - "SUMMARY") - .stream().collect(Collectors.groupingBy(Gene::getEntrezGeneId)); - + .fetchGenes(entrezGeneIds.stream().map(Object::toString).collect(Collectors.toList()), "ENTREZ_GENE_ID", + "SUMMARY") + .stream().collect(Collectors.groupingBy(Gene::getEntrezGeneId)); return expressionEnrichments.stream() - // filter Enrichments having no gene reference object(this - // happens when multiple - // entrez ids map to same hugo gene symbol) - .filter(expressionEnrichment -> geneMapByEntrezId.containsKey(expressionEnrichment.getEntrezGeneId())) - .map(expressionEnrichment -> { - Gene gene = geneMapByEntrezId.get(expressionEnrichment.getEntrezGeneId()).get(0); - expressionEnrichment.setHugoGeneSymbol(gene.getHugoGeneSymbol()); - return expressionEnrichment; - }).collect(Collectors.toList()); + // filter Enrichments having no gene reference object(this + // happens when multiple + // entrez ids map to same hugo gene symbol) + .filter(expressionEnrichment -> geneMapByEntrezId.containsKey(expressionEnrichment.getEntrezGeneId())) + .map(expressionEnrichment -> { + Gene gene = geneMapByEntrezId.get(expressionEnrichment.getEntrezGeneId()).get(0); + expressionEnrichment.setHugoGeneSymbol(gene.getHugoGeneSymbol()); + return expressionEnrichment; + }).collect(Collectors.toList()); } - @Override // transaction needs to be setup here in order to return Iterable from // molecularDataRepository in getGenericAssayMolecularAlterationsIterable @Transactional(readOnly = true) public List getGenericAssayEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularAlterationType.GENERIC_ASSAY)); - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); Map> filteredMolecularProfileCaseSets; if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { // Build sampleIdToPatientIdMap to quick find if a sample has shared patientId with other samples @@ -120,34 +117,25 @@ public List getGenericAssayEnrichments(String molecularP filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); } } else { - filteredMolecularProfileCaseSets = molecularProfileCaseSets; + filteredMolecularProfileCaseSets = molecularProfileCaseSets; } List genericAssayEnrichments = expressionEnrichmentUtil.getEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); + filteredMolecularProfileCaseSets, enrichmentType, maItr); List getGenericAssayStableIds = genericAssayEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); Map genericAssayMetaByStableId = genericAssayService - .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, - getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) - .collect(Collectors.toList()), - "SUMMARY") - .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, + getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) + .collect(Collectors.toList()), + "SUMMARY") + .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); return genericAssayEnrichments.stream().map(enrichmentDatum -> { enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); return enrichmentDatum; }).collect(Collectors.toList()); } - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } - - @Override @Transactional(readOnly = true) public List getGenericAssayBinaryEnrichments( @@ -156,7 +144,7 @@ public List getGenericAssayBinaryEnrichments( throws MolecularProfileNotFoundException { // Validate and fetch molecular profile - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, "BINARY"); // Get the molecular alterations for the provided profile Iterable maItr = molecularDataRepository @@ -193,13 +181,12 @@ public List getGenericAssayCategoricalEnrichm Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, "CATEGORICAL"); Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - Map> filteredMolecularProfileCaseSets; - filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); @@ -216,30 +203,24 @@ public List getGenericAssayCategoricalEnrichm return enrichmentDatum; }).collect(Collectors.toList()); } - - private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { + + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, String dataType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), dataType); return molecularProfile; } private void validateMolecularProfile(MolecularProfile molecularProfile, List validMolecularAlterationTypes, - boolean isBinary) throws MolecularProfileNotFoundException { + String dataType) throws MolecularProfileNotFoundException { if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { // Check alteration type throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } // Check datatype for binary or categorical - if(isBinary) { - if(!molecularProfile.getDatatype().equals("BINARY")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } else { - if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } + if(molecularProfile.getMolecularAlterationType().equals(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY) && + !molecularProfile.getDatatype().equals(dataType)) + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java deleted file mode 100644 index 424ae1a44ef..00000000000 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ /dev/null @@ -1,187 +0,0 @@ -package org.cbioportal.service.impl; - -import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.GenericAssayMolecularAlteration; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.model.MolecularProfile; -import org.cbioportal.model.Sample; -import org.cbioportal.model.GenericAssayEnrichment; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GenericAssayEnrichmentService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.MolecularProfileService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.cbioportal.service.util.FisherExactTestCalculator; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.math.BigDecimal; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - - -@Service -public class GenericAssayEnrichmentServiceImpl implements GenericAssayEnrichmentService { - - @Autowired - private MolecularDataRepository molecularDataRepository; - - @Autowired - private SampleService sampleService; - - @Autowired - private MolecularProfileService molecularProfileService; - - @Autowired - private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); - - @Autowired - private ExpressionEnrichmentUtil expressionEnrichmentUtil; - @Autowired - private GenericAssayService genericAssayService; - - @Override - @Transactional(readOnly = true) - public List getGenericAssayBinaryEnrichments( - String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - - // Validate and fetch molecular profile - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); - - // Get the molecular alterations for the provided profile - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - - // Filter the case sets based on molecular profile - Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); - - // Obtain binary enrichments from the utility - List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); - - // Calculate q-values for enrichments - calcQValues(genericAssayBinaryEnrichments); - - // Extract stable IDs from binary enrichments - List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - - // Fetch metadata of generic assays by their stable IDs - Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); - - // Assign meta properties to each enrichment - return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - } - - @Override - @Transactional(readOnly = true) - public List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); - - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - - Map> filteredMolecularProfileCaseSets; - filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); - - List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); - - calcQValues(genericAssayCategoricalEnrichments); - - List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); - - return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - } - - private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { - MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); - return molecularProfile; - } - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes, - boolean isBinary) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - // Check alteration type - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - // Check datatype for binary or categorical - if(isBinary) { - if(!molecularProfile.getDatatype().equals("BINARY")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } else { - if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } - } - - private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { - if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { - // If patient level, filter duplicates by patient id - // For now we only support sample level for samples - List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); - List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); - List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); - - Map> filteredMolecularProfileCaseSets = new HashMap<>(); - for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { - Set patientSet = new HashSet(); - List identifierListUniqueByPatientId = new ArrayList<>(); - for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { - if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { - identifierListUniqueByPatientId.add(caseIdentifier); - patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); - } - } - filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); - } - return filteredMolecularProfileCaseSets; - } else { - return molecularProfileCaseSets; - } - } - - private Map getGenericAssayMetaByStableId(List stableIds, String molecularProfileId) { - return genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds(stableIds, stableIds.stream().map(sid -> molecularProfileId) - .collect(Collectors.toList()), "SUMMARY").stream() - .collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); - } - - private void calcQValues(List enrichments) { - // Sort enrichments by pValue - Collections.sort(enrichments, GenericAssayEnrichment::compare); - BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); - BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - // Assign q-values to enrichments - for (int i = 0; i < enrichments.size(); i++) { - enrichments.get(i).setqValue(qValues[i]); - } - } -} diff --git a/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java index e4d1da579cf..a777176e26a 100644 --- a/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java @@ -207,7 +207,7 @@ public void getGenomicEnrichments() throws Exception { } @Test - public void getGenericAssayEnrichments() throws Exception { + public void getGenericAssayNumericalEnrichments() throws Exception { geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); List molecularDataList = new ArrayList(); @@ -229,7 +229,7 @@ public void getGenericAssayEnrichments() throws Exception { .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - List result = enrichmentServiceImpl.getGenericAssayEnrichments(MOLECULAR_PROFILE_ID, + List result = enrichmentServiceImpl.getGenericAssayNumericalEnrichments(MOLECULAR_PROFILE_ID, molecularProfileCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); @@ -301,7 +301,7 @@ public void getGenericAssayPatientLevelEnrichments() throws Exception { Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID5, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); - List result = enrichmentServiceImpl.getGenericAssayEnrichments(MOLECULAR_PROFILE_ID, molecularProfilePatientLevelCaseSets, EnrichmentType.SAMPLE); + List result = enrichmentServiceImpl.getGenericAssayNumericalEnrichments(MOLECULAR_PROFILE_ID, molecularProfilePatientLevelCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); GenericAssayEnrichment genericAssayEnrichment = result.get(0); diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java index b92b629caee..0adf6f5d556 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java @@ -29,7 +29,7 @@ @RunWith(MockitoJUnitRunner.class) public class GenericAssayEnrichmentServiceImplTest extends BaseServiceImplTest{ @InjectMocks - private GenericAssayEnrichmentServiceImpl genericAssayEnrichmentServiceImpl; + private ExpressionEnrichmentServiceImpl expressionEnrichmentServiceImpl; @Mock private SampleService sampleService; @Mock @@ -164,7 +164,7 @@ public void getGenericAssayBinaryEnrichments() throws Exception { .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - List result = genericAssayEnrichmentServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, + List result = expressionEnrichmentServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, molecularProfileCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); @@ -227,7 +227,7 @@ public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFo .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - List result = genericAssayEnrichmentServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, + List result = expressionEnrichmentServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, molecularProfileCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); diff --git a/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java b/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java index 0252463e558..4072480eb13 100644 --- a/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java +++ b/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java @@ -95,7 +95,7 @@ private List fetchExpressionEnrichments(Enri } if (isRequestForGenericAssayEnrichments) { - return (List) expressionEnrichmentService.getGenericAssayEnrichments( + return (List) expressionEnrichmentService.getGenericAssayNumericalEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } diff --git a/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java b/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java index 868b46cfa06..0abe4a9e3ca 100644 --- a/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java +++ b/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java @@ -186,7 +186,7 @@ public void fetchGenericAssayEnrichments() throws Exception { genericAssayEnrichment2.setpValue(TEST_P_VALUE_2); genericAssayEnrichments.add(genericAssayEnrichment2); - Mockito.when(expressionEnrichmentService.getGenericAssayEnrichments(Mockito.anyString(), Mockito.anyMap(), + Mockito.when(expressionEnrichmentService.getGenericAssayNumericalEnrichments(Mockito.anyString(), Mockito.anyMap(), Mockito.any(EnrichmentType.class))).thenReturn(genericAssayEnrichments); mockMvc.perform(MockMvcRequestBuilders.post("/generic-assay-enrichments/fetch") From b1420144361284ea024062c5f0b35bd96e9b3038 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Sun, 13 Aug 2023 18:04:37 -0400 Subject: [PATCH 18/40] modify expressionenrichment --- .../service/ExpressionEnrichmentService.java | 9 ++++----- .../service/impl/ExpressionEnrichmentServiceImpl.java | 11 ++++++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java index 51d28da2b77..d3c2a444bd8 100644 --- a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java +++ b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java @@ -3,19 +3,18 @@ import java.util.List; import java.util.Map; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.EnrichmentType; import org.cbioportal.model.GenericAssayEnrichment; import org.cbioportal.model.GenomicEnrichment; -import org.cbioportal.model.EnrichmentType; - import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.service.exception.MolecularProfileNotFoundException; public interface ExpressionEnrichmentService { List getGenomicEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; List getGenericAssayNumericalEnrichments(String molecularProfileId, diff --git a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java index 94dc510ecca..45eb9ae478e 100644 --- a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java @@ -89,7 +89,7 @@ public List getGenomicEnrichments(String molecularProfileId, // transaction needs to be setup here in order to return Iterable from // molecularDataRepository in getGenericAssayMolecularAlterationsIterable @Transactional(readOnly = true) - public List getGenericAssayEnrichments(String molecularProfileId, + public List getGenericAssayNumericalEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); @@ -203,7 +203,7 @@ public List getGenericAssayCategoricalEnrichm return enrichmentDatum; }).collect(Collectors.toList()); } - + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, String dataType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), dataType); @@ -266,5 +266,10 @@ private void calcQValues(List enrichments) enrichments.get(i).setqValue(qValues[i]); } } - + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } } From 732f24e0861891c1a446a2d0f5dc0ffa564c976f Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:54:41 -0400 Subject: [PATCH 19/40] modify imports --- .../util/ExpressionEnrichmentUtil.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index 71e7ef8e09d..79c4ace75a7 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -1,13 +1,31 @@ package org.cbioportal.service.util; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.List; import java.util.Map.Entry; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; -import io.swagger.models.auth.In; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.ExpressionEnrichment; +import org.cbioportal.model.GenericAssayEnrichment; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.GenericAssayMolecularAlteration; +import org.cbioportal.model.GenomicEnrichment; +import org.cbioportal.model.GroupStatistics; +import org.cbioportal.model.GenericAssayCountSummary; +import org.cbioportal.model.MolecularAlteration; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.MolecularProfileSamples; +import org.cbioportal.model.Sample; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.math3.stat.StatUtils; @@ -15,7 +33,6 @@ import org.apache.commons.math3.stat.inference.ChiSquareTest; import org.apache.commons.math3.stat.inference.OneWayAnova; import org.apache.commons.math3.stat.inference.TestUtils; -import org.cbioportal.model.*; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.SampleService; import org.springframework.beans.factory.annotation.Autowired; From 78ed82580ecf619700a4ed636126e1d5361a494a Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 28 Jun 2023 10:30:46 -0400 Subject: [PATCH 20/40] update backend --- .../model/GenericAssayBinaryEnrichment.java | 28 +++ .../GenericAssayCategoricalEnrichment.java | 18 ++ .../model/GenericAssayCountSummary.java | 38 ++++ .../GenericAssayBinaryDataService.java | 18 ++ .../GenericAssayCategoricalDataService.java | 16 ++ .../GenericAssayBinaryDataServiceImpl.java | 126 +++++++++++ ...enericAssayCategoricalDataServiceImpl.java | 121 ++++++++++ .../util/ExpressionEnrichmentUtil.java | 204 +++++++++++++++-- .../util/FisherExactTestCalculator.java | 45 +++- ...GenericAssayBinaryDataServiceImplTest.java | 207 ++++++++++++++++++ ...icAssayCategoricalDataServiceImplTest.java | 194 ++++++++++++++++ .../web/GenericAssayBinaryDataController.java | 74 +++++++ ...GenericAssayCategoricalDataController.java | 79 +++++++ 13 files changed, 1144 insertions(+), 24 deletions(-) create mode 100644 model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java create mode 100644 model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java create mode 100644 model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java create mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java create mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java create mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java create mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java create mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java create mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java new file mode 100644 index 00000000000..f16a7015db6 --- /dev/null +++ b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java @@ -0,0 +1,28 @@ +package org.cbioportal.model; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.List; + +public class GenericAssayBinaryEnrichment extends GenericAssayEnrichment { + @NotNull + private List counts; + @NotNull + private BigDecimal qValue; + + public List getCounts() { + return counts; + } + + public void setCounts(List counts) { + this.counts = counts; + } + + public BigDecimal getqValue() { + return qValue; + } + + public void setqValue(BigDecimal qValue) { + this.qValue = qValue; + } +} diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java new file mode 100644 index 00000000000..1632f3718c4 --- /dev/null +++ b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java @@ -0,0 +1,18 @@ +package org.cbioportal.model; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.Comparator; + +public class GenericAssayCategoricalEnrichment extends GenericAssayEnrichment { + @NotNull + private BigDecimal qValue; + + public BigDecimal getqValue() { + return qValue; + } + + public void setqValue(BigDecimal qValue) { + this.qValue = qValue; + } +} diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java b/model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java new file mode 100644 index 00000000000..2f24ed760ba --- /dev/null +++ b/model/src/main/java/org/cbioportal/model/GenericAssayCountSummary.java @@ -0,0 +1,38 @@ +package org.cbioportal.model; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +public class GenericAssayCountSummary implements Serializable { + + @NotNull + private String name; + @NotNull + private Integer count; + @NotNull + private Integer totalCount; + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getTotalCount() { + return totalCount; + } + + public void setTotalCount(Integer totalCount) { + this.totalCount = totalCount; + } +} diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java new file mode 100644 index 00000000000..91d6f4df92c --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java @@ -0,0 +1,18 @@ +package org.cbioportal.service; + +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; + +import java.util.List; +import java.util.Map; + +public interface GenericAssayBinaryDataService { + List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; + +} diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java new file mode 100644 index 00000000000..ceace7ff351 --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java @@ -0,0 +1,16 @@ +package org.cbioportal.service; + +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import java.util.List; +import java.util.Map; + +public interface GenericAssayCategoricalDataService { + List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; + +} diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java new file mode 100644 index 00000000000..55233c81a29 --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -0,0 +1,126 @@ +package org.cbioportal.service.impl; + +import org.apache.commons.lang3.BooleanUtils; +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.persistence.SampleListRepository; +import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryDataService { + + @Autowired + private MolecularDataRepository molecularDataRepository; + + @Autowired + private SampleService sampleService; + + @Autowired + private MolecularProfileService molecularProfileService; + + @Autowired + private FisherExactTestCalculator fisherExactTestCalculator; + + @Autowired + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Autowired + private GenericAssayService genericAssayService; + + @Override + public List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); + + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + + if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); + List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + filteredMolecularProfileCaseSets = new HashMap<>(); + for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { + Set patientSet = new HashSet(); + List identifierListUniqueByPatientId = new ArrayList<>(); + for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { + if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { + identifierListUniqueByPatientId.add(caseIdentifier); + patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); + } + } + filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); + } + } else { + filteredMolecularProfileCaseSets = molecularProfileCaseSets; + } + + List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + // Sort the list based on pValue. + Collections.sort(genericAssayBinaryEnrichments, new Comparator() { + @Override + public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment c2) { + return c1.getpValue().compareTo(c2.getpValue()); + } + }); + + // Extract pValues and calculate qValues. + BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); + + // Assign qValues back to the objects. + for (int i = 0; i < genericAssayBinaryEnrichments.size(); i++) { + genericAssayBinaryEnrichments.get(i).setqValue(qValues[i]); + } + + List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + Map genericAssayMetaByStableId = genericAssayService + .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, + getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) + .collect(Collectors.toList()), + "SUMMARY") + .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + + return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + + } + + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + +} diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java new file mode 100644 index 00000000000..b81c06118b4 --- /dev/null +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -0,0 +1,121 @@ +package org.cbioportal.service.impl; + +import org.apache.commons.lang3.BooleanUtils; +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.GenericAssayRepository; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.persistence.SampleListRepository; +import org.cbioportal.service.*; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class GenericAssayCategoricalDataServiceImpl implements GenericAssayCategoricalDataService { + + @Autowired + private MolecularDataRepository molecularDataRepository; + + @Autowired + private SampleService sampleService; + + @Autowired + private MolecularProfileService molecularProfileService; + + @Autowired + private FisherExactTestCalculator fisherExactTestCalculator; + + @Autowired + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Autowired + private GenericAssayService genericAssayService; + + @Override + public List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); + + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); + List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + filteredMolecularProfileCaseSets = new HashMap<>(); + for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { + Set patientSet = new HashSet(); + List identifierListUniqueByPatientId = new ArrayList<>(); + for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { + if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { + identifierListUniqueByPatientId.add(caseIdentifier); + patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); + } + } + filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); + } + } else { + filteredMolecularProfileCaseSets = molecularProfileCaseSets; + } + + List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + // Sort the list based on pValue. + Collections.sort(genericAssayCategoricalEnrichments, new Comparator() { + @Override + public int compare(GenericAssayCategoricalEnrichment c1, GenericAssayCategoricalEnrichment c2) { + return c1.getpValue().compareTo(c2.getpValue()); + } + }); + + // Extract pValues and calculate qValues. + BigDecimal[] pValues = genericAssayCategoricalEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); + + // Assign qValues back to the objects. + for (int i = 0; i < genericAssayCategoricalEnrichments.size(); i++) { + genericAssayCategoricalEnrichments.get(i).setqValue(qValues[i]); + } + + List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + Map genericAssayMetaByStableId = genericAssayService + .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, + getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) + .collect(Collectors.toList()), + "SUMMARY") + .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + + return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + +} diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index a147e0065fc..9b3c5b45678 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -1,31 +1,20 @@ package org.cbioportal.service.util; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.math3.stat.StatUtils; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; +import org.apache.commons.math3.stat.inference.ChiSquareTest; import org.apache.commons.math3.stat.inference.OneWayAnova; import org.apache.commons.math3.stat.inference.TestUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.ExpressionEnrichment; -import org.cbioportal.model.GenericAssayEnrichment; -import org.cbioportal.model.GenericAssayMolecularAlteration; -import org.cbioportal.model.GenomicEnrichment; -import org.cbioportal.model.GroupStatistics; -import org.cbioportal.model.MolecularAlteration; -import org.cbioportal.model.MolecularProfile; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.model.MolecularProfileSamples; -import org.cbioportal.model.Sample; +import org.cbioportal.model.*; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.SampleService; import org.springframework.beans.factory.annotation.Autowired; @@ -41,7 +30,10 @@ public class ExpressionEnrichmentUtil { private static final double LOG2 = Math.log(2); private static final String RNA_SEQ = "rna_seq"; - + private static final String POS = "true"; + private static final String NEG = "false"; + private static final String ALTERED = "1"; + private static final String UNALTERED = "0"; public List getEnrichments( MolecularProfile molecularProfile, Map> molecularProfileCaseSets, EnrichmentType enrichmentType, @@ -63,12 +55,12 @@ public List g .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) .filter(a -> NumberUtils.isNumber(a)) .collect(Collectors.toList()); - + // ignore group if there are less than 2 values if (molecularDataValues.size() < 2) { continue; } - + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); GroupStatistics groupStatistics = new GroupStatistics(); @@ -111,7 +103,144 @@ public List g return expressionEnrichments; } - private double[] getAlterationValues(List molecularDataValues, String molecularProfileId) { + public List getGenericAssayCategoricalEnrichments( + MolecularProfile molecularProfile, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + Iterable maItr) { + + List expressionEnrichments = new ArrayList<>(); + Map> groupCategoryStatistics = new HashMap<>(); + Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, + molecularProfile); + + for (MolecularAlteration ma : maItr) { + List groupsStatistics = new ArrayList(); + for (Entry> group : groupIndicesMap.entrySet()) { + // Get the corresponding split values for the group + List groupValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .collect(Collectors.toList()); + // Group and count the split values + Map groupedSplitValues = groupValues.stream() + .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); + + // ignore group if there are less than 2 values + if (groupValues.size() < 2) { + continue; + } + + GroupStatistics groupStatistics = new GroupStatistics(); + groupStatistics.setName(group.getKey()); + groupsStatistics.add(groupStatistics); + groupCategoryStatistics.put(group.getKey(), groupedSplitValues); + } + + // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { + long[][] array = getCategoricalValues(groupCategoryStatistics); + double pValue; + + ChiSquareTest chiSquareTest = new ChiSquareTest(); + pValue = chiSquareTest.chiSquareTest(array); + + // set p-value to 1 when the cases in all groups are altered + if (Double.isNaN(pValue)) { + pValue = 1; + } + + S expressionEnrichment = null; + GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = new GenericAssayCategoricalEnrichment(); + genericAssayCategoricalEnrichment.setStableId(ma.getStableId()); + expressionEnrichment = (S) genericAssayCategoricalEnrichment; + + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); + expressionEnrichment.setGroupsStatistics(groupsStatistics); + expressionEnrichments.add(expressionEnrichment); + } + } + return expressionEnrichments; + } + + public List getGenericAssayBinaryEnrichments( + MolecularProfile molecularProfile, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + Iterable maItr) { + List expressionEnrichments = new ArrayList<>(); + + Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, + molecularProfile); + // unaltered: 34 altered 12 1: tttf 2:ffft + for (MolecularAlteration ma : maItr) { + List genericAssayCountSummaries = new ArrayList<>(); + List groupsStatistics = new ArrayList(); + // used for p-value calculation + List groupedValues = new ArrayList(); + + for (Entry> group : groupIndicesMap.entrySet()) { + GenericAssayCountSummary genericAssayCountSummary = new GenericAssayCountSummary(); + genericAssayCountSummary.setName(group.getKey()); + // Get the corresponding split values for the group + List groupValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .collect(Collectors.toList()); + // Group and count the split values + Map groupedSplitValues = groupValues.stream() + .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); + + // get expression values to all the indices in the group, filter NA and map binary values + //unaltered:1:1,0 2:0,1 altered:1:1,1 2:0,0 + List molecularDataValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .filter(StringUtils::isNotEmpty) + .map(a -> a.equals(POS) ? ALTERED : UNALTERED) + .collect(Collectors.toList()); + + // ignore group if there are less than 2 values + if (molecularDataValues.size() < 2) { + continue; + } + + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); + + GroupStatistics groupStatistics = new GroupStatistics(); + double alteredMean = StatUtils.mean(values); + double alteredStandardDeviation = calculateStandardDeviation(values); + + // ignore if mean or standard deviation are not numbers + if (Double.isNaN(alteredMean) || Double.isNaN(alteredStandardDeviation)) { + continue; + } + + groupedValues.add(values); + groupStatistics.setName(group.getKey()); + groupStatistics.setMeanExpression(BigDecimal.valueOf(alteredMean)); + groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); + groupsStatistics.add(groupStatistics); + genericAssayCountSummaries.add(genericAssayCountSummary); + + } + + // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { + double pValue = calculatePValue(groupedValues); + if (Double.isNaN(pValue)) { + continue; + } + S expressionEnrichment = null; + GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = new GenericAssayBinaryEnrichment(); + genericAssayBinaryEnrichment.setStableId(ma.getStableId()); + genericAssayBinaryEnrichment.setCounts(genericAssayCountSummaries); + expressionEnrichment = (S) genericAssayBinaryEnrichment; + + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); + expressionEnrichment.setGroupsStatistics(groupsStatistics); + expressionEnrichments.add(expressionEnrichment); + } + } + return expressionEnrichments; + } + + private double[] getAlterationValues(List molecularDataValues, String molecularProfileId) { if (molecularProfileId.contains(RNA_SEQ)) { return molecularDataValues.stream().mapToDouble(d -> { @@ -123,6 +252,36 @@ private double[] getAlterationValues(List molecularDataValues, String mo return molecularDataValues.stream().mapToDouble(g -> Double.parseDouble(g)).toArray(); } } + + private long[][] getCategoricalValues(Map> groupCategoryStatistics) { + // Determine the number of rows and columns + int numRows = groupCategoryStatistics.size(); + Set allCategories = groupCategoryStatistics.values().stream() + .flatMap(innerMap -> innerMap.keySet().stream()) + .collect(Collectors.toSet()); + int numCols = allCategories.size(); + + // Create the 2-dimensional long array + long[][] array = new long[numRows][numCols]; + + // Iterate over the outer map (group -> categories) + List groupKeys = new ArrayList<>(groupCategoryStatistics.keySet()); + for (int row = 0; row < numRows; row++) { + String groupKey = groupKeys.get(row); + Map innerMap = groupCategoryStatistics.get(groupKey); + + // Iterate over all categories + List categoryKeys = new ArrayList<>(allCategories); + for (int col = 0; col < numCols; col++) { + String categoryKey = categoryKeys.get(col); + + // Get the count from the inner map, or set as zero if the category doesn't exist + int count = innerMap.getOrDefault(categoryKey, 0); + array[row][col] = count; + } + } + return array; + } private double calculatePValue(List alteredValues) { @@ -229,4 +388,11 @@ private Map> getCaseIdToInternalIdsMap( .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); } } + public static void main(String[] args) { + List alteredValues = null; + alteredValues.add(new double[]{0, 0}); + alteredValues.add(new double[]{0, 1}); + double pValue = TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); + System.out.println("Calculated p-value: " + pValue); + } } diff --git a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java index ed94cad2b5b..6ac8cac1047 100644 --- a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java +++ b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java @@ -2,6 +2,8 @@ import org.springframework.stereotype.Component; +import java.math.BigDecimal; + @Component public class FisherExactTestCalculator { @@ -40,9 +42,9 @@ public double getCumulativePValue(int a, int b, int c, int d) { } return p; } - + public double getTwoTailedPValue(int a, int b, int c, int d) { - + int min, i; int n = a + b + c + d; double p = 0; @@ -60,10 +62,10 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { // frequencies, of obtaining exactly the frequencies observed and any configuration more extreme. // By "more extreme," we mean any configuration (given observed marginals) with a smaller probability of // occurrence in the same direction (one-tailed) or in both directions (two-tailed). - + int initialA = a, initialB = b, initialC = c, initialD = d; p += baseP; - + min = (c < b) ? c : b; for (i = 0; i < min; i++) { double tempP = getPValue(++a, --b, --c, ++d, f); @@ -77,7 +79,7 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { b = initialB; c = initialC; d = initialD; - + min = (a < d) ? a : d; for (i = 0; i < min; i++) { double pTemp = getPValue(--a, ++b, ++c, --d, f); @@ -86,5 +88,38 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { } } return p; + } + public BigDecimal[] calcqValue(BigDecimal[] pValuesInIncreasingOrder) { + BigDecimal cachedElement = BigDecimal.valueOf(0.0); + int dataLength = pValuesInIncreasingOrder.length; + BigDecimal[] reversedQValues = new BigDecimal[dataLength]; + + reverseValues(dataLength, pValuesInIncreasingOrder); + + for (int i = 0; i < dataLength; i++) { + if (i > 0) { + BigDecimal calculatedValue = cachedElement.min( + (pValuesInIncreasingOrder[i].multiply(new BigDecimal(dataLength))).divide(new BigDecimal(dataLength - i)) + ); + cachedElement = calculatedValue; + reversedQValues[i] = calculatedValue; + } else { + cachedElement = pValuesInIncreasingOrder[i]; + reversedQValues[i] = pValuesInIncreasingOrder[i]; + } + } + + reverseValues(dataLength, reversedQValues); + + return reversedQValues; + } + + private void reverseValues(int dataLength, BigDecimal[] reversedQValues) { + for (int i = 0; i < dataLength / 2; i++) { + BigDecimal temp = reversedQValues[i]; + reversedQValues[i] = reversedQValues[dataLength - i - 1]; + reversedQValues[dataLength - i - 1] = temp; + } + } } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java new file mode 100644 index 00000000000..bfbc841a352 --- /dev/null +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java @@ -0,0 +1,207 @@ +package org.cbioportal.service.impl; + +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.service.GeneService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import java.math.BigDecimal; +import java.util.*; + +import static org.junit.Assert.*; + + +@RunWith(MockitoJUnitRunner.class) +public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ + + @InjectMocks + private GenericAssayBinaryDataServiceImpl genericAssayBinaryDataServiceImpl; + @Mock + private SampleService sampleService; + @Mock + private MolecularProfileService molecularProfileService; + @Mock + private MolecularDataRepository molecularDataRepository; + @Mock + private GeneService geneService; + @Spy + @InjectMocks + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Mock + private GenericAssayService genericAssayService; + + CancerStudy cancerStudy = new CancerStudy(); + MolecularProfile geneMolecularProfile = new MolecularProfile(); + MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); + List samples = new ArrayList<>(); + Map> molecularProfileCaseSets = new HashMap<>(); + Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + // patient level only data + public static final String SAMPLE_ID5 = "sample_id5"; + + + @Before + public void setup() throws MolecularProfileNotFoundException { + cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); + cancerStudy.setCancerStudyIdentifier(STUDY_ID); + + geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); + geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); + + geneMolecularProfile.setCancerStudy(cancerStudy); + + molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); + molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); + + Sample sample1 = new Sample(); + sample1.setStableId(SAMPLE_ID1); + sample1.setInternalId(1); + sample1.setCancerStudyIdentifier(STUDY_ID); + sample1.setPatientId(1); + samples.add(sample1); + Sample sample2 = new Sample(); + sample2.setStableId(SAMPLE_ID2); + sample2.setInternalId(2); + sample2.setCancerStudyIdentifier(STUDY_ID); + sample2.setPatientId(2); + samples.add(sample2); + Sample sample3 = new Sample(); + sample3.setStableId(SAMPLE_ID3); + sample3.setInternalId(3); + sample3.setCancerStudyIdentifier(STUDY_ID); + sample3.setPatientId(3); + samples.add(sample3); + Sample sample4 = new Sample(); + sample4.setStableId(SAMPLE_ID4); + sample4.setInternalId(4); + sample4.setCancerStudyIdentifier(STUDY_ID); + sample4.setPatientId(4); + samples.add(sample4); + + List alteredSampleIdentifieres = new ArrayList<>(); + List unalteredSampleIdentifieres = new ArrayList<>(); + List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); + + MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); + caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier1.setCaseId(SAMPLE_ID1); + alteredSampleIdentifieres.add(caseIdentifier1); + + MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); + caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier2.setCaseId(SAMPLE_ID2); + alteredSampleIdentifieres.add(caseIdentifier2); + + MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); + caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier3.setCaseId(SAMPLE_ID3); + unalteredSampleIdentifieres.add(caseIdentifier3); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); + + MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); + caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier4.setCaseId(SAMPLE_ID4); + unalteredSampleIdentifieres.add(caseIdentifier4); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); + + // patient level only data + MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); + caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier5.setCaseId(SAMPLE_ID5); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); + + molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); + + Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(geneMolecularProfile); + + Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfileSamples); + + Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), + Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); + } + + @Test + public void getGenericAssayBinaryEnrichments() throws Exception { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + + // here are 2 groups + genericAssayMolecularAlteration1.setValues("true,true,true,false"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("true,false,false,true"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayBinaryDataServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + + GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("1"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("0.0416666666666667"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.0833333333333334"), genericAssayBinaryEnrichment.getqValue()); + + genericAssayBinaryEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + + alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.707106781186548"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getqValue()); + } + + +} \ No newline at end of file diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java new file mode 100644 index 00000000000..dcd0e9bfaed --- /dev/null +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java @@ -0,0 +1,194 @@ +package org.cbioportal.service.impl; + +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.service.GeneService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import java.math.BigDecimal; +import java.util.*; + +@RunWith(MockitoJUnitRunner.class) +public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplTest{ + @InjectMocks + private ExpressionEnrichmentServiceImpl enrichmentServiceImpl; + @InjectMocks + private GenericAssayCategoricalDataServiceImpl genericAssayCategoricalDataServiceImpl; + @Mock + private SampleService sampleService; + @Mock + private MolecularProfileService molecularProfileService; + @Mock + private MolecularDataRepository molecularDataRepository; + @Mock + private GeneService geneService; + @Spy + @InjectMocks + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + @Mock + private GenericAssayService genericAssayService; + + CancerStudy cancerStudy = new CancerStudy(); + MolecularProfile geneMolecularProfile = new MolecularProfile(); + MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); + List samples = new ArrayList<>(); + Map> molecularProfileCaseSets = new HashMap<>(); + Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + // patient level only data + public static final String SAMPLE_ID5 = "sample_id5"; + + + @Before + public void setup() throws MolecularProfileNotFoundException { + cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); + cancerStudy.setCancerStudyIdentifier(STUDY_ID); + + geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); + geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); + + geneMolecularProfile.setCancerStudy(cancerStudy); + + molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); + molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); + + Sample sample1 = new Sample(); + sample1.setStableId(SAMPLE_ID1); + sample1.setInternalId(1); + sample1.setCancerStudyIdentifier(STUDY_ID); + sample1.setPatientId(1); + samples.add(sample1); + Sample sample2 = new Sample(); + sample2.setStableId(SAMPLE_ID2); + sample2.setInternalId(2); + sample2.setCancerStudyIdentifier(STUDY_ID); + sample2.setPatientId(2); + samples.add(sample2); + Sample sample3 = new Sample(); + sample3.setStableId(SAMPLE_ID3); + sample3.setInternalId(3); + sample3.setCancerStudyIdentifier(STUDY_ID); + sample3.setPatientId(3); + samples.add(sample3); + Sample sample4 = new Sample(); + sample4.setStableId(SAMPLE_ID4); + sample4.setInternalId(4); + sample4.setCancerStudyIdentifier(STUDY_ID); + sample4.setPatientId(4); + samples.add(sample4); + + List alteredSampleIdentifieres = new ArrayList<>(); + List unalteredSampleIdentifieres = new ArrayList<>(); + List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); + + MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); + caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier1.setCaseId(SAMPLE_ID1); + alteredSampleIdentifieres.add(caseIdentifier1); + + MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); + caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier2.setCaseId(SAMPLE_ID2); + alteredSampleIdentifieres.add(caseIdentifier2); + + MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); + caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier3.setCaseId(SAMPLE_ID3); + unalteredSampleIdentifieres.add(caseIdentifier3); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); + + MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); + caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier4.setCaseId(SAMPLE_ID4); + unalteredSampleIdentifieres.add(caseIdentifier4); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); + + // patient level only data + MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); + caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier5.setCaseId(SAMPLE_ID5); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); + + molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); + + Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(geneMolecularProfile); + + Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfileSamples); + + Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), + Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); + } + + @Test + public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFoundException { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + genericAssayMolecularAlteration1.setValues("category1,category1,category2,category2"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("category2,category2,category1,category1"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayCategoricalDataServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + + genericAssayCategoricalEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + } + +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java new file mode 100644 index 00000000000..5d16690163a --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -0,0 +1,74 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Binary Data", description = " ") +public class GenericAssayBinaryDataController { + @Autowired + private GenericAssayBinaryDataService genericAssayBinaryDataService; + + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java new file mode 100644 index 00000000000..976a8076c3b --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -0,0 +1,79 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.commons.lang3.StringUtils; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayData; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayCategoricalDataService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.GenericAssayNotFoundException; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.GenericAssayFilter; +import org.cbioportal.web.parameter.HeaderKeyConstants; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +import org.cbioportal.web.parameter.Projection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.*; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Categorical Data", description = " ") +public class GenericAssayCategoricalDataController { + + @Autowired + private GenericAssayCategoricalDataService genericAssayCategoricalDataService; + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} From 203ca2a3101be32159aa9f377f9784d97a2bc5af Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 26 Jul 2023 14:17:22 -0400 Subject: [PATCH 21/40] finish tests --- .../GenericAssayBinaryDataServiceImpl.java | 5 ++- ...enericAssayCategoricalDataServiceImpl.java | 11 ++++-- .../util/ExpressionEnrichmentUtil.java | 39 ++++++++----------- .../util/FisherExactTestCalculator.java | 2 +- ...GenericAssayBinaryDataServiceImplTest.java | 24 ++++++------ ...icAssayCategoricalDataServiceImplTest.java | 13 +++---- .../web/GenericAssayBinaryDataController.java | 2 +- ...GenericAssayCategoricalDataController.java | 27 ++++++------- ...volvedCancerStudyExtractorInterceptor.java | 6 ++- 9 files changed, 66 insertions(+), 63 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 55233c81a29..7ffc558f0ea 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -14,6 +14,7 @@ import org.cbioportal.service.util.FisherExactTestCalculator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; @@ -33,7 +34,7 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData private MolecularProfileService molecularProfileService; @Autowired - private FisherExactTestCalculator fisherExactTestCalculator; + private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); @Autowired private ExpressionEnrichmentUtil expressionEnrichmentUtil; @@ -41,6 +42,7 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData private GenericAssayService genericAssayService; @Override + @Transactional(readOnly = true) public List getGenericAssayBinaryEnrichments( String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) @@ -90,6 +92,7 @@ public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment // Extract pValues and calculate qValues. BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); // Assign qValues back to the objects. diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index b81c06118b4..99b1c6e91f5 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -32,20 +32,20 @@ public class GenericAssayCategoricalDataServiceImpl implements GenericAssayCateg private MolecularProfileService molecularProfileService; @Autowired - private FisherExactTestCalculator fisherExactTestCalculator; + private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); @Autowired - private ExpressionEnrichmentUtil expressionEnrichmentUtil; + private ExpressionEnrichmentUtil expressionEnrichmentUtil = new ExpressionEnrichmentUtil(); @Autowired private GenericAssayService genericAssayService; @Override + @Transactional(readOnly = true) public List getGenericAssayCategoricalEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); Iterable maItr = molecularDataRepository @@ -56,7 +56,10 @@ public List getGenericAssayCategoricalEnrichm List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + Map sampleIdToPatientIdMap = samples.stream() + .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) + .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); filteredMolecularProfileCaseSets = new HashMap<>(); for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index 9b3c5b45678..a07454a4b5f 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -7,6 +7,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import io.swagger.models.auth.In; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.math3.stat.StatUtils; @@ -43,7 +44,6 @@ public List g Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, molecularProfile); for (MolecularAlteration ma : maItr) { - List groupsStatistics = new ArrayList(); // used for p-value calculation List groupedValues = new ArrayList(); @@ -112,7 +112,7 @@ public List g Map> groupCategoryStatistics = new HashMap<>(); Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, molecularProfile); - + for (MolecularAlteration ma : maItr) { List groupsStatistics = new ArrayList(); for (Entry> group : groupIndicesMap.entrySet()) { @@ -136,12 +136,16 @@ public List g } // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { long[][] array = getCategoricalValues(groupCategoryStatistics); double pValue; - - ChiSquareTest chiSquareTest = new ChiSquareTest(); - pValue = chiSquareTest.chiSquareTest(array); + if(array[0].length <= 1) { + pValue = 1; + } else { + ChiSquareTest chiSquareTest = new ChiSquareTest(); + pValue = chiSquareTest.chiSquareTest(array); + } // set p-value to 1 when the cases in all groups are altered if (Double.isNaN(pValue)) { @@ -179,16 +183,8 @@ public List g for (Entry> group : groupIndicesMap.entrySet()) { GenericAssayCountSummary genericAssayCountSummary = new GenericAssayCountSummary(); genericAssayCountSummary.setName(group.getKey()); - // Get the corresponding split values for the group - List groupValues = group.getValue().stream() - .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) - .collect(Collectors.toList()); - // Group and count the split values - Map groupedSplitValues = groupValues.stream() - .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); // get expression values to all the indices in the group, filter NA and map binary values - //unaltered:1:1,0 2:0,1 altered:1:1,1 2:0,0 List molecularDataValues = group.getValue().stream() .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) .filter(StringUtils::isNotEmpty) @@ -199,9 +195,12 @@ public List g if (molecularDataValues.size() < 2) { continue; } - + genericAssayCountSummary.setTotalCount(molecularDataValues.size()); + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); - + genericAssayCountSummary.setCount((int) Arrays.stream(values) + .filter(num -> num == 1) + .count()); GroupStatistics groupStatistics = new GroupStatistics(); double alteredMean = StatUtils.mean(values); double alteredStandardDeviation = calculateStandardDeviation(values); @@ -217,11 +216,11 @@ public List g groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); groupsStatistics.add(groupStatistics); genericAssayCountSummaries.add(genericAssayCountSummary); - } // calculate p-value and add enrichment if atleast 2 groups have data if (groupsStatistics.size() > 1) { + double pValue = calculatePValue(groupedValues); if (Double.isNaN(pValue)) { continue; @@ -388,11 +387,5 @@ private Map> getCaseIdToInternalIdsMap( .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); } } - public static void main(String[] args) { - List alteredValues = null; - alteredValues.add(new double[]{0, 0}); - alteredValues.add(new double[]{0, 1}); - double pValue = TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); - System.out.println("Calculated p-value: " + pValue); - } + } diff --git a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java index 6ac8cac1047..4584341e2e2 100644 --- a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java +++ b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java @@ -99,7 +99,7 @@ public BigDecimal[] calcqValue(BigDecimal[] pValuesInIncreasingOrder) { for (int i = 0; i < dataLength; i++) { if (i > 0) { BigDecimal calculatedValue = cachedElement.min( - (pValuesInIncreasingOrder[i].multiply(new BigDecimal(dataLength))).divide(new BigDecimal(dataLength - i)) + (pValuesInIncreasingOrder[i].multiply(new BigDecimal(dataLength))).divide(new BigDecimal(dataLength - i), BigDecimal.ROUND_HALF_UP) ); cachedElement = calculatedValue; reversedQValues[i] = calculatedValue; diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java index bfbc841a352..f7f423f6cda 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java @@ -9,6 +9,7 @@ import org.cbioportal.service.SampleService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -36,8 +37,7 @@ public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ private MolecularProfileService molecularProfileService; @Mock private MolecularDataRepository molecularDataRepository; - @Mock - private GeneService geneService; + @Spy @InjectMocks private ExpressionEnrichmentUtil expressionEnrichmentUtil; @@ -50,6 +50,8 @@ public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ List samples = new ArrayList<>(); Map> molecularProfileCaseSets = new HashMap<>(); Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + private FisherExactTestCalculator fisherExactTestCalculator; + // patient level only data public static final String SAMPLE_ID5 = "sample_id5"; @@ -175,15 +177,15 @@ public void getGenericAssayBinaryEnrichments() throws Exception { GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("1"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0"), alteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("1.0"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.0"), alteredGroupStats.getStandardDeviation()); - Assert.assertEquals(new BigDecimal("0.0416666666666667"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.0833333333333334"), genericAssayBinaryEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("0.49999999999999983"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.99999999999999966"), genericAssayBinaryEnrichment.getqValue()); genericAssayBinaryEnrichment = result.get(1); Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); @@ -192,15 +194,15 @@ public void getGenericAssayBinaryEnrichments() throws Exception { unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.707106781186548"), unalteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.707106781186548"), alteredGroupStats.getStandardDeviation()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), alteredGroupStats.getStandardDeviation()); - Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("1"), genericAssayBinaryEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getqValue()); } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java index dcd0e9bfaed..405641dfc92 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java @@ -24,8 +24,6 @@ @RunWith(MockitoJUnitRunner.class) public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplTest{ - @InjectMocks - private ExpressionEnrichmentServiceImpl enrichmentServiceImpl; @InjectMocks private GenericAssayCategoricalDataServiceImpl genericAssayCategoricalDataServiceImpl; @Mock @@ -34,8 +32,7 @@ public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplT private MolecularProfileService molecularProfileService; @Mock private MolecularDataRepository molecularDataRepository; - @Mock - private GeneService geneService; + @Spy @InjectMocks private ExpressionEnrichmentUtil expressionEnrichmentUtil; @@ -174,8 +171,8 @@ public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFo GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); genericAssayCategoricalEnrichment = result.get(1); Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); @@ -187,8 +184,8 @@ public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFo alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.31731050786291115"), genericAssayCategoricalEnrichment.getqValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); } } diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java index 5d16690163a..60a7fddc58d 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -41,7 +41,7 @@ public class GenericAssayBinaryDataController { method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + public ResponseEntity> fetchGenericAssayBinaryDataEnrichmentInMultipleMolecularProfiles( @ApiIgnore @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java index 976a8076c3b..c3344ce94e9 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -4,10 +4,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayData; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.*; import org.cbioportal.service.GenericAssayCategoricalDataService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.SampleService; @@ -56,7 +53,13 @@ public ResponseEntity> fetchGenericAssay @ApiIgnore @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) throws MolecularProfileNotFoundException, UnsupportedOperationException { - + + return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), + HttpStatus.OK); + } + private List fetchExpressionEnrichments(EnrichmentType enrichmentType, + List interceptedMolecularProfileCasesGroupFilters + ) throws MolecularProfileNotFoundException { Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); @@ -65,15 +68,13 @@ public ResponseEntity> fetchGenericAssay .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) .collect(Collectors.toSet()); - + if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - - return new ResponseEntity<>( - genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), - HttpStatus.OK); + return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } - } + + diff --git a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java index f56a51727b0..dc81162be46 100644 --- a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java +++ b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java @@ -102,6 +102,8 @@ public class InvolvedCancerStudyExtractorInterceptor extends HandlerInterceptorA public static final String TREATMENTS_PATIENT_PATH = "/treatments/patient"; public static final String TREATMENTS_SAMPLE_PATH = "/treatments/sample"; public static final String GENERIC_ASSAY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/fetch"; + public static final String GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/categorical/fetch"; + public static final String GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/binary/fetch"; public static final String CLINICAL_EVENT_TYPE_COUNT_FETCH_PATH = "/clinical-event-type-counts/fetch"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { @@ -151,7 +153,9 @@ public class InvolvedCancerStudyExtractorInterceptor extends HandlerInterceptorA } else if (requestPathInfo.equals(MUTATION_ENRICHMENT_FETCH_PATH) || requestPathInfo.equals(COPY_NUMBER_ENRICHMENT_FETCH_PATH) || requestPathInfo.equals(EXPRESSION_ENRICHMENT_FETCH_PATH) || - requestPathInfo.equals(GENERIC_ASSAY_ENRICHMENT_FETCH_PATH)) { + requestPathInfo.equals(GENERIC_ASSAY_ENRICHMENT_FETCH_PATH) || + requestPathInfo.equals(GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH) || + requestPathInfo.equals(GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH)) { return extractAttributesFromMolecularProfileCasesGroups(request); } else if (requestPathInfo.equals(ALTERATION_ENRICHMENT_FETCH_PATH)) { return extractAttributesFromMolecularProfileCasesGroupsAndAlterationTypes(request); From 477555054535686746afee0f43463dfafb001dc3 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:04:39 -0400 Subject: [PATCH 22/40] modify controller file structure --- ...GenericAssayCategoricalDataController.java | 80 ------------------- ... => GenericAssayEnrichmentController.java} | 47 ++++++++++- ...volvedCancerStudyExtractorInterceptor.java | 4 +- 3 files changed, 46 insertions(+), 85 deletions(-) delete mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java rename web/src/main/java/org/cbioportal/web/{GenericAssayBinaryDataController.java => GenericAssayEnrichmentController.java} (53%) diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java deleted file mode 100644 index c3344ce94e9..00000000000 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.cbioportal.web; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.*; -import org.cbioportal.service.GenericAssayCategoricalDataService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.GenericAssayNotFoundException; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.web.config.annotation.InternalApi; -import org.cbioportal.web.parameter.GenericAssayFilter; -import org.cbioportal.web.parameter.HeaderKeyConstants; -import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; -import org.cbioportal.web.parameter.Projection; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -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.*; -import springfox.documentation.annotations.ApiIgnore; - -import javax.validation.Valid; -import java.util.*; -import java.util.stream.Collectors; - -@InternalApi -@RestController -@Validated -@Api(tags = "Generic Assay Categorical Data", description = " ") -public class GenericAssayCategoricalDataController { - - @Autowired - private GenericAssayCategoricalDataService genericAssayCategoricalDataService; - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", - method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( - @ApiIgnore - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") - @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, - @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") - @Valid @RequestBody(required = false) List groups, - @ApiIgnore - @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) - throws MolecularProfileNotFoundException, UnsupportedOperationException { - - return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), - HttpStatus.OK); - } - private List fetchExpressionEnrichments(EnrichmentType enrichmentType, - List interceptedMolecularProfileCasesGroupFilters - ) throws MolecularProfileNotFoundException { - Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters - .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, - MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); - - Set molecularProfileIds = groupCaseIdentifierSet.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) - .collect(Collectors.toSet()); - - if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); - } - return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); - } -} - - diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java similarity index 53% rename from web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java rename to web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java index 60a7fddc58d..bac54097958 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java @@ -5,8 +5,10 @@ import io.swagger.annotations.ApiParam; import org.cbioportal.model.EnrichmentType; import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.GenericAssayCategoricalDataService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; import org.cbioportal.web.config.annotation.InternalApi; @@ -30,14 +32,35 @@ @InternalApi @RestController @Validated -@Api(tags = "Generic Assay Binary Data", description = " ") -public class GenericAssayBinaryDataController { +@Api(tags = "Generic Assay Enrichment Data", description = " ") +public class GenericAssayEnrichmentController { + @Autowired + private GenericAssayCategoricalDataService genericAssayCategoricalDataService; @Autowired private GenericAssayBinaryDataService genericAssayBinaryDataService; + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-categorical-enrichments/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), + HttpStatus.OK); + } @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", + @RequestMapping(value = "/generic-assay-binary-enrichments/fetch", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") @@ -71,4 +94,22 @@ public ResponseEntity> fetchGenericAssayBinar HttpStatus.OK); } + private List fetchExpressionEnrichments(EnrichmentType enrichmentType, + List interceptedMolecularProfileCasesGroupFilters + ) throws MolecularProfileNotFoundException { + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); + } + return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); + } } diff --git a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java index dc81162be46..91720ee1f81 100644 --- a/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java +++ b/web/src/main/java/org/cbioportal/web/util/InvolvedCancerStudyExtractorInterceptor.java @@ -102,8 +102,8 @@ public class InvolvedCancerStudyExtractorInterceptor extends HandlerInterceptorA public static final String TREATMENTS_PATIENT_PATH = "/treatments/patient"; public static final String TREATMENTS_SAMPLE_PATH = "/treatments/sample"; public static final String GENERIC_ASSAY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/fetch"; - public static final String GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/categorical/fetch"; - public static final String GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH = "/generic-assay-enrichments/binary/fetch"; + public static final String GENERIC_ASSAY_CATEGORICAL_ENRICHMENT_FETCH_PATH = "/generic-assay-categorical-enrichments/fetch"; + public static final String GENERIC_ASSAY_BINARY_ENRICHMENT_FETCH_PATH = "/generic-assay-binary-enrichments/fetch"; public static final String CLINICAL_EVENT_TYPE_COUNT_FETCH_PATH = "/clinical-event-type-counts/fetch"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { From ef5a47410850fe80f530e7feff9757c5afa38a0e Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:15:34 -0400 Subject: [PATCH 23/40] modify import --- .../impl/GenericAssayBinaryDataServiceImpl.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 7ffc558f0ea..2958530d8ba 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -4,7 +4,6 @@ import org.cbioportal.model.*; import org.cbioportal.model.meta.GenericAssayMeta; import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.persistence.SampleListRepository; import org.cbioportal.service.GenericAssayBinaryDataService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.MolecularProfileService; @@ -17,7 +16,16 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; -import java.util.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; From 2cc1329e431a63603b2dccace5c0da71cf764264 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 28 Jun 2023 10:30:46 -0400 Subject: [PATCH 24/40] update backend --- .../GenericAssayBinaryDataServiceImpl.java | 13 +- ...enericAssayCategoricalDataServiceImpl.java | 2 + .../util/ExpressionEnrichmentUtil.java | 448 +++++++++--------- .../util/FisherExactTestCalculator.java | 3 +- ...GenericAssayBinaryDataServiceImplTest.java | 209 -------- ...icAssayCategoricalDataServiceImplTest.java | 191 -------- .../web/GenericAssayBinaryDataController.java | 74 +++ ...GenericAssayCategoricalDataController.java | 79 +++ 8 files changed, 382 insertions(+), 637 deletions(-) delete mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java delete mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java create mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 2958530d8ba..c02c725fbb0 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -14,18 +14,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - import java.math.BigDecimal; -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.Map; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -44,6 +34,7 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData @Autowired private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); + @Autowired private ExpressionEnrichmentUtil expressionEnrichmentUtil; @Autowired diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index 99b1c6e91f5..9d6ab72ff84 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -46,6 +46,7 @@ public List getGenericAssayCategoricalEnrichm throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); Iterable maItr = molecularDataRepository @@ -57,6 +58,7 @@ public List getGenericAssayCategoricalEnrichm List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream() .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index a07454a4b5f..71e7ef8e09d 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -24,90 +24,90 @@ @Component public class ExpressionEnrichmentUtil { - @Autowired - private SampleService sampleService; - @Autowired - private MolecularDataRepository molecularDataRepository; + @Autowired + private SampleService sampleService; + @Autowired + private MolecularDataRepository molecularDataRepository; - private static final double LOG2 = Math.log(2); - private static final String RNA_SEQ = "rna_seq"; + private static final double LOG2 = Math.log(2); + private static final String RNA_SEQ = "rna_seq"; private static final String POS = "true"; private static final String NEG = "false"; private static final String ALTERED = "1"; private static final String UNALTERED = "0"; - public List getEnrichments( - MolecularProfile molecularProfile, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType, - Iterable maItr) { - List expressionEnrichments = new ArrayList<>(); - - Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, - molecularProfile); - for (MolecularAlteration ma : maItr) { - List groupsStatistics = new ArrayList(); - // used for p-value calculation - List groupedValues = new ArrayList(); - - for (Entry> group : groupIndicesMap.entrySet()) { - - // get expression values to all the indices in the group - List molecularDataValues = group.getValue().stream() - .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) - .filter(a -> NumberUtils.isNumber(a)) - .collect(Collectors.toList()); - - // ignore group if there are less than 2 values - if (molecularDataValues.size() < 2) { - continue; - } - - double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); - - GroupStatistics groupStatistics = new GroupStatistics(); - double alteredMean = StatUtils.mean(values); - double alteredStandardDeviation = calculateStandardDeviation(values); - - // ignore if mean or standard deviation are not numbers - if (Double.isNaN(alteredMean) || Double.isNaN(alteredStandardDeviation)) { - continue; - } - - groupedValues.add(values); - groupStatistics.setName(group.getKey()); - groupStatistics.setMeanExpression(BigDecimal.valueOf(alteredMean)); - groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); - groupsStatistics.add(groupStatistics); - } - - // calculate p-value and add enrichment if atleast 2 groups have data - if (groupsStatistics.size() > 1) { - double pValue = calculatePValue(groupedValues); - if (Double.isNaN(pValue)) { - continue; - } - S expressionEnrichment = null; - if (ma instanceof GenericAssayMolecularAlteration) { - GenericAssayEnrichment genericAssayEnrichment = new GenericAssayEnrichment(); - genericAssayEnrichment.setStableId(ma.getStableId()); - expressionEnrichment = (S) genericAssayEnrichment; - } else { - GenomicEnrichment genomicEnrichment = new GenomicEnrichment(); - genomicEnrichment.setEntrezGeneId(Integer.valueOf(ma.getStableId())); - expressionEnrichment = (S) genomicEnrichment; - } - expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); - expressionEnrichment.setGroupsStatistics(groupsStatistics); - expressionEnrichments.add(expressionEnrichment); - } - } - return expressionEnrichments; - } + public List getEnrichments( + MolecularProfile molecularProfile, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + Iterable maItr) { + List expressionEnrichments = new ArrayList<>(); + + Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, + molecularProfile); + for (MolecularAlteration ma : maItr) { + List groupsStatistics = new ArrayList(); + // used for p-value calculation + List groupedValues = new ArrayList(); + + for (Entry> group : groupIndicesMap.entrySet()) { + + // get expression values to all the indices in the group + List molecularDataValues = group.getValue().stream() + .map(sampleIndex -> ma.getSplitValues()[sampleIndex]) + .filter(a -> NumberUtils.isNumber(a)) + .collect(Collectors.toList()); + + // ignore group if there are less than 2 values + if (molecularDataValues.size() < 2) { + continue; + } + + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); + + GroupStatistics groupStatistics = new GroupStatistics(); + double alteredMean = StatUtils.mean(values); + double alteredStandardDeviation = calculateStandardDeviation(values); + + // ignore if mean or standard deviation are not numbers + if (Double.isNaN(alteredMean) || Double.isNaN(alteredStandardDeviation)) { + continue; + } + + groupedValues.add(values); + groupStatistics.setName(group.getKey()); + groupStatistics.setMeanExpression(BigDecimal.valueOf(alteredMean)); + groupStatistics.setStandardDeviation(BigDecimal.valueOf(alteredStandardDeviation)); + groupsStatistics.add(groupStatistics); + } + + // calculate p-value and add enrichment if atleast 2 groups have data + if (groupsStatistics.size() > 1) { + double pValue = calculatePValue(groupedValues); + if (Double.isNaN(pValue)) { + continue; + } + S expressionEnrichment = null; + if (ma instanceof GenericAssayMolecularAlteration) { + GenericAssayEnrichment genericAssayEnrichment = new GenericAssayEnrichment(); + genericAssayEnrichment.setStableId(ma.getStableId()); + expressionEnrichment = (S) genericAssayEnrichment; + } else { + GenomicEnrichment genomicEnrichment = new GenomicEnrichment(); + genomicEnrichment.setEntrezGeneId(Integer.valueOf(ma.getStableId())); + expressionEnrichment = (S) genomicEnrichment; + } + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); + expressionEnrichment.setGroupsStatistics(groupsStatistics); + expressionEnrichments.add(expressionEnrichment); + } + } + return expressionEnrichments; + } public List getGenericAssayCategoricalEnrichments( MolecularProfile molecularProfile, Map> molecularProfileCaseSets, EnrichmentType enrichmentType, Iterable maItr) { - + List expressionEnrichments = new ArrayList<>(); Map> groupCategoryStatistics = new HashMap<>(); Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, @@ -123,12 +123,12 @@ public List g // Group and count the split values Map groupedSplitValues = groupValues.stream() .collect(Collectors.toMap(Function.identity(), v -> 1, Integer::sum)); - + // ignore group if there are less than 2 values if (groupValues.size() < 2) { continue; } - + GroupStatistics groupStatistics = new GroupStatistics(); groupStatistics.setName(group.getKey()); groupsStatistics.add(groupStatistics); @@ -151,7 +151,7 @@ public List g if (Double.isNaN(pValue)) { pValue = 1; } - + S expressionEnrichment = null; GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = new GenericAssayCategoricalEnrichment(); genericAssayCategoricalEnrichment.setStableId(ma.getStableId()); @@ -173,7 +173,7 @@ public List g Map> groupIndicesMap = getGroupIndicesMap(molecularProfileCaseSets, enrichmentType, molecularProfile); - // unaltered: 34 altered 12 1: tttf 2:ffft + for (MolecularAlteration ma : maItr) { List genericAssayCountSummaries = new ArrayList<>(); List groupsStatistics = new ArrayList(); @@ -196,7 +196,7 @@ public List g continue; } genericAssayCountSummary.setTotalCount(molecularDataValues.size()); - + double[] values = getAlterationValues(molecularDataValues, molecularProfile.getStableId()); genericAssayCountSummary.setCount((int) Arrays.stream(values) .filter(num -> num == 1) @@ -230,7 +230,7 @@ public List g genericAssayBinaryEnrichment.setStableId(ma.getStableId()); genericAssayBinaryEnrichment.setCounts(genericAssayCountSummaries); expressionEnrichment = (S) genericAssayBinaryEnrichment; - + expressionEnrichment.setpValue(BigDecimal.valueOf(pValue)); expressionEnrichment.setGroupsStatistics(groupsStatistics); expressionEnrichments.add(expressionEnrichment); @@ -241,151 +241,151 @@ public List g private double[] getAlterationValues(List molecularDataValues, String molecularProfileId) { - if (molecularProfileId.contains(RNA_SEQ)) { - return molecularDataValues.stream().mapToDouble(d -> { - double datum = Double.parseDouble(d); - // reset to 0 if there are any negative values and then do log1p - return Math.log1p(datum < 0 ? 0 : datum) / LOG2; - }).toArray(); - } else { - return molecularDataValues.stream().mapToDouble(g -> Double.parseDouble(g)).toArray(); - } - } - + if (molecularProfileId.contains(RNA_SEQ)) { + return molecularDataValues.stream().mapToDouble(d -> { + double datum = Double.parseDouble(d); + // reset to 0 if there are any negative values and then do log1p + return Math.log1p(datum < 0 ? 0 : datum) / LOG2; + }).toArray(); + } else { + return molecularDataValues.stream().mapToDouble(g -> Double.parseDouble(g)).toArray(); + } + } + private long[][] getCategoricalValues(Map> groupCategoryStatistics) { - // Determine the number of rows and columns - int numRows = groupCategoryStatistics.size(); - Set allCategories = groupCategoryStatistics.values().stream() - .flatMap(innerMap -> innerMap.keySet().stream()) - .collect(Collectors.toSet()); - int numCols = allCategories.size(); - - // Create the 2-dimensional long array - long[][] array = new long[numRows][numCols]; - - // Iterate over the outer map (group -> categories) - List groupKeys = new ArrayList<>(groupCategoryStatistics.keySet()); - for (int row = 0; row < numRows; row++) { - String groupKey = groupKeys.get(row); - Map innerMap = groupCategoryStatistics.get(groupKey); - - // Iterate over all categories - List categoryKeys = new ArrayList<>(allCategories); - for (int col = 0; col < numCols; col++) { - String categoryKey = categoryKeys.get(col); - - // Get the count from the inner map, or set as zero if the category doesn't exist - int count = innerMap.getOrDefault(categoryKey, 0); - array[row][col] = count; - } + // Determine the number of rows and columns + int numRows = groupCategoryStatistics.size(); + Set allCategories = groupCategoryStatistics.values().stream() + .flatMap(innerMap -> innerMap.keySet().stream()) + .collect(Collectors.toSet()); + int numCols = allCategories.size(); + + // Create the 2-dimensional long array + long[][] array = new long[numRows][numCols]; + + // Iterate over the outer map (group -> categories) + List groupKeys = new ArrayList<>(groupCategoryStatistics.keySet()); + for (int row = 0; row < numRows; row++) { + String groupKey = groupKeys.get(row); + Map innerMap = groupCategoryStatistics.get(groupKey); + + // Iterate over all categories + List categoryKeys = new ArrayList<>(allCategories); + for (int col = 0; col < numCols; col++) { + String categoryKey = categoryKeys.get(col); + + // Get the count from the inner map, or set as zero if the category doesn't exist + int count = innerMap.getOrDefault(categoryKey, 0); + array[row][col] = count; } - return array; + } + return array; + } + + private double calculatePValue(List alteredValues) { + + if (alteredValues.size() == 2) { + return TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); + } else { + // calculate Anova statisitcs if there are more than 2 groups + OneWayAnova oneWayAnova = new OneWayAnova(); + return oneWayAnova.anovaPValue(alteredValues); + } + } + + private double calculateStandardDeviation(double[] values) { + + DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(); + for (double value : values) { + descriptiveStatistics.addValue(value); + } + return descriptiveStatistics.getStandardDeviation(); + } + + /** + * + * This method maps valid samples in molecularProfileCaseSets to indices in + * genetic_alteration.VALUES column. Recall this column of the + * genetic_alteration table is a comma separated list of scalar values. Each + * value in this list is associated with a sample at the same position found in + * the genetic_profile_samples.ORDERED_SAMPLE_LIST column. + * + * @param molecularProfileCaseSets + * @param enrichmentType + * @param molecularProfile + * @return + */ + private Map> getGroupIndicesMap( + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + MolecularProfile molecularProfile) { + + MolecularProfileSamples commaSeparatedSampleIdsOfMolecularProfile = molecularDataRepository + .getCommaSeparatedSampleIdsOfMolecularProfile(molecularProfile.getStableId()); + + List internalSampleIds = Arrays.stream(commaSeparatedSampleIdsOfMolecularProfile.getSplitSampleIds()) + .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); + + Map internalSampleIdToIndexMap = IntStream.range(0, internalSampleIds.size()).boxed() + .collect(Collectors.toMap(internalSampleIds::get, Function.identity())); + + Map> selectedCaseIdToInternalIdsMap = getCaseIdToInternalIdsMap(molecularProfileCaseSets, + enrichmentType, molecularProfile); + + // this block map caseIds(sampleIds or patientids) to sampleIndices which + // represents the position fount in the + // genetic_profile_samples.ORDERED_SAMPLE_LIST column + Map> groupIndicesMap = molecularProfileCaseSets.entrySet().stream() + .collect(Collectors.toMap(entity -> entity.getKey(), entity -> { + List sampleIndices = new ArrayList<>(); + entity.getValue().forEach(molecularProfileCaseIdentifier -> { + // consider only valid samples + if (selectedCaseIdToInternalIdsMap.containsKey(molecularProfileCaseIdentifier.getCaseId())) { + List sampleInternalIds = selectedCaseIdToInternalIdsMap + .get(molecularProfileCaseIdentifier.getCaseId()); + + // only consider samples which are profiled for the give molecular profile id + sampleInternalIds.forEach(sampleInternalId -> { + if (internalSampleIdToIndexMap.containsKey(sampleInternalId)) { + sampleIndices.add(internalSampleIdToIndexMap.get(sampleInternalId)); + } + }); + } + }); + return sampleIndices; + })); + return groupIndicesMap; + } + + private Map> getCaseIdToInternalIdsMap( + Map> molecularProfileCaseSets, EnrichmentType enrichmentType, + MolecularProfile molecularProfile) { + + if (enrichmentType.equals(EnrichmentType.PATIENT)) { + List patientIds = molecularProfileCaseSets.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getCaseId)) + .collect(Collectors.toList()); + + List samples = sampleService + .getAllSamplesOfPatientsInStudy(molecularProfile.getCancerStudyIdentifier(), patientIds, "SUMMARY"); + + return samples.stream().collect(Collectors.groupingBy(Sample::getPatientStableId, + Collectors.mapping(Sample::getInternalId, Collectors.toList()))); + } else { + List sampleIds = new ArrayList<>(); + List studyIds = new ArrayList<>(); + + molecularProfileCaseSets.values().forEach(molecularProfileCaseIdentifiers -> { + molecularProfileCaseIdentifiers.forEach(molecularProfileCaseIdentifier -> { + sampleIds.add(molecularProfileCaseIdentifier.getCaseId()); + studyIds.add(molecularProfile.getCancerStudyIdentifier()); + }); + }); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + + return samples.stream() + .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); + } } - private double calculatePValue(List alteredValues) { - - if (alteredValues.size() == 2) { - return TestUtils.tTest(alteredValues.get(0), alteredValues.get(1)); - } else { - // calculate Anova statisitcs if there are more than 2 groups - OneWayAnova oneWayAnova = new OneWayAnova(); - return oneWayAnova.anovaPValue(alteredValues); - } - } - - private double calculateStandardDeviation(double[] values) { - - DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(); - for (double value : values) { - descriptiveStatistics.addValue(value); - } - return descriptiveStatistics.getStandardDeviation(); - } - - /** - * - * This method maps valid samples in molecularProfileCaseSets to indices in - * genetic_alteration.VALUES column. Recall this column of the - * genetic_alteration table is a comma separated list of scalar values. Each - * value in this list is associated with a sample at the same position found in - * the genetic_profile_samples.ORDERED_SAMPLE_LIST column. - * - * @param molecularProfileCaseSets - * @param enrichmentType - * @param molecularProfile - * @return - */ - private Map> getGroupIndicesMap( - Map> molecularProfileCaseSets, EnrichmentType enrichmentType, - MolecularProfile molecularProfile) { - - MolecularProfileSamples commaSeparatedSampleIdsOfMolecularProfile = molecularDataRepository - .getCommaSeparatedSampleIdsOfMolecularProfile(molecularProfile.getStableId()); - - List internalSampleIds = Arrays.stream(commaSeparatedSampleIdsOfMolecularProfile.getSplitSampleIds()) - .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); - - Map internalSampleIdToIndexMap = IntStream.range(0, internalSampleIds.size()).boxed() - .collect(Collectors.toMap(internalSampleIds::get, Function.identity())); - - Map> selectedCaseIdToInternalIdsMap = getCaseIdToInternalIdsMap(molecularProfileCaseSets, - enrichmentType, molecularProfile); - - // this block map caseIds(sampleIds or patientids) to sampleIndices which - // represents the position fount in the - // genetic_profile_samples.ORDERED_SAMPLE_LIST column - Map> groupIndicesMap = molecularProfileCaseSets.entrySet().stream() - .collect(Collectors.toMap(entity -> entity.getKey(), entity -> { - List sampleIndices = new ArrayList<>(); - entity.getValue().forEach(molecularProfileCaseIdentifier -> { - // consider only valid samples - if (selectedCaseIdToInternalIdsMap.containsKey(molecularProfileCaseIdentifier.getCaseId())) { - List sampleInternalIds = selectedCaseIdToInternalIdsMap - .get(molecularProfileCaseIdentifier.getCaseId()); - - // only consider samples which are profiled for the give molecular profile id - sampleInternalIds.forEach(sampleInternalId -> { - if (internalSampleIdToIndexMap.containsKey(sampleInternalId)) { - sampleIndices.add(internalSampleIdToIndexMap.get(sampleInternalId)); - } - }); - } - }); - return sampleIndices; - })); - return groupIndicesMap; - } - - private Map> getCaseIdToInternalIdsMap( - Map> molecularProfileCaseSets, EnrichmentType enrichmentType, - MolecularProfile molecularProfile) { - - if (enrichmentType.equals(EnrichmentType.PATIENT)) { - List patientIds = molecularProfileCaseSets.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getCaseId)) - .collect(Collectors.toList()); - - List samples = sampleService - .getAllSamplesOfPatientsInStudy(molecularProfile.getCancerStudyIdentifier(), patientIds, "SUMMARY"); - - return samples.stream().collect(Collectors.groupingBy(Sample::getPatientStableId, - Collectors.mapping(Sample::getInternalId, Collectors.toList()))); - } else { - List sampleIds = new ArrayList<>(); - List studyIds = new ArrayList<>(); - - molecularProfileCaseSets.values().forEach(molecularProfileCaseIdentifiers -> { - molecularProfileCaseIdentifiers.forEach(molecularProfileCaseIdentifier -> { - sampleIds.add(molecularProfileCaseIdentifier.getCaseId()); - studyIds.add(molecularProfile.getCancerStudyIdentifier()); - }); - }); - List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - - return samples.stream() - .collect(Collectors.toMap(Sample::getStableId, x -> Arrays.asList(x.getInternalId()))); - } - } - -} +} \ No newline at end of file diff --git a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java index 4584341e2e2..150fb370178 100644 --- a/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java +++ b/service/src/main/java/org/cbioportal/service/util/FisherExactTestCalculator.java @@ -88,7 +88,7 @@ public double getTwoTailedPValue(int a, int b, int c, int d) { } } return p; - } + } public BigDecimal[] calcqValue(BigDecimal[] pValuesInIncreasingOrder) { BigDecimal cachedElement = BigDecimal.valueOf(0.0); int dataLength = pValuesInIncreasingOrder.length; @@ -120,6 +120,5 @@ private void reverseValues(int dataLength, BigDecimal[] reversedQValues) { reversedQValues[i] = reversedQValues[dataLength - i - 1]; reversedQValues[dataLength - i - 1] = temp; } - } } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java deleted file mode 100644 index f7f423f6cda..00000000000 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImplTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.cbioportal.service.impl; - -import org.cbioportal.model.*; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GeneService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.MolecularProfileService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.cbioportal.service.util.FisherExactTestCalculator; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import java.math.BigDecimal; -import java.util.*; - -import static org.junit.Assert.*; - - -@RunWith(MockitoJUnitRunner.class) -public class GenericAssayBinaryDataServiceImplTest extends BaseServiceImplTest{ - - @InjectMocks - private GenericAssayBinaryDataServiceImpl genericAssayBinaryDataServiceImpl; - @Mock - private SampleService sampleService; - @Mock - private MolecularProfileService molecularProfileService; - @Mock - private MolecularDataRepository molecularDataRepository; - - @Spy - @InjectMocks - private ExpressionEnrichmentUtil expressionEnrichmentUtil; - @Mock - private GenericAssayService genericAssayService; - - CancerStudy cancerStudy = new CancerStudy(); - MolecularProfile geneMolecularProfile = new MolecularProfile(); - MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); - List samples = new ArrayList<>(); - Map> molecularProfileCaseSets = new HashMap<>(); - Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); - private FisherExactTestCalculator fisherExactTestCalculator; - - // patient level only data - public static final String SAMPLE_ID5 = "sample_id5"; - - - @Before - public void setup() throws MolecularProfileNotFoundException { - cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); - cancerStudy.setCancerStudyIdentifier(STUDY_ID); - - geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); - geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); - - geneMolecularProfile.setCancerStudy(cancerStudy); - - molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); - molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); - - Sample sample1 = new Sample(); - sample1.setStableId(SAMPLE_ID1); - sample1.setInternalId(1); - sample1.setCancerStudyIdentifier(STUDY_ID); - sample1.setPatientId(1); - samples.add(sample1); - Sample sample2 = new Sample(); - sample2.setStableId(SAMPLE_ID2); - sample2.setInternalId(2); - sample2.setCancerStudyIdentifier(STUDY_ID); - sample2.setPatientId(2); - samples.add(sample2); - Sample sample3 = new Sample(); - sample3.setStableId(SAMPLE_ID3); - sample3.setInternalId(3); - sample3.setCancerStudyIdentifier(STUDY_ID); - sample3.setPatientId(3); - samples.add(sample3); - Sample sample4 = new Sample(); - sample4.setStableId(SAMPLE_ID4); - sample4.setInternalId(4); - sample4.setCancerStudyIdentifier(STUDY_ID); - sample4.setPatientId(4); - samples.add(sample4); - - List alteredSampleIdentifieres = new ArrayList<>(); - List unalteredSampleIdentifieres = new ArrayList<>(); - List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); - - MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); - caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier1.setCaseId(SAMPLE_ID1); - alteredSampleIdentifieres.add(caseIdentifier1); - - MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); - caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier2.setCaseId(SAMPLE_ID2); - alteredSampleIdentifieres.add(caseIdentifier2); - - MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); - caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier3.setCaseId(SAMPLE_ID3); - unalteredSampleIdentifieres.add(caseIdentifier3); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); - - MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); - caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier4.setCaseId(SAMPLE_ID4); - unalteredSampleIdentifieres.add(caseIdentifier4); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); - - // patient level only data - MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); - caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier5.setCaseId(SAMPLE_ID5); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); - - molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); - - Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(geneMolecularProfile); - - Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(molecularProfileSamples); - - Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), - Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); - } - - @Test - public void getGenericAssayBinaryEnrichments() throws Exception { - geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); - - List molecularDataList = new ArrayList(); - GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); - - // here are 2 groups - genericAssayMolecularAlteration1.setValues("true,true,true,false"); - molecularDataList.add(genericAssayMolecularAlteration1); - - GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); - genericAssayMolecularAlteration2.setValues("true,false,false,true"); - molecularDataList.add(genericAssayMolecularAlteration2); - Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, - "SUMMARY")).thenReturn(molecularDataList); - - Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( - Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), - Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) - .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), - new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - - List result = genericAssayBinaryDataServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, - molecularProfileCaseSets, EnrichmentType.SAMPLE); - - Assert.assertEquals(2, result.size()); - GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = result.get(0); - Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayBinaryEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); - - GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); - - GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("1.0"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.0"), alteredGroupStats.getStandardDeviation()); - - Assert.assertEquals(new BigDecimal("0.49999999999999983"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.99999999999999966"), genericAssayBinaryEnrichment.getqValue()); - - genericAssayBinaryEnrichment = result.get(1); - Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); - - unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); - - alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); - Assert.assertEquals(new BigDecimal("0.7071067811865476"), alteredGroupStats.getStandardDeviation()); - - Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getqValue()); - } - - -} \ No newline at end of file diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java deleted file mode 100644 index 405641dfc92..00000000000 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImplTest.java +++ /dev/null @@ -1,191 +0,0 @@ -package org.cbioportal.service.impl; - -import org.cbioportal.model.*; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GeneService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.MolecularProfileService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import java.math.BigDecimal; -import java.util.*; - -@RunWith(MockitoJUnitRunner.class) -public class GenericAssayCategoricalDataServiceImplTest extends BaseServiceImplTest{ - @InjectMocks - private GenericAssayCategoricalDataServiceImpl genericAssayCategoricalDataServiceImpl; - @Mock - private SampleService sampleService; - @Mock - private MolecularProfileService molecularProfileService; - @Mock - private MolecularDataRepository molecularDataRepository; - - @Spy - @InjectMocks - private ExpressionEnrichmentUtil expressionEnrichmentUtil; - @Mock - private GenericAssayService genericAssayService; - - CancerStudy cancerStudy = new CancerStudy(); - MolecularProfile geneMolecularProfile = new MolecularProfile(); - MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); - List samples = new ArrayList<>(); - Map> molecularProfileCaseSets = new HashMap<>(); - Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); - // patient level only data - public static final String SAMPLE_ID5 = "sample_id5"; - - - @Before - public void setup() throws MolecularProfileNotFoundException { - cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); - cancerStudy.setCancerStudyIdentifier(STUDY_ID); - - geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); - geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); - - geneMolecularProfile.setCancerStudy(cancerStudy); - - molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); - molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); - - Sample sample1 = new Sample(); - sample1.setStableId(SAMPLE_ID1); - sample1.setInternalId(1); - sample1.setCancerStudyIdentifier(STUDY_ID); - sample1.setPatientId(1); - samples.add(sample1); - Sample sample2 = new Sample(); - sample2.setStableId(SAMPLE_ID2); - sample2.setInternalId(2); - sample2.setCancerStudyIdentifier(STUDY_ID); - sample2.setPatientId(2); - samples.add(sample2); - Sample sample3 = new Sample(); - sample3.setStableId(SAMPLE_ID3); - sample3.setInternalId(3); - sample3.setCancerStudyIdentifier(STUDY_ID); - sample3.setPatientId(3); - samples.add(sample3); - Sample sample4 = new Sample(); - sample4.setStableId(SAMPLE_ID4); - sample4.setInternalId(4); - sample4.setCancerStudyIdentifier(STUDY_ID); - sample4.setPatientId(4); - samples.add(sample4); - - List alteredSampleIdentifieres = new ArrayList<>(); - List unalteredSampleIdentifieres = new ArrayList<>(); - List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); - - MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); - caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier1.setCaseId(SAMPLE_ID1); - alteredSampleIdentifieres.add(caseIdentifier1); - - MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); - caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier2.setCaseId(SAMPLE_ID2); - alteredSampleIdentifieres.add(caseIdentifier2); - - MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); - caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier3.setCaseId(SAMPLE_ID3); - unalteredSampleIdentifieres.add(caseIdentifier3); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); - - MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); - caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier4.setCaseId(SAMPLE_ID4); - unalteredSampleIdentifieres.add(caseIdentifier4); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); - - // patient level only data - MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); - caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); - caseIdentifier5.setCaseId(SAMPLE_ID5); - unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); - - molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); - molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); - - Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(geneMolecularProfile); - - Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) - .thenReturn(molecularProfileSamples); - - Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), - Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); - } - - @Test - public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFoundException { - geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); - - List molecularDataList = new ArrayList(); - GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); - genericAssayMolecularAlteration1.setValues("category1,category1,category2,category2"); - molecularDataList.add(genericAssayMolecularAlteration1); - - GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); - genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); - genericAssayMolecularAlteration2.setValues("category2,category2,category1,category1"); - molecularDataList.add(genericAssayMolecularAlteration2); - Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, - "SUMMARY")).thenReturn(molecularDataList); - - Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( - Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), - Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) - .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), - new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - - List result = genericAssayCategoricalDataServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, - molecularProfileCaseSets, EnrichmentType.SAMPLE); - - Assert.assertEquals(2, result.size()); - GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = result.get(0); - Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayCategoricalEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); - - GroupStatistics unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - - GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); - - genericAssayCategoricalEnrichment = result.get(1); - Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); - Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); - - unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); - Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); - - alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); - Assert.assertEquals("altered samples", alteredGroupStats.getName()); - - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); - Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); - } - -} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java new file mode 100644 index 00000000000..5d16690163a --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -0,0 +1,74 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Binary Data", description = " ") +public class GenericAssayBinaryDataController { + @Autowired + private GenericAssayBinaryDataService genericAssayBinaryDataService; + + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java new file mode 100644 index 00000000000..976a8076c3b --- /dev/null +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -0,0 +1,79 @@ +package org.cbioportal.web; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.commons.lang3.StringUtils; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayData; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.service.GenericAssayCategoricalDataService; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.GenericAssayNotFoundException; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.web.config.annotation.InternalApi; +import org.cbioportal.web.parameter.GenericAssayFilter; +import org.cbioportal.web.parameter.HeaderKeyConstants; +import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; +import org.cbioportal.web.parameter.Projection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +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.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; +import java.util.*; +import java.util.stream.Collectors; + +@InternalApi +@RestController +@Validated +@Api(tags = "Generic Assay Categorical Data", description = " ") +public class GenericAssayCategoricalDataController { + + @Autowired + private GenericAssayCategoricalDataService genericAssayCategoricalDataService; + + @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") + @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", + method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") + public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + @ApiIgnore + @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, + @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") + @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, + @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") + @Valid @RequestBody(required = false) List groups, + @ApiIgnore + @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) + throws MolecularProfileNotFoundException, UnsupportedOperationException { + + Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters + .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, + MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); + + Set molecularProfileIds = groupCaseIdentifierSet.values().stream() + .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() + .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) + .collect(Collectors.toSet()); + + if (molecularProfileIds.size() > 1) { + throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + } + + return new ResponseEntity<>( + genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), + HttpStatus.OK); + } + +} From 6d9896bd1472ef7eacc0a8f679f4224dd211702a Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 26 Jul 2023 14:17:22 -0400 Subject: [PATCH 25/40] finish tests --- .../GenericAssayBinaryDataServiceImpl.java | 1 - ...enericAssayCategoricalDataServiceImpl.java | 4 +-- .../web/GenericAssayBinaryDataController.java | 2 +- ...GenericAssayCategoricalDataController.java | 27 ++++++++++--------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index c02c725fbb0..38f208200af 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -34,7 +34,6 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData @Autowired private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); - @Autowired private ExpressionEnrichmentUtil expressionEnrichmentUtil; @Autowired diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index 9d6ab72ff84..c66650cdef4 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -46,7 +46,6 @@ public List getGenericAssayCategoricalEnrichm throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); Iterable maItr = molecularDataRepository @@ -57,8 +56,7 @@ public List getGenericAssayCategoricalEnrichm List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - - + Map sampleIdToPatientIdMap = samples.stream() .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java index 5d16690163a..60a7fddc58d 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java @@ -41,7 +41,7 @@ public class GenericAssayBinaryDataController { method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( + public ResponseEntity> fetchGenericAssayBinaryDataEnrichmentInMultipleMolecularProfiles( @ApiIgnore @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java index 976a8076c3b..c3344ce94e9 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java @@ -4,10 +4,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayData; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.*; import org.cbioportal.service.GenericAssayCategoricalDataService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.SampleService; @@ -56,7 +53,13 @@ public ResponseEntity> fetchGenericAssay @ApiIgnore @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) throws MolecularProfileNotFoundException, UnsupportedOperationException { - + + return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), + HttpStatus.OK); + } + private List fetchExpressionEnrichments(EnrichmentType enrichmentType, + List interceptedMolecularProfileCasesGroupFilters + ) throws MolecularProfileNotFoundException { Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); @@ -65,15 +68,13 @@ public ResponseEntity> fetchGenericAssay .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) .collect(Collectors.toSet()); - + if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); + throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - - return new ResponseEntity<>( - genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), - HttpStatus.OK); + return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } - } + + From e26844e3cee8f827bab9d930dd3b24fa6f43a0f8 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:04:39 -0400 Subject: [PATCH 26/40] modify controller file structure --- .../web/GenericAssayBinaryDataController.java | 74 ----------------- ...GenericAssayCategoricalDataController.java | 80 ------------------- 2 files changed, 154 deletions(-) delete mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java delete mode 100644 web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java deleted file mode 100644 index 60a7fddc58d..00000000000 --- a/web/src/main/java/org/cbioportal/web/GenericAssayBinaryDataController.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.cbioportal.web; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.GenericAssayBinaryDataService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; -import org.cbioportal.web.config.annotation.InternalApi; -import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; -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.*; -import springfox.documentation.annotations.ApiIgnore; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -@InternalApi -@RestController -@Validated -@Api(tags = "Generic Assay Binary Data", description = " ") -public class GenericAssayBinaryDataController { - @Autowired - private GenericAssayBinaryDataService genericAssayBinaryDataService; - - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/binary/fetch", - method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation("Fetch generic assay binary data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayBinaryDataEnrichmentInMultipleMolecularProfiles( - @ApiIgnore - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") - @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, - @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") - @Valid @RequestBody(required = false) List groups, - @ApiIgnore - @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) - throws MolecularProfileNotFoundException, UnsupportedOperationException { - - Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters - .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, - MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); - - Set molecularProfileIds = groupCaseIdentifierSet.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) - .collect(Collectors.toSet()); - - if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study enrichments is not yet implemented"); - } - - return new ResponseEntity<>( - genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), - HttpStatus.OK); - } - -} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java b/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java deleted file mode 100644 index c3344ce94e9..00000000000 --- a/web/src/main/java/org/cbioportal/web/GenericAssayCategoricalDataController.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.cbioportal.web; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; -import org.cbioportal.model.*; -import org.cbioportal.service.GenericAssayCategoricalDataService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.GenericAssayNotFoundException; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.web.config.annotation.InternalApi; -import org.cbioportal.web.parameter.GenericAssayFilter; -import org.cbioportal.web.parameter.HeaderKeyConstants; -import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; -import org.cbioportal.web.parameter.Projection; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -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.*; -import springfox.documentation.annotations.ApiIgnore; - -import javax.validation.Valid; -import java.util.*; -import java.util.stream.Collectors; - -@InternalApi -@RestController -@Validated -@Api(tags = "Generic Assay Categorical Data", description = " ") -public class GenericAssayCategoricalDataController { - - @Autowired - private GenericAssayCategoricalDataService genericAssayCategoricalDataService; - - @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") - @RequestMapping(value = "/generic-assay-enrichments/categorical/fetch", - method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation("Fetch generic assay categorical data enrichments in a molecular profile") - public ResponseEntity> fetchGenericAssayCategoricalDataEnrichmentInMultipleMolecularProfiles( - @ApiIgnore - @RequestAttribute(required = false, value = "involvedCancerStudies") Collection involvedCancerStudies, - @ApiParam("Type of the enrichment e.g. SAMPLE or PATIENT") - @RequestParam(defaultValue = "SAMPLE") EnrichmentType enrichmentType, - @ApiParam(required = true, value = "List of groups containing sample and molecular profile identifiers") - @Valid @RequestBody(required = false) List groups, - @ApiIgnore - @Valid @RequestAttribute(required = false, value = "interceptedMolecularProfileCasesGroupFilters") List interceptedMolecularProfileCasesGroupFilters) - throws MolecularProfileNotFoundException, UnsupportedOperationException { - - return new ResponseEntity<>(fetchExpressionEnrichments(enrichmentType, interceptedMolecularProfileCasesGroupFilters), - HttpStatus.OK); - } - private List fetchExpressionEnrichments(EnrichmentType enrichmentType, - List interceptedMolecularProfileCasesGroupFilters - ) throws MolecularProfileNotFoundException { - Map> groupCaseIdentifierSet = interceptedMolecularProfileCasesGroupFilters - .stream().collect(Collectors.toMap(MolecularProfileCasesGroupFilter::getName, - MolecularProfileCasesGroupFilter::getMolecularProfileCaseIdentifiers)); - - Set molecularProfileIds = groupCaseIdentifierSet.values().stream() - .flatMap(molecularProfileCaseSet -> molecularProfileCaseSet.stream() - .map(MolecularProfileCaseIdentifier::getMolecularProfileId)) - .collect(Collectors.toSet()); - - if (molecularProfileIds.size() > 1) { - throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); - } - return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( - molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); - } -} - - From 4571b265f6c92611b323ae3ffb8b84697d1df35f Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:19:31 -0400 Subject: [PATCH 27/40] refactor some variables --- .../service/impl/GenericAssayBinaryDataServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 38f208200af..4a6e820e8a8 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -89,8 +89,7 @@ public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment }); // Extract pValues and calculate qValues. - BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); - + BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(GenericAssayBinaryEnrichment ::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); // Assign qValues back to the objects. From 6be68ef22d6dcb3780577b2f3ad2190cc0aae24f Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 00:13:11 -0400 Subject: [PATCH 28/40] modify enrichment compare and validate issue --- .../org/cbioportal/model/ExpressionEnrichment.java | 2 +- .../model/GenericAssayCategoricalEnrichment.java | 2 +- .../cbioportal/model/GenericAssayEnrichment.java | 5 ++++- .../impl/GenericAssayBinaryDataServiceImpl.java | 13 +++++-------- .../GenericAssayCategoricalDataServiceImpl.java | 10 ++++------ 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java index 57e6df2a5db..40ee2d11107 100644 --- a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java @@ -6,7 +6,7 @@ import javax.validation.constraints.NotNull; -public class ExpressionEnrichment implements Serializable { +public abstract class ExpressionEnrichment implements Serializable { @NotNull private List groupsStatistics; diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java index 1632f3718c4..2fdb661cf38 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayCategoricalEnrichment.java @@ -2,7 +2,6 @@ import javax.validation.constraints.NotNull; import java.math.BigDecimal; -import java.util.Comparator; public class GenericAssayCategoricalEnrichment extends GenericAssayEnrichment { @NotNull @@ -15,4 +14,5 @@ public BigDecimal getqValue() { public void setqValue(BigDecimal qValue) { this.qValue = qValue; } + } diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java index 8278694f9be..371032595cf 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java @@ -5,7 +5,7 @@ import javax.validation.constraints.NotNull; -public class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { +public abstract class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { @NotNull private String stableId; @@ -38,4 +38,7 @@ public void setGenericEntityMetaProperties(HashMap genericEntity this.genericEntityMetaProperties = genericEntityMetaProperties; } + public static int compare(GenericAssayEnrichment c1, GenericAssayEnrichment c2) { + return c1.getpValue().compareTo(c2.getpValue()); + } } diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java index 4a6e820e8a8..73566b87561 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java @@ -80,14 +80,7 @@ public List getGenericAssayBinaryEnrichments( List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); - // Sort the list based on pValue. - Collections.sort(genericAssayBinaryEnrichments, new Comparator() { - @Override - public int compare(GenericAssayBinaryEnrichment c1, GenericAssayBinaryEnrichment c2) { - return c1.getpValue().compareTo(c2.getpValue()); - } - }); - + Collections.sort(genericAssayBinaryEnrichments, GenericAssayEnrichment::compare); // Extract pValues and calculate qValues. BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(GenericAssayBinaryEnrichment ::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); @@ -121,6 +114,10 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } + System.out.println(molecularProfile.getGenericAssayType()); + if(!molecularProfile.getGenericAssayType().equals("BINARY")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } } } diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java index c66650cdef4..cacaa1ca0cc 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java @@ -81,12 +81,7 @@ public List getGenericAssayCategoricalEnrichm filteredMolecularProfileCaseSets, enrichmentType, maItr); // Sort the list based on pValue. - Collections.sort(genericAssayCategoricalEnrichments, new Comparator() { - @Override - public int compare(GenericAssayCategoricalEnrichment c1, GenericAssayCategoricalEnrichment c2) { - return c1.getpValue().compareTo(c2.getpValue()); - } - }); + Collections.sort(genericAssayCategoricalEnrichments, GenericAssayEnrichment::compare); // Extract pValues and calculate qValues. BigDecimal[] pValues = genericAssayCategoricalEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); @@ -119,6 +114,9 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } + if(!molecularProfile.getGenericAssayType().equals("CATEGORICAL")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } } } From 54c8cc3255c1faf46fff8a3243a5fb2bc678cd47 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:44:33 -0400 Subject: [PATCH 29/40] refactor the controllers and services --- .../model/GenericAssayBinaryEnrichment.java | 11 +- .../model/GenericAssayEnrichment.java | 12 +- .../GenericAssayCategoricalDataService.java | 16 -- ...ava => GenericAssayEnrichmentService.java} | 7 +- ...enericAssayCategoricalDataServiceImpl.java | 122 ---------------- ...=> GenericAssayEnrichmentServiceImpl.java} | 137 ++++++++++++------ ...GenericAssayEnrichmentServiceImplTest.java | 4 + .../web/GenericAssayEnrichmentController.java | 12 +- 8 files changed, 117 insertions(+), 204 deletions(-) delete mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java rename service/src/main/java/org/cbioportal/service/{GenericAssayBinaryDataService.java => GenericAssayEnrichmentService.java} (52%) delete mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java rename service/src/main/java/org/cbioportal/service/impl/{GenericAssayBinaryDataServiceImpl.java => GenericAssayEnrichmentServiceImpl.java} (51%) create mode 100644 service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java index f16a7015db6..f7ccbc7c3b5 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayBinaryEnrichment.java @@ -7,8 +7,6 @@ public class GenericAssayBinaryEnrichment extends GenericAssayEnrichment { @NotNull private List counts; - @NotNull - private BigDecimal qValue; public List getCounts() { return counts; @@ -17,12 +15,5 @@ public List getCounts() { public void setCounts(List counts) { this.counts = counts; } - - public BigDecimal getqValue() { - return qValue; - } - - public void setqValue(BigDecimal qValue) { - this.qValue = qValue; - } + } diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java index 371032595cf..074aa8926d9 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java @@ -1,16 +1,19 @@ package org.cbioportal.model; import java.io.Serializable; +import java.math.BigDecimal; import java.util.HashMap; import javax.validation.constraints.NotNull; -public abstract class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { +public class GenericAssayEnrichment extends ExpressionEnrichment implements Serializable { @NotNull private String stableId; @NotNull private String name; + @NotNull + private BigDecimal qValue; @NotNull private HashMap genericEntityMetaProperties; @@ -41,4 +44,11 @@ public void setGenericEntityMetaProperties(HashMap genericEntity public static int compare(GenericAssayEnrichment c1, GenericAssayEnrichment c2) { return c1.getpValue().compareTo(c2.getpValue()); } + public BigDecimal getqValue() { + return qValue; + } + + public void setqValue(BigDecimal qValue) { + this.qValue = qValue; + } } diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java deleted file mode 100644 index ceace7ff351..00000000000 --- a/service/src/main/java/org/cbioportal/service/GenericAssayCategoricalDataService.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.cbioportal.service; - -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import java.util.List; -import java.util.Map; - -public interface GenericAssayCategoricalDataService { - List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, - EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException; - -} diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java b/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java similarity index 52% rename from service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java rename to service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java index 91d6f4df92c..80451d6e7e9 100644 --- a/service/src/main/java/org/cbioportal/service/GenericAssayBinaryDataService.java +++ b/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java @@ -2,17 +2,22 @@ import org.cbioportal.model.EnrichmentType; import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import java.util.List; import java.util.Map; -public interface GenericAssayBinaryDataService { +public interface GenericAssayEnrichmentService { List getGenericAssayBinaryEnrichments( String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; + List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; } diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java deleted file mode 100644 index cacaa1ca0cc..00000000000 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayCategoricalDataServiceImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.cbioportal.service.impl; - -import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.*; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.persistence.GenericAssayRepository; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.persistence.SampleListRepository; -import org.cbioportal.service.*; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.cbioportal.service.util.FisherExactTestCalculator; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -@Service -public class GenericAssayCategoricalDataServiceImpl implements GenericAssayCategoricalDataService { - - @Autowired - private MolecularDataRepository molecularDataRepository; - - @Autowired - private SampleService sampleService; - - @Autowired - private MolecularProfileService molecularProfileService; - - @Autowired - private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); - - @Autowired - private ExpressionEnrichmentUtil expressionEnrichmentUtil = new ExpressionEnrichmentUtil(); - @Autowired - private GenericAssayService genericAssayService; - - @Override - @Transactional(readOnly = true) - public List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - - MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); - - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - - Map> filteredMolecularProfileCaseSets; - if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { - List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); - List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); - List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - - Map sampleIdToPatientIdMap = samples.stream() - .filter(sample -> sample != null && sample.getStableId() != null && sample.getPatientId() != null) - .collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); - - filteredMolecularProfileCaseSets = new HashMap<>(); - for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { - Set patientSet = new HashSet(); - List identifierListUniqueByPatientId = new ArrayList<>(); - for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { - if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { - identifierListUniqueByPatientId.add(caseIdentifier); - patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); - } - } - filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); - } - } else { - filteredMolecularProfileCaseSets = molecularProfileCaseSets; - } - - List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); - - // Sort the list based on pValue. - Collections.sort(genericAssayCategoricalEnrichments, GenericAssayEnrichment::compare); - - // Extract pValues and calculate qValues. - BigDecimal[] pValues = genericAssayCategoricalEnrichments.stream().map(a -> a.getpValue()).toArray(BigDecimal[]::new); - BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - - // Assign qValues back to the objects. - for (int i = 0; i < genericAssayCategoricalEnrichments.size(); i++) { - genericAssayCategoricalEnrichments.get(i).setqValue(qValues[i]); - } - - List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - - Map genericAssayMetaByStableId = genericAssayService - .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, - getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) - .collect(Collectors.toList()), - "SUMMARY") - .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); - - return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - } - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - if(!molecularProfile.getGenericAssayType().equals("CATEGORICAL")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } - -} diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java similarity index 51% rename from service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java rename to service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index 73566b87561..336519ab893 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayBinaryDataServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -4,7 +4,7 @@ import org.cbioportal.model.*; import org.cbioportal.model.meta.GenericAssayMeta; import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GenericAssayBinaryDataService; +import org.cbioportal.service.GenericAssayEnrichmentService; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.MolecularProfileService; import org.cbioportal.service.SampleService; @@ -19,8 +19,9 @@ import java.util.function.Function; import java.util.stream.Collectors; + @Service -public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryDataService { +public class GenericAssayEnrichmentServiceImpl implements GenericAssayEnrichmentService { @Autowired private MolecularDataRepository molecularDataRepository; @@ -43,25 +44,95 @@ public class GenericAssayBinaryDataServiceImpl implements GenericAssayBinaryData @Transactional(readOnly = true) public List getGenericAssayBinaryEnrichments( String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { - MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + + filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY)); + calcQValues(genericAssayBinaryEnrichments); + + List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + + } + + @Override + @Transactional(readOnly = true) + public List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); Map> filteredMolecularProfileCaseSets; - + filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + calcQValues(genericAssayCategoricalEnrichments); + + List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); + return molecularProfile; + } + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes, boolean isBinary) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + if(isBinary) { + if(!molecularProfile.getDatatype().equals("BINARY")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } else { + if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + } + + private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); - filteredMolecularProfileCaseSets = new HashMap<>(); + Map> filteredMolecularProfileCaseSets = new HashMap<>(); for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { Set patientSet = new HashSet(); List identifierListUniqueByPatientId = new ArrayList<>(); @@ -73,51 +144,25 @@ public List getGenericAssayBinaryEnrichments( } filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); } + return filteredMolecularProfileCaseSets; } else { - filteredMolecularProfileCaseSets = molecularProfileCaseSets; + return molecularProfileCaseSets; } + } - List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); + private Map getGenericAssayMetaByStableId(List stableIds, String molecularProfileId) { + return genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds(stableIds, stableIds.stream().map(sid -> molecularProfileId) + .collect(Collectors.toList()), "SUMMARY").stream() + .collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + } - Collections.sort(genericAssayBinaryEnrichments, GenericAssayEnrichment::compare); - // Extract pValues and calculate qValues. - BigDecimal[] pValues = genericAssayBinaryEnrichments.stream().map(GenericAssayBinaryEnrichment ::getpValue).toArray(BigDecimal[]::new); + private void calcQValues(List enrichments) { + Collections.sort(enrichments, GenericAssayEnrichment::compare); + BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - // Assign qValues back to the objects. - for (int i = 0; i < genericAssayBinaryEnrichments.size(); i++) { - genericAssayBinaryEnrichments.get(i).setqValue(qValues[i]); - } - - List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - - Map genericAssayMetaByStableId = genericAssayService - .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, - getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) - .collect(Collectors.toList()), - "SUMMARY") - .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); - - return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - - } - - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - System.out.println(molecularProfile.getGenericAssayType()); - if(!molecularProfile.getGenericAssayType().equals("BINARY")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + for (int i = 0; i < enrichments.size(); i++) { + enrichments.get(i).setqValue(qValues[i]); } } - } diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java new file mode 100644 index 00000000000..e0f6127b3a1 --- /dev/null +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java @@ -0,0 +1,4 @@ +package org.cbioportal.service.impl; + +public class GenericAssayEnrichmentServiceImplTest { +} diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java index bac54097958..569996ddcf1 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java @@ -7,10 +7,8 @@ import org.cbioportal.model.GenericAssayBinaryEnrichment; import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.GenericAssayBinaryDataService; -import org.cbioportal.service.GenericAssayCategoricalDataService; +import org.cbioportal.service.GenericAssayEnrichmentService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.impl.GenericAssayBinaryDataServiceImpl; import org.cbioportal.web.config.annotation.InternalApi; import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; import org.springframework.beans.factory.annotation.Autowired; @@ -35,9 +33,7 @@ @Api(tags = "Generic Assay Enrichment Data", description = " ") public class GenericAssayEnrichmentController { @Autowired - private GenericAssayCategoricalDataService genericAssayCategoricalDataService; - @Autowired - private GenericAssayBinaryDataService genericAssayBinaryDataService; + private GenericAssayEnrichmentService genericAssayEnrichmentService; @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") @RequestMapping(value = "/generic-assay-categorical-enrichments/fetch", @@ -89,7 +85,7 @@ public ResponseEntity> fetchGenericAssayBinar } return new ResponseEntity<>( - genericAssayBinaryDataService.getGenericAssayBinaryEnrichments( + genericAssayEnrichmentService.getGenericAssayBinaryEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), HttpStatus.OK); } @@ -109,7 +105,7 @@ private List fetchExpressionEnrichments(Enric if (molecularProfileIds.size() > 1) { throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - return genericAssayCategoricalDataService.getGenericAssayCategoricalEnrichments( + return genericAssayEnrichmentService.getGenericAssayCategoricalEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } } From 74bd2ae8ff5e7e524cb0bff8ac38d09b8aca6adb Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 13:32:00 -0400 Subject: [PATCH 30/40] refactor test --- ...GenericAssayEnrichmentServiceImplTest.java | 259 +++++++++++++++++- 1 file changed, 258 insertions(+), 1 deletion(-) diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java index e0f6127b3a1..b92b629caee 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java @@ -1,4 +1,261 @@ package org.cbioportal.service.impl; -public class GenericAssayEnrichmentServiceImplTest { +import org.cbioportal.model.*; +import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.persistence.MolecularDataRepository; +import org.cbioportal.service.GenericAssayService; +import org.cbioportal.service.MolecularProfileService; +import org.cbioportal.service.SampleService; +import org.cbioportal.service.exception.MolecularProfileNotFoundException; +import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import java.math.BigDecimal; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + + +@RunWith(MockitoJUnitRunner.class) +public class GenericAssayEnrichmentServiceImplTest extends BaseServiceImplTest{ + @InjectMocks + private GenericAssayEnrichmentServiceImpl genericAssayEnrichmentServiceImpl; + @Mock + private SampleService sampleService; + @Mock + private MolecularProfileService molecularProfileService; + @Mock + private MolecularDataRepository molecularDataRepository; + + @Mock + private GenericAssayService genericAssayService; + + @Spy + @InjectMocks + private ExpressionEnrichmentUtil expressionEnrichmentUtil; + + CancerStudy cancerStudy = new CancerStudy(); + MolecularProfile geneMolecularProfile = new MolecularProfile(); + MolecularProfileSamples molecularProfileSamples = new MolecularProfileSamples(); + List samples = new ArrayList<>(); + Map> molecularProfileCaseSets = new HashMap<>(); + Map> molecularProfilePatientLevelCaseSets = new HashMap<>(); + // patient level only data + public static final String SAMPLE_ID5 = "sample_id5"; + + + @Before + public void setup() throws MolecularProfileNotFoundException { + cancerStudy.setReferenceGenome(ReferenceGenome.HOMO_SAPIENS_DEFAULT_GENOME_NAME); + cancerStudy.setCancerStudyIdentifier(STUDY_ID); + + geneMolecularProfile.setCancerStudyIdentifier(STUDY_ID); + geneMolecularProfile.setStableId(MOLECULAR_PROFILE_ID); + + geneMolecularProfile.setCancerStudy(cancerStudy); + + molecularProfileSamples.setMolecularProfileId(MOLECULAR_PROFILE_ID); + molecularProfileSamples.setCommaSeparatedSampleIds("1,2,3,4"); + + Sample sample1 = new Sample(); + sample1.setStableId(SAMPLE_ID1); + sample1.setInternalId(1); + sample1.setCancerStudyIdentifier(STUDY_ID); + sample1.setPatientId(1); + samples.add(sample1); + Sample sample2 = new Sample(); + sample2.setStableId(SAMPLE_ID2); + sample2.setInternalId(2); + sample2.setCancerStudyIdentifier(STUDY_ID); + sample2.setPatientId(2); + samples.add(sample2); + Sample sample3 = new Sample(); + sample3.setStableId(SAMPLE_ID3); + sample3.setInternalId(3); + sample3.setCancerStudyIdentifier(STUDY_ID); + sample3.setPatientId(3); + samples.add(sample3); + Sample sample4 = new Sample(); + sample4.setStableId(SAMPLE_ID4); + sample4.setInternalId(4); + sample4.setCancerStudyIdentifier(STUDY_ID); + sample4.setPatientId(4); + samples.add(sample4); + + List alteredSampleIdentifieres = new ArrayList<>(); + List unalteredSampleIdentifieres = new ArrayList<>(); + List unalteredPatientLevelSampleIdentifieres = new ArrayList<>(); + + MolecularProfileCaseIdentifier caseIdentifier1 = new MolecularProfileCaseIdentifier(); + caseIdentifier1.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier1.setCaseId(SAMPLE_ID1); + alteredSampleIdentifieres.add(caseIdentifier1); + + MolecularProfileCaseIdentifier caseIdentifier2 = new MolecularProfileCaseIdentifier(); + caseIdentifier2.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier2.setCaseId(SAMPLE_ID2); + alteredSampleIdentifieres.add(caseIdentifier2); + + MolecularProfileCaseIdentifier caseIdentifier3 = new MolecularProfileCaseIdentifier(); + caseIdentifier3.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier3.setCaseId(SAMPLE_ID3); + unalteredSampleIdentifieres.add(caseIdentifier3); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier3); + + MolecularProfileCaseIdentifier caseIdentifier4 = new MolecularProfileCaseIdentifier(); + caseIdentifier4.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier4.setCaseId(SAMPLE_ID4); + unalteredSampleIdentifieres.add(caseIdentifier4); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier4); + + // patient level only data + MolecularProfileCaseIdentifier caseIdentifier5 = new MolecularProfileCaseIdentifier(); + caseIdentifier5.setMolecularProfileId(MOLECULAR_PROFILE_ID); + caseIdentifier5.setCaseId(SAMPLE_ID5); + unalteredPatientLevelSampleIdentifieres.add(caseIdentifier5); + + molecularProfileCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfileCaseSets.put("unaltered samples", unalteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("altered samples", alteredSampleIdentifieres); + molecularProfilePatientLevelCaseSets.put("unaltered samples", unalteredPatientLevelSampleIdentifieres); + + Mockito.when(molecularProfileService.getMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(geneMolecularProfile); + + Mockito.when(molecularDataRepository.getCommaSeparatedSampleIdsOfMolecularProfile(MOLECULAR_PROFILE_ID)) + .thenReturn(molecularProfileSamples); + + Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), + Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); + } + + @Test + public void getGenericAssayBinaryEnrichments() throws Exception { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + geneMolecularProfile.setDatatype("BINARY"); + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + + // here are 2 groups + genericAssayMolecularAlteration1.setValues("true,true,true,false"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("true,false,false,true"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayEnrichmentServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayBinaryEnrichment genericAssayBinaryEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); + + GroupStatistics alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("1.0"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.0"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("0.49999999999999983"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.99999999999999966"), genericAssayBinaryEnrichment.getqValue()); + + genericAssayBinaryEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayBinaryEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayBinaryEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), unalteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), unalteredGroupStats.getStandardDeviation()); + + alteredGroupStats = genericAssayBinaryEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + Assert.assertEquals(new BigDecimal("0.5"), alteredGroupStats.getMeanExpression()); + Assert.assertEquals(new BigDecimal("0.7071067811865476"), alteredGroupStats.getStandardDeviation()); + + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("1.0"), genericAssayBinaryEnrichment.getqValue()); + } + + + @Test + public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFoundException { + geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); + geneMolecularProfile.setDatatype("CATEGORICAL"); + List molecularDataList = new ArrayList(); + GenericAssayMolecularAlteration genericAssayMolecularAlteration1 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration1.setGenericAssayStableId(HUGO_GENE_SYMBOL_1); + genericAssayMolecularAlteration1.setValues("category1,category1,category2,category2"); + molecularDataList.add(genericAssayMolecularAlteration1); + + GenericAssayMolecularAlteration genericAssayMolecularAlteration2 = new GenericAssayMolecularAlteration(); + genericAssayMolecularAlteration2.setGenericAssayStableId(HUGO_GENE_SYMBOL_2); + genericAssayMolecularAlteration2.setValues("category2,category2,category1,category1"); + molecularDataList.add(genericAssayMolecularAlteration2); + Mockito.when(molecularDataRepository.getGenericAssayMolecularAlterationsIterable(MOLECULAR_PROFILE_ID, null, + "SUMMARY")).thenReturn(molecularDataList); + + Mockito.when(genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds( + Arrays.asList(HUGO_GENE_SYMBOL_1, HUGO_GENE_SYMBOL_2), + Arrays.asList(MOLECULAR_PROFILE_ID, MOLECULAR_PROFILE_ID), "SUMMARY")) + .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), + new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); + + List result = genericAssayEnrichmentServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, + molecularProfileCaseSets, EnrichmentType.SAMPLE); + + Assert.assertEquals(2, result.size()); + GenericAssayCategoricalEnrichment genericAssayCategoricalEnrichment = result.get(0); + Assert.assertEquals(HUGO_GENE_SYMBOL_1, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + GroupStatistics unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + GroupStatistics alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); + + genericAssayCategoricalEnrichment = result.get(1); + Assert.assertEquals(HUGO_GENE_SYMBOL_2, genericAssayCategoricalEnrichment.getStableId()); + Assert.assertEquals(2, genericAssayCategoricalEnrichment.getGroupsStatistics().size()); + + unalteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(0); + Assert.assertEquals("unaltered samples", unalteredGroupStats.getName()); + + alteredGroupStats = genericAssayCategoricalEnrichment.getGroupsStatistics().get(1); + Assert.assertEquals("altered samples", alteredGroupStats.getName()); + + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getpValue()); + Assert.assertEquals(new BigDecimal("0.04550026389635764"), genericAssayCategoricalEnrichment.getqValue()); + } + } From 5bc13aa50f31f36f0ab3ae92ec6d32ed92f40561 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:03:53 -0400 Subject: [PATCH 31/40] Update GenericAssayEnrichmentServiceImpl.java --- .../service/impl/GenericAssayEnrichmentServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index 336519ab893..a8bceceae2d 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -110,7 +110,8 @@ private MolecularProfile getAndValidateMolecularProfile(String molecularProfileI } private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes, boolean isBinary) throws MolecularProfileNotFoundException { + List validMolecularAlterationTypes, + boolean isBinary) throws MolecularProfileNotFoundException { if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } From fa8d5ec82436f4c30b50bdced959999993c49d19 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 10:46:11 -0400 Subject: [PATCH 32/40] fixed simplification issues --- .../main/java/org/cbioportal/model/ExpressionEnrichment.java | 2 +- .../service/impl/GenericAssayEnrichmentServiceImpl.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java index 40ee2d11107..57e6df2a5db 100644 --- a/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/ExpressionEnrichment.java @@ -6,7 +6,7 @@ import javax.validation.constraints.NotNull; -public abstract class ExpressionEnrichment implements Serializable { +public class ExpressionEnrichment implements Serializable { @NotNull private List groupsStatistics; diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index a8bceceae2d..d49876b0dbc 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -51,9 +51,7 @@ public List getGenericAssayBinaryEnrichments( Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - Map> filteredMolecularProfileCaseSets; - - filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); From fe2acc86748a3744733b06b664bdea7fc9f77923 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 11:05:28 -0400 Subject: [PATCH 33/40] add inline comments --- .../impl/GenericAssayEnrichmentServiceImpl.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index d49876b0dbc..948f54df1cf 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -47,28 +47,36 @@ public List getGenericAssayBinaryEnrichments( Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { + // Validate and fetch molecular profile MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + + // Get the molecular alterations for the provided profile Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + // Filter the case sets based on molecular profile Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + // Obtain binary enrichments from the utility List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); + // Calculate q-values for enrichments calcQValues(genericAssayBinaryEnrichments); + // Extract stable IDs from binary enrichments List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + // Fetch metadata of generic assays by their stable IDs Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + // Assign meta properties to each enrichment return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { enrichmentDatum.setGenericEntityMetaProperties( genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); return enrichmentDatum; }).collect(Collectors.toList()); - } @Override @@ -111,8 +119,10 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, List validMolecularAlterationTypes, boolean isBinary) throws MolecularProfileNotFoundException { if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + // Check alteration type throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } + // Check datatype for binary or categorical if(isBinary) { if(!molecularProfile.getDatatype().equals("BINARY")) { throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); @@ -126,6 +136,8 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + // If patient level, filter duplicates by patient id + // For now we only support sample level for samples List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); @@ -156,10 +168,11 @@ private Map getGenericAssayMetaByStableId(List } private void calcQValues(List enrichments) { + // Sort enrichments by pValue Collections.sort(enrichments, GenericAssayEnrichment::compare); BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - + // Assign q-values to enrichments for (int i = 0; i < enrichments.size(); i++) { enrichments.get(i).setqValue(qValues[i]); } From 7a473edc1164980d681416883313acc434484e3a Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 11:28:01 -0400 Subject: [PATCH 34/40] modify import --- .../service/impl/GenericAssayEnrichmentServiceImpl.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java index 948f54df1cf..424ae1a44ef 100644 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java @@ -1,8 +1,15 @@ package org.cbioportal.service.impl; import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.*; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.GenericAssayMolecularAlteration; +import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.Sample; +import org.cbioportal.model.GenericAssayEnrichment; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.GenericAssayEnrichmentService; import org.cbioportal.service.GenericAssayService; From ca00f3300f10d66846fc372e89189b0ba362da40 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Fri, 11 Aug 2023 13:40:38 -0400 Subject: [PATCH 35/40] solve core test issue --- .../service/ExpressionEnrichmentService.java | 17 +- .../impl/ExpressionEnrichmentServiceImpl.java | 154 ++++++++++++++++-- .../web/GenericAssayEnrichmentController.java | 8 +- 3 files changed, 163 insertions(+), 16 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java index ae602d46b35..04295d959b8 100644 --- a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java +++ b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java @@ -3,20 +3,33 @@ import java.util.List; import java.util.Map; -import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.GenericAssayEnrichment; import org.cbioportal.model.GenomicEnrichment; +import org.cbioportal.model.EnrichmentType; + import org.cbioportal.model.MolecularProfileCaseIdentifier; import org.cbioportal.service.exception.MolecularProfileNotFoundException; public interface ExpressionEnrichmentService { List getGenomicEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; List getGenericAssayEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; + List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; + + List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, + EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException; } diff --git a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java index fb8fe8ef62a..aeb5f65818e 100644 --- a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java @@ -1,19 +1,12 @@ package org.cbioportal.service.impl; +import java.math.BigDecimal; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.Gene; -import org.cbioportal.model.GeneMolecularAlteration; -import org.cbioportal.model.GenericAssayEnrichment; -import org.cbioportal.model.GenericAssayMolecularAlteration; -import org.cbioportal.model.GenomicEnrichment; -import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.*; import org.cbioportal.model.MolecularProfile.MolecularAlterationType; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.model.Sample; import org.cbioportal.model.meta.GenericAssayMeta; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.ExpressionEnrichmentService; @@ -23,6 +16,7 @@ import org.cbioportal.service.SampleService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.service.util.ExpressionEnrichmentUtil; +import org.cbioportal.service.util.FisherExactTestCalculator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -42,7 +36,8 @@ public class ExpressionEnrichmentServiceImpl implements ExpressionEnrichmentServ private GenericAssayService genericAssayService; @Autowired private SampleService sampleService; - + @Autowired + private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); @Override // transaction needs to be setup here in order to return Iterable from // molecularDataService in fetchCoExpressions @@ -152,4 +147,143 @@ private void validateMolecularProfile(MolecularProfile molecularProfile, } } + + @Override + @Transactional(readOnly = true) + public List getGenericAssayBinaryEnrichments( + String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + // Validate and fetch molecular profile + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + + // Get the molecular alterations for the provided profile + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + // Filter the case sets based on molecular profile + Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + // Obtain binary enrichments from the utility + List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + // Calculate q-values for enrichments + calcQValues(genericAssayBinaryEnrichments); + + // Extract stable IDs from binary enrichments + List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + + // Fetch metadata of generic assays by their stable IDs + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + // Assign meta properties to each enrichment + return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + @Override + @Transactional(readOnly = true) + public List getGenericAssayCategoricalEnrichments(String molecularProfileId, + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { + + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); + + Iterable maItr = molecularDataRepository + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); + + Map> filteredMolecularProfileCaseSets; + filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + + List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, + filteredMolecularProfileCaseSets, enrichmentType, maItr); + + calcQValues(genericAssayCategoricalEnrichments); + + List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); + + return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { + enrichmentDatum.setGenericEntityMetaProperties( + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + return enrichmentDatum; + }).collect(Collectors.toList()); + } + + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { + MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); + return molecularProfile; + } + + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes, + boolean isBinary) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + // Check alteration type + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + // Check datatype for binary or categorical + if(isBinary) { + if(!molecularProfile.getDatatype().equals("BINARY")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } else { + if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } + } + + private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { + if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { + // If patient level, filter duplicates by patient id + // For now we only support sample level for samples + List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); + List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); + List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); + Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); + + Map> filteredMolecularProfileCaseSets = new HashMap<>(); + for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { + Set patientSet = new HashSet(); + List identifierListUniqueByPatientId = new ArrayList<>(); + for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { + if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { + identifierListUniqueByPatientId.add(caseIdentifier); + patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); + } + } + filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); + } + return filteredMolecularProfileCaseSets; + } else { + return molecularProfileCaseSets; + } + } + + private Map getGenericAssayMetaByStableId(List stableIds, String molecularProfileId) { + return genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds(stableIds, stableIds.stream().map(sid -> molecularProfileId) + .collect(Collectors.toList()), "SUMMARY").stream() + .collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + } + + private void calcQValues(List enrichments) { + // Sort enrichments by pValue + Collections.sort(enrichments, GenericAssayEnrichment::compare); + BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); + BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); + // Assign q-values to enrichments + for (int i = 0; i < enrichments.size(); i++) { + enrichments.get(i).setqValue(qValues[i]); + } + } + } diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java index 569996ddcf1..5e864bdbbd0 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java @@ -7,7 +7,7 @@ import org.cbioportal.model.GenericAssayBinaryEnrichment; import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.GenericAssayEnrichmentService; +import org.cbioportal.service.ExpressionEnrichmentService; import org.cbioportal.service.exception.MolecularProfileNotFoundException; import org.cbioportal.web.config.annotation.InternalApi; import org.cbioportal.web.parameter.MolecularProfileCasesGroupFilter; @@ -33,7 +33,7 @@ @Api(tags = "Generic Assay Enrichment Data", description = " ") public class GenericAssayEnrichmentController { @Autowired - private GenericAssayEnrichmentService genericAssayEnrichmentService; + private ExpressionEnrichmentService expressionEnrichmentService; @PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection', T(org.cbioportal.utils.security.AccessLevel).READ)") @RequestMapping(value = "/generic-assay-categorical-enrichments/fetch", @@ -85,7 +85,7 @@ public ResponseEntity> fetchGenericAssayBinar } return new ResponseEntity<>( - genericAssayEnrichmentService.getGenericAssayBinaryEnrichments( + expressionEnrichmentService.getGenericAssayBinaryEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType), HttpStatus.OK); } @@ -105,7 +105,7 @@ private List fetchExpressionEnrichments(Enric if (molecularProfileIds.size() > 1) { throw new UnsupportedOperationException("Multi-study expression enrichments is not yet implemented"); } - return genericAssayEnrichmentService.getGenericAssayCategoricalEnrichments( + return expressionEnrichmentService.getGenericAssayCategoricalEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } } From 1f9dfb00ac3701082b76050b17ee6d61ff005c6d Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Sun, 13 Aug 2023 16:53:16 -0400 Subject: [PATCH 36/40] test check --- .../service/ExpressionEnrichmentService.java | 2 +- .../GenericAssayEnrichmentService.java | 23 --- .../impl/ExpressionEnrichmentServiceImpl.java | 131 ++++++------ .../GenericAssayEnrichmentServiceImpl.java | 187 ------------------ .../ExpressionEnrichmentServiceImplTest.java | 6 +- ...GenericAssayEnrichmentServiceImplTest.java | 6 +- .../web/ExpressionEnrichmentController.java | 2 +- .../ExpressionEnrichmentControllerTest.java | 2 +- 8 files changed, 65 insertions(+), 294 deletions(-) delete mode 100644 service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java delete mode 100644 service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java diff --git a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java index 04295d959b8..51d28da2b77 100644 --- a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java +++ b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java @@ -18,7 +18,7 @@ List getGenomicEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; - List getGenericAssayEnrichments(String molecularProfileId, + List getGenericAssayNumericalEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; List getGenericAssayBinaryEnrichments( diff --git a/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java b/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java deleted file mode 100644 index 80451d6e7e9..00000000000 --- a/service/src/main/java/org/cbioportal/service/GenericAssayEnrichmentService.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.cbioportal.service; - -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; - -import java.util.List; -import java.util.Map; - -public interface GenericAssayEnrichmentService { - List getGenericAssayBinaryEnrichments( - String molecularProfileId, - Map> molecularProfileCaseSets, - EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException; - - List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, - EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException; -} diff --git a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java index aeb5f65818e..94dc510ecca 100644 --- a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java @@ -5,9 +5,19 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.*; import org.cbioportal.model.MolecularProfile.MolecularAlterationType; import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.GenericAssayMolecularAlteration; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.Sample; +import org.cbioportal.model.GenericAssayEnrichment; +import org.cbioportal.model.GenomicEnrichment; +import org.cbioportal.model.Gene; +import org.cbioportal.model.GeneMolecularAlteration; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.ExpressionEnrichmentService; import org.cbioportal.service.GeneService; @@ -43,62 +53,49 @@ public class ExpressionEnrichmentServiceImpl implements ExpressionEnrichmentServ // molecularDataService in fetchCoExpressions @Transactional(readOnly = true) public List getGenomicEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - List validGenomicMolecularAlterationTypes = Arrays.asList( - MolecularAlterationType.MICRO_RNA_EXPRESSION, MolecularAlterationType.MRNA_EXPRESSION, - MolecularAlterationType.MRNA_EXPRESSION_NORMALS, MolecularAlterationType.RNA_EXPRESSION, - MolecularAlterationType.METHYLATION, MolecularAlterationType.METHYLATION_BINARY, - MolecularAlterationType.PHOSPHORYLATION, MolecularAlterationType.PROTEIN_LEVEL, - MolecularAlterationType.PROTEIN_ARRAY_PROTEIN_LEVEL, - MolecularAlterationType.PROTEIN_ARRAY_PHOSPHORYLATION); - + MolecularAlterationType.MICRO_RNA_EXPRESSION, MolecularAlterationType.MRNA_EXPRESSION, + MolecularAlterationType.MRNA_EXPRESSION_NORMALS, MolecularAlterationType.RNA_EXPRESSION, + MolecularAlterationType.METHYLATION, MolecularAlterationType.METHYLATION_BINARY, + MolecularAlterationType.PHOSPHORYLATION, MolecularAlterationType.PROTEIN_LEVEL, + MolecularAlterationType.PROTEIN_ARRAY_PROTEIN_LEVEL, + MolecularAlterationType.PROTEIN_ARRAY_PHOSPHORYLATION); validateMolecularProfile(molecularProfile, validGenomicMolecularAlterationTypes); - Iterable maItr = molecularDataRepository - .getGeneMolecularAlterationsIterableFast(molecularProfile.getStableId()); - + .getGeneMolecularAlterationsIterableFast(molecularProfile.getStableId()); List expressionEnrichments = expressionEnrichmentUtil.getEnrichments(molecularProfile, - molecularProfileCaseSets, enrichmentType, maItr); - + molecularProfileCaseSets, enrichmentType, maItr); List entrezGeneIds = expressionEnrichments.stream().map(GenomicEnrichment::getEntrezGeneId) - .collect(Collectors.toList()); - + .collect(Collectors.toList()); Map> geneMapByEntrezId = geneService - .fetchGenes(entrezGeneIds.stream().map(Object::toString).collect(Collectors.toList()), "ENTREZ_GENE_ID", - "SUMMARY") - .stream().collect(Collectors.groupingBy(Gene::getEntrezGeneId)); - + .fetchGenes(entrezGeneIds.stream().map(Object::toString).collect(Collectors.toList()), "ENTREZ_GENE_ID", + "SUMMARY") + .stream().collect(Collectors.groupingBy(Gene::getEntrezGeneId)); return expressionEnrichments.stream() - // filter Enrichments having no gene reference object(this - // happens when multiple - // entrez ids map to same hugo gene symbol) - .filter(expressionEnrichment -> geneMapByEntrezId.containsKey(expressionEnrichment.getEntrezGeneId())) - .map(expressionEnrichment -> { - Gene gene = geneMapByEntrezId.get(expressionEnrichment.getEntrezGeneId()).get(0); - expressionEnrichment.setHugoGeneSymbol(gene.getHugoGeneSymbol()); - return expressionEnrichment; - }).collect(Collectors.toList()); + // filter Enrichments having no gene reference object(this + // happens when multiple + // entrez ids map to same hugo gene symbol) + .filter(expressionEnrichment -> geneMapByEntrezId.containsKey(expressionEnrichment.getEntrezGeneId())) + .map(expressionEnrichment -> { + Gene gene = geneMapByEntrezId.get(expressionEnrichment.getEntrezGeneId()).get(0); + expressionEnrichment.setHugoGeneSymbol(gene.getHugoGeneSymbol()); + return expressionEnrichment; + }).collect(Collectors.toList()); } - @Override // transaction needs to be setup here in order to return Iterable from // molecularDataRepository in getGenericAssayMolecularAlterationsIterable @Transactional(readOnly = true) public List getGenericAssayEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularAlterationType.GENERIC_ASSAY)); - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - + .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); Map> filteredMolecularProfileCaseSets; if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { // Build sampleIdToPatientIdMap to quick find if a sample has shared patientId with other samples @@ -120,34 +117,25 @@ public List getGenericAssayEnrichments(String molecularP filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); } } else { - filteredMolecularProfileCaseSets = molecularProfileCaseSets; + filteredMolecularProfileCaseSets = molecularProfileCaseSets; } List genericAssayEnrichments = expressionEnrichmentUtil.getEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); + filteredMolecularProfileCaseSets, enrichmentType, maItr); List getGenericAssayStableIds = genericAssayEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); + .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); Map genericAssayMetaByStableId = genericAssayService - .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, - getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) - .collect(Collectors.toList()), - "SUMMARY") - .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); + .getGenericAssayMetaByStableIdsAndMolecularIds(getGenericAssayStableIds, + getGenericAssayStableIds.stream().map(stableId -> molecularProfileId) + .collect(Collectors.toList()), + "SUMMARY") + .stream().collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); return genericAssayEnrichments.stream().map(enrichmentDatum -> { enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); + genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); return enrichmentDatum; }).collect(Collectors.toList()); } - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } - - @Override @Transactional(readOnly = true) public List getGenericAssayBinaryEnrichments( @@ -156,7 +144,7 @@ public List getGenericAssayBinaryEnrichments( throws MolecularProfileNotFoundException { // Validate and fetch molecular profile - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, "BINARY"); // Get the molecular alterations for the provided profile Iterable maItr = molecularDataRepository @@ -193,13 +181,12 @@ public List getGenericAssayCategoricalEnrichm Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); + MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, "CATEGORICAL"); Iterable maItr = molecularDataRepository .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - Map> filteredMolecularProfileCaseSets; - filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); + Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, filteredMolecularProfileCaseSets, enrichmentType, maItr); @@ -216,30 +203,24 @@ public List getGenericAssayCategoricalEnrichm return enrichmentDatum; }).collect(Collectors.toList()); } - - private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { + + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, String dataType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); + validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), dataType); return molecularProfile; } private void validateMolecularProfile(MolecularProfile molecularProfile, List validMolecularAlterationTypes, - boolean isBinary) throws MolecularProfileNotFoundException { + String dataType) throws MolecularProfileNotFoundException { if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { // Check alteration type throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } // Check datatype for binary or categorical - if(isBinary) { - if(!molecularProfile.getDatatype().equals("BINARY")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } else { - if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } + if(molecularProfile.getMolecularAlterationType().equals(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY) && + !molecularProfile.getDatatype().equals(dataType)) + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); } private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { diff --git a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java deleted file mode 100644 index 424ae1a44ef..00000000000 --- a/service/src/main/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImpl.java +++ /dev/null @@ -1,187 +0,0 @@ -package org.cbioportal.service.impl; - -import org.apache.commons.lang3.BooleanUtils; -import org.cbioportal.model.EnrichmentType; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; -import org.cbioportal.model.GenericAssayMolecularAlteration; -import org.cbioportal.model.MolecularProfileCaseIdentifier; -import org.cbioportal.model.meta.GenericAssayMeta; -import org.cbioportal.model.MolecularProfile; -import org.cbioportal.model.Sample; -import org.cbioportal.model.GenericAssayEnrichment; -import org.cbioportal.persistence.MolecularDataRepository; -import org.cbioportal.service.GenericAssayEnrichmentService; -import org.cbioportal.service.GenericAssayService; -import org.cbioportal.service.MolecularProfileService; -import org.cbioportal.service.SampleService; -import org.cbioportal.service.exception.MolecularProfileNotFoundException; -import org.cbioportal.service.util.ExpressionEnrichmentUtil; -import org.cbioportal.service.util.FisherExactTestCalculator; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.math.BigDecimal; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - - -@Service -public class GenericAssayEnrichmentServiceImpl implements GenericAssayEnrichmentService { - - @Autowired - private MolecularDataRepository molecularDataRepository; - - @Autowired - private SampleService sampleService; - - @Autowired - private MolecularProfileService molecularProfileService; - - @Autowired - private FisherExactTestCalculator fisherExactTestCalculator = new FisherExactTestCalculator(); - - @Autowired - private ExpressionEnrichmentUtil expressionEnrichmentUtil; - @Autowired - private GenericAssayService genericAssayService; - - @Override - @Transactional(readOnly = true) - public List getGenericAssayBinaryEnrichments( - String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - - // Validate and fetch molecular profile - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, true); - - // Get the molecular alterations for the provided profile - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - - // Filter the case sets based on molecular profile - Map> filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); - - // Obtain binary enrichments from the utility - List genericAssayBinaryEnrichments = expressionEnrichmentUtil.getGenericAssayBinaryEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); - - // Calculate q-values for enrichments - calcQValues(genericAssayBinaryEnrichments); - - // Extract stable IDs from binary enrichments - List getGenericAssayStableIds = genericAssayBinaryEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - - // Fetch metadata of generic assays by their stable IDs - Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); - - // Assign meta properties to each enrichment - return genericAssayBinaryEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - } - - @Override - @Transactional(readOnly = true) - public List getGenericAssayCategoricalEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) - throws MolecularProfileNotFoundException { - - MolecularProfile molecularProfile = getAndValidateMolecularProfile(molecularProfileId, false); - - Iterable maItr = molecularDataRepository - .getGenericAssayMolecularAlterationsIterable(molecularProfile.getStableId(), null, "SUMMARY"); - - Map> filteredMolecularProfileCaseSets; - filteredMolecularProfileCaseSets = filterMolecularProfileCaseSets(molecularProfile, molecularProfileCaseSets); - - List genericAssayCategoricalEnrichments = expressionEnrichmentUtil.getGenericAssayCategoricalEnrichments(molecularProfile, - filteredMolecularProfileCaseSets, enrichmentType, maItr); - - calcQValues(genericAssayCategoricalEnrichments); - - List getGenericAssayStableIds = genericAssayCategoricalEnrichments.stream() - .map(GenericAssayEnrichment::getStableId).collect(Collectors.toList()); - Map genericAssayMetaByStableId = getGenericAssayMetaByStableId(getGenericAssayStableIds, molecularProfileId); - - return genericAssayCategoricalEnrichments.stream().map(enrichmentDatum -> { - enrichmentDatum.setGenericEntityMetaProperties( - genericAssayMetaByStableId.get(enrichmentDatum.getStableId()).getGenericEntityMetaProperties()); - return enrichmentDatum; - }).collect(Collectors.toList()); - } - - private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, boolean isBinary) throws MolecularProfileNotFoundException { - MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); - validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), isBinary); - return molecularProfile; - } - - private void validateMolecularProfile(MolecularProfile molecularProfile, - List validMolecularAlterationTypes, - boolean isBinary) throws MolecularProfileNotFoundException { - if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { - // Check alteration type - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - // Check datatype for binary or categorical - if(isBinary) { - if(!molecularProfile.getDatatype().equals("BINARY")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } else { - if(!molecularProfile.getDatatype().equals("CATEGORICAL")) { - throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); - } - } - } - - private Map> filterMolecularProfileCaseSets(MolecularProfile molecularProfile, Map> molecularProfileCaseSets) { - if (BooleanUtils.isTrue(molecularProfile.getPatientLevel())) { - // If patient level, filter duplicates by patient id - // For now we only support sample level for samples - List sampleIds = molecularProfileCaseSets.values().stream().flatMap(Collection::stream).map(MolecularProfileCaseIdentifier::getCaseId).collect(Collectors.toList()); - List studyIds = Collections.nCopies(sampleIds.size(), molecularProfile.getCancerStudyIdentifier()); - List samples = sampleService.fetchSamples(studyIds, sampleIds, "ID"); - Map sampleIdToPatientIdMap = samples.stream().collect(Collectors.toMap(Sample::getStableId, Sample::getPatientId)); - - Map> filteredMolecularProfileCaseSets = new HashMap<>(); - for (Map.Entry> pair : molecularProfileCaseSets.entrySet()) { - Set patientSet = new HashSet(); - List identifierListUniqueByPatientId = new ArrayList<>(); - for (MolecularProfileCaseIdentifier caseIdentifier : pair.getValue()) { - if (!patientSet.contains(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId()))) { - identifierListUniqueByPatientId.add(caseIdentifier); - patientSet.add(sampleIdToPatientIdMap.get(caseIdentifier.getCaseId())); - } - } - filteredMolecularProfileCaseSets.put(pair.getKey(), identifierListUniqueByPatientId); - } - return filteredMolecularProfileCaseSets; - } else { - return molecularProfileCaseSets; - } - } - - private Map getGenericAssayMetaByStableId(List stableIds, String molecularProfileId) { - return genericAssayService.getGenericAssayMetaByStableIdsAndMolecularIds(stableIds, stableIds.stream().map(sid -> molecularProfileId) - .collect(Collectors.toList()), "SUMMARY").stream() - .collect(Collectors.toMap(GenericAssayMeta::getStableId, Function.identity())); - } - - private void calcQValues(List enrichments) { - // Sort enrichments by pValue - Collections.sort(enrichments, GenericAssayEnrichment::compare); - BigDecimal[] pValues = enrichments.stream().map(T::getpValue).toArray(BigDecimal[]::new); - BigDecimal[] qValues = fisherExactTestCalculator.calcqValue(pValues); - // Assign q-values to enrichments - for (int i = 0; i < enrichments.size(); i++) { - enrichments.get(i).setqValue(qValues[i]); - } - } -} diff --git a/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java index e4d1da579cf..a777176e26a 100644 --- a/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImplTest.java @@ -207,7 +207,7 @@ public void getGenomicEnrichments() throws Exception { } @Test - public void getGenericAssayEnrichments() throws Exception { + public void getGenericAssayNumericalEnrichments() throws Exception { geneMolecularProfile.setMolecularAlterationType(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY); List molecularDataList = new ArrayList(); @@ -229,7 +229,7 @@ public void getGenericAssayEnrichments() throws Exception { .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - List result = enrichmentServiceImpl.getGenericAssayEnrichments(MOLECULAR_PROFILE_ID, + List result = enrichmentServiceImpl.getGenericAssayNumericalEnrichments(MOLECULAR_PROFILE_ID, molecularProfileCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); @@ -301,7 +301,7 @@ public void getGenericAssayPatientLevelEnrichments() throws Exception { Mockito.when(sampleService.fetchSamples(Arrays.asList(STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID, STUDY_ID), Arrays.asList(SAMPLE_ID3, SAMPLE_ID4, SAMPLE_ID5, SAMPLE_ID1, SAMPLE_ID2), "ID")).thenReturn(samples); - List result = enrichmentServiceImpl.getGenericAssayEnrichments(MOLECULAR_PROFILE_ID, molecularProfilePatientLevelCaseSets, EnrichmentType.SAMPLE); + List result = enrichmentServiceImpl.getGenericAssayNumericalEnrichments(MOLECULAR_PROFILE_ID, molecularProfilePatientLevelCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); GenericAssayEnrichment genericAssayEnrichment = result.get(0); diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java index b92b629caee..0adf6f5d556 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java @@ -29,7 +29,7 @@ @RunWith(MockitoJUnitRunner.class) public class GenericAssayEnrichmentServiceImplTest extends BaseServiceImplTest{ @InjectMocks - private GenericAssayEnrichmentServiceImpl genericAssayEnrichmentServiceImpl; + private ExpressionEnrichmentServiceImpl expressionEnrichmentServiceImpl; @Mock private SampleService sampleService; @Mock @@ -164,7 +164,7 @@ public void getGenericAssayBinaryEnrichments() throws Exception { .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - List result = genericAssayEnrichmentServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, + List result = expressionEnrichmentServiceImpl.getGenericAssayBinaryEnrichments(MOLECULAR_PROFILE_ID, molecularProfileCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); @@ -227,7 +227,7 @@ public void getGenericAssayCategoricalEnrichments() throws MolecularProfileNotFo .thenReturn(Arrays.asList(new GenericAssayMeta(HUGO_GENE_SYMBOL_1), new GenericAssayMeta(HUGO_GENE_SYMBOL_2))); - List result = genericAssayEnrichmentServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, + List result = expressionEnrichmentServiceImpl.getGenericAssayCategoricalEnrichments(MOLECULAR_PROFILE_ID, molecularProfileCaseSets, EnrichmentType.SAMPLE); Assert.assertEquals(2, result.size()); diff --git a/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java b/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java index 0252463e558..4072480eb13 100644 --- a/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java +++ b/web/src/main/java/org/cbioportal/web/ExpressionEnrichmentController.java @@ -95,7 +95,7 @@ private List fetchExpressionEnrichments(Enri } if (isRequestForGenericAssayEnrichments) { - return (List) expressionEnrichmentService.getGenericAssayEnrichments( + return (List) expressionEnrichmentService.getGenericAssayNumericalEnrichments( molecularProfileIds.iterator().next(), groupCaseIdentifierSet, enrichmentType); } diff --git a/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java b/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java index 868b46cfa06..0abe4a9e3ca 100644 --- a/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java +++ b/web/src/test/java/org/cbioportal/web/ExpressionEnrichmentControllerTest.java @@ -186,7 +186,7 @@ public void fetchGenericAssayEnrichments() throws Exception { genericAssayEnrichment2.setpValue(TEST_P_VALUE_2); genericAssayEnrichments.add(genericAssayEnrichment2); - Mockito.when(expressionEnrichmentService.getGenericAssayEnrichments(Mockito.anyString(), Mockito.anyMap(), + Mockito.when(expressionEnrichmentService.getGenericAssayNumericalEnrichments(Mockito.anyString(), Mockito.anyMap(), Mockito.any(EnrichmentType.class))).thenReturn(genericAssayEnrichments); mockMvc.perform(MockMvcRequestBuilders.post("/generic-assay-enrichments/fetch") From ab597023c81aa72ceaf935063a40be9dc65053ab Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Sun, 13 Aug 2023 18:04:37 -0400 Subject: [PATCH 37/40] modify expressionenrichment --- .../service/ExpressionEnrichmentService.java | 9 ++++----- .../service/impl/ExpressionEnrichmentServiceImpl.java | 11 ++++++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java index 51d28da2b77..d3c2a444bd8 100644 --- a/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java +++ b/service/src/main/java/org/cbioportal/service/ExpressionEnrichmentService.java @@ -3,19 +3,18 @@ import java.util.List; import java.util.Map; -import org.cbioportal.model.GenericAssayBinaryEnrichment; -import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.EnrichmentType; import org.cbioportal.model.GenericAssayEnrichment; import org.cbioportal.model.GenomicEnrichment; -import org.cbioportal.model.EnrichmentType; - import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; import org.cbioportal.service.exception.MolecularProfileNotFoundException; public interface ExpressionEnrichmentService { List getGenomicEnrichments(String molecularProfileId, - Map> molecularProfileCaseSets, EnrichmentType enrichmentType) + Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException; List getGenericAssayNumericalEnrichments(String molecularProfileId, diff --git a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java index 94dc510ecca..45eb9ae478e 100644 --- a/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java +++ b/service/src/main/java/org/cbioportal/service/impl/ExpressionEnrichmentServiceImpl.java @@ -89,7 +89,7 @@ public List getGenomicEnrichments(String molecularProfileId, // transaction needs to be setup here in order to return Iterable from // molecularDataRepository in getGenericAssayMolecularAlterationsIterable @Transactional(readOnly = true) - public List getGenericAssayEnrichments(String molecularProfileId, + public List getGenericAssayNumericalEnrichments(String molecularProfileId, Map> molecularProfileCaseSets, EnrichmentType enrichmentType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); @@ -203,7 +203,7 @@ public List getGenericAssayCategoricalEnrichm return enrichmentDatum; }).collect(Collectors.toList()); } - + private MolecularProfile getAndValidateMolecularProfile(String molecularProfileId, String dataType) throws MolecularProfileNotFoundException { MolecularProfile molecularProfile = molecularProfileService.getMolecularProfile(molecularProfileId); validateMolecularProfile(molecularProfile, Arrays.asList(MolecularProfile.MolecularAlterationType.GENERIC_ASSAY), dataType); @@ -266,5 +266,10 @@ private void calcQValues(List enrichments) enrichments.get(i).setqValue(qValues[i]); } } - + private void validateMolecularProfile(MolecularProfile molecularProfile, + List validMolecularAlterationTypes) throws MolecularProfileNotFoundException { + if (!validMolecularAlterationTypes.contains(molecularProfile.getMolecularAlterationType())) { + throw new MolecularProfileNotFoundException(molecularProfile.getStableId()); + } + } } From 13ea407aa949d414021db8e13264db9f7e7b7764 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:54:41 -0400 Subject: [PATCH 38/40] modify imports --- .../util/ExpressionEnrichmentUtil.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java index 71e7ef8e09d..79c4ace75a7 100644 --- a/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java +++ b/service/src/main/java/org/cbioportal/service/util/ExpressionEnrichmentUtil.java @@ -1,13 +1,31 @@ package org.cbioportal.service.util; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.List; import java.util.Map.Entry; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; -import io.swagger.models.auth.In; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.ExpressionEnrichment; +import org.cbioportal.model.GenericAssayEnrichment; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.GenericAssayMolecularAlteration; +import org.cbioportal.model.GenomicEnrichment; +import org.cbioportal.model.GroupStatistics; +import org.cbioportal.model.GenericAssayCountSummary; +import org.cbioportal.model.MolecularAlteration; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.MolecularProfileSamples; +import org.cbioportal.model.Sample; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.math3.stat.StatUtils; @@ -15,7 +33,6 @@ import org.apache.commons.math3.stat.inference.ChiSquareTest; import org.apache.commons.math3.stat.inference.OneWayAnova; import org.apache.commons.math3.stat.inference.TestUtils; -import org.cbioportal.model.*; import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.SampleService; import org.springframework.beans.factory.annotation.Autowired; From 24158cdb1aeb4c7a6e82add9885e57a646f08954 Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Wed, 16 Aug 2023 18:37:41 -0400 Subject: [PATCH 39/40] update imports --- .../impl/GenericAssayEnrichmentServiceImplTest.java | 13 ++++++++++++- .../web/GenericAssayEnrichmentController.java | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java index 0adf6f5d556..017a5ab005f 100644 --- a/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java +++ b/service/src/test/java/org/cbioportal/service/impl/GenericAssayEnrichmentServiceImplTest.java @@ -1,7 +1,18 @@ package org.cbioportal.service.impl; -import org.cbioportal.model.*; import org.cbioportal.model.meta.GenericAssayMeta; +import org.cbioportal.model.EnrichmentType; +import org.cbioportal.model.MolecularProfileCaseIdentifier; +import org.cbioportal.model.MolecularProfile; +import org.cbioportal.model.MolecularProfileSamples; +import org.cbioportal.model.CancerStudy; +import org.cbioportal.model.ReferenceGenome; +import org.cbioportal.model.Sample; +import org.cbioportal.model.GenericAssayMolecularAlteration; +import org.cbioportal.model.GenericAssayBinaryEnrichment; +import org.cbioportal.model.GenericAssayCategoricalEnrichment; +import org.cbioportal.model.GroupStatistics; + import org.cbioportal.persistence.MolecularDataRepository; import org.cbioportal.service.GenericAssayService; import org.cbioportal.service.MolecularProfileService; diff --git a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java index 5e864bdbbd0..294c580582e 100644 --- a/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java +++ b/web/src/main/java/org/cbioportal/web/GenericAssayEnrichmentController.java @@ -17,7 +17,12 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestAttribute; import springfox.documentation.annotations.ApiIgnore; import javax.validation.Valid; From b51a6e3be6769544956c8f9253d4fd82d5a6dddf Mon Sep 17 00:00:00 2001 From: Djokovic0311 <55948986+Djokovic0311@users.noreply.github.com> Date: Thu, 17 Aug 2023 16:03:34 -0400 Subject: [PATCH 40/40] Update GenericAssayEnrichment.java --- .../org/cbioportal/model/GenericAssayEnrichment.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java index 074aa8926d9..02491c2221b 100644 --- a/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java +++ b/model/src/main/java/org/cbioportal/model/GenericAssayEnrichment.java @@ -40,10 +40,7 @@ public HashMap getGenericEntityMetaProperties() { public void setGenericEntityMetaProperties(HashMap genericEntityMetaProperties) { this.genericEntityMetaProperties = genericEntityMetaProperties; } - - public static int compare(GenericAssayEnrichment c1, GenericAssayEnrichment c2) { - return c1.getpValue().compareTo(c2.getpValue()); - } + public BigDecimal getqValue() { return qValue; } @@ -51,4 +48,8 @@ public BigDecimal getqValue() { public void setqValue(BigDecimal qValue) { this.qValue = qValue; } + + public static int compare(GenericAssayEnrichment c1, GenericAssayEnrichment c2) { + return c1.getpValue().compareTo(c2.getpValue()); + } }