scMKL_analysis / app.py
ivango17's picture
fixed JASPAR umaps
38f0a6e
import seaborn as sns
import pandas as pd
import plotting as pl
import numpy as np
import matplotlib as plt
from shinywidgets import render_widget
from shiny import render, reactive
from shiny.express import input, ui
#############
# Constants #
#############
all_datasets = ['MCF7', 'T47D', 'lymphoma', 'prostate_rna', 'prostate_atac', 'LUAD', 'LUSC']
rna_datasets = ['MCF7', 'T47D', 'lymphoma', 'prostate_rna', 'LUAD', 'LUSC']
atac_datasets = ['MCF7', 'T47D', 'lymphoma', 'prostate_atac']
MCF7_T47D_mg_options = [
'RNA - Hallmark', 'ATAC - Hallmark', 'ATAC_TFIDF - Hallmark',
'ATAC - Cistrome', 'ATAC_TFIDF - Cistrome',
"ATAC - Motifs", "ATAC_TFIDF - Motifs",
'RNA+ATAC - Hallmark', 'RNA+ATAC_TFIDF - Hallmark',
'RNA+ATAC - Hallmark+Cistrome', 'RNA+ATAC_TFIDF - Hallmark+Cistrome',
'RNA+ATAC - Hallmark+Motifs', 'RNA+ATAC_TFIDF - Hallmark+Motifs'
]
lymphoma_mg_options = [
'RNA - Hallmark', 'ATAC - Hallmark', 'ATAC_TFIDF - Hallmark',
"ATAC - Motifs", "ATAC_TFIDF - Motifs",
'RNA+ATAC - Hallmark', 'RNA+ATAC_TFIDF - Hallmark',
'RNA+ATAC - Hallmark+Motifs', 'RNA+ATAC_TFIDF - Hallmark+Motifs'
]
prostate_rna_mg_options = [
'RNA - Hallmark'
]
prostate_atac_mg_options = [
'ATAC - Hallmark', 'ATAC_TFIDF - Hallmark', 'GAS - Hallmark',
"ATAC - Motifs", "ATAC_TFIDF - Motifs", "ATAC_TFIDF - Motifs", 'GAS+ATAC - Neuronal+Motifs',
'GAS+ATAC - Hallmark', 'GAS+ATAC_TFIDF - Hallmark', 'GAS+ATAC - Hallmark+Motifs', 'GAS+ATAC_TFIDF - Hallmark+Motifs'
]
luad_rna_mg_options = [
'RNA - Hallmark'
]
lusc_rna_mg_options = [
'RNA - Hallmark'
]
mg_colors = {'RNA - hallmark' : "#cf1322", 'ATAC - hallmark' : "#1c13cf", 'ATAC_TFIDF - hallmark' : "#3329f0",
'ATAC - cistrome' : "#2968f0", 'ATAC_TFIDF - cistrome' : "#437dfa",
'ATAC - motifs' : "#6e43fa", 'ATAC_TFIDF - motifs' : "#5b3ac7",
'GAS - hallmark' : "#09b526", 'GAS+ATAC - hallmark+motifs' : "#107a06", 'GAS+ATAC_TFIDF - hallmark+motifs' : "#37b02c",
'RNA+ATAC - hallmark' : "#7014d9", 'RNA+ATAC_TFIDF - hallmark' : "#974deb", 'RNA+ATAC - hallmark+cistrome' : "#3c2275", 'RNA+ATAC_TFIDF - hallmark+cistrome' : "#2d0c75", 'RNA+ATAC - hallmark+motifs' : "#750c5d", 'RNA+ATAC_TFIDF - hallmark+motifs' : "#b5098d"}
################
# Data Read-in #
################
# Reading in performance and selection results
stats_df = pd.concat([pd.read_csv(f'data/model_performance/{dataset}_stats.tsv.gz', sep = "\t") for dataset in all_datasets])
selections_df = pd.concat([pd.read_csv(f'data/group_selections/{dataset}_group_selections.tsv.gz', sep = '\t') for dataset in all_datasets])
selected_features_df = pd.concat([pd.read_csv(f'data/feature_selections/{dataset}_feature_selections.tsv.gz', sep = "\t") for dataset in all_datasets])
# Reading in differentail features
deg_df = pd.concat([pd.read_csv(f'data/differentially_expressed_genes/{dataset}_DEGs.tsv.gz', sep = "\t") for dataset in rna_datasets])
dar_df = pd.concat([pd.read_csv(f'data/differentially_accessible_regions/{dataset}_DARs.tsv.gz', sep = "\t") for dataset in atac_datasets])
# Reading in standard sc analysis workflow
subset_groupings = np.load("data/subset_all_groupings.pkl", allow_pickle = True)
umap_dict = np.load("data/umap_embeddings.pkl", allow_pickle = True)
hallmark_geneset_df = pd.read_csv("data/hallmark_enrichment_selection_overlap.tsv", sep = "\t")
GO_BP_df = pd.read_csv("data/geneset_enrichment.tsv", sep = "\t")
GO_BP_df = GO_BP_df[GO_BP_df['Gene Set'] == 'GO Biological Processes RNA']
gene_group_frequency_df = pd.read_csv("data/gene-group_distribution.tsv", sep = "\t")
# Reading in dataset info
datasets_df = pd.read_csv("data/dataset_info.csv", sep = ',', quotechar="'")
###############
# Application #
###############
# Title
ui.page_opts(title="scMKL")
############
# Overview #
############
with ui.nav_panel("Overview"):
with ui.navset_tab():
with ui.nav_panel('About scMKL'):
# About
ui.markdown(
'''
# About scMKL
scMKL (single-cell Multiple Kernel Learning) is a binary classifier. It takes advantage of **Random Fourier Features** (RFFs) to create a **multiple approximate kernels** that is passed to Group Lasso to make classifications.
Single-cell features are grouped into groupings such as gene sets for transcriptomics data. The data is then transformed with **RFF**s to create kernels that are then used as parameters in **Group Lasso**. This enables
scMKL to be scalable to the volume of single-cell data.
**Group Lasso** assigns weights to each grouping based on how predictive those groupings are for distinguishing between two cell classes. The regularization coefficient Group Lasso takes allows the user to manipulate the number of nonzero
groupings that are used in the final model and can be tuned for optimal accuracy. This feature makes the results of scMKL interpretable.
'''
)
@render.image
def image1():
img1 = {"src": "data/images/scMKL_workflow.png", "width": "750px"}
return img1
ui.markdown("This frame work gives a straight-forward approach to integrating different data types such as RNA and ATAC data into a single model.")
@render.image
def image2():
img2 = {"src": "data/images/workflow_overview.png", "width": "750px"}
return img2
with ui.nav_panel('Experimental Design'):
# Dataset info
ui.markdown(
'''
# Experimental Design
Seven single-cell datasets were used to evaluate the performance of scMKL and compare to other methods of single-cell analysis as shown below.
scMKL was used to predict cell labels for each data set.
'''
)
@render.data_frame
def summary_data():
return render.DataGrid(datasets_df, selection_mode="rows")
ui.markdown(
'''
To obtain robust results, we used 100 different train/test splits. For each split, we used 10 different sparsity arguments giving a range of group
selection for each. This layout yields 1,000 models total for each groupings/modality combination.
'''
)
with ui.card():
ui.markdown(
'''
## Citations
- Ors, Aysegul, Alex Daniel Chitsazan, Aaron Reid Doe, Ryan M. Mulqueen, Cigdem Ak, Yahong Wen, Syber Haverlack et al. "Estrogen regulates divergent transcriptional and epigenetic cell states in breast cancer."*Nucleic acids research* 50, no. 20 (2022): 11492-11508.
- Identification of a tumor-specific gene regulatory network in human B-cell lymphoma, Single Cell Multiome ATAC + Gene Expression, 10x Genomics, (2021)
- Song, Hanbing, Hannah NW Weinstein, Paul Allegakoen, Marc H. Wadsworth, Jamie Xie, Heiko Yang, Ethan A. Castro et al. "Single-cell analysis of human primary prostate cancer reveals the heterogeneity of tumor-associated epithelial cell states." *Nature communications* 13, no. 1 (2022): 141.
- Eksi, Sebnem Ece, Alex Chitsazan, Zeynep Sayar, George V. Thomas, Andrew J. Fields, Ryan P. Kopp, Paul T. Spellman, and Andrew C. Adey. "Epigenetic loss of heterogeneity from low to high grade localized prostate tumours." *Nature communications* 12, no. 1 (2021): 7292.
- Wolf, F. Alexander, Philipp Angerer, and Fabian J. Theis. "SCANPY: large-scale single-cell gene expression data analysis." *Genome biology* 19 (2018): 1-5.
- Fang, Zhuoqing, Xinyuan Liu, and Gary Peltz. "GSEApy: a comprehensive package for performing gene set enrichment analysis in Python." *Bioinformatics* 39, no. 1 (2023): btac757.
- McInnes, Leland, John Healy, and James Melville. "Umap: Uniform manifold approximation and projection for dimension reduction." *arXiv preprint arXiv:1802.03426* (2018).
- Chen, Tianqi, and Carlos Guestrin. "Xgboost: A scalable tree boosting system." In *Proceedings of the 22nd acm sigkdd international conference on knowledge discovery and data mining*, pp. 785-794. 2016.
- Tolstikhin, Ilya O., Neil Houlsby, Alexander Kolesnikov, Lucas Beyer, Xiaohua Zhai, Thomas Unterthiner, Jessica Yung et al. "Mlp-mixer: An all-mlp architecture for vision." Advances in neural information processing systems 34 (2021): 24261-24272.
'''
)
#####################
# Prior Information #
#####################
with ui.nav_panel("Prior Information"):
ui.markdown("# Feature Groupings")
with ui.navset_pill_list(widths = (2,10)):
# Hallmark
with ui.nav_panel("Hallmark Gene Sets"):
ui.markdown("# Hallmark Gene Sets")
with ui.card():
ui.markdown(
'''
### Background
There are 50 gene sets composed of between 32 and 200 genes in Hallmark gene sets. The length of these genes sum to 7,322 genes.
However, there are only 4,384 unique genes in this collection of gene sets indicating overlap between the groups.
To use Hallmark gene sets for ATAC data, features in each ATAC data set were matched with regions that overlapped with or was in proximity of the gene bodies of genes in each gene set.
'''
)
ui.markdown("[https://www.gsea-msigdb.org](https://www.gsea-msigdb.org)")
ui.input_radio_buttons("dataset_grouping_selection", "Dataset",
{"MCF7" : "MCF7", "T47D": "T47D",
"lymphoma": "Lymphoma",
"prostate" : "Prostate", 'LUAD' : 'LUAD',
'LUSC' : 'LUSC'},
selected = "MCF7")
with ui.layout_columns(col_widths={"sm": (6, 6)}):
with ui.card():
ui.card_header("Hallmark RNA Groupings")
ui.markdown("#### Top Group Feature Overlap")
@render.image
def hallmarkr_overlap():
if input.dataset_grouping_selection() == "prostate":
hr_overlap = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection()}_rna_RNA_HALLMARK_upsetplot.png", "width" : "650px", "height" : "350px"}
return hr_overlap
else:
hr_overlap = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection()}_RNA_HALLMARK_upsetplot.png", "width" : "650px", "height" : "350px"}
return hr_overlap
ui.markdown("#### Proportion of Unique Features in Grouping")
@render.image
def hallmarkr_uniq():
hr_uniq = {"src": f"data/figures/grouping_figures/HALLMARK_RNA_unique_features_barplot.png", "width" : "650px"}
return hr_uniq
with ui.card():
ui.card_header("Hallmark ATAC Groupings")
ui.markdown("#### Top Group Feature Overlap")
@render.image
def hallmarka_overlap():
if input.dataset_grouping_selection() == "prostate":
ha_overlap = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection()}_atac_ATAC_HALLMARK_upsetplot.png", "width" : "650px", "height" : "350px"}
return ha_overlap
else:
ha_overlap = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection()}_ATAC_HALLMARK_upsetplot.png", "width" : "650px", "height" : "350px"}
return ha_overlap
ui.markdown("#### Proportion of Unique Features in Grouping")
@render.image
def hallmarka_uniq():
if input.dataset_grouping_selection() == "prostate":
ha_uniq = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection()}_atac_HALLMARK_ATAC_unique_features_barplot.png", "width" : "650px"}
return ha_uniq
else:
ha_uniq = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection()}_HALLMARK_ATAC_unique_features_barplot.png", "width" : "650px"}
return ha_uniq
# Cistrome
with ui.nav_panel("Cistrome TFBMs"):
ui.markdown("# Cistrome TFBMs")
with ui.card():
ui.markdown(
'''
### Background
The Cistrome database contains tissue specific regions of transcription factor binding motifs (TFBMs). TFBMs were
matched with assay features to create groupings of TFBMs by transcription factor for both MCF7 and T47D cell-lines.
'''
)
ui.markdown("[http://cistrome.org](http://cistrome.org)")
ui.input_radio_buttons("dataset_grouping_selection_2", "Dataset",
{"MCF7" : "MCF7", "T47D": "T47D"},
selected = "MCF7")
with ui.layout_columns(col_widths={"sm": (6, 6)}):
with ui.card():
ui.markdown("#### Top Group Feature Overlap")
@render.image
def cistrome_overlap():
c_overlap = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection_2()}_ATAC_CISTROME_upsetplot.png", "width" : "800px"}
return c_overlap
with ui.card(height = "900px"):
ui.markdown("### Proportion of Unique Features in Grouping")
@render.image
def cistrome_uniq():
c_uniq = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection_2()}_CISTROME_unique_features_barplot.png", "width" : "650px"}
return c_uniq
# JASPAR
with ui.nav_panel("JASPAR TFBMs"):
ui.markdown("# JASPAR TFBMs")
with ui.card():
ui.markdown(
'''
### Background
The JASPAR database contains regions of
transcription factor binding motifs (TFBMs) that
are not tissue specific. Using motifmatchr, we
matched data ATAC peaks to known transcription
factor binding motifs using *motifmatchr* where
each group contained peaks associated with a
single transcription factor's binding motifs.
Interestingly, there are no unique features in the
top JASPAR groupings which could be an indication
of the importance of feature groupings.
'''
)
ui.markdown("[https://jaspar.elixir.no/]"
"(https://jaspar.elixir.no/)")
ui.input_radio_buttons("dataset_grouping_selection_3", "Dataset",
{"MCF7" : "MCF7", "T47D": "T47D",
"lymphoma": "Lymphoma",
"prostate_atac" : "Prostate ATAC"},
selected = "MCF7")
with ui.layout_columns(col_widths={"sm": (6, 6)}):
with ui.card():
ui.markdown("#### Top Group Feature Overlap")
@render.image
def motif_overlap():
figure_dir = 'data/figures/grouping_figures/'
dataset = input.dataset_grouping_selection_3()
suffix = "_ATAC_MOTIFS_upsetplot.png"
filename = figure_dir + dataset + suffix
m_overlap = {"src": filename, "width" : "800px"}
return m_overlap
with ui.card(height = "900px"):
ui.markdown("### Proportion of Unique Features in Grouping")
@render.image
def motif_uniq():
m_uniq = {"src": f"data/figures/grouping_figures/{input.dataset_grouping_selection_3()}_MOTIFS_unique_features_barplot.png", "width" : "650px"}
return m_uniq
# We may add this back
# Neuronal Gene Sets
# with ui.nav_panel("Neuronal Gene Sets"):
# ui.markdown("# Neuronal Gene Sets")
# with ui.card():
# ui.markdown(
# '''
# ### Background
# These five gene sets are all related to neural function or development and contain between six and 70 genes.
# In total, this grouping set contains 115 unique genes with 6 of those genes in at least two groups.
# '''
# )
# ui.p("Labrecque et al., 2019")
# ui.p("Beltran et al., 2016")
# with ui.card():
# ui.card_header("Neuronal RNA Groupings")
# ui.markdown("#### Group Feature Overlap")
# @render.image
# def neuronal_overlap():
# n_overlap = {"src": "data/figures/grouping_figures/neuronal_RNA_unique_features_new.png", "width" : "650px"}
# return n_overlap
#####################
# scMKL Performance #
#####################
with ui.nav_panel("scMKL Performance"):
ui.markdown("# scMKL Performance")
with ui.layout_columns(col_widths={"sm": (2, 2, 8)}):
with ui.card():
ui.markdown("### Selections")
# Data set selection
ui.input_radio_buttons("dataset_selection_MP",
"Datasets",
{"MCF7": "MCF7", "T47D": "T47D", "lymphoma": "Lymphoma", "prostate_rna" : "Prostate RNA", "prostate_atac" : "Prostate ATAC", 'LUSC' : 'LUSC', 'LUAD' : 'LUAD'},
selected = "MCF7"
)
# Metric selection
ui.input_select("metric_selection_MP",
"Metric", {"AUROC" :"Area Under ROC", "RAM_usage" : "Memory Usage (GB)", "Inference_time" : "Time (s)", "Number_of_Selected_Groups" : "Number of Groups Selected"},
selected = 'AUROC'
)
ui.input_select("x_intersection", "Additional Options", {
"all" : "Show all runs from selections",
"intersect" : "Show only intersecting x-axis values",
"best" : "Show only runs with optimized alpha"
},
selected = "best")
# x_variable selection
ui.input_select("x_variable_MP", "x-axis variable", {"Mean_Number_of_Selected_Groups" : 'Mean Number of Selected Groups by Alpha', 'Alpha' : 'Alpha', "Number_of_Selected_Groups" : "Number of Selected Groups"},
selected = "Mean_Number_of_Selected_Groups")
ui.input_checkbox('select_all', 'Select All Datatype - Groupings', False)
with ui.card():
# Modality/Grouping Selection (updates based on dataset selected)
ui.input_selectize("modality_selections_MP", "Datatype - Grouping", MCF7_T47D_mg_options, multiple = True, selected = MCF7_T47D_mg_options[0])
@reactive.effect
def mg_selection():
dataset_mod_choices = {
"MCF7" : MCF7_T47D_mg_options,
"T47D" : MCF7_T47D_mg_options,
"lymphoma" : lymphoma_mg_options,
"prostate_rna" : prostate_rna_mg_options,
"prostate_atac": prostate_atac_mg_options,
'LUAD' : luad_rna_mg_options,
'LUSC' : lusc_rna_mg_options
}
user_choice = input.dataset_selection_MP()
if input.select_all():
ui.update_selectize("modality_selections_MP",
label = "Datatype - Grouping",
choices = dataset_mod_choices[user_choice],
selected = dataset_mod_choices[user_choice]
)
else:
ui.update_selectize("modality_selections_MP",
label = "Datatype - Grouping",
choices = dataset_mod_choices[user_choice],
selected = dataset_mod_choices[user_choice][0]
)
with ui.card():
ui.input_action_button("model_performance_run", "Create Plot", width = "200px")
@render_widget()
@reactive.event(input.model_performance_run)
def stats_bp():
stats_plot = pl.performance_boxplot(stats_df, dataset = input.dataset_selection_MP(), modality = input.modality_selections_MP(), metric = input.metric_selection_MP(), x_flag = input.x_intersection(), x_var = input.x_variable_MP(), color_dict = mg_colors)
return stats_plot
####################
# Model Comparison #
####################
with ui.nav_panel("Model Comparison"):
ui.markdown('''
# scMKL vs. Other State-of-the-Art Models
##### ***XGBoost*** uses gradient boosting decision trees to classify samples.
##### ***MLP*** uses a layered feedforward neural network to classify samples.
'''
)
with ui.layout_columns(col_widths={"sm": (4, 8)}):
with ui.card():
ui.markdown("##### When scMKL is selected, the best performing alpha is used to plot results")
# Data set selection
ui.input_radio_buttons("dataset_selection_sVO", "Datasets",
{"MCF7": "MCF7",
"T47D": "T47D",
"lymphoma": "Lymphoma",
'LUAD' : 'LUAD',
'LUSC' : 'LUSC',
"prostate_rna" : "Prostate_RNA",
"prostate_atac" : "Prostate_ATAC"},
selected = "MCF7"
)
# Model Selection
ui.input_checkbox_group("model_selections", "Models", ['scMKL',
'XGBoost',
'MLP'
],
selected = 'scMKL')
# Metric Selection
ui.input_radio_buttons("metrics_selection_sVO", "Metrics", {"AUROC" :"Area Under ROC",
"RAM_usage" : "Memory Usage (GB)",
"Inference_time" : "Time (s)"
},
selected = "AUROC")
with ui.card():
@render_widget()
def comp_bp():
comp_plot = pl.comparison_boxplot(stats_df, input.dataset_selection_sVO(), input.model_selections(), input.metrics_selection_sVO())
return comp_plot
#################
# scMKL Results #
#################
with ui.nav_panel("scMKL Results"):
ui.markdown(
'''
# scMKL Interpretation via Weights and Selection
'''
)
with ui.layout_columns(col_widths={"sm": (3, 9)}):
with ui.card():
ui.markdown("### Selections")
# Data set selection
ui.input_radio_buttons("dataset_selection_SR", "Datasets",
{"MCF7": "MCF7",
"T47D": "T47D",
"lymphoma": "Lymphoma",
"prostate_rna" : "Prostate RNA",
"prostate_atac" : "Prostate ATAC",
'LUAD' : 'LUAD',
'LUSC' : 'LUSC'},
selected = "MCF7"
)
# Modality/Grouping Selection (updates based on dataset selected)
ui.input_radio_buttons("modality_selections_SR", "Datatype - Grouping", MCF7_T47D_mg_options,
selected = 'RNA - Hallmark')
@reactive.effect
def update_runs():
x = input.dataset_selection_SR()
updated_dtype_grouping = {
"MCF7" : MCF7_T47D_mg_options,
"T47D" : MCF7_T47D_mg_options,
"lymphoma" : lymphoma_mg_options,
"prostate_rna" : prostate_rna_mg_options,
"prostate_atac": prostate_atac_mg_options,
'LUAD' : luad_rna_mg_options,
'LUSC' : lusc_rna_mg_options
}
ui.update_radio_buttons("modality_selections_SR",
label = "Datatype - Grouping",
choices = updated_dtype_grouping[x],
selected = updated_dtype_grouping[x][0])
with ui.card(height = '1000px'):
ui.input_action_button("weights_plots", "Create Plots", width = "200px")
with ui.navset_tab():
with ui.nav_panel('Normalized Group Weights'):
ui.markdown("### Top Group Normalized Weights")
@render_widget()
@reactive.event(input.weights_plots)
def norm_bp():
norm_plot = pl.weights_boxplot(selections_df, input.dataset_selection_SR(), input.modality_selections_SR())
return norm_plot
with ui.nav_panel('Group Selection'):
ui.markdown("### Heatmap of scMKL Group Selection Frequency")
@render.image
@reactive.event(input.weights_plots)
def heatmap():
heatmap = {"src": f"data/figures/heatmaps/{input.dataset_selection_SR()}_{pl.format_datatype_grouping(input.modality_selections_SR()).replace(' - ', '_')}_selection_heatmap.png",
"width": "1400px"}
return heatmap
with ui.nav_panel('Feature Selection'):
ui.markdown(
'''
### scMKL Feature Selections
**NOTE**: Motif grouping feature selections are unavailable
''')
@render_widget()
@reactive.event(input.weights_plots)
def feature_selection():
feature_plot = pl.plot_features(selected_features_df, input.dataset_selection_SR(), input.modality_selections_SR())
return feature_plot
##################
# scanpy Results #
##################
with ui.nav_panel("scanpy Results"):
ui.markdown("# Single-cell Analysis with scanpy")
with ui.layout_columns(col_widths={"sm": (3, 9)}):
with ui.card():
ui.markdown("### Dataset and Modality")
# Data set selection
ui.input_radio_buttons("dataset_selection_sA",
"Datasets",
{"MCF7": "MCF7",
"T47D": "T47D",
"lymphoma": "Lymphoma",
"prostate_rna" : "Prostate_RNA",
"prostate_atac" : "Prostate_ATAC",
'LUAD' : 'LUAD',
'LUSC' : 'LUSC'
},
selected = "MCF7"
)
# Modality
ui.input_radio_buttons("modality_selection_sA",
"Modality",
{"RNA" : "RNA", "ATAC" : "ATAC"}, selected = "RNA")
@reactive.effect
def _():
x = input.dataset_selection_sA()
multimodal = ['RNA', 'ATAC']
modality_choices = {"MCF7" : multimodal,
"T47D" : multimodal,
"lymphoma" : multimodal,
"prostate_rna" : ["RNA"],
"prostate_atac" : ["ATAC"],
'LUAD' : ["RNA"],
'LUSC' : ["RNA"]
}
ui.update_radio_buttons("modality_selection_sA",
label = "Modality",
choices = modality_choices[x],
selected = modality_choices[x][0])
ui.markdown("##### Subsets")
# Subset Grouping
ui.input_select('grouping_selection', "Collection", ['Hallmark'], selected = 'Hallmark')
# ui.input_radio_buttons('grouping_selection', "Grouping", ['Hallmark'], selected = 'Hallmark')
ui.input_select("group_selection", "Group Subset", ["None", "Estrogen Response Early", "Estrogen Response Late", "Protein Secretion", "E2F Targets", "TGF Beta Signaling", "Apical Surface", "G2M Checkpoint"])
# ui.input_radio_buttons("group_selection", "Group Subset", ["None", "Estrogen Response Early", "Estrogen Response Late", "Protein Secretion", "E2F Targets", "TGF Beta Signaling", "Apical Surface", "G2M Checkpoint"])
@reactive.effect
def update_grouping_selection():
user_choice = input.modality_selection_sA()
user_choice_dataset = input.dataset_selection_sA()
if (user_choice_dataset == "MCF7") or (user_choice_dataset == "T47D"):
grouping_choices = {'RNA' : ['Hallmark'],
'ATAC' : ['Hallmark', 'Cistrome', 'JASPAR']}
else:
grouping_choices = {'RNA' : ['Hallmark'],
'ATAC' : ['Hallmark', 'JASPAR']}
ui.update_select('grouping_selection',
label = 'Collection',
choices = grouping_choices[user_choice],
selected = grouping_choices[user_choice][0])
@reactive.effect
def update_group_selection():
user_choice_grouping = input.grouping_selection()
user_choice_modality = input.modality_selection_sA()
user_choice_dataset = input.dataset_selection_sA()
user_choice = f"{user_choice_modality}_{user_choice_grouping}"
subset_choices = { "RNA_Hallmark" : ["None", 'PROTEIN_SECRETION', 'MYC_TARGETS_V1', 'ESTROGEN_RESPONSE_EARLY', 'ANDROGEN_RESPONSE', 'E2F_TARGETS', 'ESTROGEN_RESPONSE_LATE', 'REACTIVE_OXYGEN_SPECIES_PATHWAY', 'hallmark_HALLMARK_APICAL_SURFACE'],
"ATAC_Hallmark" : ["None", "Estrogen Response Early", "Estrogen Response Late", "Hedgehog Signaling", "Notch Signaling", "Coagulation", "Androgen Response"],
"ATAC_Cistrome" : ["None", 'MED12 41516'] if user_choice_dataset == 'MCF7' else ["None", 'NR3C1 68849'],
"ATAC_JASPAR" : ["None", 'POU2F3 - MA0627.3', 'ESR1 - MA0112.4', 'OTX2 - MA0712.3']}
ui.update_select("group_selection",
label = "Group Subset",
choices = subset_choices[user_choice],
selected = subset_choices[user_choice][0])
# Cell Labels Selection
ui.input_select("label_selection", "Labels",
{"Class" : "Class", "hclust" : "Agglomerative Clustering", "kmeans" : "K-Means Clustering", "louvain" : "Louvain", "leiden" : "Leiden"},
selected = "Class")
ui.markdown("**NOTE**: When group subset is None, most variable features are used.")
with ui.card():
with ui.navset_tab():
with ui.nav_panel('UMAP'):
@render_widget()
def umap():
umap_plot = pl.plot_umap(umap_dict, input.modality_selection_sA(), input.dataset_selection_sA(), input.grouping_selection(), input.label_selection(), input.group_selection())
return umap_plot
with ui.nav_panel('Volcano Plot'):
@render_widget()
def volcano_plot():
vol_df = {"RNA" : deg_df, "ATAC" : dar_df}
volcano_plot = pl.create_volcano(vol_df[input.modality_selection_sA()], input.dataset_selection_sA(), input.modality_selection_sA(), input.grouping_selection(), input.group_selection(), subset_groupings)
return volcano_plot
@render.text
def number_of_sample_classes0():
classes, counts = np.unique(umap_dict[input.modality_selection_sA()][input.dataset_selection_sA()]["Most Variable Features"]['Cell Labels']["Class"], return_counts = True)
return f"{classes[0]} Samples: {counts[0]}"
@render.text
def number_of_sample_classes1():
classes, counts = np.unique(umap_dict[input.modality_selection_sA()][input.dataset_selection_sA()]["Most Variable Features"]['Cell Labels']["Class"], return_counts = True)
return f"{classes[1]} Samples: {counts[1]}"
##################
# GSEApy Results #
##################
with ui.nav_panel("GSEApy Results"):
with ui.layout_columns(col_widths = {'sm' : (4, 8)}):
with ui.card():
ui.markdown(
'''
### Gene Set Enrichment Analysis
##### Using the differentially expressed genes calculated by ***scanpy***, gene set enrichment was computed using ***GSEApy***
'''
)
ui.input_radio_buttons("dataset_selection_GR", "Dataset Selection", {"MCF7" : "MCF7",
"T47D" : "T47D",
"lymphoma" : "Lymphoma",
"prostate_rna" : "Prostate_RNA",
'LUAD' : 'LUAD',
'LUSC' : 'LUSC'},
selected = "MCF7"
)
@render_widget
def gene_dist():
gene_dist_plot = pl.gene_distribution(gene_group_frequency_df)
return gene_dist_plot
with ui.card():
ui.markdown('### GO Biological Process Gene Sets')
@render_widget
def GO_figure():
GO_figure = pl.GO_plot(GO_BP_df, input.dataset_selection_GR())
return GO_figure
with ui.card():
ui.markdown("### Hallmark Gene Sets")
@render_widget
def hallmark_plot():
hallmark_plot = pl.hallmark_genesets_plot(hallmark_geneset_df, input.dataset_selection_GR())
return hallmark_plot
with ui.nav_panel("Contributers & Links"):
with ui.card():
ui.markdown(
'''
## Links
GitHub: https://github.com/ohsu-cedar-comp-hub/scMKL
PyPi: https://pypi.org/project/scmkl/
API : https://ohsu-cedar-comp-hub.github.io/scMKL/
Conda: https://anaconda.org/ivango17/scmkl
Publication: Coming Soon
'''
)
with ui.layout_columns():
with ui.card():
ui.markdown(
'''
### Sam Kupp
- Implementation
- Analysis
Computational Biologist
*CEDAR, Oregon Health & Science University*
'''
)
with ui.card():
ui.markdown(
'''
### Ian VanGordon
- Implementation
- Analysis
Computational Biologist
*CEDAR, Oregon Health & Science University*
'''
)
with ui.card():
ui.markdown(
'''
### Cigdem Ak
- Direction
- Implementation
Postdoctoral Scholar
*CEDAR, Oregon Health & Science University*
'''
)
ui.nav_spacer()
with ui.nav_control():
ui.input_dark_mode(mode = 'light')