Skip to content

Configuration API

SeqNado uses Pydantic for its configuration management. This page documents the primary configuration models.

Main Configuration

seqnado.config.SeqnadoConfig

Bases: BaseModel

Configuration for the SeqNado workflow.

organism property

organism: str

Return the organism (string) from the genome configuration.

shift_for_tn5_insertion property

shift_for_tn5_insertion: bool

Return the Tn5 shift configuration for the specified assay.

mcc_viewpoints property

mcc_viewpoints: str

Return the MCC viewpoints file path.

set_default_pcr_duplicates

set_default_pcr_duplicates(values)

Set default PCR duplicate handling based on assay type.

Source code in seqnado/config/core.py
@model_validator(mode="before")
def set_default_pcr_duplicates(cls, values):
    """Set default PCR duplicate handling based on assay type."""
    from seqnado import PCRDuplicateHandling

    if "pcr_duplicates" not in values or values["pcr_duplicates"] is None:
        assay = values.get("assay")
        # Normalize assay to Assay enum if it's a string
        if isinstance(assay, str):
            assay = Assay(assay)
        # Default to REMOVE for ATAC, ChIP, CAT, SNP, and METH; KEEP for RNA
        if assay in [Assay.ATAC, Assay.CHIP, Assay.CAT, Assay.SNP, Assay.METH]:
            values["pcr_duplicates"] = PCRDuplicatesConfig(strategy=PCRDuplicateHandling.REMOVE)
        else:
            values["pcr_duplicates"] = PCRDuplicatesConfig(strategy=PCRDuplicateHandling.NONE)

    return values

migrate_remove_blacklist_to_qc

migrate_remove_blacklist_to_qc(values)

Support legacy top-level remove_blacklist by moving it under qc.

Source code in seqnado/config/core.py
@model_validator(mode="before")
def migrate_remove_blacklist_to_qc(cls, values):
    """Support legacy top-level remove_blacklist by moving it under qc."""
    if not isinstance(values, dict):
        return values

    if "remove_blacklist" in values:
        qc_values = dict(values.get("qc") or {})
        qc_values.setdefault("remove_blacklist", values.pop("remove_blacklist"))
        values["qc"] = qc_values

    return values

sync_peak_caller_tool_defaults

sync_peak_caller_tool_defaults() -> SeqnadoConfig

Ensure peak-caller-specific tool configs exist when those methods are selected.

Source code in seqnado/config/core.py
@model_validator(mode="after")
def sync_peak_caller_tool_defaults(self) -> "SeqnadoConfig":
    """Ensure peak-caller-specific tool configs exist when those methods are selected."""
    peak_calling = getattr(self.assay_config, "peak_calling", None)
    methods = getattr(peak_calling, "method", None) or []

    if self.third_party_tools is None:
        self.third_party_tools = ThirdPartyToolsConfig.for_assay(self.assay)

    if PeakCallingMethod.SEACR in methods and self.third_party_tools.seacr is None:
        self.third_party_tools.seacr = Seacr()

    return self

validate_qc_remove_blacklist

validate_qc_remove_blacklist() -> SeqnadoConfig

Require a genome blacklist when blacklist removal is enabled.

Source code in seqnado/config/core.py
@model_validator(mode="after")
def validate_qc_remove_blacklist(self) -> "SeqnadoConfig":
    """Require a genome blacklist when blacklist removal is enabled."""
    if self.qc.remove_blacklist and not self.genome.blacklist:
        raise ValueError(
            "qc.remove_blacklist can only be True if genome blacklist is provided."
        )
    return self

from_yaml classmethod

from_yaml(path: Path) -> SeqnadoConfig

Load configuration from a YAML file.

Source code in seqnado/config/core.py
@classmethod
def from_yaml(cls, path: Path) -> "SeqnadoConfig":
    """Load configuration from a YAML file."""
    import yaml

    with open(path, "r") as f:
        data = yaml.safe_load(f)

    return cls(**data)

validate_assay_config_matches_assay

validate_assay_config_matches_assay(v, info)

Ensure the assay_config type matches the specified assay.

Source code in seqnado/config/core.py
@field_validator("assay_config", mode="before")
def validate_assay_config_matches_assay(cls, v, info):
    """Ensure the assay_config type matches the specified assay."""
    if v is None:
        return v

    assay = info.data.get("assay")
    if assay is None:
        return v

    expected_config_class = ASSAY_CONFIG_MAP.get(assay)
    if expected_config_class and not isinstance(v, expected_config_class):
        if isinstance(v, dict):
            # Try to create the appropriate config from dict
            return expected_config_class(**v)
        else:
            raise ValueError(
                f"assay_config must be of type {expected_config_class.__name__} for assay {assay.value}"
            )

    return v

create_assay_config classmethod

create_assay_config(
    assay: Assay, **kwargs
) -> AssaySpecificConfig

Create the appropriate assay config for the given assay type.

Source code in seqnado/config/core.py
@classmethod
def create_assay_config(cls, assay: Assay, **kwargs) -> AssaySpecificConfig:
    """Create the appropriate assay config for the given assay type."""
    config_class = cls._ASSAY_CONFIG_MAP.get(assay)
    if config_class is None:
        raise ValueError(
            f"No configuration class available for assay {assay.value}"
        )

    return config_class(**kwargs)

seqnado.config.ProjectConfig

Bases: BaseModel

Configuration for the SeqNado project.

Genome Configuration

seqnado.config.GenomeConfig

Bases: BaseModel

Configuration for genome-related files and indices.

Assay Specific Configurations

seqnado.config.ATACAssayConfig

Bases: BaseAssayConfig, PeakCallingMixin

Configuration specific to ATAC-seq assays.

seqnado.config.ChIPAssayConfig

Bases: BaseAssayConfig, PeakCallingMixin

Configuration specific to ChIP-seq assays.

seqnado.config.RNAAssayConfig

Bases: BaseAssayConfig

Configuration specific to RNA-seq assays.

validate_spikein_methods classmethod

validate_spikein_methods(v)

Filter out incompatible spike-in methods for RNA-seq.

WITH_INPUT requires paired input/control samples, which is a ChIP-seq concept. RNA-seq supports only ORLANDO, DESEQ2, and EDGER.

Source code in seqnado/config/core.py
@field_validator("spikein")
@classmethod
def validate_spikein_methods(cls, v):
    """Filter out incompatible spike-in methods for RNA-seq.

    WITH_INPUT requires paired input/control samples, which is a ChIP-seq concept.
    RNA-seq supports only ORLANDO, DESEQ2, and EDGER.
    """
    if v is not None and SpikeInMethod.WITH_INPUT in v.method:
        from seqnado.utils import warn_once
        warn_once(
            "The 'with_input' spike-in method is not compatible with RNA-seq and will be skipped. "
            "RNA-seq supports: 'orlando', 'deseq2', 'edger'. "
            "WITH_INPUT requires paired input/control samples (ChIP-seq concept)."
        )
        # Filter out the incompatible method
        v.method = [m for m in v.method if m != SpikeInMethod.WITH_INPUT]
    return v

← Back to API Overview