From a666032caaef63a422090f4a6cea3c1ba6a0f839 Mon Sep 17 00:00:00 2001 From: zwright Date: Mon, 15 Sep 2025 15:01:14 -0400 Subject: [PATCH 01/20] KPMP-6138: Use separate queries --- src/main/java/org/kpmp/QueryController.java | 5 + .../ClusterHiearchyRepository.java | 26 ++++ .../cellTypeSummary/ClusterHierarchy2025.java | 130 ++++++++++++++++++ .../ClusterHierarchyService.java | 63 +++++++++ .../graphql/knowledge_environment.graphqls | 3 +- 5 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchy2025.java diff --git a/src/main/java/org/kpmp/QueryController.java b/src/main/java/org/kpmp/QueryController.java index 9a0bd551..ae4ad966 100755 --- a/src/main/java/org/kpmp/QueryController.java +++ b/src/main/java/org/kpmp/QueryController.java @@ -123,6 +123,11 @@ public List getClusterHieararchies(@Argument String cellType) return clusterHierarchyService.findClustersByCellType(cellType); } + @QueryMapping + public List getClusterHieararchies2025(@Argument String cellType) throws IOException { + return clusterHierarchyService.findClustersByCellType2025(cellType); + } + @QueryMapping public PlotData getUmapPlotData(@Argument String dataType, @Argument String geneSymbol, @Argument String enrollmentCategory) throws Exception { try { diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 59b1da10..362c7336 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -2,6 +2,7 @@ import java.util.List; +import org.kpmp.cluster.Cluster; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; @@ -13,6 +14,30 @@ interface ClusterHiearchyRepository extends CrudRepository findAll(); + @Cacheable("clusterHierarchyRNA2025ByCellType") + @Query(value = "SELECT ch.*, c.cell_type_order, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch JOIN cell_type c on ch.cell_type_id = c.cell_type_id WHERE cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type", nativeQuery = true) + List findRnaSeqByCellTypeOrRegion(@Param("cell_type") String cell_type); + + @Cacheable("clusterHierarchyRT2025ByCellType") + @Query(value = "SELECT rt.*, 0 AS cluster_id, c.cell_type_order, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + + "JOIN cell_type c on ch.cell_type_id = c.cell_type_id " + + "WHERE rt.abbreviation <> 'Ti' AND (cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type)", nativeQuery = true) + List findRTByCellTypeOrRegion(@Param("cell_type") String cell_type); + + @Cacheable("clusterHierarchyRP2025ByCellType") + @Query(value = "SELECT rt.*, 0 AS cluster_id, c.cell_type_order, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + + "JOIN cell_type c on ch.cell_type_id = c.cell_type_id " + + "WHERE rt.abbreviation <> 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type)", nativeQuery = true) + List findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); + + @Cacheable("clusterHierarchyRNA2025ByCluster") + @Query(value = "SELECT * FROM cluster_hierarchy_2025_v WHERE cluster_name = :cluster_name", nativeQuery = true) + List findRnaSeqByCluster(@Param("cluster_name") String cell_type); + + @Cacheable("clusterHierarchyRegional2025ByCluster") + @Query(value = "SELECT * FROM rt_segment_hierarchy_2025_v WHERE (cell_type IS NULL AND (structure_subregion = :cluster_name OR structure_region = :cluster_name)) OR cell_type = :cluster_name LIMIT 1", nativeQuery = true) + List findRegionalByCluster(@Param("cluster_name") String cell_type); + @Cacheable("clusterHierarchyCt") @Query(value = "CALL cluster_hierarchy_sp(:cell_type);", nativeQuery = true) List findByCellType(@Param("cell_type") String cellType); @@ -20,4 +45,5 @@ interface ClusterHiearchyRepository extends CrudRepository findDataTypesByClusterName(String clusterName) { } return dataTypesRepresented; } + + public List findClustersByCellType2025(String cellType) { + + ArrayList result = new ArrayList<>(); + Map clusterToHierarchy = new HashMap<>(); + List clusterHierarchiesRNASeq = clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion(cellType); + List clusterHierarchiesRegional = clusterHierarchyRepo.findRTRPByCellTypeOrRegion(cellType); + clusterHierarchiesRegional.addAll(clusterHierarchiesRegional); + + for (ClusterHierarchy clusterHierarchy : clusterHierarchiesRegional) { + String clusterName = clusterHierarchy.getClusterName(); + if (clusterToHierarchy.containsKey(clusterName)) { + if (clusterName == null) { + result.add(clusterHierarchy); + } else if (clusterName != null && clusterName.equals(clusterHierarchy.getCellType())) { + clusterToHierarchy.put(clusterName, clusterHierarchy); + } + } else { + clusterToHierarchy.put(clusterName, clusterHierarchy); + } + } + if (cellType.equals("Tubules") || cellType.equals("Interstitium")) { + ClusterHierarchy tiCluster = new ClusterHierarchy(); + tiCluster.setStructureRegion("Tubulo-interstitium"); + tiCluster.setIsSingleCellCluster("N"); + tiCluster.setIsSingleNucCluster("N"); + tiCluster.setIsRegionalProteomics("Y"); + tiCluster.setIsRegionalTranscriptomics("Y"); + tiCluster.setCellTypeOrder(0.01); + result.add(tiCluster); + } + result.addAll(clusterToHierarchy.values()); + Collections.sort(result, new Comparator() { + @Override + public int compare(ClusterHierarchy a, ClusterHierarchy b) { + return a.getCellTypeOrder().compareTo(b.getCellTypeOrder()); + } + }); + return result; + } + + public List findDataTypesByClusterName2025(String clusterName) { + List dataTypesRepresented = new ArrayList<>(); + if (clusterName.equals("Tubulo-interstitium")) { + dataTypesRepresented.add(FullDataTypeEnum.REGIONAL_PROTEOMICS.getAbbreviation()); + dataTypesRepresented.add(FullDataTypeEnum.REGIONAL_TRANSCRIPTOMICS.getAbbreviation()); + } else { + ClusterHierarchy clustersInDataTypes = clusterHierarchyRepo.findFirstByClusterOrRegion(clusterName); + if (clustersInDataTypes.getIsSingleCellCluster().equalsIgnoreCase("Y")) { + dataTypesRepresented.add(FullDataTypeEnum.SINGLE_CELL.getAbbreviation()); + } + if (clustersInDataTypes.getIsSingleNucCluster().equalsIgnoreCase("Y")) { + dataTypesRepresented.add(FullDataTypeEnum.SINGLE_NUCLEUS.getAbbreviation()); + } + if (clustersInDataTypes.getIsRegionalTranscriptomics().equalsIgnoreCase("Y")) { + dataTypesRepresented.add(FullDataTypeEnum.REGIONAL_TRANSCRIPTOMICS.getAbbreviation()); + } + if (clustersInDataTypes.getIsRegionalProteomics().equalsIgnoreCase("Y")) { + dataTypesRepresented.add(FullDataTypeEnum.REGIONAL_PROTEOMICS.getAbbreviation()); + } + } + return dataTypesRepresented; + } } diff --git a/src/main/resources/graphql/knowledge_environment.graphqls b/src/main/resources/graphql/knowledge_environment.graphqls index f2f04c9a..8a44833e 100755 --- a/src/main/resources/graphql/knowledge_environment.graphqls +++ b/src/main/resources/graphql/knowledge_environment.graphqls @@ -4,7 +4,8 @@ type Query { geneExpressionSummary(dataType: String, geneSymbol: String, cellType: String, enrollmentCategory: String) : [GeneExpressionSummary] geneExpressionSummary2025(dataType: String, geneSymbol: String, cellType: String, enrollmentCategory: String) : [GeneExpressionSummary2025] getClusterHieararchies(cellType: String!): [ClusterHierarchy] - getUmapPlotData(dataType: String!, geneSymbol: String!, enrollmentCategory: String): PlotData + getClusterHieararchies2025(cellType: String!): [ClusterHierarchy] + getUmapPlotData(dataType: String!, geneSymbol: String!, enrollmentCategory: String): PlotData getUmapPlotData2025(dataType: String!, geneSymbol: String!, enrollmentCategory: String): PlotData2025 dataTypesForConcept(geneSymbol: String, clusterName: String): [String] getDataTypeSummaryInformation: [DataTypeSummaryInformation] From d9652cde51fa35a705ced5ef54380dd440118e83 Mon Sep 17 00:00:00 2001 From: zwright Date: Tue, 16 Sep 2025 13:38:24 -0400 Subject: [PATCH 02/20] KPMP-6138: Disambiguate --- .../cellTypeSummary/ClusterHiearchyRepository.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 362c7336..f3ae9ea8 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -15,19 +15,19 @@ interface ClusterHiearchyRepository extends CrudRepository findAll(); @Cacheable("clusterHierarchyRNA2025ByCellType") - @Query(value = "SELECT ch.*, c.cell_type_order, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch JOIN cell_type c on ch.cell_type_id = c.cell_type_id WHERE cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type", nativeQuery = true) + @Query(value = "SELECT ch.*, c.cell_type_order, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch JOIN cell_type c on ch.cell_type_id = c.cell_type_id WHERE ch.cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type", nativeQuery = true) List findRnaSeqByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRT2025ByCellType") @Query(value = "SELECT rt.*, 0 AS cluster_id, c.cell_type_order, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + - "JOIN cell_type c on ch.cell_type_id = c.cell_type_id " + - "WHERE rt.abbreviation <> 'Ti' AND (cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type)", nativeQuery = true) + "JOIN cell_type c on rt.cell_type_id = c.cell_type_id " + + "WHERE rt.abbreviation <> 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRP2025ByCellType") @Query(value = "SELECT rt.*, 0 AS cluster_id, c.cell_type_order, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + - "JOIN cell_type c on ch.cell_type_id = c.cell_type_id " + - "WHERE rt.abbreviation <> 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type)", nativeQuery = true) + "JOIN cell_type c on rt.cell_type_id = c.cell_type_id " + + "WHERE rt.abbreviation <> 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRNA2025ByCluster") From 35719d24d68ae0a37ce2a84d5298e605bbf8c500 Mon Sep 17 00:00:00 2001 From: zwright Date: Tue, 16 Sep 2025 13:50:47 -0400 Subject: [PATCH 03/20] KPMP-6138: Disambiguate take 2 --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index f3ae9ea8..683f5326 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -15,7 +15,7 @@ interface ClusterHiearchyRepository extends CrudRepository findAll(); @Cacheable("clusterHierarchyRNA2025ByCellType") - @Query(value = "SELECT ch.*, c.cell_type_order, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch JOIN cell_type c on ch.cell_type_id = c.cell_type_id WHERE ch.cell_type = :cell_type OR structure_region = :cell_type OR structure_subregion = :cell_type", nativeQuery = true) + @Query(value = "SELECT ch.*, c.cell_type_order, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch JOIN cell_type c on ch.cell_type_id = c.cell_type_id WHERE ch.cell_type = :cell_type OR ch.structure_region = :cell_type OR ch.structure_subregion = :cell_type", nativeQuery = true) List findRnaSeqByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRT2025ByCellType") From 57b74afe570ea746dc643eb0ad23c4b78c8a6838 Mon Sep 17 00:00:00 2001 From: zwright Date: Tue, 16 Sep 2025 13:59:04 -0400 Subject: [PATCH 04/20] KPMP-6138: Remove cell_type_order --- .../kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 683f5326..762330d9 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -15,18 +15,16 @@ interface ClusterHiearchyRepository extends CrudRepository findAll(); @Cacheable("clusterHierarchyRNA2025ByCellType") - @Query(value = "SELECT ch.*, c.cell_type_order, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch JOIN cell_type c on ch.cell_type_id = c.cell_type_id WHERE ch.cell_type = :cell_type OR ch.structure_region = :cell_type OR ch.structure_subregion = :cell_type", nativeQuery = true) + @Query(value = "SELECT ch.*, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch WHERE ch.cell_type = :cell_type OR ch.structure_region = :cell_type OR ch.structure_subregion = :cell_type", nativeQuery = true) List findRnaSeqByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRT2025ByCellType") - @Query(value = "SELECT rt.*, 0 AS cluster_id, c.cell_type_order, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + - "JOIN cell_type c on rt.cell_type_id = c.cell_type_id " + + @Query(value = "SELECT rt.*, 0 AS cluster_id, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + "WHERE rt.abbreviation <> 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRP2025ByCellType") - @Query(value = "SELECT rt.*, 0 AS cluster_id, c.cell_type_order, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + - "JOIN cell_type c on rt.cell_type_id = c.cell_type_id " + + @Query(value = "SELECT rt.*, 0 AS cluster_id, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + "WHERE rt.abbreviation <> 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); From 76828962f3a5d509371f97d0bfadafc7a981bf33 Mon Sep 17 00:00:00 2001 From: zwright Date: Tue, 16 Sep 2025 14:14:06 -0400 Subject: [PATCH 05/20] KPMP-6138: Get that cluster_name --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 4 ++-- .../org/kpmp/cellTypeSummary/ClusterHierarchyService.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 762330d9..7d2f8b88 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -19,12 +19,12 @@ interface ClusterHiearchyRepository extends CrudRepository findRnaSeqByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRT2025ByCellType") - @Query(value = "SELECT rt.*, 0 AS cluster_id, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + + @Query(value = "SELECT rt.*, 0 AS cluster_id, NULL AS `cluster_name`, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + "WHERE rt.abbreviation <> 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRP2025ByCellType") - @Query(value = "SELECT rt.*, 0 AS cluster_id, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + + @Query(value = "SELECT rt.*, 0 AS cluster_id, rt.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + "WHERE rt.abbreviation <> 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java index 61ed805a..a74fa15b 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java @@ -87,7 +87,9 @@ public List findClustersByCellType2025(String cellType) { Map clusterToHierarchy = new HashMap<>(); List clusterHierarchiesRNASeq = clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion(cellType); List clusterHierarchiesRegional = clusterHierarchyRepo.findRTRPByCellTypeOrRegion(cellType); - clusterHierarchiesRegional.addAll(clusterHierarchiesRegional); + List clusterHierarchiesRT = clusterHierarchyRepo.findRTByCellTypeOrRegion(cellType); + clusterHierarchiesRNASeq.addAll(clusterHierarchiesRegional); + clusterHierarchiesRNASeq.addAll(clusterHierarchiesRT); for (ClusterHierarchy clusterHierarchy : clusterHierarchiesRegional) { String clusterName = clusterHierarchy.getClusterName(); From f48709b740a1514cb4e8749040a11b8363a3a3a6 Mon Sep 17 00:00:00 2001 From: zwright Date: Tue, 16 Sep 2025 15:40:55 -0400 Subject: [PATCH 06/20] KPMP-6138: Use the correct collection --- .../java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java index a74fa15b..799f0c79 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java @@ -91,7 +91,7 @@ public List findClustersByCellType2025(String cellType) { clusterHierarchiesRNASeq.addAll(clusterHierarchiesRegional); clusterHierarchiesRNASeq.addAll(clusterHierarchiesRT); - for (ClusterHierarchy clusterHierarchy : clusterHierarchiesRegional) { + for (ClusterHierarchy clusterHierarchy : clusterHierarchiesRNASeq) { String clusterName = clusterHierarchy.getClusterName(); if (clusterToHierarchy.containsKey(clusterName)) { if (clusterName == null) { From d81d21e3f4619fb29762f7c6b3e44f72846cddad Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 10:51:16 -0400 Subject: [PATCH 07/20] KPMP-6138: Try taking out RT-specific --- .../org/kpmp/cellTypeSummary/ClusterHierarchyService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java index 799f0c79..41b822e5 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java @@ -87,9 +87,9 @@ public List findClustersByCellType2025(String cellType) { Map clusterToHierarchy = new HashMap<>(); List clusterHierarchiesRNASeq = clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion(cellType); List clusterHierarchiesRegional = clusterHierarchyRepo.findRTRPByCellTypeOrRegion(cellType); - List clusterHierarchiesRT = clusterHierarchyRepo.findRTByCellTypeOrRegion(cellType); + //List clusterHierarchiesRT = clusterHierarchyRepo.findRTByCellTypeOrRegion(cellType); clusterHierarchiesRNASeq.addAll(clusterHierarchiesRegional); - clusterHierarchiesRNASeq.addAll(clusterHierarchiesRT); + //clusterHierarchiesRNASeq.addAll(clusterHierarchiesRT); for (ClusterHierarchy clusterHierarchy : clusterHierarchiesRNASeq) { String clusterName = clusterHierarchy.getClusterName(); From e205a9c2d34f66519896014977ee4c8bc9a4b4e1 Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 11:49:47 -0400 Subject: [PATCH 08/20] KPMP-6138: Try union --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 7d2f8b88..817d1b3a 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -25,7 +25,10 @@ interface ClusterHiearchyRepository extends CrudRepository 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) + "WHERE rt.abbreviation <> 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type) " + + "UNION ALL " + + "SELECT rt.*, 0 AS cluster_id, NULL AS `cluster_name`, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + + "WHERE rt.abbreviation <> 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRNA2025ByCluster") From 3204f68875381a82982324bc34b7be89d9115fce Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 13:55:20 -0400 Subject: [PATCH 09/20] KPMP-6138: find parent regions --- .../ClusterHiearchyRepository.java | 18 ++++++++++++++++++ .../ClusterHierarchyService.java | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 817d1b3a..6ee7563a 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -31,6 +31,24 @@ interface ClusterHiearchyRepository extends CrudRepository 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) List findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); + @Cacheable("clusterHierarchy2025ByCellTypeRegionsSubregions") + @Query(value = "SELECT v1.*, c.cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + + "JOIN cell_type c on v1.cell_type_id = c.cell_type_id " + + "WHERE v1.cell_type IS NULL AND v1.structure_subregion IS NULL AND v1.structure_region IN (" + + "SELECT v2.structure_region FROM cell_type_2025 v2 " + + "WHERE v2.cell_type = :cell_type OR " + + "v2.structure_subregion = :cell_type OR " + + "v2.structure_region = :cell_type) " + + "UNION ALL " + + "SELECT v1.*, c.cell_type_order FROM knowledge_environment.rt_segment_hierarchy_2025_v v1 " + + "JOIN cell_type c on v1.cell_type_id = c.cell_type_id " + + "WHERE v1.cell_type IS NULL AND v1.structure_subregion IN ( " + + "SELECT v2.structure_subregion FROM cell_type_2025 v2 " + + "WHERE v2.cell_type = :cell_type OR " + + "v2.structure_subregion = :cell_type OR " + + "v2.structure_region = :cell_type)", nativeQuery = true) + List findRTRPParentRegions(@Param("cell_type") String cell_type); + @Cacheable("clusterHierarchyRNA2025ByCluster") @Query(value = "SELECT * FROM cluster_hierarchy_2025_v WHERE cluster_name = :cluster_name", nativeQuery = true) List findRnaSeqByCluster(@Param("cluster_name") String cell_type); diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java index 41b822e5..c331d19d 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java @@ -88,8 +88,9 @@ public List findClustersByCellType2025(String cellType) { List clusterHierarchiesRNASeq = clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion(cellType); List clusterHierarchiesRegional = clusterHierarchyRepo.findRTRPByCellTypeOrRegion(cellType); //List clusterHierarchiesRT = clusterHierarchyRepo.findRTByCellTypeOrRegion(cellType); + List clusterHierarchiesParentRegions = clusterHierarchyRepo.findRTRPParentRegions(cellType) clusterHierarchiesRNASeq.addAll(clusterHierarchiesRegional); - //clusterHierarchiesRNASeq.addAll(clusterHierarchiesRT); + clusterHierarchiesRNASeq.addAll(clusterHierarchiesParentRegions); for (ClusterHierarchy clusterHierarchy : clusterHierarchiesRNASeq) { String clusterName = clusterHierarchy.getClusterName(); From 755c7f48d70168c56f3499318279c3a88af7561b Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 14:11:22 -0400 Subject: [PATCH 10/20] KPMP-6138: semicolon --- .../java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java index c331d19d..0bc8722f 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java @@ -88,7 +88,7 @@ public List findClustersByCellType2025(String cellType) { List clusterHierarchiesRNASeq = clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion(cellType); List clusterHierarchiesRegional = clusterHierarchyRepo.findRTRPByCellTypeOrRegion(cellType); //List clusterHierarchiesRT = clusterHierarchyRepo.findRTByCellTypeOrRegion(cellType); - List clusterHierarchiesParentRegions = clusterHierarchyRepo.findRTRPParentRegions(cellType) + List clusterHierarchiesParentRegions = clusterHierarchyRepo.findRTRPParentRegions(cellType); clusterHierarchiesRNASeq.addAll(clusterHierarchiesRegional); clusterHierarchiesRNASeq.addAll(clusterHierarchiesParentRegions); From a363c49c58e9895d19f00b45d4eb5cee08820b05 Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 14:21:21 -0400 Subject: [PATCH 11/20] KPMP-6138: 0 cluster id --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 6ee7563a..c8bcf21a 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -32,7 +32,7 @@ interface ClusterHiearchyRepository extends CrudRepository findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchy2025ByCellTypeRegionsSubregions") - @Query(value = "SELECT v1.*, c.cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + + @Query(value = "SELECT v1.*, 0 AS cluster_id, c.cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + "JOIN cell_type c on v1.cell_type_id = c.cell_type_id " + "WHERE v1.cell_type IS NULL AND v1.structure_subregion IS NULL AND v1.structure_region IN (" + "SELECT v2.structure_region FROM cell_type_2025 v2 " + @@ -40,7 +40,7 @@ interface ClusterHiearchyRepository extends CrudRepository Date: Wed, 17 Sep 2025 14:27:16 -0400 Subject: [PATCH 12/20] KPMP-6138: gets those other cols in there --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index c8bcf21a..5b4f834b 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -32,7 +32,7 @@ interface ClusterHiearchyRepository extends CrudRepository findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchy2025ByCellTypeRegionsSubregions") - @Query(value = "SELECT v1.*, 0 AS cluster_id, c.cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + + @Query(value = "SELECT v1.*, 0 AS cluster_id, v1.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc, c.cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + "JOIN cell_type c on v1.cell_type_id = c.cell_type_id " + "WHERE v1.cell_type IS NULL AND v1.structure_subregion IS NULL AND v1.structure_region IN (" + "SELECT v2.structure_region FROM cell_type_2025 v2 " + @@ -40,7 +40,7 @@ interface ClusterHiearchyRepository extends CrudRepository Date: Wed, 17 Sep 2025 14:31:22 -0400 Subject: [PATCH 13/20] KPMP-6138: remove cell type order --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 5b4f834b..3b25f649 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -32,16 +32,14 @@ interface ClusterHiearchyRepository extends CrudRepository findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchy2025ByCellTypeRegionsSubregions") - @Query(value = "SELECT v1.*, 0 AS cluster_id, v1.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc, c.cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + - "JOIN cell_type c on v1.cell_type_id = c.cell_type_id " + + @Query(value = "SELECT v1.*, 0 AS cluster_id, v1.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v v1 " + "WHERE v1.cell_type IS NULL AND v1.structure_subregion IS NULL AND v1.structure_region IN (" + "SELECT v2.structure_region FROM cell_type_2025 v2 " + "WHERE v2.cell_type = :cell_type OR " + "v2.structure_subregion = :cell_type OR " + "v2.structure_region = :cell_type) " + "UNION ALL " + - "SELECT v1.*, 0 AS cluster_id, v1.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc, c.cell_type_order FROM knowledge_environment.rt_segment_hierarchy_2025_v v1 " + - "JOIN cell_type c on v1.cell_type_id = c.cell_type_id " + + "SELECT v1.*, 0 AS cluster_id, v1.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM knowledge_environment.rt_segment_hierarchy_2025_v v1 " + "WHERE v1.cell_type IS NULL AND v1.structure_subregion IN ( " + "SELECT v2.structure_subregion FROM cell_type_2025 v2 " + "WHERE v2.cell_type = :cell_type OR " + From 1de2bd5330ee6eb952912a3ceafa32f2be03b8af Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 16:06:51 -0400 Subject: [PATCH 14/20] KPMP-6138: order by --- .../ClusterHiearchyRepository.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 3b25f649..84b08677 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -15,24 +15,21 @@ interface ClusterHiearchyRepository extends CrudRepository findAll(); @Cacheable("clusterHierarchyRNA2025ByCellType") - @Query(value = "SELECT ch.*, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch WHERE ch.cell_type = :cell_type OR ch.structure_region = :cell_type OR ch.structure_subregion = :cell_type", nativeQuery = true) + @Query(value = "SELECT ch.*, 'N' AS is_rt, 'N' AS is_rp, 'Y' AS is_single_cell, 'Y' as is_single_nuc FROM cluster_hierarchy_2025_v ch WHERE ch.cell_type = :cell_type OR ch.structure_region = :cell_type OR ch.structure_subregion = :cell_type " + + "ORDER BY ch.cell_type_order ASC", nativeQuery = true) List findRnaSeqByCellTypeOrRegion(@Param("cell_type") String cell_type); - @Cacheable("clusterHierarchyRT2025ByCellType") - @Query(value = "SELECT rt.*, 0 AS cluster_id, NULL AS `cluster_name`, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + - "WHERE rt.abbreviation <> 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) - List findRTByCellTypeOrRegion(@Param("cell_type") String cell_type); - @Cacheable("clusterHierarchyRP2025ByCellType") - @Query(value = "SELECT rt.*, 0 AS cluster_id, rt.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + + @Query(value = "SELECT * FROM (SELECT rt.*, 0 AS cluster_id, rt.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + "WHERE rt.abbreviation <> 'Ti' AND rt.abbreviation <> 'INT' AND rt.structure_subregion IS NULL AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type) " + "UNION ALL " + "SELECT rt.*, 0 AS cluster_id, NULL AS `cluster_name`, 'Y' AS is_rt, 'N' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v rt " + - "WHERE rt.abbreviation <> 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)", nativeQuery = true) + "WHERE rt.abbreviation <> 'Ti' AND (rt.cell_type = :cell_type OR rt.structure_region = :cell_type OR rt.structure_subregion = :cell_type)) x ORDER BY x.cell_type_order ASC", nativeQuery = true) List findRTRPByCellTypeOrRegion(@Param("cell_type") String cell_type); + // This query gets the regions or subregions that RT/RP data are in given a more specific cell type. @Cacheable("clusterHierarchy2025ByCellTypeRegionsSubregions") - @Query(value = "SELECT v1.*, 0 AS cluster_id, v1.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v v1 " + + @Query(value = "SELECT * FROM (SELECT v1.*, 0 AS cluster_id, v1.cell_type AS cluster_name, 'Y' AS is_rt, 'Y' AS is_rp, 'N' AS is_single_cell, 'N' as is_single_nuc FROM rt_segment_hierarchy_2025_v v1 " + "WHERE v1.cell_type IS NULL AND v1.structure_subregion IS NULL AND v1.structure_region IN (" + "SELECT v2.structure_region FROM cell_type_2025 v2 " + "WHERE v2.cell_type = :cell_type OR " + @@ -44,7 +41,7 @@ interface ClusterHiearchyRepository extends CrudRepository findRTRPParentRegions(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRNA2025ByCluster") From 2525dec51a492c4fc5c75a13895a7c681e387c0f Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 16:23:45 -0400 Subject: [PATCH 15/20] KPMP-6138: group by --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 84b08677..119f38dc 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -41,7 +41,7 @@ interface ClusterHiearchyRepository extends CrudRepository findRTRPParentRegions(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRNA2025ByCluster") From 94fe6a2712f2a7eedd81fddffd697ca5f4273d04 Mon Sep 17 00:00:00 2001 From: zwright Date: Wed, 17 Sep 2025 16:28:00 -0400 Subject: [PATCH 16/20] KPMP-6138: remove region match --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 119f38dc..650c945c 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -33,15 +33,13 @@ interface ClusterHiearchyRepository extends CrudRepository findRTRPParentRegions(@Param("cell_type") String cell_type); @Cacheable("clusterHierarchyRNA2025ByCluster") From f73f8f8e533e0c5f1e7cec6858eb21d3c77b9a67 Mon Sep 17 00:00:00 2001 From: zwright Date: Thu, 18 Sep 2025 14:28:38 -0400 Subject: [PATCH 17/20] KPMP-6138: cluster query --- src/main/java/org/kpmp/QueryController.java | 11 +++++++++++ .../cellTypeSummary/ClusterHiearchyRepository.java | 11 ++++++++++- .../kpmp/cellTypeSummary/ClusterHierarchyService.java | 3 +-- .../resources/graphql/knowledge_environment.graphqls | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kpmp/QueryController.java b/src/main/java/org/kpmp/QueryController.java index ae4ad966..dfddaf09 100755 --- a/src/main/java/org/kpmp/QueryController.java +++ b/src/main/java/org/kpmp/QueryController.java @@ -189,6 +189,17 @@ public List dataTypesForConcept(@Argument String geneSymbol, @Argument S } + @QueryMapping + public List dataTypesForConcept2025(@Argument String geneSymbol, @Argument String clusterName) throws Exception { + if (geneSymbol != null && !geneSymbol.isEmpty()) { + return geneExpressionSummaryService.findDataTypesByGene(geneSymbol); + } else if (clusterName != null && !clusterName.isEmpty()) { + return clusterHierarchyService.findDataTypesByClusterName2025(clusterName); + } + throw new Exception("Must provide either a cluster or a gene symbol."); + + } + @QueryMapping public RTExpressionByEnrollmentCategory getRTGeneExpressionByEnrollment(@Argument String comparisonType, @Argument String geneSymbol) throws Exception { diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 650c945c..4c99109d 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -50,7 +50,16 @@ interface ClusterHiearchyRepository extends CrudRepository findRegionalByCluster(@Param("cluster_name") String cell_type); - @Cacheable("clusterHierarchyCt") + @Query(value = "CREATE DEFINER=`root`@`%` PROCEDURE `knowledge_environment`.`cluster_hierarchy_by_cluster_sp`(IN `cluster` char(100)) " + + "SELECT v1.*, null as cell_type_order FROM cluster_hierarchy_2025_v v1 " + + "WHERE v1.cluster_name = cluster " + + "UNION ALL " + + "SELECT v1.*, null as cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + + "WHERE v1.cell_type IS NULL AND (v1.structure_subregion = cluster OR v1.structure_region = cluster) LIMIT 1", nativeQuery = true) + ClusterHierarchy findFirstByClusterOrRegion2025(@Param("cluster_name") String cell_type); + + + @Cacheable("clusterHierarchyCt") @Query(value = "CALL cluster_hierarchy_sp(:cell_type);", nativeQuery = true) List findByCellType(@Param("cell_type") String cellType); diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java index 0bc8722f..d8328271 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java @@ -87,7 +87,6 @@ public List findClustersByCellType2025(String cellType) { Map clusterToHierarchy = new HashMap<>(); List clusterHierarchiesRNASeq = clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion(cellType); List clusterHierarchiesRegional = clusterHierarchyRepo.findRTRPByCellTypeOrRegion(cellType); - //List clusterHierarchiesRT = clusterHierarchyRepo.findRTByCellTypeOrRegion(cellType); List clusterHierarchiesParentRegions = clusterHierarchyRepo.findRTRPParentRegions(cellType); clusterHierarchiesRNASeq.addAll(clusterHierarchiesRegional); clusterHierarchiesRNASeq.addAll(clusterHierarchiesParentRegions); @@ -130,7 +129,7 @@ public List findDataTypesByClusterName2025(String clusterName) { dataTypesRepresented.add(FullDataTypeEnum.REGIONAL_PROTEOMICS.getAbbreviation()); dataTypesRepresented.add(FullDataTypeEnum.REGIONAL_TRANSCRIPTOMICS.getAbbreviation()); } else { - ClusterHierarchy clustersInDataTypes = clusterHierarchyRepo.findFirstByClusterOrRegion(clusterName); + ClusterHierarchy clustersInDataTypes = clusterHierarchyRepo.findFirstByClusterOrRegion2025(clusterName); if (clustersInDataTypes.getIsSingleCellCluster().equalsIgnoreCase("Y")) { dataTypesRepresented.add(FullDataTypeEnum.SINGLE_CELL.getAbbreviation()); } diff --git a/src/main/resources/graphql/knowledge_environment.graphqls b/src/main/resources/graphql/knowledge_environment.graphqls index 8a44833e..77465dc5 100755 --- a/src/main/resources/graphql/knowledge_environment.graphqls +++ b/src/main/resources/graphql/knowledge_environment.graphqls @@ -8,6 +8,7 @@ type Query { getUmapPlotData(dataType: String!, geneSymbol: String!, enrollmentCategory: String): PlotData getUmapPlotData2025(dataType: String!, geneSymbol: String!, enrollmentCategory: String): PlotData2025 dataTypesForConcept(geneSymbol: String, clusterName: String): [String] + dataTypesForConcept2025(geneSymbol: String, clusterName: String): [String] getDataTypeSummaryInformation: [DataTypeSummaryInformation] getDataTypeSummaryInformation2025: [DataTypeSummaryInformation2025] getRTGeneExpressionByEnrollment(comparisonType: String, geneSymbol: String): RTGeneExpressionByEnrollment From 4892f91082a60033564c5a88299c34258dd7d400 Mon Sep 17 00:00:00 2001 From: zwright Date: Thu, 18 Sep 2025 15:49:40 -0400 Subject: [PATCH 18/20] KPMP-6138: bad copy/paste --- .../org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index 4c99109d..f98bf099 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -50,8 +50,7 @@ interface ClusterHiearchyRepository extends CrudRepository findRegionalByCluster(@Param("cluster_name") String cell_type); - @Query(value = "CREATE DEFINER=`root`@`%` PROCEDURE `knowledge_environment`.`cluster_hierarchy_by_cluster_sp`(IN `cluster` char(100)) " + - "SELECT v1.*, null as cell_type_order FROM cluster_hierarchy_2025_v v1 " + + @Query(value = "SELECT v1.*, null as cell_type_order FROM cluster_hierarchy_2025_v v1 " + "WHERE v1.cluster_name = cluster " + "UNION ALL " + "SELECT v1.*, null as cell_type_order FROM rt_segment_hierarchy_2025_v v1 " + From c4c4b1e7d33daff4c5882afffd35a913c8b13971 Mon Sep 17 00:00:00 2001 From: zwright Date: Mon, 22 Sep 2025 13:02:12 -0400 Subject: [PATCH 19/20] KPMP-6138: add test --- .../ClusterHierarchyService.java | 2 +- .../ClusterHierarchyServiceTest.java | 231 ++++++++++++++++++ 2 files changed, 232 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java index d8328271..61af0743 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchyService.java @@ -96,7 +96,7 @@ public List findClustersByCellType2025(String cellType) { if (clusterToHierarchy.containsKey(clusterName)) { if (clusterName == null) { result.add(clusterHierarchy); - } else if (clusterName != null && clusterName.equals(clusterHierarchy.getCellType())) { + } else if (clusterName.equals(clusterHierarchy.getCellType())) { clusterToHierarchy.put(clusterName, clusterHierarchy); } } else { diff --git a/src/test/java/org/kpmp/cellTypeSummary/ClusterHierarchyServiceTest.java b/src/test/java/org/kpmp/cellTypeSummary/ClusterHierarchyServiceTest.java index 7deefc75..37d8c396 100755 --- a/src/test/java/org/kpmp/cellTypeSummary/ClusterHierarchyServiceTest.java +++ b/src/test/java/org/kpmp/cellTypeSummary/ClusterHierarchyServiceTest.java @@ -211,4 +211,235 @@ public void testFindDataTypesByClusterNameTi() throws Exception { assertFalse(dataTypes.contains(FullDataTypeEnum.SINGLE_CELL.getAbbreviation())); assertFalse(dataTypes.contains(FullDataTypeEnum.SINGLE_NUCLEUS.getAbbreviation())); } + + //////// 2025 Set + + @Test + public void testFindClustersByCellType2025() { + + ClusterHierarchy clusterHierarchy1 = new ClusterHierarchy(); + clusterHierarchy1.setCellType("celltype"); + clusterHierarchy1.setClusterName(null); + clusterHierarchy1.setCellTypeOrder(3.2); + ClusterHierarchy clusterHierarchy2 = new ClusterHierarchy(); + clusterHierarchy2.setCellType("celltype2"); + clusterHierarchy2.setClusterName(null); + clusterHierarchy2.setCellTypeOrder(2.0); + ClusterHierarchy clusterHierarchy3 = new ClusterHierarchy(); + clusterHierarchy3.setCellType("celltype1"); + clusterHierarchy3.setClusterName(null); + clusterHierarchy3.setCellTypeOrder(1.0); + + List hierarchiesRTRP = new ArrayList<>(Arrays.asList(clusterHierarchy1)); + List hierarchiesRNA = new ArrayList<>(Arrays.asList(clusterHierarchy2)); + List hierarchiesParent = new ArrayList<>(Arrays.asList(clusterHierarchy3)); + + when(clusterHierarchyRepo.findRTRPByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRTRP); + when(clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRNA); + when(clusterHierarchyRepo.findRTRPParentRegions("cell type")).thenReturn(hierarchiesParent); + + assertEquals(3, service.findClustersByCellType2025("cell type").size()); + } + + @Test + public void testFindClustersByCellType_remvoesDups2025() { + ClusterHierarchy clusterHierarchy1 = new ClusterHierarchy(); + clusterHierarchy1.setCellType("celltype"); + clusterHierarchy1.setClusterName("cluster"); + clusterHierarchy1.setCellTypeOrder(3.2); + ClusterHierarchy clusterHierarchy2 = new ClusterHierarchy(); + clusterHierarchy2.setCellType("celltype"); + clusterHierarchy2.setClusterName("cluster"); + clusterHierarchy2.setCellTypeOrder(2.0); + ClusterHierarchy clusterHierarchy3 = new ClusterHierarchy(); + clusterHierarchy3.setCellType("cluster"); + clusterHierarchy3.setClusterName("cluster"); + clusterHierarchy3.setCellTypeOrder(1.0); + + List hierarchiesRTRP = new ArrayList<>(Arrays.asList(clusterHierarchy1)); + List hierarchiesRNA = new ArrayList<>(Arrays.asList(clusterHierarchy2)); + List hierarchiesParent = new ArrayList<>(Arrays.asList(clusterHierarchy3)); + + when(clusterHierarchyRepo.findRTRPByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRTRP); + when(clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRNA); + when(clusterHierarchyRepo.findRTRPParentRegions("cell type")).thenReturn(hierarchiesParent); + + assertEquals(Arrays.asList(clusterHierarchy3), service.findClustersByCellType2025("cell type")); + } + + @Test + public void testFindClustersByCellType_remvoesDupsUnlessNull2025() { + ClusterHierarchy clusterHierarchy1 = new ClusterHierarchy(); + clusterHierarchy1.setCellType("celltype"); + clusterHierarchy1.setClusterName(null); + clusterHierarchy1.setCellTypeOrder(3.2); + ClusterHierarchy clusterHierarchy2 = new ClusterHierarchy(); + clusterHierarchy2.setCellType("celltype"); + clusterHierarchy2.setClusterName(null); + clusterHierarchy2.setCellTypeOrder(2.0); + ClusterHierarchy clusterHierarchy3 = new ClusterHierarchy(); + clusterHierarchy3.setCellType("cluster"); + clusterHierarchy3.setClusterName(null); + clusterHierarchy3.setCellTypeOrder(1.0); + + List hierarchiesRTRP = new ArrayList<>(Arrays.asList(clusterHierarchy1)); + List hierarchiesRNA = new ArrayList<>(Arrays.asList(clusterHierarchy2)); + List hierarchiesParent = new ArrayList<>(Arrays.asList(clusterHierarchy3)); + + when(clusterHierarchyRepo.findRTRPByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRTRP); + when(clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRNA); + when(clusterHierarchyRepo.findRTRPParentRegions("cell type")).thenReturn(hierarchiesParent); + + + List expected = Arrays.asList(clusterHierarchy1, clusterHierarchy2, clusterHierarchy3); + + List result = service.findClustersByCellType2025("cell type"); + + assertEquals(expected.size(), result.size()); + assertEquals(true, result.containsAll(expected)); + } + + @Test + public void testFindClustersByCellType_sorts2025() { + ClusterHierarchy clusterHierarchy1 = new ClusterHierarchy(); + clusterHierarchy1.setCellType("celltype"); + clusterHierarchy1.setClusterName(null); + clusterHierarchy1.setCellTypeOrder(3.2); + ClusterHierarchy clusterHierarchy2 = new ClusterHierarchy(); + clusterHierarchy2.setCellType("celltype"); + clusterHierarchy2.setClusterName(null); + clusterHierarchy2.setCellTypeOrder(2.0); + ClusterHierarchy clusterHierarchy3 = new ClusterHierarchy(); + clusterHierarchy3.setCellType("cluster"); + clusterHierarchy3.setClusterName(null); + clusterHierarchy3.setCellTypeOrder(1.0); + + List hierarchiesRTRP = new ArrayList<>(Arrays.asList(clusterHierarchy1)); + List hierarchiesRNA = new ArrayList<>(Arrays.asList(clusterHierarchy2)); + List hierarchiesParent = new ArrayList<>(Arrays.asList(clusterHierarchy3)); + + when(clusterHierarchyRepo.findRTRPByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRTRP); + when(clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion("cell type")).thenReturn(hierarchiesRNA); + when(clusterHierarchyRepo.findRTRPParentRegions("cell type")).thenReturn(hierarchiesParent); + + assertEquals(Arrays.asList(clusterHierarchy3, clusterHierarchy2, clusterHierarchy1), service.findClustersByCellType2025("cell type")); + } + + @Test + public void testFindDataTypesByClusterNameWhenBothY2025() throws Exception { + ClusterHierarchy clusterHierarchy = new ClusterHierarchy(); + clusterHierarchy.setIsSingleCellCluster("Y"); + clusterHierarchy.setIsSingleNucCluster("Y"); + clusterHierarchy.setIsRegionalTranscriptomics("N"); + clusterHierarchy.setIsRegionalProteomics("N"); + when(clusterHierarchyRepo.findFirstByClusterOrRegion2025("cluster")).thenReturn(clusterHierarchy); + + List dataTypes = service.findDataTypesByClusterName2025("cluster"); + + assertEquals(2, dataTypes.size()); + assertEquals(Arrays.asList(FullDataTypeEnum.SINGLE_CELL.getAbbreviation(), + FullDataTypeEnum.SINGLE_NUCLEUS.getAbbreviation()), dataTypes); + verify(clusterHierarchyRepo).findFirstByClusterOrRegion2025("cluster"); + } + + @Test + public void testFindDataTypesByClusterNameWhenSingleCellY2025() throws Exception { + ClusterHierarchy clusterHierarchy = new ClusterHierarchy(); + clusterHierarchy.setIsSingleCellCluster("Y"); + clusterHierarchy.setIsSingleNucCluster("N"); + clusterHierarchy.setIsRegionalTranscriptomics("N"); + clusterHierarchy.setIsRegionalProteomics("N"); + when(clusterHierarchyRepo.findFirstByClusterOrRegion2025("cluster")).thenReturn(clusterHierarchy); + + List dataTypes = service.findDataTypesByClusterName2025("cluster"); + + assertEquals(1, dataTypes.size()); + assertEquals(Arrays.asList(FullDataTypeEnum.SINGLE_CELL.getAbbreviation()), dataTypes); + verify(clusterHierarchyRepo).findFirstByClusterOrRegion2025("cluster"); + } + + @Test + public void testFindDataTypesByClusterNameWhenSingleNucY2025() throws Exception { + ClusterHierarchy clusterHierarchy = new ClusterHierarchy(); + clusterHierarchy.setIsSingleCellCluster("N"); + clusterHierarchy.setIsSingleNucCluster("y"); + clusterHierarchy.setIsRegionalTranscriptomics("N"); + clusterHierarchy.setIsRegionalProteomics("N"); + when(clusterHierarchyRepo.findFirstByClusterOrRegion2025("cluster")).thenReturn(clusterHierarchy); + + List dataTypes = service.findDataTypesByClusterName2025("cluster"); + + assertEquals(1, dataTypes.size()); + assertEquals(Arrays.asList(FullDataTypeEnum.SINGLE_NUCLEUS.getAbbreviation()), dataTypes); + verify(clusterHierarchyRepo).findFirstByClusterOrRegion2025("cluster"); + } + + @Test + public void testFindDataTypesByClusterNameWhenNeitherY2025() throws Exception { + ClusterHierarchy clusterHierarchy = new ClusterHierarchy(); + clusterHierarchy.setIsSingleCellCluster("N"); + clusterHierarchy.setIsSingleNucCluster("N"); + clusterHierarchy.setIsRegionalTranscriptomics("N"); + clusterHierarchy.setIsRegionalProteomics("N"); + when(clusterHierarchyRepo.findFirstByClusterOrRegion2025("cluster")).thenReturn(clusterHierarchy); + + List dataTypes = service.findDataTypesByClusterName2025("cluster"); + + assertEquals(0, dataTypes.size()); + verify(clusterHierarchyRepo).findFirstByClusterOrRegion2025("cluster"); + } + + @Test + public void testFindDataTypesByClusterNameWhenRTY2025() throws Exception { + ClusterHierarchy clusterHierarchy = new ClusterHierarchy(); + clusterHierarchy.setIsSingleCellCluster("N"); + clusterHierarchy.setIsSingleNucCluster("N"); + clusterHierarchy.setIsRegionalTranscriptomics("Y"); + clusterHierarchy.setIsRegionalProteomics("N"); + when(clusterHierarchyRepo.findFirstByClusterOrRegion2025("cluster")).thenReturn(clusterHierarchy); + + List dataTypes = service.findDataTypesByClusterName2025("cluster"); + + assertEquals(1, dataTypes.size()); + verify(clusterHierarchyRepo).findFirstByClusterOrRegion2025("cluster"); + } + + + @Test + public void testFindDataTypesByClusterNameWhenRPY2025() throws Exception { + ClusterHierarchy clusterHierarchy = new ClusterHierarchy(); + clusterHierarchy.setIsSingleCellCluster("N"); + clusterHierarchy.setIsSingleNucCluster("N"); + clusterHierarchy.setIsRegionalTranscriptomics("N"); + clusterHierarchy.setIsRegionalProteomics("Y"); + when(clusterHierarchyRepo.findFirstByClusterOrRegion2025("cluster")).thenReturn(clusterHierarchy); + + List dataTypes = service.findDataTypesByClusterName2025("cluster"); + + assertEquals(1, dataTypes.size()); + assertEquals(Arrays.asList("rp"), dataTypes); + verify(clusterHierarchyRepo).findFirstByClusterOrRegion2025("cluster"); + } + + @Test + public void testFindClustersByCellTypeTubulesOrInterstitium2025() throws Exception { + List clusterHierarchies = new ArrayList<>(); + when(clusterHierarchyRepo.findRTRPByCellTypeOrRegion("cell type")).thenReturn(clusterHierarchies); + when(clusterHierarchyRepo.findRnaSeqByCellTypeOrRegion("cell type")).thenReturn(clusterHierarchies); + when(clusterHierarchyRepo.findRTRPParentRegions("cell type")).thenReturn(clusterHierarchies); + List clusters = service.findClustersByCellType2025("Tubules"); + assertEquals("Tubulo-interstitium", clusters.get(0).getStructureRegion()); + List clusters2 = service.findClustersByCellType2025("Interstitium"); + assertEquals("Tubulo-interstitium", clusters2.get(0).getStructureRegion()); + } + + @Test + public void testFindDataTypesByClusterNameTi2025() throws Exception { + List dataTypes = service.findDataTypesByClusterName2025("Tubulo-interstitium"); + assertTrue(dataTypes.contains(FullDataTypeEnum.REGIONAL_PROTEOMICS.getAbbreviation())); + assertTrue(dataTypes.contains(FullDataTypeEnum.REGIONAL_TRANSCRIPTOMICS.getAbbreviation())); + assertFalse(dataTypes.contains(FullDataTypeEnum.SINGLE_CELL.getAbbreviation())); + assertFalse(dataTypes.contains(FullDataTypeEnum.SINGLE_NUCLEUS.getAbbreviation())); + } + } From 97ca8dae92e0d87bd19b6a0c60f56f9e6bdacff8 Mon Sep 17 00:00:00 2001 From: zwright Date: Mon, 22 Sep 2025 16:01:40 -0400 Subject: [PATCH 20/20] KPMP-6138: unused code --- .../kpmp/cellTypeSummary/ClusterHiearchyRepository.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java index f98bf099..1a6701fd 100755 --- a/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java +++ b/src/main/java/org/kpmp/cellTypeSummary/ClusterHiearchyRepository.java @@ -42,14 +42,6 @@ interface ClusterHiearchyRepository extends CrudRepository findRTRPParentRegions(@Param("cell_type") String cell_type); - @Cacheable("clusterHierarchyRNA2025ByCluster") - @Query(value = "SELECT * FROM cluster_hierarchy_2025_v WHERE cluster_name = :cluster_name", nativeQuery = true) - List findRnaSeqByCluster(@Param("cluster_name") String cell_type); - - @Cacheable("clusterHierarchyRegional2025ByCluster") - @Query(value = "SELECT * FROM rt_segment_hierarchy_2025_v WHERE (cell_type IS NULL AND (structure_subregion = :cluster_name OR structure_region = :cluster_name)) OR cell_type = :cluster_name LIMIT 1", nativeQuery = true) - List findRegionalByCluster(@Param("cluster_name") String cell_type); - @Query(value = "SELECT v1.*, null as cell_type_order FROM cluster_hierarchy_2025_v v1 " + "WHERE v1.cluster_name = cluster " + "UNION ALL " +