Marker inputs and table schema
easydecon accepts markers through several routes. prepare_markers is the
shared source controller used by the workflow and by the backward-compatible
read_markers_dataframe wrapper. Inputs are resolved in this priority order:
prepared_markersmarkers_dffilenameadata
If none of these is provided, marker preparation raises a ValueError.
Input routes
markers_dfA pandas DataFrame passed directly. It is copied before standardization and prepared as
marker_method="existing".filenameA CSV or Excel file read into a marker DataFrame and prepared as
marker_method="existing".adatawith existing Scanpy resultsIf
adata.uns[marker_key]exists, easydecon reads it withscanpy.get.rank_genes_groups_df.- Scanpy-generated markers
With
marker_method="scanpy"andgroupby=..., easydecon runsscanpy.tl.rank_genes_groupswhen the marker key is missing.- pseudobulk PyDESeq2
With
marker_method="pydeseq2"andsample_col=..., easydecon builds one-vs-rest pseudobulk count tables and runs PyDESeq2.- reference-profile markers
With
marker_method="reference", easydecon selects markers from normalized reference profiles without calculating p-values.PreparedMarkersA reusable, spatial-unfiltered marker preparation produced by
ed.prepare_markers.
Aliases marker_method="deseq2" and "pseudobulk_deseq2" normalize to
"pydeseq2". Alias marker_method="rctd_like" normalizes to "reference" for
compatibility; examples use "reference".
Generated-marker workflow examples
Scanpy-generated markers:
result = ed.run_easydecon(
sdata=sdata,
adata=sc_adata,
groupby="cell_type",
marker_method="scanpy",
filtering_algorithm="permutation",
method="wjaccard",
return_result_object=True,
)
Prepare once, select per spatial dataset
PreparedMarkers is independent of a spatial gene universe. Use
prepare_markers when you want to prepare markers once and reuse them, or let
run_easydecon do this automatically and retrieve result.prepared_markers.
prepared = ed.prepare_markers(
markers_df=deseq_df,
source="deseq_table",
)
result = ed.run_easydecon(
sdata,
prepared_markers=prepared,
return_result_object=True,
)
selected = ed.select_prepared_markers(
prepared,
gene_universe=sdata.tables["table"].var_names,
)
read_markers_dataframe remains supported when you want the selected marker
DataFrame directly for one spatial dataset; internally it delegates to
prepare_markers and select_prepared_markers.
PyDESeq2 markers:
result = ed.run_easydecon(
sdata=sdata,
adata=sc_adata,
groupby="cell_type",
sample_col="donor",
marker_method="pydeseq2",
filtering_algorithm="permutation",
method="wjaccard",
return_result_object=True,
)
Reference-profile markers:
result = ed.run_easydecon(
sdata=sdata,
adata=sc_adata,
groupby="cell_type",
marker_method="reference",
filtering_algorithm="permutation",
method="wjaccard",
return_result_object=True,
)
Canonical columns
Required after standardization:
groupMarker group or cell type.
namesGene identifier.
Optional but commonly used:
logfoldchangesEffect-size or marker-weight column.
pvals_adjAdjusted p-value column.
scoresRanking or scoring column.
marker_rankRank assigned within group, or within group and role.
marker_sourceSource label such as
dataframe,file,reference_profile, orpydeseq2_pseudobulk.marker_roleOne of
positive,negative,presence, oridentity.
MarkerSchema and resolve_marker_columns recognize common aliases such as
cell_type, cluster, gene, gene_symbol, log2FoldChange, avg_log2FC,
padj, and score. Matching is case-insensitive, but returned DataFrames use
canonical column names.
Manual marker table
import pandas as pd
markers_df = pd.DataFrame(
{
"group": ["T cell", "T cell", "B cell"],
"names": ["CD3D", "CD3E", "MS4A1"],
"logfoldchanges": [2.1, 1.8, 2.4],
"pvals_adj": [0.001, 0.004, 0.001],
"scores": [8.0, 7.5, 9.0],
}
)
Gene identifiers in names must match table.var_names after any upstream
normalization. No marker genes remain if the table uses different identifiers,
for example Ensembl IDs in one table and gene symbols in the other.
Top-N behavior
Direct ed.read_markers_dataframe(...) applies top_n_genes during marker
selection. In ed.run_easydecon(...), markers are selected with
top_n_genes=None, then top_n_genes is applied during Phase 1 and Phase 2
role routing. With marker roles, the limit is per group and role.
top_n_markers is separate. It limits markers inside selected Phase 2 scoring
methods such as AUC and UCell-like scoring, after marker-table routing.
Marker roles and signed Scanpy inference
Manual marker tables may include marker_role. Missing or blank roles are
treated as positive. Unknown roles raise an error.
marker_role_inference="scanpy_signed" is implemented for Scanpy-style signed
marker rows. It infers positive and negative roles from signed
logfoldchanges, optionally checking finite score signs. It is opt-in and
intended for marker_roles="shared" when negative-marker-capable
method="ucell" scoring is desired.
Reference-profile marker generation can create presence, identity, and
negative roles with marker_roles="phase_specific". Scanpy and PyDESeq2 do
not automatically create phase-specific presence/identity roles.