Skip to content

Commit

Permalink
Implement basic column mapping functionalities
Browse files Browse the repository at this point in the history
  • Loading branch information
nictru committed Mar 8, 2024
1 parent ab93745 commit 3ffba68
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
ui.nav_panel("4. Download",
ui.download_button("download", "Download filtered data")
),
title="Quality control for SIMBA🦁",
window_title="SIMBA🦁: QC"
title="Preprocessing for SIMBA🦁",
window_title="SIMBA🦁: Preprocessing"
)


Expand Down
62 changes: 53 additions & 9 deletions src/metadata.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
from shiny import App, module, reactive, render, ui
from shiny import module, reactive, render, ui
import anndata as ad
import pandas as pd

mandatory_columns = ["batch", "cell_type", "condition", "sex", "patient", "tissue"]

@module.ui
def metadata_ui():
return ui.div(
ui.output_ui("column_cards")
return ui.accordion(
ui.accordion_panel("Columns",
ui.output_ui("column_cards")),
ui.accordion_panel("Preview")
)

@module.server
def metadata_server(input, output, session,
_adata: reactive.Value[ad.AnnData],
_metadata: reactive.Value[pd.DataFrame]
):
_input_columns = reactive.value([])
_additional_columns = reactive.value([])
_all_columns = reactive.value(mandatory_columns)

@reactive.effect
def update_input_columns():
adata = _adata.get()
if adata is None:
return
categorical_columns = adata.obs.select_dtypes(include=["category"]).columns.tolist()
_input_columns.set(categorical_columns)

@reactive.effect
@reactive.event((input["add_column"]))
def add_column():
Expand All @@ -30,19 +41,52 @@ def add_column():
def update_columns():
_all_columns.set(mandatory_columns + _additional_columns.get())


def column_card(column: str):
select_accession = f"select_type_{column}"
type_string = input[select_accession].get() if select_accession in input else None
adata = _adata.get()

if adata is None:
print("No adata")
return None

if type_string == "Concat existing columns":
interface = ui.input_selectize(f"select_{column}", "Columns", _input_columns.get(), multiple=True)
elif type_string == "Map existing":
mapcol_accession = f"select_mapcol_{column}"
series = adata.obs[input[mapcol_accession].get()] if mapcol_accession in input else None

interface = ui.div(
ui.input_select(mapcol_accession, "Column", _input_columns.get()),
*([ui.input_text(f"mapping_{column}_{col}", col, placeholder="New value") for col in series.unique()] if series is not None else [])
)
else:
interface = ui.input_text(f"input_{column}", "Value", placeholder="Unknown")


return ui.card(
ui.card_header(column),
ui.input_select(select_accession, "Type", ["Constant value", "Concat existing columns", "Map existing"], selected=type_string),
interface,
ui.card_footer(
ui.input_action_button("remove_column", "Remove")
)
)

@render.ui
def column_cards():
add_card = ui.card(
ui.card_header("Add column"),
ui.input_text("column_name", "", placeholder="Column name"),
ui.input_action_button("add_column", "Add column")
ui.card_footer(
ui.input_action_button("add_column", "Add")
)
)

return ui.layout_columns(
*[ui.card(
ui.card_header(column),
ui.p("This is a column")
)
for column in _all_columns.get()],
*[column_card(column) for column in _all_columns.get()],
add_card
)


0 comments on commit 3ffba68

Please sign in to comment.