Skip to content

Instantly share code, notes, and snippets.

@CodingBash
Created January 31, 2026 14:23
Show Gist options
  • Select an option

  • Save CodingBash/2ac7e305c747ff220d44d0909dc4a71d to your computer and use it in GitHub Desktop.

Select an option

Save CodingBash/2ac7e305c747ff220d44d0909dc4a71d to your computer and use it in GitHub Desktop.
package edu.columbia.biology.service;
import org.springframework.security.core.Authentication;
import edu.columbia.biology.model.FitDetails;
public interface FitService {
/**
* Given fitId, retrieve the fitDetails
*
* @return
*/
public FitDetails retrieveFitDetails(int fitId, boolean isSiteAdmin);
public String retrieveFitScoringJson(int fitId);
/**
* Determine if fit is user accessible
*
* @param principal
* @param fitId
* @return
*/
public boolean isFitUserAccessible(Authentication authentication, int fitId);
}
package edu.columbia.biology.service;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import edu.columbia.biology.mapper.FitsRepositoryMapper;
import edu.columbia.biology.model.FitDetails;
import edu.columbia.biology.model.FitsMetadataInformation;
import edu.columbia.biology.model.PostprocContainerTO;
import edu.columbia.biology.model.PostprocEntryTO;
import edu.columbia.biology.model.PostprocItem;
import edu.columbia.biology.processor.CellxPrincipalProcessor;
import edu.columbia.biology.processor.PostprocProcessor;
import edu.columbia.biology.repository.CellxGlobalFitCurationCommentRepository;
import edu.columbia.biology.repository.FitsRepository;
import edu.columbia.biology.view_model.PostprocComponent;
@Service
public class FitServiceImpl implements FitService {
@Autowired
private PostprocProcessor postprocProcessor;
@Autowired
private CellxPrincipalProcessor cellxPrincipalProcessor;
@Autowired
private FitsRepository fitsRepository;
@Autowired
private FitsRepositoryMapper fitsRepositoryMapper;
@Autowired
private StudyService studyService;
@Autowired
private PostprocService postprocService;
@Qualifier("publicAccessiblePostprocs")
@Autowired
private List<String> publicAccessiblePostprocs;
/**
* TODO: The code here could be optimized for faster loading. Also perhaps
* postprocs could be loaded asyncronously by sending the postproc entries to
* the page, then asyncronosuly loading the postproc on expand? Therefore, it
* could also be cacheable?
*/
@Override
public FitDetails retrieveFitDetails(int fitId, boolean isSiteAdmin) {
FitsMetadataInformation fitsMetadataInformation = retrieveFitsMetadataInformation(fitId);
List<PostprocItem> postprocItems = postprocService.retrievePostprocItems(fitId);
// Non site admins only have access to basicModelViewer and resourceMotif
if (!isSiteAdmin) {
postprocItems = postprocItems.stream()
.filter(postprocItem -> publicAccessiblePostprocs.contains(postprocItem.getPostMethodName()))
.collect(Collectors.toList());
}
return new FitDetails(fitsMetadataInformation, postprocItems);
}
@Override
public boolean isFitUserAccessible(Authentication authentication, int fitId) {
if (cellxPrincipalProcessor.isSiteAdmin(authentication)) {
return true;
} else {
List<String> fitStudyNames = studyService.retrieveFitAssociatedStudies(fitId);
List<String> userAccessibleStudies = studyService.retrieveUserAccessibleStudies(authentication);
return userAccessibleStudies.containsAll(fitStudyNames);
}
}
@Override
public String retrieveFitScoringJson(int fitId) {
return fitsRepository.retrieveFitScoringJson(fitId);
}
public boolean isFitGlobalAccessible(Authentication authentication, int fitId) {
if (cellxPrincipalProcessor.isSiteAdmin(authentication)) {
return true;
} else {
List<String> fitStudyNames = studyService.retrieveFitAssociatedStudies(fitId);
List<String> userAccessibleStudies = studyService.retrieveUserAccessibleStudies(authentication);
return userAccessibleStudies.containsAll(fitStudyNames);
}
}
/**
* Given the fitId, retrieve the fit's metadata information
*
* @param fitId
* @return
*/
private FitsMetadataInformation retrieveFitsMetadataInformation(int fitId) {
return fitsRepositoryMapper.retrieveFitMetadataMapper(fitsRepository.retrieveFitMetadata(fitId));
}
}
package edu.columbia.biology.repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import edu.columbia.biology.entity.Fits;
/**
* Generated by Spring Data Generator on 14/01/2019
*/
@Repository
@Transactional
public interface FitsRepository extends JpaRepository<Fits, Integer>, JpaSpecificationExecutor<Fits> {
// TODO: [CONVENIENT] All added queries and repository methods somehow needs to
// be externalized to a properties/yaml file.
@Query("SELECT f from edu.columbia.biology.entity.Fits f WHERE f.regressorId = ?1")
Collection<Fits> findAllByRegressorId(Integer regressorId);
/**
* Retrieve every fit - used for administrator view
*
* TODO: Is this method still used? 3/12/21 YES I believe for admins?
*
* @deprecated
*/
@Deprecated
@Query(value = "SELECT fits.fit_id, cellx_global_fit_curation.curated,"
+ "CAST(ARRAY_AGG(DISTINCT experiment.study_name) AS text) AS study_name_list, "
+ "CAST(ARRAY_AGG(DISTINCT study.study_display_name) AS text) AS study_display_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.experiment_name) AS text) AS experiment_name_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.gene_symbol) AS text) AS gene_symbol_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.factor_id) AS text) AS factor_id_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.tax_id) AS text) AS tax_id_list FROM fits, "
+ "INNER JOIN count_fit ON fits.fit_id = count_fit.fit_id "
+ "INNER JOIN count_table ON count_fit.count_table_id = count_table.count_table_id "
+ "INNER JOIN experiment ON count_table.study_name = experiment.study_name AND count_table.experiment_name = experiment.experiment_name "
+ "INNER JOIN factor_complex ON experiment.complex_id = factor_complex.complex_id "
+ "INNER JOIN factor ON factor_complex.factor_id = factor.factor_id "
+ "LEFT JOIN cellx_global_fit_curation ON fits.fit_id = cellx_global_fit_curation.fit_id "
+ "WHERE fits.iscomplete=TRUE "
+ "GROUP BY fits.fit_id, cellx_global_fit_curation.curated ", nativeQuery = true)
Collection<Object[]> retrieveAllFits();
/**
* Retrieve every fit in a public study - used for administrator view
*/
@Query(value = "SELECT fits.fit_id, fits.fit_path, cellx_global_fit_curation.curated,\r\n "
+ "CAST(ARRAY_AGG(DISTINCT cellx_global_fit_curation_tag.tag) AS text) AS tag_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.study_name) AS text) AS study_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT study.study_display_name) AS text) AS study_display_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.experiment_name) AS text) AS experiment_name_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.gene_symbol) AS text) AS gene_symbol_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.factor_id) AS text) AS factor_id_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.tax_id) AS text) AS tax_id_list, " + "fits.ranking_score, "
+ "fit_group_curated.group_id AS pipeline_group_id, " + "fit_group_curated.metric AS pipeline_metric, "
+ "fit_group_curated.metric_value AS pipeline_metric_value, "
+ "fit_group_curated.iscurated AS pipeline_curated FROM fits "
+ "INNER JOIN fit_group_curated ON fits.fit_id = fit_group_curated.fit_id "
+ "INNER JOIN count_fit ON fits.fit_id = count_fit.fit_id "
+ "INNER JOIN count_table ON count_fit.count_table_id = count_table.count_table_id "
+ "INNER JOIN experiment ON count_table.study_name = experiment.study_name AND count_table.experiment_name = experiment.experiment_name "
+ "INNER JOIN study ON study.study_name = experiment.study_name "
+ "INNER JOIN factor_complex ON experiment.complex_id = factor_complex.complex_id "
+ "INNER JOIN factor ON factor_complex.factor_id = factor.factor_id "
+ "LEFT JOIN cellx_global_fit_curation ON fits.fit_id = cellx_global_fit_curation.fit_id "
+ "LEFT JOIN cellx_global_fit_curation_tag ON fits.fit_id = cellx_global_fit_curation_tag.fit_id "
+ "WHERE fits.iscomplete=TRUE " + "GROUP BY fits.fit_id, fits.fit_path, cellx_global_fit_curation.curated, "
+ "fit_group_curated.group_id, fit_group_curated.metric, fit_group_curated.metric_value, fit_group_curated.iscurated "
+ "HAVING NOT true=any(ARRAY_AGG(DISTINCT study.isembargoed))", nativeQuery = true)
Collection<Object[]> retrievePublicFits();
/**
* Retrieve every fit in a public study that is also curated - for users
*/
@Query(value = "SELECT fits.fit_id, fits.fit_path, cellx_global_fit_curation.curated, \r\n"
+ "CAST(ARRAY_AGG(DISTINCT cellx_global_fit_curation_tag.tag) AS text) AS tag_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.study_name) AS text) AS study_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT study.study_display_name) AS text) AS study_display_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.experiment_name) AS text) AS experiment_name_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.gene_symbol) AS text) AS gene_symbol_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.factor_id) AS text) AS factor_id_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.tax_id) AS text) AS tax_id_list, " + "fits.ranking_score, "
+ "fit_group_curated.group_id AS pipeline_group_id, " + "fit_group_curated.metric AS pipeline_metric, "
+ "fit_group_curated.metric_value AS pipeline_metric_value, "
+ "fit_group_curated.iscurated AS pipeline_curated FROM fits "
+ "INNER JOIN fit_group_curated ON fits.fit_id = fit_group_curated.fit_id "
+ "INNER JOIN count_fit ON fits.fit_id = count_fit.fit_id "
+ "INNER JOIN count_table ON count_fit.count_table_id = count_table.count_table_id "
+ "INNER JOIN experiment ON count_table.study_name = experiment.study_name AND count_table.experiment_name = experiment.experiment_name "
+ "INNER JOIN study ON study.study_name = experiment.study_name "
+ "INNER JOIN factor_complex ON experiment.complex_id = factor_complex.complex_id "
+ "INNER JOIN factor ON factor_complex.factor_id = factor.factor_id "
+ "LEFT JOIN cellx_global_fit_curation ON fits.fit_id = cellx_global_fit_curation.fit_id "
+ "LEFT JOIN cellx_global_fit_curation_tag ON fits.fit_id = cellx_global_fit_curation_tag.fit_id "
+ "WHERE ((fits.iscomplete=TRUE) AND (cellx_global_fit_curation.curated IS NOT FALSE) AND ((cellx_global_fit_curation.curated IS TRUE) OR ((cellx_global_fit_curation.curated IS NULL) AND (fit_group_curated.iscurated IS TRUE)))) "
+ "GROUP BY fits.fit_id, fits.fit_path, cellx_global_fit_curation.curated, "
+ "fit_group_curated.group_id, fit_group_curated.metric, fit_group_curated.metric_value, fit_group_curated.iscurated "
+ "HAVING NOT true=any(ARRAY_AGG(DISTINCT study.isembargoed)) AND ARRAY_AGG(DISTINCT cellx_global_fit_curation_tag.tag) @> '{\"GOOD\"}'", nativeQuery = true)
Collection<Object[]> retrievePublicCuratedFits();
// TODO: Replace the cellx tables with the new version in celldb-devtest version
/**
* Retrieve every fit that a user has access to
*
* @Deprecated - method not yet used
*/
@Deprecated
@Query(value = "SELECT fits.fit_id, fits.fit_path, postproc.postproc_id, postproc.output_string, "
+ "CAST(ARRAY_AGG(DISTINCT experiment.study_name) AS text) AS study_name_list, "
+ "CAST(ARRAY_AGG(DISTINCT study.study_display_name) AS text) AS study_display_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.experiment_name) AS text) AS experiment_name_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.gene_symbol) AS text) AS gene_symbol_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.factor_id) AS text) AS factor_id_list, "
+ "CAST(ARRAY_AGG(DISTINCT factor.tax_id) AS text) AS tax_id_list FROM fits "
+ "INNER JOIN count_fit ON fits.fit_id = count_fit.fit_id "
+ "INNER JOIN count_table ON count_fit.count_table_id = count_table.count_table_id "
+ "INNER JOIN experiment ON count_table.study_name = experiment.study_name AND count_table.experiment_name = experiment.experiment_name "
+ "INNER JOIN study ON study.study_name = experiment.study_name "
+ "LEFT JOIN cellx_group_study ON study.study_name = cellx_group_study.study_name "
+ "LEFT JOIN cellx_group ON cellx_group_study.group_id = cellx_group.group_id "
+ "LEFT JOIN cellx_group_user ON cellx_group.group_id = cellx_group_user.group_id "
+ "INNER JOIN factor_complex ON experiment.complex_id = factor_complex.complex_id "
+ "INNER JOIN factor ON factor_complex.factor_id = factor.factor_id "
+ "INNER JOIN fit_post ON fits.fit_id = fit_post.fit_id "
+ "INNER JOIN postproc ON fit_post.postproc_id = postproc.postproc_id "
+ "WHERE postproc.post_method_name='summaryQC' AND fits.iscomplete=TRUE AND (cellx_group_user.user_id = ?1 OR cellx_group_user.user_id IS NULL)"
+ "GROUP BY fits.fit_id, postproc.postproc_id, postproc.output_string "
+ "HAVING NOT false=any(ARRAY_AGG(DISTINCT CASE WHEN study.isembargoed = false OR cellx_group_user.user_id = ?1 THEN true ELSE false END))", nativeQuery = true)
Collection<Object[]> retrieveUserAccessibleFits(Integer userId);
/**
* Retrieve studies associated with a fit
*/
@Query("SELECT DISTINCT countTable.studyName FROM edu.columbia.biology.entity.Fits fits "
+ "INNER JOIN edu.columbia.biology.entity.CountFit countFit ON fits.fitId = countFit.fitId "
+ "INNER JOIN edu.columbia.biology.entity.CountTable countTable ON countFit.countTableId = countTable.countTableId "
+ "WHERE fits.fitId = ?1")
Collection<String> retrieveFitStudies(Integer fitId);
@Query("SELECT fits.scoringJson FROM edu.columbia.biology.entity.Fits fits WHERE fits.fitId = ?1")
String retrieveFitScoringJson(Integer fitId);
/**
* Retrieve fit metadata
*/
@Query(value = "SELECT fits.fit_id, fits.fit_path,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.study_name) AS text) AS study_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT study.study_display_name) AS text) AS study_display_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT experiment.experiment_name) AS text) AS experiment_name_list,\r\n"
+ "CAST(ARRAY_AGG(DISTINCT factor.gene_symbol) AS text) AS gene_symbol_list, \r\n"
+ "CAST(ARRAY_AGG(DISTINCT factor.factor_id) AS text) AS factor_id_list, \r\n"
+ "CAST(ARRAY_AGG(DISTINCT factor.tax_id) AS text) AS tax_id_list \r\n" + "FROM fits\r\n"
+ "INNER JOIN count_fit ON fits.fit_id = count_fit.fit_id\r\n"
+ "INNER JOIN count_table ON count_fit.count_table_id = count_table.count_table_id \r\n"
+ "INNER JOIN experiment ON count_table.study_name = experiment.study_name AND count_table.experiment_name = experiment.experiment_name \r\n"
+ "INNER JOIN study ON experiment.study_name = study.study_name\r\n"
+ "INNER JOIN factor_complex ON experiment.complex_id = factor_complex.complex_id \r\n"
+ "INNER JOIN factor ON factor_complex.factor_id = factor.factor_id \r\n" + "WHERE fits.fit_id = ?1\r\n"
+ "GROUP BY fits.fit_id, fits.fit_path\r\n" + "LIMIT 1", nativeQuery = true)
List<Object[]> retrieveFitMetadata(Integer fitId);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment