Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demo rfc80 poc mutation&genomic data count unit tests #10961

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ public interface StudyViewRepository {
int getTotalSampleTreatmentCount(StudyViewFilterContext studyViewFilterContext);

List<GenomicDataCountItem> getCNACounts(StudyViewFilterContext studyViewFilterContext, List<GenomicDataFilter> genomicDataFilters);

Map<String, Integer> getMutationCounts(StudyViewFilterContext studyViewFilterContext, GenomicDataFilter genomicDataFilter);

List<GenomicDataCountItem> getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List<GenomicDataFilter> genomicDataFilters);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.cbioportal.web.parameter.GenomicDataFilter;

import java.util.List;
import java.util.Map;


public interface StudyViewMapper {
Expand Down Expand Up @@ -62,7 +61,5 @@ public interface StudyViewMapper {

List<GenomicDataCountItem> getCNACounts(StudyViewFilterHelper studyViewFilterHelper, List<GenomicDataFilter> genomicDataFilters);

Map<String, Integer> getMutationCounts(StudyViewFilterHelper studyViewFilterHelper, GenomicDataFilter genomicDataFilter);

List<GenomicDataCountItem> getMutationCountsByType(StudyViewFilterHelper studyViewFilterHelper, List<GenomicDataFilter> genomicDataFilters);
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,6 @@ public List<GenomicDataCountItem> getCNACounts(StudyViewFilterContext studyViewF

return mapper.getCNACounts(createStudyViewFilterHelper(studyViewFilterContext), genomicDataFilters);
}

public Map<String, Integer> getMutationCounts(StudyViewFilterContext studyViewFilterContext, GenomicDataFilter genomicDataFilter) {

return mapper.getMutationCounts(createStudyViewFilterHelper(studyViewFilterContext), genomicDataFilter);
}

public List<GenomicDataCountItem> getMutationCountsByType(StudyViewFilterContext studyViewFilterContext, List<GenomicDataFilter> genomicDataFilters) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,19 @@ public List<GenomicDataCountItem> getCNACountsByGeneSpecific(StudyViewFilter stu
@Override
public List<GenomicDataCountItem> getMutationCountsByGeneSpecific(StudyViewFilter studyViewFilter, List<GenomicDataFilter> genomicDataFilters) {
List<GenomicDataCountItem> genomicDataCountItemList = new ArrayList<>();
int totalCount = studyViewRepository.getFilteredSamplesCount(createContext(studyViewFilter));
List<AlterationCountByGene> alterationCountByGenes = alterationCountService.getMutatedGenes(createContext(studyViewFilter));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fuzhaoyuan (@haynescd) if I understand correctly this PR switches from using it's own query (via the old getMututionCounts method of the repository) to just leveraging the getMutatedGenes method that was built for the mutated_genes endpoint. This is slightly painful because it means we're calling this thing at least twice for every filtering operation in the study view. I wonder if we could adapt getMutatedGenes so that it could take an optional gene parameter and then query only that, which would have massive savings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the same could be said for getFilteredSamplesCount. The study view is already calling that once. @haynescd this is probably too ambitious for this phase, but the solution for this redundancy would be a global cache of promises where the keys are hashes of the studyview filters. That way, we can fire off all these requests (endpoints) at the same time and whoever is first kicks off a given filtering operation and subsequent consumers just subscribe to that cached promise.

for (GenomicDataFilter genomicDataFilter : genomicDataFilters) {
Map<String, Integer> counts = studyViewRepository.getMutationCounts(createContext(studyViewFilter), genomicDataFilter);
AlterationCountByGene filteredAlterationCount = alterationCountByGenes.stream()
.filter(g -> g.getHugoGeneSymbol().equals(genomicDataFilter.getHugoGeneSymbol()))
.findFirst()
.orElse(new AlterationCountByGene());
int mutatedCount = filteredAlterationCount.getNumberOfAlteredCases();
int profiledCount = filteredAlterationCount.getNumberOfProfiledCases();
List<GenomicDataCount> genomicDataCountList = new ArrayList<>();
if (counts.getOrDefault("mutatedCount", 0) > 0)
genomicDataCountList.add(new GenomicDataCount("Mutated", "MUTATED", counts.get("mutatedCount"), counts.get("mutatedCount")));
if (counts.getOrDefault("notMutatedCount", 0) > 0)
genomicDataCountList.add(new GenomicDataCount("Not Mutated", "NOT_MUTATED", counts.get("notMutatedCount"), counts.get("notMutatedCount")));
if (counts.getOrDefault("notProfiledCount", 0) > 0)
genomicDataCountList.add(new GenomicDataCount("Not Profiled", "NOT_PROFILED", counts.get("notProfiledCount"), counts.get("notProfiledCount")));
genomicDataCountList.add(new GenomicDataCount("Mutated", "MUTATED", mutatedCount, mutatedCount));
genomicDataCountList.add(new GenomicDataCount("Not Mutated", "NOT_MUTATED", profiledCount - mutatedCount, profiledCount - mutatedCount));
genomicDataCountList.add(new GenomicDataCount("Not Profiled", "NOT_PROFILED", totalCount - profiledCount, totalCount - profiledCount));
genomicDataCountItemList.add(new GenomicDataCountItem(genomicDataFilter.getHugoGeneSymbol(), "mutations", genomicDataCountList));
}
return genomicDataCountItemList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ public class GenomicDataFilter extends DataFilter implements Serializable {
private String hugoGeneSymbol;
private String profileType;

public GenomicDataFilter() {}

public GenomicDataFilter(String hugoGeneSymbol, String profileType) {
this.hugoGeneSymbol = hugoGeneSymbol;
this.profileType = profileType;
}

public String getHugoGeneSymbol() {
return hugoGeneSymbol;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,28 +270,6 @@
FROM cna_sum
</select>

<!-- for /mutation-data-counts/fetch (returns GenomicDataCountItem objects) mutation counts pie chart part -->
<select id="getMutationCounts">
WITH profiled_count as (
SELECT count(distinct sgp.sample_unique_id)
FROM sample_to_gene_panel_derived sgp
JOIN gene_panel_to_gene_derived gpg ON sgp.gene_panel_id = gpg.gene_panel_id
WHERE sample_unique_id IN (<include refid="sampleUniqueIdsFromStudyViewFilter"/>)
AND gpg.gene = #{genomicDataFilter.hugoGeneSymbol}
),
mutated_count as (
SELECT count(distinct sample_unique_id)
FROM genomic_event_derived
WHERE sample_unique_id IN (<include refid="sampleUniqueIdsFromStudyViewFilter"/>)
AND hugo_gene_symbol = #{genomicDataFilter.hugoGeneSymbol}
AND variant_type = 'mutation'
)
SELECT
cast((SELECT * FROM mutated_count) as INTEGER) as mutatedCount,
cast(((SELECT * FROM profiled_count) - (SELECT * FROM mutated_count)) as INTEGER) as notMutatedCount,
cast(((SELECT * FROM (<include refid="getTotalSampleCount"/>)) - (SELECT * FROM profiled_count)) as INTEGER) as notProfiledCount
</select>

<!-- for /mutation-data-counts/fetch - (returns GenomicDataCountItem objects) mutation type counts table part-->
<select id="getMutationCountsByType" resultMap="GenomicDataCountItemResultMap">
SELECT
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.cbioportal.persistence.mybatisclickhouse;

import org.cbioportal.model.GenomicDataCount;
import org.cbioportal.model.GenomicDataCountItem;
import org.cbioportal.persistence.helper.StudyViewFilterHelper;
import org.cbioportal.persistence.mybatisclickhouse.config.MyBatisConfig;
import org.cbioportal.web.parameter.GenomicDataFilter;
import org.cbioportal.web.parameter.StudyViewFilter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@Import(MyBatisConfig.class)
@DataJpaTest
@DirtiesContext
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = AbstractTestcontainers.Initializer.class)
public class GenomicDataFilterTest extends AbstractTestcontainers {

private static final String STUDY_TCGA_PUB = "study_tcga_pub";
private static final String STUDY_ACC_TCGA = "acc_tcga";

@Autowired
private StudyViewMapper studyViewMapper;

@Test
public void getCNACounts() {
StudyViewFilter studyViewFilter = new StudyViewFilter();
studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB));

GenomicDataFilter genomicDataFilterCNA = new GenomicDataFilter("AKT1", "cna");
List<GenomicDataCountItem> actualCountsCNA = studyViewMapper.getCNACounts(StudyViewFilterHelper.build(studyViewFilter, null, null), List.of(genomicDataFilterCNA));
List<GenomicDataCountItem> expectedCountsCNA = List.of(
new GenomicDataCountItem("AKT1", "cna", List.of(
new GenomicDataCount("Homozygously deleted", "-2", 2),
new GenomicDataCount("Heterozygously deleted", "-1", 2),
new GenomicDataCount("Diploid", "0", 2),
new GenomicDataCount("Gained", "1", 2),
new GenomicDataCount("Amplified", "2", 2),
new GenomicDataCount("NA", "NA", 5)
)));
assertThat(actualCountsCNA)
.usingRecursiveComparison()
.ignoringCollectionOrder()
.isEqualTo(expectedCountsCNA);

GenomicDataFilter genomicDataFilterGISTIC = new GenomicDataFilter("AKT1", "gistic");
List<GenomicDataCountItem> actualCountsGISTIC = studyViewMapper.getCNACounts(StudyViewFilterHelper.build(studyViewFilter, null, null), List.of(genomicDataFilterGISTIC));
List<GenomicDataCountItem> expectedCountsGISTIC = List.of(
new GenomicDataCountItem("AKT1", "gistic", List.of(
new GenomicDataCount("Homozygously deleted", "-2", 2),
new GenomicDataCount("Heterozygously deleted", "-1", 3),
new GenomicDataCount("Diploid", "0", 3),
new GenomicDataCount("Gained", "1", 3),
new GenomicDataCount("Amplified", "2", 3),
new GenomicDataCount("NA", "NA", 1)
)));
assertThat(actualCountsGISTIC)
.usingRecursiveComparison()
.ignoringCollectionOrder()
.isEqualTo(expectedCountsGISTIC);
}

@Test
public void getMutationCountsByType() {
StudyViewFilter studyViewFilter = new StudyViewFilter();
studyViewFilter.setStudyIds(List.of(STUDY_TCGA_PUB));

GenomicDataFilter genomicDataFilterMutation = new GenomicDataFilter("AKT1", "mutation");
List<GenomicDataCountItem> actualMutationCountsByType = studyViewMapper.getMutationCountsByType(StudyViewFilterHelper.build(studyViewFilter, null, null), List.of(genomicDataFilterMutation));
List<GenomicDataCountItem> expectedMutationCountsByType = List.of(
new GenomicDataCountItem("AKT1", "mutations", List.of(
new GenomicDataCount("nonsense mutation", "nonsense_mutation", 1, 1),
new GenomicDataCount("missense mutation", "missense_mutation", 1, 1)
)));
assertThat(actualMutationCountsByType)
.usingRecursiveComparison()
.ignoringCollectionOrder()
.isEqualTo(expectedMutationCountsByType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void getMutatedGenes() {
AlterationFilterHelper.build(studyViewFilter.getAlterationFilter()));
assertEquals(3, alterationCountByGenes.size());

var testBrca1AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "brca1")).findFirst();
var testBrca1AlterationCount = alterationCountByGenes.stream().filter(a -> Objects.equals(a.getHugoGeneSymbol(), "BRCA1")).findFirst();
assert (testBrca1AlterationCount.isPresent());
assertEquals(Integer.valueOf(5), testBrca1AlterationCount.get().getTotalCount());
}
Expand Down Expand Up @@ -118,7 +118,7 @@ public void getTotalProfiledCountsByGene() {

assertEquals(3, totalProfiledCountsMap.size());

var akt2TotalProfiledCounts = totalProfiledCountsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("akt2")).findFirst();
var akt2TotalProfiledCounts = totalProfiledCountsMap.stream().filter(c -> c.getHugoGeneSymbol().equals("AKT2")).findFirst();
assertTrue(akt2TotalProfiledCounts.isPresent());
assertEquals(4, akt2TotalProfiledCounts.get().getNumberOfProfiledCases().intValue());
}
Expand Down
Loading
Loading