Skip to content

Commit

Permalink
init singlecell endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthijsPon committed Nov 14, 2024
1 parent 74516be commit 7f2c3d1
Show file tree
Hide file tree
Showing 15 changed files with 725 additions and 2 deletions.
47 changes: 47 additions & 0 deletions dev/test.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
DROP TABLE IF EXISTS single_cell_expression;
CREATE TABLE IF NOT EXISTS single_cell_expression (
GENETIC_PROFILE_ID int NOT NULL,
SAMPLE_ID int NOT NULL,
TISSUE varchar(255) NOT NULL,
CELL_TYPE varchar(255) NOT NULL,
ENTREZ_GENE_ID int NOT NULL,
EXPRESSION_VALUE float,
FOREIGN KEY(GENETIC_PROFILE_ID) REFERENCES genetic_profile(GENETIC_PROFILE_ID),
FOREIGN KEY(SAMPLE_ID) REFERENCES sample(INTERNAL_ID),
FOREIGN KEY(ENTREZ_GENE_ID) REFERENCES gene(ENTREZ_GENE_ID)
);

DELETE FROM genetic_profile WHERE STABLE_ID = "single_cell_expression";
INSERT INTO genetic_profile (
GENETIC_PROFILE_ID, STABLE_ID, CANCER_STUDY_ID, GENETIC_ALTERATION_TYPE,
DATATYPE, NAME, DESCRIPTION, SHOW_PROFILE_IN_ANALYSIS_TAB
) VALUES (
2, "SINGLE_CELL_EXPRESSION", 1, "single_cell_expression",
"single_cell_expression", "Single Cell Expression", "Test Single Cell Expression", 1
);

DELETE FROM gene WHERE ENTREZ_GENE_ID = 100;
INSERT INTO gene (
ENTREZ_GENE_ID, HUGO_GENE_SYMBOL, GENETIC_ENTITY_ID
) VALUES (
100, "TEST_GENE", 1
);

INSERT INTO single_cell_expression (
GENETIC_PROFILE_ID, SAMPLE_ID, TISSUE, CELL_TYPE, ENTREZ_GENE_ID, EXPRESSION_VALUE
) VALUES (
2, 1, "omentum", "B cell", 7157, 1.34
), (
2, 2, "omentum", "D cell", 7157, 4.24
), (
2, 2, "omentum", "D cell", 100, -1.24
), (
2, 2, "awesome tissue", "D cell", 7157, 8.24
), (
2, 2, "awesome tissue", "D cell", 100, NULL
);


/* command:
mysql -hlocalhost -P3306 --protocol=tcp --default-auth=mysql_native_password --get-server-public-key -ucbio -pP@ssword1 cbioportal < dev/test.sql
*/
5 changes: 3 additions & 2 deletions src/main/java/org/cbioportal/model/MolecularProfile.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public enum MolecularAlterationType {
PROTEIN_ARRAY_PROTEIN_LEVEL,
PROTEIN_ARRAY_PHOSPHORYLATION,
GENESET_SCORE,
GENERIC_ASSAY
GENERIC_ASSAY,
SINGLE_CELL_EXPRESSION
}

public enum DataType {
Expand Down Expand Up @@ -165,4 +166,4 @@ public Boolean getPatientLevel() {
public void setPatientLevel(Boolean patientLevel) {
this.patientLevel = patientLevel;
}
}
}
33 changes: 33 additions & 0 deletions src/main/java/org/cbioportal/model/SingleCellExpression.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.cbioportal.model;

import jakarta.validation.constraints.NotNull;

public class SingleCellExpression extends Alteration {

@NotNull
private String tissue;
@NotNull
private String cellType;
@NotNull
private Float expressionValue;

public String getTissue() {
return tissue;
}
public void setTissue(String tissue) {
this.tissue = tissue;
}
public String getCellType() {
return cellType;
}
public void setCellType(String cellType) {
this.cellType = cellType;
}
public Float getExpressionValue() {
return expressionValue;
}
public void setExpressionValue(Float expressionValue) {
this.expressionValue = expressionValue;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package org.cbioportal.model;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import jakarta.validation.constraints.NotNull;

public class SingleCellExpressionGroupedBySample extends UniqueKeyBase {

@NotNull
private String molecularProfileId;
@NotNull
private String sampleId;
@NotNull
private String patientId;
@NotNull
private String studyId;
@NotNull
private List<SingleCellExpressionGroupedByTissue> singleCellExpressionGroupedByTissues;

public SingleCellExpressionGroupedBySample(String sampleId, List<SingleCellExpression> singleCellExpressions) {
// TODO: do a check if all are equal?
this.sampleId = sampleId;
this.molecularProfileId = singleCellExpressions.get(0).getMolecularProfileId();
this.patientId = singleCellExpressions.get(0).getPatientId();
this.studyId = singleCellExpressions.get(0).getStudyId();

Map<String, List<SingleCellExpression>> tissueMap = singleCellExpressions.stream()
.collect(Collectors.groupingBy(SingleCellExpression::getTissue));
this.singleCellExpressionGroupedByTissues = tissueMap.entrySet().stream()
.map(e -> new SingleCellExpressionGroupedByTissue(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}

public String getMolecularProfileId() {
return molecularProfileId;
}
public void setMolecularProfileId(String molecularProfileId) {
this.molecularProfileId = molecularProfileId;
}
public String getSampleId() {
return sampleId;
}
public void setSampleId(String sampleId) {
this.sampleId = sampleId;
}
public String getPatientId() {
return patientId;
}
public void setPatientId(String patientId) {
this.patientId = patientId;
}
public String getStudyId() {
return studyId;
}
public void setStudyId(String studyId) {
this.studyId = studyId;
}
public List<SingleCellExpressionGroupedByTissue> getSingleCellExpressionGroupedByTissues() {
return singleCellExpressionGroupedByTissues;
}
public void setSingleCellExpressionGroupedByTissues(
List<SingleCellExpressionGroupedByTissue> singleCellExpressionGroupedByTissues) {
this.singleCellExpressionGroupedByTissues = singleCellExpressionGroupedByTissues;
}

class SingleCellExpressionGroupedByTissue {
@NotNull
private String tissue;
@NotNull
private List<SingleCellExpressionGroupedByCellType> singleCellExpressionGroupedByCellTypes;

public SingleCellExpressionGroupedByTissue(String tissue,
List<SingleCellExpression> singleCellExpressions) {
this.tissue = tissue;

Map<String, List<SingleCellExpression>> cellTypeMap = singleCellExpressions.stream()
.collect(Collectors.groupingBy(SingleCellExpression::getCellType));
this.singleCellExpressionGroupedByCellTypes = cellTypeMap.entrySet().stream()
.map(e -> new SingleCellExpressionGroupedByCellType(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}
public String getTissue() {
return tissue;
}
public void setTissue(String tissue) {
this.tissue = tissue;
}
public List<SingleCellExpressionGroupedByCellType> getSingleCellExpressionGroupedByCellTypes() {
return singleCellExpressionGroupedByCellTypes;
}
public void setSingleCellExpressionGroupedByCellTypes(
List<SingleCellExpressionGroupedByCellType> singleCellExpressionGroupedByCellTypes) {
this.singleCellExpressionGroupedByCellTypes = singleCellExpressionGroupedByCellTypes;
}

class SingleCellExpressionGroupedByCellType {
@NotNull
private String cellType;
@NotNull
private List<geneExpression> geneExpressions;

public SingleCellExpressionGroupedByCellType(String cellType,
List<SingleCellExpression> singleCellExpressions) {
this.cellType = cellType;

this.geneExpressions = singleCellExpressions.stream()
.map(e -> new geneExpression(e.getEntrezGeneId(), e.getExpressionValue()))
.collect(Collectors.toList());
}
public String getCellType() {
return cellType;
}
public void setCellType(String cellType) {
this.cellType = cellType;
}
public List<geneExpression> getGeneExpressions() {
return geneExpressions;
}
public void setGeneExpressions(List<geneExpression> geneExpressions) {
this.geneExpressions = geneExpressions;
}

class geneExpression {
@NotNull
private Integer entrezGeneId;
private Float expressionValue;

public geneExpression(Integer entrezGeneId, Float expressionValue) {
this.entrezGeneId = entrezGeneId;
this.expressionValue = expressionValue;
}

public Integer getEntrezGeneId() {
return entrezGeneId;
}
public void setEntrezGeneId(Integer entrezGeneId) {
this.entrezGeneId = entrezGeneId;
}
public Float getExpressionValue() {
return expressionValue;
}
public void setExpressionValue(Float expressionValue) {
this.expressionValue = expressionValue;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.cbioportal.persistence;

import java.util.List;

import org.cbioportal.model.SingleCellExpression;
import org.springframework.cache.annotation.Cacheable;

public interface SingleCellExpressionRepository {

@Cacheable(cacheResolver = "generalRepositoryCacheResolver", condition = "@cacheEnabledConfig.getEnabled()")
public List<SingleCellExpression> fetchSingleCellExpressionInMolecularProfile(
String molecularProfileId, String sampleListId, List<Integer> entrezGeneIds, Integer pageSize,
Integer pageNumber, String sortBy, String direction);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.cbioportal.persistence.mybatis;

import org.cbioportal.model.SingleCellExpression;

import java.util.List;

public interface SingleCellExpressionMapper {

public List<SingleCellExpression> fetchSingleCellExpressionInMolecularProfile(
String molecularProfileId, String sampleListId, List<Integer> entrezGeneIds, Integer limit, Integer offset,
String sortBy, String direction);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.cbioportal.persistence.mybatis;

import java.util.List;

import org.cbioportal.model.SingleCellExpression;
import org.cbioportal.persistence.SingleCellExpressionRepository;
import org.cbioportal.persistence.mybatis.util.PaginationCalculator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class SingleCellExpressionMyBatisRepository implements SingleCellExpressionRepository {

@Autowired
private SingleCellExpressionMapper singleCellExpressionMapper;

@Override
public List<SingleCellExpression> fetchSingleCellExpressionInMolecularProfile(
String molecularProfileId, String sampleListId, List<Integer> entrezGeneIds, Integer pageSize, Integer pageNumber,
String sortBy, String direction) {

List<SingleCellExpression> singleCellExpressions = singleCellExpressionMapper
.fetchSingleCellExpressionInMolecularProfile(molecularProfileId,
sampleListId, entrezGeneIds, pageSize, PaginationCalculator.offset(pageSize, pageNumber), sortBy, direction);
return singleCellExpressions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.cbioportal.service;

import java.util.List;

import org.cbioportal.service.exception.MolecularProfileNotFoundException;

import org.cbioportal.model.SingleCellExpression;
import org.cbioportal.model.SingleCellExpressionGroupedBySample;

public interface SingleCellExpressionService {

List<SingleCellExpression> fetchSingleCellExpressionInMolecularProfile(
String molecularProfileId, String sampleListId,
List<Integer> entrezGeneIds, Integer pageSize, Integer pageNumber,
String sortBy, String direction)
throws MolecularProfileNotFoundException;

List<SingleCellExpressionGroupedBySample> fetchSingleCellExpressionInMolecularProfileGroupedBySample(
String molecularProfileId, String sampleListId,
List<Integer> entrezGeneIds, Integer pageSize, Integer pageNumber)
throws MolecularProfileNotFoundException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.cbioportal.service.impl;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.cbioportal.service.SingleCellExpressionService;
import org.cbioportal.service.exception.MolecularProfileNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.cbioportal.model.SingleCellExpression;
import org.cbioportal.model.SingleCellExpressionGroupedBySample;
import org.cbioportal.persistence.SingleCellExpressionRepository;

@Service
public class SingleCellExpressionServiceImpl implements SingleCellExpressionService {

@Autowired
private SingleCellExpressionRepository singleCellExpressionRepository;

@Override
public List<SingleCellExpression> fetchSingleCellExpressionInMolecularProfile(
String molecularProfileId, String sampleListId,
List<Integer> entrezGeneIds, Integer pageSize, Integer pageNumber,
String sortBy, String direction)
throws MolecularProfileNotFoundException {

return singleCellExpressionRepository.fetchSingleCellExpressionInMolecularProfile(
molecularProfileId, sampleListId, entrezGeneIds, pageSize, pageNumber, sortBy, direction);
}

@Override
public List<SingleCellExpressionGroupedBySample> fetchSingleCellExpressionInMolecularProfileGroupedBySample(
String molecularProfileId, String sampleListId, List<Integer> entrezGeneIds,
Integer pageSize, Integer pageNumber)
throws MolecularProfileNotFoundException {

List<SingleCellExpression> singleCellExpressionData = fetchSingleCellExpressionInMolecularProfile(
molecularProfileId, sampleListId, entrezGeneIds, pageSize, pageNumber, "sampleId", "ASC");

Map<String, List<SingleCellExpression>> singleCellExpressionGroupedBySamples = singleCellExpressionData.stream()
.collect(Collectors.groupingBy(SingleCellExpression::getSampleId));

return singleCellExpressionGroupedBySamples.entrySet().stream()
.map(e -> new SingleCellExpressionGroupedBySample(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}

}
Loading

0 comments on commit 7f2c3d1

Please sign in to comment.