Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serafina/execution reduction #2

Merged
merged 14 commits into from
May 11, 2024
182 changes: 90 additions & 92 deletions src/app.py
Original file line number Diff line number Diff line change
@@ -1,92 +1,90 @@
from shiny import App, reactive, ui, render, Session
import scanpy as sc
import os
import tempfile
import anndata as ad
import pandas as pd

from sliders import slider_ui, slider_server
from distributions import distributions_server
from plots import plots_server, plots_ui
from metadata import metadata_server, metadata_ui
from helpers import calculate_qc_metrics


_pretty_names = reactive.value({
'total_counts': 'Total counts',
'n_genes_by_counts': 'Number of genes with counts',
'pct_counts_mt': 'Percentage of counts from mitochondrial genes',
})


app_ui = ui.page_navbar(
ui.nav_panel("1. Upload", ui.input_file("file_input", label="Upload your file", accept=".h5ad")),
ui.nav_panel("2. Metadata", metadata_ui("metadata")),
ui.nav_panel("3. Quality control",
ui.layout_sidebar(
ui.sidebar(
slider_ui("sliders")
),
plots_ui("plots")
)
),
ui.nav_panel("4. Download",
ui.download_button("download", "Download filtered data")
),
title="Preprocessing for SIMBA🦁",
window_title="SIMBA🦁: Preprocessing"
)


def server(input, output, session: Session):
_adata: reactive.Value[ad.AnnData] = reactive.value(None)
_adata_meta: reactive.Value[ad.AnnData] = reactive.value(None)
_adata_filtered: reactive.Value[ad.AnnData] = reactive.value(None)
_file_name = reactive.value(None)
_distributions = reactive.value({})
_metadata = reactive.value(None)

distributions_server("distributions", _adata_meta, _pretty_names, _distributions)
slider_server("sliders", _adata_meta, _adata_filtered, _pretty_names, _distributions)
plots_server("plots", _adata_filtered, _pretty_names, _distributions)
metadata_server("metadata", _adata, _metadata)

@reactive.effect
def load_adata():
file = input["file_input"].get()
if file is None:
return
if len(file) > 1:
print("Only one file at a time")
return

used_file = file[0]
_file_name.set(used_file["name"])
adata = sc.read_h5ad(used_file["datapath"])
calculate_qc_metrics(adata)
_adata.set(adata)

@reactive.effect
def update_adata_meta():
adata = _adata.get()
metadata = _metadata.get()
if adata is None or metadata is None:
return
adata_meta = adata.copy()
adata_meta.obs = metadata.copy()
calculate_qc_metrics(adata_meta)
_adata_meta.set(adata_meta)

@render.download(
filename = lambda: _file_name.get().replace(".h5ad", "_filtered.h5ad"),
)
def download():
adata_filtered = _adata_filtered.get()
if adata_filtered is None:
return

with tempfile.NamedTemporaryFile(suffix=".h5ad", delete=False) as temp:
adata_filtered.write(temp.name)
return temp.name

app = App(app_ui, server, static_assets=os.path.join(os.path.dirname(__file__), "media"))
from shiny import App, reactive, ui, render, Session
import scanpy as sc
import os
import tempfile
import anndata as ad
import pandas as pd

from sliders import slider_ui, slider_server
from distributions import distributions_server
from plots import plots_server, plots_ui
from metadata import metadata_server, metadata_ui
from helpers import calculate_qc_metrics


_pretty_names = reactive.value({
'total_counts': 'Total counts',
'n_genes_by_counts': 'Number of genes with counts',
'pct_counts_mt': 'Percentage of counts from mitochondrial genes',
})


app_ui = ui.page_navbar(
ui.nav_panel("1. Upload", ui.input_file("file_input", label="Upload your file", accept=".h5ad")),
ui.nav_panel("2. Metadata", metadata_ui("metadata")),
ui.nav_panel("3. Quality control",
ui.layout_sidebar(
ui.sidebar(
slider_ui("sliders")
),
plots_ui("plots")
)
),
ui.nav_panel("4. Download",
ui.download_button("download", "Download filtered data")
),
title="Preprocessing for SIMBA🦁",
window_title="SIMBA🦁: Preprocessing"
)


def server(input, output, session: Session):
_adata: reactive.Value[ad.AnnData] = reactive.value(None)
_adata_meta: reactive.Value[ad.AnnData] = reactive.value(None)
_adata_filtered: reactive.Value[ad.AnnData] = reactive.value(None)
_file_name = reactive.value(None)
_distributions = reactive.value({})
_metadata = reactive.value(None)
_calculate_metrics_bool = reactive.value(False)

distributions_server("distributions", _adata_meta, _pretty_names, _distributions)
slider_server("sliders", _adata, _metadata, _adata_meta, _adata_filtered, _pretty_names, _distributions, _calculate_metrics_bool)
plots_server("plots", _adata_filtered, _pretty_names, _distributions)
metadata_server("metadata", _adata, _metadata)

@reactive.effect
def load_adata():
file = input["file_input"].get()
if file is None:
return
if len(file) > 1:
print("Only one file at a time")
return

used_file = file[0]
_file_name.set(used_file["name"])
adata = sc.read_h5ad(used_file["datapath"])
_adata.set(adata)
_calculate_metrics_bool.set(True)

@reactive.effect
def update_adata_meta():
adata = _adata.get()
metadata = _metadata.get()
if adata is None or metadata is None:
return
_calculate_metrics_bool.set(True)

@render.download(
filename = lambda: _file_name.get().replace(".h5ad", "_filtered.h5ad"),
)
def download():
adata_filtered = _adata_filtered.get()
if adata_filtered is None:
return

with tempfile.NamedTemporaryFile(suffix=".h5ad", delete=False) as temp:
adata_filtered.write(temp.name)
return temp.name

app = App(app_ui, server, static_assets=os.path.join(os.path.dirname(__file__), "media"))
Loading