eRegulons

eRegulon objects, dataframe assembly and conversion helpers.

rustscenic.eregulon

eRegulon assembly - the SCENIC+ endpoint.

A classical SCENIC regulon is just a TF + its co-expressed target genes. An eRegulon adds chromatin grounding:

TF -> enhancer (motif enrichment, from cistarget)
       |
       v
    enhancer -> gene (accessibility vs expression correlation,
                      from rustscenic.enhancer)

An eRegulon is therefore a three-way intersection:

1. The TF's enriched motifs / peaks (cistarget output)
2. The enhancer -> gene links on those peaks (enhancer output)
3. The TF -> gene predictions from expression (GRN output, optional)

This module produces eRegulon records from those three rustscenic outputs. The scale-sensitive table assembly runs in Rust; Python keeps the public dataclass API and pandas/AnnData-facing glue.

ERegulon dataclass

ERegulon(
    tf: str,
    enhancers: list[str] = list(),
    target_genes: list[str] = list(),
    n_enhancer_links: int = 0,
    motif_auc: float = 0.0,
    target_to_peaks: dict = dict(),
)

A chromatin-aware regulon.

Attributes:

Name Type Description
tf str

TF identifier used for the assembled module.

enhancers list[str]

Peak IDs whose accessibility correlates with at least one of this eRegulon's target genes (the peaks that carry the TF's motif and are linked to a target gene by rustscenic.enhancer).

target_genes list[str]

Genes linked to supporting motif-enriched peaks. When GRN intersection is enabled, these must also be TF targets in the GRN; disabling it skips that GRN filter.

n_enhancer_links int

Number of actual (peak, gene) edges surviving the assembly filters.

motif_auc float

Mean motif-enrichment AUC across the supporting peaks (from cistarget).

target_to_peaks dict

Target gene mapped to the peaks supporting its retained edges. Used to flatten actual edges without a Cartesian product.

tf instance-attribute

tf: str

enhancers class-attribute instance-attribute

enhancers: list[str]

target_genes class-attribute instance-attribute

target_genes: list[str]
n_enhancer_links: int

motif_auc class-attribute instance-attribute

motif_auc: float

target_to_peaks class-attribute instance-attribute

target_to_peaks: dict

__len__

__len__() -> int

Return the number of target genes in this eRegulon.

build_eregulons

build_eregulons(
    grn: DataFrame | None,
    cistarget: DataFrame,
    enhancer_links: DataFrame,
    *,
    min_target_genes: int = 5,
    min_enhancer_links: int = 2,
    cistarget_auc_threshold: float = 0.05,
    use_grn_intersection: bool = True,
) -> list[ERegulon]

Assemble eRegulons by intersecting the three SCENIC+ edge types.

Parameters:

Name Type Description Default
grn DataFrame | None

rustscenic.grn.infer or rustscenic.grn.add_correlation output. Signed input is detected from the regulation column: neutral edges are excluded and bare TF names are converted to the matching <TF>_activator / <TF>_repressor keys before intersection. Pass None to skip GRN filtering (accept any enhancer-linked gene as a target).

required
cistarget DataFrame

rustscenic.cistarget.enrich output with at minimum the columns ['regulon', 'motif', 'auc'] and - critically - 'peak_id' or 'region_id' identifying which peak each motif was enriched in. The 'regulon' column should map back to the source TF (either a bare TF name or TF_regulon).

required
enhancer_links DataFrame

rustscenic.enhancer.link_peaks_to_genes output. Required columns: ['peak_id', 'gene', 'correlation'].

required
min_target_genes int

Drop eRegulons with fewer than this many surviving target genes. Typical scenicplus cut-off is 10; we default to 5 because our smaller-regulon test fixtures exercise this path.

5
min_enhancer_links int

Drop eRegulons with fewer than this many (peak, gene) edges. Catches cases where a TF motif enrichment is supported by only one or two peak-gene pairs (weak evidence).

2
cistarget_auc_threshold float

Filter cistarget rows below this AUC before assembling. Set to 0 to keep everything.

0.05
use_grn_intersection bool

If True (default), a target gene is kept only if the enhancer-linked gene is also a predicted target of the TF in the GRN. If False, keep all enhancer-linked genes regardless of GRN support. Set False when you trust the chromatin grounding more than the GBM predictions.

True

Returns:

Type Description
list[ERegulon] sorted by descending ``n_enhancer_links``.

build_eregulons_dataframe

build_eregulons_dataframe(
    grn: DataFrame | None,
    cistarget: DataFrame,
    enhancer_links: DataFrame,
    *,
    min_target_genes: int = 5,
    min_enhancer_links: int = 2,
    cistarget_auc_threshold: float = 0.05,
    use_grn_intersection: bool = True,
) -> pd.DataFrame

Assemble eRegulons as a long DataFrame using the Rust table path.

This is the preferred API for large/HPC runs because it avoids building Python ERegulon objects before writing parquet. build_eregulons remains available when callers need the object representation.

Parameters:

Name Type Description Default
grn DataFrame | None

TF-target edge table, optionally signed by regulation. None skips GRN support filtering.

required
cistarget DataFrame

Motif enrichment table with regulon, motif, auc and a peak_id or region_id column.

required
enhancer_links DataFrame

Peak-gene links with peak_id, gene and correlation columns.

required
min_target_genes int

Minimum number of surviving target genes per eRegulon.

5
min_enhancer_links int

Minimum number of surviving peak-gene links per eRegulon.

2
cistarget_auc_threshold float

Minimum motif AUC retained before assembly; zero disables this filter.

0.05
use_grn_intersection bool

Keep only enhancer-linked genes also supported by the TF's GRN edges when true and grn is provided.

True

Returns:

Type Description
DataFrame

Long table with tf, enhancer, target_gene, n_enhancer_links and motif_auc columns.

regulons_from_dataframe

regulons_from_dataframe(
    eregulons: DataFrame,
    *,
    feature_col: str = "target_gene",
    suffix_with_index: bool = False,
) -> list[tuple[str, list[str]]]

Build AUCell regulon pairs from the Rust-backed long eRegulon table.

This avoids reconstructing public ERegulon objects, nested target_to_peaks dictionaries, and Python-side feature de-duplication in benchmark and HPC paths that only need (regulon, features) pairs.

Parameters:

Name Type Description Default
eregulons DataFrame

Long eRegulon table containing tf and the selected feature column.

required
feature_col str

Column whose values become regulon features, for example target_gene or enhancer.

'target_gene'
suffix_with_index bool

Ask the Rust conversion helper to append an index to regulon names.

False

Returns:

Type Description
list[tuple[str, list[str]]]

Regulon names and their de-duplicated feature lists for AUCell.

eregulons_to_dataframe

eregulons_to_dataframe(eregulons: Sequence[ERegulon]) -> pd.DataFrame

Flatten a list of ERegulon objects into a long-format DataFrame.

One row per (TF, enhancer, target_gene) triple. Useful for parquet persistence, joining back to downstream AUCell scoring, and quick cross-regulon aggregation.

Parameters:

Name Type Description Default
eregulons Sequence[ERegulon]

Sequence of ERegulon objects to flatten using target_to_peaks.

required

Returns:

Type Description
DataFrame

Columns tf, enhancer, target_gene, n_enhancer_links and motif_auc, with one row per actual peak-target edge.