Skip to content

Commit

Permalink
✨ Add StructuralVariant-genes endpoint (#10854)
Browse files Browse the repository at this point in the history
* ✨ Add StructuralVariant-genes endpoint

* Fix sonar issues

* Update MatchingGenePanel request to return list

* Create and use sample_derive

* Update where sample_derived is stored to fix unit test
  • Loading branch information
haynescd authored Jun 24, 2024
1 parent bb5456a commit 505847b
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import org.cbioportal.model.AlterationCountByGene;
import org.cbioportal.model.ClinicalData;
import org.cbioportal.model.ClinicalDataCount;
import org.cbioportal.model.GenomicDataCount;
import org.cbioportal.model.CopyNumberCountByGene;
import org.cbioportal.model.GenomicDataCount;
import org.cbioportal.model.Sample;
import org.cbioportal.persistence.enums.ClinicalAttributeDataSource;
import org.cbioportal.persistence.enums.ClinicalAttributeDataType;
Expand All @@ -13,6 +13,7 @@

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

public interface StudyViewRepository {
List<Sample> getFilteredSamples(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);
Expand All @@ -24,6 +25,7 @@ public interface StudyViewRepository {
List<AlterationCountByGene> getMutatedGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);

List<CopyNumberCountByGene> getCnaGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);
List<AlterationCountByGene> getStructuralVariantGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);

List<ClinicalDataCount> getClinicalDataCounts(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, List<String> filteredAttributes);

Expand All @@ -39,7 +41,7 @@ public interface StudyViewRepository {

int getFilteredSamplesCount(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);

Map<String, AlterationCountByGene> getMatchingGenePanelIds(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, String alterationType);
Map<String, Set<String>> getMatchingGenePanelIds(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, String alterationType);

int getTotalProfiledCountsByAlterationType(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, String alterationType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ List<AlterationCountByGene> getMutatedGenes(StudyViewFilter studyViewFilter, Cat

List<CopyNumberCountByGene> getCnaGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter,
boolean applyPatientIdFilters, AlterationFilterHelper alterationFilterHelper);

List<AlterationCountByGene> getStructuralVariantGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter,
boolean applyPatientIdFilters, AlterationFilterHelper alterationFilterHelper);

List<ClinicalDataCount> getPatientClinicalDataCounts(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter,
boolean applyPatientIdFilters, List<String> attributeIds, List<String> filteredAttributeValues);
Expand All @@ -45,8 +48,7 @@ List<ClinicalDataCount> getClinicalDataCounts(StudyViewFilter studyViewFilter, C

int getFilteredSamplesCount(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, boolean applyPatientIdFilters);

@MapKey("hugoGeneSymbol")
Map<String, AlterationCountByGene> getMatchingGenePanelIds(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, boolean applyPatientIdFilters, String alterationType);
List<GenePanelToGene> getMatchingGenePanelIds(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, boolean applyPatientIdFilters, String alterationType);

int getTotalProfiledCountByAlterationType(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, boolean applyPatientIdFilters, String alterationType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import org.cbioportal.model.AlterationCountByGene;
import org.cbioportal.model.ClinicalData;
import org.cbioportal.model.ClinicalDataCount;
import org.cbioportal.model.GenePanelToGene;
import org.cbioportal.model.GenomicDataCount;
import org.cbioportal.model.CopyNumberCountByGene;
import org.cbioportal.model.Sample;
Expand All @@ -16,6 +17,8 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Repository
public class StudyViewMyBatisRepository implements StudyViewRepository {
Expand Down Expand Up @@ -47,6 +50,13 @@ public List<CopyNumberCountByGene> getCnaGenes(StudyViewFilter studyViewFilter,
AlterationFilterHelper.build(studyViewFilter.getAlterationFilter()));
}

@Override
public List<AlterationCountByGene> getStructuralVariantGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter) {
return mapper.getStructuralVariantGenes(studyViewFilter, categorizedClinicalDataCountFilter,
shouldApplyPatientIdFilters(categorizedClinicalDataCountFilter),
AlterationFilterHelper.build(studyViewFilter.getAlterationFilter()));
}

@Override
public List<ClinicalDataCount> getClinicalDataCounts(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, List<String> filteredAttributes) {
return mapper.getClinicalDataCounts(studyViewFilter, categorizedClinicalDataCountFilter, shouldApplyPatientIdFilters(categorizedClinicalDataCountFilter),
Expand Down Expand Up @@ -103,9 +113,12 @@ public int getFilteredSamplesCount(StudyViewFilter studyViewFilter, CategorizedC
}

@Override
public Map<String, AlterationCountByGene> getMatchingGenePanelIds(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, String alterationType) {
public Map<String, Set<String>> getMatchingGenePanelIds(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter, String alterationType) {
return mapper.getMatchingGenePanelIds(studyViewFilter, categorizedClinicalDataCountFilter,
shouldApplyPatientIdFilters(categorizedClinicalDataCountFilter), alterationType);
shouldApplyPatientIdFilters(categorizedClinicalDataCountFilter), alterationType)
.stream()
.collect(Collectors.groupingBy(GenePanelToGene::getHugoGeneSymbol,
Collectors.mapping(GenePanelToGene::getGenePanelId, Collectors.toSet())));
}

@Override
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,6 @@ Pair<List<CopyNumberCountByGene>, Long> getPatientCnaGeneCounts(List<MolecularPr
List<AlterationCountByGene> getMutatedGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);
List<CopyNumberCountByGene> getCnaGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);

List<AlterationCountByGene> getStructuralVariantGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter);

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public interface StudyViewColumnarService {

List<AlterationCountByGene> getMutatedGenes(StudyViewFilter interceptedStudyViewFilter);
List<CopyNumberCountByGene> getCnaGenes(StudyViewFilter interceptedStudyViewFilter);
List<AlterationCountByGene> getStructuralVariantGenes(StudyViewFilter studyViewFilter);

List<ClinicalDataCountItem> getClinicalDataCounts(StudyViewFilter studyViewFilter, List<String> filteredAttributes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,13 @@ public List<CopyNumberCountByGene> getCnaGenes(StudyViewFilter studyViewFilter,
var copyNumberCountByGenes = studyViewRepository.getCnaGenes(studyViewFilter, categorizedClinicalDataCountFilter);
return populateAlterationCounts(copyNumberCountByGenes, studyViewFilter, categorizedClinicalDataCountFilter, AlterationType.COPY_NUMBER_ALTERATION);
}


@Override
public List<AlterationCountByGene> getStructuralVariantGenes(StudyViewFilter studyViewFilter, CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter) {
var alterationCountByGenes = studyViewRepository.getStructuralVariantGenes(studyViewFilter, categorizedClinicalDataCountFilter);
return populateAlterationCounts(alterationCountByGenes, studyViewFilter, categorizedClinicalDataCountFilter, AlterationType.STRUCTURAL_VARIANT);
}

private < T extends AlterationCountByGene> List<T> populateAlterationCounts(@NonNull List<T> alterationCounts,
@NonNull StudyViewFilter studyViewFilter,
@NonNull CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter,
Expand All @@ -276,13 +282,13 @@ private < T extends AlterationCountByGene> List<T> populateAlterationCounts(@Non
alterationType.toString());
var profiledCountWithoutGenePanelData = studyViewRepository.getTotalProfiledCountsByAlterationType(studyViewFilter, categorizedClinicalDataCountFilter, alterationType.toString());
var matchingGenePanelIdsMap = studyViewRepository.getMatchingGenePanelIds(studyViewFilter,
categorizedClinicalDataCountFilter, AlterationType.MUTATION_EXTENDED.toString());
categorizedClinicalDataCountFilter, alterationType.toString());

updatedAlterationCounts
updatedAlterationCounts.parallelStream()
.forEach(alterationCountByGene -> {
String hugoGeneSymbol = alterationCountByGene.getHugoGeneSymbol();
var matchingGenePanelIds = matchingGenePanelIdsMap.get(hugoGeneSymbol) != null ?
matchingGenePanelIdsMap.get(hugoGeneSymbol).getMatchingGenePanelIds() : null;
Set<String> matchingGenePanelIds = matchingGenePanelIdsMap.get(hugoGeneSymbol) != null ?
matchingGenePanelIdsMap.get(hugoGeneSymbol) : Collections.emptySet();

int totalProfiledCount = getTotalProfiledCount(alterationCountByGene.getHugoGeneSymbol(),
profiledCountsMap, profiledCountWithoutGenePanelData, matchingGenePanelIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public List<CopyNumberCountByGene> getCnaGenes(StudyViewFilter studyViewFilter)
return alterationCountService.getCnaGenes(studyViewFilter, categorizedClinicalDataCountFilter);
}

@Override
public List<AlterationCountByGene> getStructuralVariantGenes(StudyViewFilter studyViewFilter) {
CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter = extractClinicalDataCountFilters(studyViewFilter);
return alterationCountService.getStructuralVariantGenes(studyViewFilter, categorizedClinicalDataCountFilter);
}

@Override
public List<ClinicalDataCountItem> getClinicalDataCounts(StudyViewFilter studyViewFilter, List<String> filteredAttributes) {
CategorizedClinicalDataCountFilter categorizedClinicalDataCountFilter = extractClinicalDataCountFilters(studyViewFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@ public ResponseEntity<List<CopyNumberCountByGene>> fetchCnaGenes(
);
}

@PostMapping(value = "/column-store/structuralvariant-genes/fetch",
consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(description = "Fetch structural variant genes by study view filter")
@ApiResponse(responseCode = "200", description = "OK",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = AlterationCountByGene.class))))
public ResponseEntity<List<AlterationCountByGene>> fetchStructuralVariantGenes(
@Parameter(required = true, description = "Study view filter")
@Valid @RequestBody(required = false) StudyViewFilter studyViewFilter,
@Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface. This attribute is needed for the @PreAuthorize tag above.
@RequestAttribute(required = false, value = "involvedCancerStudies") Collection<String> involvedCancerStudies,
@Parameter(hidden = true) // prevent reference to this attribute in the swagger-ui interface.
@Valid @RequestAttribute(required = false, value = "interceptedStudyViewFilter") StudyViewFilter interceptedStudyViewFilter
) {
return new ResponseEntity<>(studyViewColumnarService.getStructuralVariantGenes(interceptedStudyViewFilter), HttpStatus.OK);
}

@PreAuthorize("hasPermission(#involvedCancerStudies, 'Collection<CancerStudyId>', T(org.cbioportal.utils.security.AccessLevel).READ)")
@PostMapping(value = "/column-store/clinical-data-counts/fetch",
consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
Expand Down
16 changes: 15 additions & 1 deletion src/main/resources/db-scripts/clickhouse/clickhouse.sql
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,18 @@ CREATE TABLE gene_panel_to_gene
gene_panel_id LowCardinality(String),
gene String
) ENGINE = MergeTree()
ORDER BY (gene_panel_id);
ORDER BY (gene_panel_id);

CREATE TABLE sample_derived
(
sample_unique_id String,
sample_unique_id_base64 String,
sample_stable_id String,
patient_unique_id String,
patient_unique_id_base64 String,
patient_stable_id String,
cancer_study_identifier LowCardinality(String),
internal_id Int
)
ENGINE = MergeTree
ORDER BY (cancer_study_identifier, sample_unique_id);
Loading

0 comments on commit 505847b

Please sign in to comment.