API Referenceο
siRNAforge - Comprehensive siRNA design toolkit for gene silencing. Comprehensive gene silencing design and analysis.
This module exposes package metadata (author/email/version) in a single place. The version is resolved from installed package metadata (importlib.metadata). When running from a source checkout (not installed), it falls back to reading pyproject.toml if available, otherwise uses a conservative placeholder.
Configurationο
Reference Policyο
Reference/default resolution utilities for workflow inputs.
- class sirnaforge.config.reference_policy.ReferenceChoice(value: str | None, state: ReferenceState, reason: str)[source]ο
Bases:
objectNormalized representation of a resolved reference input.
- state: ReferenceStateο
- static explicit(value: str, reason: str = 'user-provided') ReferenceChoice[source]ο
Create an explicit user-selected reference choice.
- static default(value: str, reason: str = 'auto-selected') ReferenceChoice[source]ο
Create a default-sourced reference choice.
- static disabled(reason: str) ReferenceChoice[source]ο
Create a disabled reference choice with context.
- class sirnaforge.config.reference_policy.ReferenceSelection(choices: tuple[~sirnaforge.config.reference_policy.ReferenceChoice, ...]=<factory>, disabled_reason: str | None = None)[source]ο
Bases:
objectContainer describing zero or more resolved references.
- choices: tuple[ReferenceChoice, ...]ο
- static disabled(reason: str) ReferenceSelection[source]ο
Create a disabled selection with a descriptive reason.
- class sirnaforge.config.reference_policy.ReferencePolicyResolver(spec: WorkflowInputSpec)[source]ο
Bases:
objectResolve workflow defaults while preserving intent metadata.
- __init__(spec: WorkflowInputSpec)[source]ο
Create a resolver for a specific workflow input specification.
- resolve_transcriptomes() ReferenceSelection[source]ο
Return one or more transcriptome references.
- class sirnaforge.config.reference_policy.ReferenceState(*values)[source]ο
-
Describe how a reference input was selected.
- EXPLICIT = 'explicit'ο
- DEFAULT = 'default'ο
- DISABLED = 'disabled'ο
- class sirnaforge.config.reference_policy.WorkflowInputSpec(input_fasta: str | None = None, transcriptome_argument: str | None = None, default_transcriptomes: Sequence[str] = <factory>, design_only: bool = False, allow_transcriptome_for_input_fasta: bool = False)[source]ο
Bases:
objectRaw workflow inputs prior to policy resolution.
- sirnaforge.config.reference_policy.render_reference_selection_label(selection: ReferenceSelection) str[source]ο
Render a stable, human-readable label for CLI/config summaries.
Command Line Interfaceο
Modern CLI for siRNAforge using Typer and Rich.
- sirnaforge.cli.patched_init(self: Console, *args: Any, **kwargs: Any) None[source]ο
Force simplified terminal capabilities for deterministic CI output.
- class sirnaforge.cli.TranscriptLike(*args, **kwargs)[source]ο
Bases:
ProtocolMinimal transcript-like interface used by CLI filters.
- __init__(*args, **kwargs)ο
- sirnaforge.cli.filter_transcripts(transcripts: list[TTranscript], include_types: list[str] | None = None, exclude_types: list[str] | None = None, canonical_only: bool = False) list[TTranscript][source]ο
Filter transcript records by type and canonical status.
- Parameters:
transcripts β Iterable of transcript-like objects that expose
transcript_typeandis_canonicalattributes.include_types β Optional iterable of transcript types to keep.
exclude_types β Optional iterable of transcript types to drop.
canonical_only β When True, keep only canonical isoforms.
- Returns:
A list of transcripts that match the requested filters.
- sirnaforge.cli.extract_canonical_transcripts(transcripts: list[TranscriptInfo], gene_name: str, output_dir: Path | str | None = None) tuple[Path | None, int][source]ο
Write canonical isoforms to a separate FASTA file.
- Parameters:
transcripts β Iterable of transcript-like objects (must expose
is_canonicaland sequence attributes used by the underlying save routine).gene_name β Name used to derive the output FASTA filename.
output_dir β Directory to write the FASTA file into (defaults to CWD).
- Returns:
A tuple of
(canonical_fasta_path, count)where the path is None when no canonical isoforms are available.
- sirnaforge.cli.search(query: str = <typer.models.ArgumentInfo object>, output: Path = <typer.models.OptionInfo object>, database: str = <typer.models.OptionInfo object>, all_databases: bool = <typer.models.OptionInfo object>, fallback: bool = <typer.models.OptionInfo object>, no_sequence: bool = <typer.models.OptionInfo object>, canonical_only: bool = <typer.models.OptionInfo object>, extract_canonical: bool = <typer.models.OptionInfo object>, transcript_types: str = <typer.models.OptionInfo object>, exclude_types: str = <typer.models.OptionInfo object>, verbose: bool = <typer.models.OptionInfo object>) None[source]ο
Search transcript references and optionally fetch sequences.
This command queries Ensembl/RefSeq/Gencode (depending on flags) for a gene or transcript identifier. When sequences are fetched, it writes them to a FASTA file and can optionally also emit a canonical-only FASTA.
- sirnaforge.cli.workflow(gene_query: str = <typer.models.ArgumentInfo object>, input_fasta: str | None = <typer.models.OptionInfo object>, output_dir: Path = <typer.models.OptionInfo object>, database: str = <typer.models.OptionInfo object>, design_mode: str = <typer.models.OptionInfo object>, zfn_subfinger_mutation: list[str] = <typer.models.OptionInfo object>, zfn_max_mismatches_per_subfinger: int | None = <typer.models.OptionInfo object>, zfn_max_substitutions_overall: int | None = <typer.models.OptionInfo object>, zfn_left_half_site: str | None = <typer.models.OptionInfo object>, zfn_right_half_site: str | None = <typer.models.OptionInfo object>, zfn_search_space: str | None = <typer.models.OptionInfo object>, zfn_search_space_index: str | None = <typer.models.OptionInfo object>, zfn_search_backend: ZFNSearchBackend = <typer.models.OptionInfo object>, zfn_algorithm: ZFNAlgorithm = <typer.models.OptionInfo object>, zfn_dimer_mode: DimerMode = <typer.models.OptionInfo object>, zfn_spacer_lengths: str = <typer.models.OptionInfo object>, zfn_max_mismatches: int = <typer.models.OptionInfo object>, zfn_window_stride: int | None = <typer.models.OptionInfo object>, zfn_top_n_sites: int | None = <typer.models.OptionInfo object>, zfn_report_n_sites: int | None = <typer.models.OptionInfo object>, cores: int | None = <typer.models.OptionInfo object>, zfn_annotation: str | None = <typer.models.OptionInfo object>, top_n_candidates: int | None = <typer.models.OptionInfo object>, species: str = <typer.models.OptionInfo object>, query_species: str | None = <typer.models.OptionInfo object>, mirna_db: str = <typer.models.OptionInfo object>, mirna_species: str | None = <typer.models.OptionInfo object>, transcriptome_fasta: str | None = <typer.models.OptionInfo object>, transcriptome_filter: str | None = <typer.models.OptionInfo object>, offtarget_indices: str | None = <typer.models.OptionInfo object>, gc_min: float = <typer.models.OptionInfo object>, gc_max: float = <typer.models.OptionInfo object>, sirna_length: int = <typer.models.OptionInfo object>, modification_pattern: str = <typer.models.OptionInfo object>, overhang: str = <typer.models.OptionInfo object>, skip_off_targets: bool = <typer.models.OptionInfo object>, snp: list[str] = <typer.models.OptionInfo object>, snp_file: Path | None = <typer.models.OptionInfo object>, variant_mode: VariantMode = <typer.models.OptionInfo object>, min_af: float = <typer.models.OptionInfo object>, clinvar_filter_levels: str = <typer.models.OptionInfo object>, variant_assembly: str = <typer.models.OptionInfo object>, verbose: bool = <typer.models.OptionInfo object>, log_file: Path | None = <typer.models.OptionInfo object>, nextflow_docker_image: str | None = <typer.models.OptionInfo object>, max_hits: int | None = <typer.models.OptionInfo object>, max_off_targets: int | None = <typer.models.OptionInfo object>, json_summary: bool = <typer.models.OptionInfo object>) None[source]ο
Run the end-to-end workflow: transcripts β siRNA design β off-target.
This is the main orchestration command. It resolves transcriptome and miRNA reference policies, designs candidates, and then runs off-target analysis on the selected top candidates.
- sirnaforge.cli.offtarget(input_candidates_fasta: Path = <typer.models.OptionInfo object>, output_dir: Path = <typer.models.OptionInfo object>, species: str = <typer.models.OptionInfo object>, query_species: str | None = <typer.models.OptionInfo object>, mirna_db: str = <typer.models.OptionInfo object>, mirna_species: str | None = <typer.models.OptionInfo object>, transcriptome_fasta: str | None = <typer.models.OptionInfo object>, transcriptome_filter: str | None = <typer.models.OptionInfo object>, offtarget_indices: str | None = <typer.models.OptionInfo object>, verbose: bool = <typer.models.OptionInfo object>, log_file: Path | None = <typer.models.OptionInfo object>, nextflow_docker_image: str | None = <typer.models.OptionInfo object>) None[source]ο
Run off-target analysis on pre-designed siRNA candidates.
This command accepts a FASTA file containing pre-designed siRNA guide sequences of any length and runs comprehensive off-target analysis including: - Transcriptome alignment (BWA-MEM2) - miRNA seed match analysis - Off-target hit classification and scoring
The embedded Nextflow pipeline is used for parallel processing across species.
Notes
--speciesdrives transcriptome fetching and miRNA lookup.--offtarget-indicescan override the indices used for alignment usingspecies:/abs/path/index_prefixentries.
- sirnaforge.cli.zfn(output_dir: Path = <typer.models.OptionInfo object>, zfn_subfinger_mutation: list[str] = <typer.models.OptionInfo object>, zfn_max_mismatches_per_subfinger: int | None = <typer.models.OptionInfo object>, zfn_max_substitutions_overall: int | None = <typer.models.OptionInfo object>, zfn_left_half_site: str = <typer.models.OptionInfo object>, zfn_right_half_site: str = <typer.models.OptionInfo object>, zfn_search_space: str | None = <typer.models.OptionInfo object>, zfn_search_space_index: str | None = <typer.models.OptionInfo object>, zfn_search_backend: ZFNSearchBackend = <typer.models.OptionInfo object>, zfn_algorithm: ZFNAlgorithm = <typer.models.OptionInfo object>, zfn_dimer_mode: DimerMode = <typer.models.OptionInfo object>, zfn_spacer_lengths: str = <typer.models.OptionInfo object>, zfn_max_mismatches: int = <typer.models.OptionInfo object>, zfn_window_stride: int | None = <typer.models.OptionInfo object>, zfn_top_n_sites: int | None = <typer.models.OptionInfo object>, zfn_report_n_sites: int | None = <typer.models.OptionInfo object>, cores: int | None = <typer.models.OptionInfo object>, zfn_annotation: str | None = <typer.models.OptionInfo object>, verbose: bool = <typer.models.OptionInfo object>, log_file: Path | None = <typer.models.OptionInfo object>, nextflow_docker_image: str | None = <typer.models.OptionInfo object>, json_summary: bool = <typer.models.OptionInfo object>) None[source]ο
Evaluate a ZFN pair and run exhaustive genome-wide off-target search (EXPERIMENTAL).
- sirnaforge.cli.design(input_file: Path = <typer.models.ArgumentInfo object>, output: Path = <typer.models.OptionInfo object>, design_mode: str = <typer.models.OptionInfo object>, length: int = <typer.models.OptionInfo object>, top_n: int | None = <typer.models.OptionInfo object>, gc_min: float = <typer.models.OptionInfo object>, gc_max: float = <typer.models.OptionInfo object>, max_poly_runs: int = <typer.models.OptionInfo object>, genome_index: Path | None = <typer.models.OptionInfo object>, snp_file: Path | None = <typer.models.OptionInfo object>, skip_structure: bool = <typer.models.OptionInfo object>, skip_off_targets: bool = <typer.models.OptionInfo object>, modification_pattern: str = <typer.models.OptionInfo object>, overhang: str = <typer.models.OptionInfo object>, verbose: bool = <typer.models.OptionInfo object>) None[source]ο
Design siRNA candidates from a transcript FASTA file.
Outputs a TSV/CSV-like table of candidates, optionally including secondary structure scoring, off-target checks, and chemical modification annotations.
- sirnaforge.cli.validate(input_file: Path = <typer.models.ArgumentInfo object>) None[source]ο
Validate a FASTA file and report basic statistics.
This performs lightweight validation (parseable FASTA, presence of sequences, and common issues like short/ambiguous sequences).
- sirnaforge.cli.cache(clear: bool = <typer.models.OptionInfo object>, clear_mirna: bool = <typer.models.OptionInfo object>, clear_transcriptome: bool = <typer.models.OptionInfo object>, dry_run: bool = <typer.models.OptionInfo object>, info: bool = <typer.models.OptionInfo object>) None[source]ο
Inspect and clear the unified reference cache.
This command can display cache statistics and/or delete cached assets for miRNA databases and transcriptomes.
- exception sirnaforge.cli.SequencesShowError[source]ο
Bases:
RuntimeErrorRaised when sequence display/formatting input is invalid.
- sirnaforge.cli.sequences_show(input_file: Path = <typer.models.ArgumentInfo object>, sequence_id: str | None = <typer.models.OptionInfo object>, format: str = <typer.models.OptionInfo object>) None[source]ο
Show sequences from a FASTA file in table, JSON, or FASTA format.
Use
--idto select a single record.--formatcontrols output:table(default),json(header metadata only), orfasta.
- sirnaforge.cli.sequences_annotate(input_fasta: Path = <typer.models.ArgumentInfo object>, metadata_json: Path = <typer.models.ArgumentInfo object>, output: Path | None = <typer.models.OptionInfo object>, verbose: bool = <typer.models.OptionInfo object>) None[source]ο
Merge metadata from a JSON file into FASTA headers.
The JSON is expected to conform to the project metadata schema used by the modification/annotation utilities.
- sirnaforge.cli.internal_zfn_make_shards(genome_fasta: Path = <typer.models.OptionInfo object>, left_half_site: str = <typer.models.OptionInfo object>, right_half_site: str = <typer.models.OptionInfo object>, spacer_lengths: str = <typer.models.OptionInfo object>, max_mismatches: int = <typer.models.OptionInfo object>, sharding_enabled: str = <typer.models.OptionInfo object>, shard_chunk_mb: float = <typer.models.OptionInfo object>, shard_overlap_bp: int = <typer.models.OptionInfo object>, shard_chromosomes: str = <typer.models.OptionInfo object>, output: Path = <typer.models.OptionInfo object>) None[source]ο
Build ZFN shard manifest for Nextflow execution.
- sirnaforge.cli.internal_zfn_build_search_index(genome_fasta: Path = <typer.models.OptionInfo object>, search_backend: ZFNSearchBackend = <typer.models.OptionInfo object>, output_dir: Path | None = <typer.models.OptionInfo object>) None[source]ο
Build a persisted ZFN search-space index bundle for indexed backends.
- sirnaforge.cli.internal_zfn_search_shard(shard_id: str = <typer.models.OptionInfo object>, shard_chrom: str = <typer.models.OptionInfo object>, scan_start_1: int = <typer.models.OptionInfo object>, scan_end_1: int = <typer.models.OptionInfo object>, core_start_1: int | None = <typer.models.OptionInfo object>, core_end_1: int | None = <typer.models.OptionInfo object>, shard_max_mismatches: int = <typer.models.OptionInfo object>, left_half_site: str = <typer.models.OptionInfo object>, right_half_site: str = <typer.models.OptionInfo object>, genome_fasta: Path = <typer.models.OptionInfo object>, search_backend: ZFNSearchBackend = <typer.models.OptionInfo object>, search_space_index: Path | None = <typer.models.OptionInfo object>, algorithm: ZFNAlgorithm = <typer.models.OptionInfo object>, dimer_mode: DimerMode = <typer.models.OptionInfo object>, spacer_lengths: str = <typer.models.OptionInfo object>, annotation_file: Path | None = <typer.models.OptionInfo object>, output_sites_csv: Path = <typer.models.OptionInfo object>, output_summary_json: Path = <typer.models.OptionInfo object>) None[source]ο
Run one shard-scoped ZFN search and emit shard artifacts.
Core Modulesο
Design Engineο
Core siRNA design algorithms and functionality.
- class sirnaforge.core.design.SiRNADesigner(parameters: DesignParameters)[source]ο
Bases:
objectMain siRNA design engine following the algorithm specification.
- __init__(parameters: DesignParameters) None[source]ο
Initialize designer with given parameters.
- design_from_file(input_file: str) DesignResult[source]ο
Design siRNAs from input FASTA file.
- design_from_sequence(sequence: str, transcript_id: str = 'seq1') DesignResult[source]ο
Design siRNAs from a single sequence.
- static stamp_repeat_verdict(candidate: SiRNACandidate, observations: dict[str, RepeatObservation]) None[source]ο
Stamp repeat metadata and verdict on a single candidate if its guide is flagged.
The REPEAT_ELEMENT verdict is applied only if the candidate is currently passing (passes_filters is True or PASS). A candidate that already failed for another reason (GC, asymmetry, etc.) retains its earlier verdict β precedence is: existing failure > REPEAT_ELEMENT > PASS.
- Parameters:
candidate β Candidate to potentially flag.
observations β Mapping from normalized guide sequence to RepeatObservation.
- sirnaforge.core.design.mirna_max_biogenesis_bonus(scoring_weights: Mapping[str, float] | None = None) float[source]ο
Maximum attainable miRNA biogenesis bonus: the divisor that puts a miRNA run on one scale.
Exposed as a function so post-screen rescoring can recover the divisor for a candidate that never passed through MiRNADesigner._score_candidates (and therefore carries no MIRNA_BONUS_MAX_KEY), instead of leaving that row on an undivided scale.
- sirnaforge.core.design.apply_mirna_biogenesis_bonus(base_score: float, mirna_bonus: float, max_mirna_bonus: float) float[source]ο
Fold the miRNA biogenesis bonus into a 0-100 composite score.
The bonuses widen the attainable range, so rescale by the maximum attainable total instead of clamping: clamping parked every strong candidate at exactly 100.0 and erased the ranking at the top. Order is preserved, since this is monotone in (base score + bonus).
- class sirnaforge.core.design.MiRNADesigner(parameters: DesignParameters)[source]ο
Bases:
SiRNADesignermiRNA-biogenesis-aware siRNA designer with specialized scoring.
Extends SiRNADesigner with scoring rules optimized for miRNA-like processing: - Argonaute selection preferences (pos1 A/U, mismatch at pos1) - 3β supplementary pairing analysis (positions 13-16) - Conservative thermodynamic thresholds - Seed region quality assessment
- __init__(parameters: DesignParameters) None[source]ο
Initialize miRNA designer with miRNA-specific config validation.
Thermodynamics Analysisο
Thermodynamic calculations for siRNA design using ViennaRNA.
- class sirnaforge.core.thermodynamics.ThermodynamicCalculator(temperature: float = 37.0)[source]ο
Bases:
objectCalculate thermodynamic properties for siRNA candidates using ViennaRNA.
- __init__(temperature: float = 37.0)[source]ο
Initialize thermodynamic calculator.
- Parameters:
temperature β Temperature in Celsius for calculations
- calculate_duplex_stability(guide: str, passenger: str) float[source]ο
Calculate duplex stability (deltaG) using ViennaRNA.
Both strands are supplied 5β->3β and are already complementary, so neither is reverse-complemented here: ViennaRNAβs
&cofold notation pairs the two strands antiparallel on its own.
- calculate_asymmetry_score(candidate: SiRNACandidate) tuple[float, float, float][source]ο
Calculate thermodynamic asymmetry score using ViennaRNA.
Duplex ends are antiparallel, so the guide 5β end pairs with the passenger 3β end and vice versa. Both windows are
END_WINDOW_NTlong so the two ΞG values are directly comparable.- Returns:
Tuple of (5β end stability, 3β end stability, asymmetry score)
- calculate_target_accessibility(target_sequence: str, start_pos: int, sirna_length: int) tuple[float, float][source]ο
Calculate target site accessibility using ViennaRNA.
- Parameters:
target_sequence β Full target mRNA sequence
start_pos β Start position of siRNA target site (0-based)
sirna_length β Length of siRNA
- Returns:
Tuple of (average_unpaired_probability, mfe)
- calculate_melting_temperature(guide: str, passenger: str) float[source]ο
Calculate duplex melting temperature in Β°C.
Uses the RNA nearest-neighbour parameters of Xia et al. (1998) via Biopython. Tm needs ΞH and ΞS separately, which ViennaRNAβs MFE does not provide, so scaling ΞG cannot produce a physical Tm: at the corrected duplex ΞG of a 21mer (about -39 kcal/mol) the previous
37 + 2 * -ΞGapproximation returned 101-124 Β°C.- Parameters:
guide β Guide strand, 5β->3β
passenger β Passenger strand, 5β->3β (expected reverse complement of guide)
- static meets_asymmetry_threshold(asymmetry_score: float, threshold: float) bool[source]ο
Check an already-computed asymmetry score against a threshold.
Callers that have just computed the score use this instead of
is_thermodynamically_favorable()to avoid re-folding both duplex ends.
- is_thermodynamically_favorable(candidate: SiRNACandidate, threshold: float = 0.65) bool[source]ο
Check if candidate meets thermodynamic asymmetry threshold.
Off-Target Predictionο
Off-target analysis for siRNA design.
This module provides comprehensive off-target analysis functionality for siRNA design, including both miRNA seed match analysis and transcriptome off-target detection. Uses BWA-MEM2 for transcriptome alignments and supports in-process miRNA seed scanning. Optimized for both standalone use and parallelized Nextflow workflows.
- class sirnaforge.core.off_target.BwaAnalyzer(index_prefix: str | Path, mode: str = 'transcriptome', seed_length: int = 12, min_score: int = 15, max_hits: int | None = None, seed_start: int = 2, seed_end: int = 8)[source]ο
Bases:
objectBWA-MEM2 based analyzer for both transcriptome and miRNA seed off-target search.
- __init__(index_prefix: str | Path, mode: str = 'transcriptome', seed_length: int = 12, min_score: int = 15, max_hits: int | None = None, seed_start: int = 2, seed_end: int = 8)[source]ο
Initialize BWA-MEM2 analyzer.
- Parameters:
index_prefix β Path to BWA index
mode β Analysis mode - βtranscriptomeβ for long targets, βmirna_seedβ for short targets
seed_length β BWA seed length parameter
min_score β Minimum alignment score
max_hits β Maximum hits to return (
None= no limit / exhaustive)seed_start β Seed region start (1-based)
seed_end β Seed region end (1-based)
- class sirnaforge.core.off_target.OffTargetAnalysisManager(species: str, transcriptome_path: str | Path | None = None, mirna_path: str | Path | None = None, transcriptome_index: str | Path | None = None, mirna_index: str | Path | None = None)[source]ο
Bases:
objectManager class for comprehensive off-target analysis using BWA-MEM2.
- __init__(species: str, transcriptome_path: str | Path | None = None, mirna_path: str | Path | None = None, transcriptome_index: str | Path | None = None, mirna_index: str | Path | None = None)[source]ο
Initialize the off-target analysis manager.
- analyze_mirna_off_targets(sequences: dict[str, str] | str | Path, output_prefix: str | Path) tuple[Path, Path][source]ο
Analyze miRNA off-targets using BWA-MEM2 in miRNA seed mode.
- class sirnaforge.core.off_target.MiRNASeedBackend(*values)[source]ο
-
Internal backend options for miRNA seed scanning.
- BWA = 'bwa'ο
- EXHAUSTIVE_PYTHON = 'exhaustive_python'ο
- PYAHOCORASICK = 'pyahocorasick'ο
- sirnaforge.core.off_target.create_temp_fasta(sequences: dict[str, str]) str[source]ο
Create temporary FASTA file from sequences.
- sirnaforge.core.off_target.validate_and_write_sequences(input_file: str, output_file: str, expected_length: int = 21) tuple[int, int, list[str]][source]ο
Validate siRNA sequences and write valid ones to output file.
- sirnaforge.core.off_target.build_bwa_index(fasta_file: str | Path, index_prefix: str | Path) Path[source]ο
Build BWA-MEM2 index for both transcriptome and miRNA off-target analysis.
- sirnaforge.core.off_target.validate_sirna_sequences(sequences: dict[str, str], expected_length: int = 21) tuple[dict[str, str], dict[str, str], list[str]][source]ο
Validate siRNA sequences using existing FastaUtils.
- sirnaforge.core.off_target.parse_fasta_file(fasta_file: str | Path) dict[str, str][source]ο
Parse FASTA file using existing FastaUtils.
- sirnaforge.core.off_target.write_fasta_file(sequences: dict[str, str], output_file: str) None[source]ο
Write sequences to FASTA file using existing FastaUtils.
- sirnaforge.core.off_target.check_tool_availability(tool: str) bool[source]ο
Check if external tool is available.
- sirnaforge.core.off_target.validate_index_files(index_prefix: str | Path, tool: str = 'bwa') bool[source]ο
Validate that index files exist for given tool.
- sirnaforge.core.off_target.mirna_seed_hit_identity(hit: dict[str, Any], *, coord_is_one_based: bool = False) tuple[str, str, int, int, int, float][source]ο
Return the semantic identity tuple used for backend comparison.
This normalizes the current in-process seed-scan rows and the existing BWA-derived rows onto the same comparison contract.
- sirnaforge.core.off_target.normalize_mirna_seed_hit(hit: dict[str, Any], *, coord_is_one_based: bool = False) _NormalizedMiRNASeedHit[source]ο
Normalize backend-specific miRNA seed hit metadata onto one adapter/parity contract.
- sirnaforge.core.off_target.run_bwa_alignment_analysis(candidates_file: str | Path, index_prefix: str | Path, species: str, output_dir: str | Path, max_hits: int | None = None, bwa_k: int = 12, bwa_T: int = 15, seed_start: int = 2, seed_end: int = 8) Path[source]ο
Run BWA-MEM2 alignment analysis for candidate sequences using Pydantic models.
This is the main function called by OFFTARGET_ANALYSIS Nextflow module.
- Parameters:
candidates_file β Path to FASTA file with candidate sequences
index_prefix β Path to BWA-MEM2 index prefix
species β Species identifier
output_dir β Directory to write results
max_hits β Maximum hits to report per candidate (
None= no limit / exhaustive)bwa_k β BWA seed length parameter
bwa_T β BWA minimum score threshold
seed_start β Seed region start position (1-based)
seed_end β Seed region end position (1-based)
- Returns:
Path to output directory containing results
- sirnaforge.core.off_target.aggregate_offtarget_results(results_dir: str | Path, output_dir: str | Path, genome_species: str) Path[source]ο
Aggregate transcriptome off-target analysis results using Pandera.
Uses pandas + Pandera for efficient bulk reading and validation instead of manual line-by-line parsing with Pydantic models.
NOTE: This function ONLY aggregates genome/transcriptome hits. miRNA results are aggregated separately by aggregate_mirna_results() to keep output files distinct and properly typed.
- Parameters:
results_dir β Directory containing individual analysis results
output_dir β Directory to write aggregated results
genome_species β Comma-separated list of genome species analyzed
- Returns:
Path to output directory containing aggregated results
- sirnaforge.core.off_target.scan_mirna_seed_matches(sequences: dict[str, str], mirna_sequences: dict[str, str], *, backend: MiRNASeedBackend | str = MiRNASeedBackend.PYAHOCORASICK, seed_start: int = 2, seed_end: int = 8, max_mismatches: int = 2, max_hits: int | None = None) list[dict[str, Any]][source]ο
Scan miRNA FASTA records using an in-process seed-scanning backend.
The returned rows preserve the existing internal hit shape used by miRNA analysis, so callers can continue adapting them to DataFrame-based outputs.
- sirnaforge.core.off_target.run_mirna_seed_analysis(candidates_file: str | Path, candidate_id: str, mirna_db: str, mirna_species: list[str], output_dir: str | Path, backend: MiRNASeedBackend | str = MiRNASeedBackend.PYAHOCORASICK, seed_start: int = 2, seed_end: int = 8) Path[source]ο
Run miRNA seed match analysis for candidate sequences.
This function uses the MiRNADatabaseManager to download and cache miRNA databases, builds BWA indices if needed, and performs seed match analysis.
The scan produces raw alignments: the guide seed window placed at every position along each miRNA. Only alignments where the guide seed lands on the miRNAβs own seed region (0-based
coord == seed_start - 1) are counted as hits in the filtered outputs and summarytotal_hits; perfect matches in non-seed regions are retained in the*_rawfiles but are not real miRNA seed off-targets.- Parameters:
candidates_file β Path to FASTA file with candidate sequences
candidate_id β Candidate identifier
mirna_db β miRNA database name (mirgenedb, mirbase, etc.)
mirna_species β List of species to analyze against
output_dir β Directory to write results
backend β miRNA seed backend to use for analysis (pyahocorasick by default)
seed_start β Seed region start position (1-based, default 2)
seed_end β Seed region end position (1-based, default 8)
- Returns:
Path to output directory containing results
- sirnaforge.core.off_target.aggregate_mirna_results(results_dir: str | Path, output_dir: str | Path, mirna_db: str, mirna_species: str) Path[source]ο
Aggregate miRNA seed analysis results from multiple candidates using pandas.
Uses pandas + Pandera for efficient bulk reading and validation instead of manual line-by-line parsing with Pydantic models.
- Parameters:
results_dir β Directory containing individual miRNA analysis results
output_dir β Directory to write aggregated results
mirna_db β miRNA database used for analysis
mirna_species β Comma-separated list of species analyzed
- Returns:
Path to output directory containing aggregated results
ZFN Designο
Warning
EXPERIMENTAL. Every sirnaforge.zfn.* and sirnaforge.models.zfn API below is
experimental in 0.6.0 with known unfixed defects, tracked in
#82. Do not use ZFN output for any
decision without independent validation. Calling
sirnaforge.zfn.design.ZFNDesigner.evaluate_pair() logs the full notice at WARNING
on first use in a process. Two defects that change nothing visible in the returned objects:
ZFNCandidate.worst_site_score / best_offtarget_score are inverted (minimum and
maximum site score respectively, whereas the highest-scoring off-target is the most
dangerous one), and right_half_site must be supplied as the reverse complement of its
published plus-strand text or it matches nothing. See ZFN Module Guide.
Experimental-status notice for the ZFN arm.
This lives in its own module rather than in sirnaforge.zfn.__init__ because the
package __init__ imports design, and design has to emit the notice too β
reaching back into the package from one of its own submodules would be circular.
The notice is emitted at most once per process. Every ZFN entry point calls
emit_zfn_experimental_warning(), so whichever one a caller happens to reach first
carries the text, and the ones layered beneath it (CLI -> workflow -> designer) do not
repeat it. It is a statement about the moduleβs status, not about a result, so repeating
it per candidate or per run would only train users to skip it.
βOnceβ means once as the user sees it, not once per log record. When a rich console is
supplied, the log record and the panel would otherwise both land on the same terminal
stream and print the whole notice twice β sirnaforge.utils.logging_utils attaches a
StreamHandler(sys.stdout) to the root logger on first get_logger call, and rich
writes to sys.stdout too. emit_zfn_experimental_warning() therefore keeps the
log record (so log files, caplog and library callers still get it) but mutes, for that
one record only, the handlers writing to the consoleβs own stream.
Where the notice lands with no console: wherever the host applicationβs logging sends
WARNING. Under sirnaforgeβs own get_logger()
that is stdout, not stderr β because a handler is always installed, loggingβs
last-resort stderr handler never fires.
- sirnaforge.zfn.experimental.emit_zfn_experimental_warning(console: Console | None = None) bool[source]ο
Announce the ZFN armβs experimental status, at most once per process.
The notice is logged at
WARNINGon every path, so it reaches log files and any handler the host application configured. It is rendered to the terminal exactly once: with aconsolethe user sees the rich panel, without one they see whatever the log handlers show (stdout, under sirnaforgeβs own logging setup).- Parameters:
console β Rich console to render a highlighted notice on. Omit it for library callers β the warning still reaches the log.
- Returns:
True if this call emitted the notice, False if an earlier call already did.
- sirnaforge.zfn.experimental.reset_zfn_experimental_warning() None[source]ο
Re-arm the once-per-process latch. For tests that exercise several ZFN entry points.
High-level ZFN pair evaluation workflow.
- class sirnaforge.zfn.design.ZFNDesigner(searcher: ZFNOffTargetSearcher | None = None)[source]ο
Bases:
objectEvaluate one provided ZFN pair with exhaustive off-target search.
- __init__(searcher: ZFNOffTargetSearcher | None = None) None[source]ο
Initialize with a searcher implementation.
- evaluate_pair(params: ZFNDesignParameters, annotation: GenomicAnnotationConfig | None = None) ZFNDesignResult[source]ο
Run end-to-end pair evaluation and return typed results.
- build_candidate(params: ZFNDesignParameters, sites: list[ZFNOffTargetSite]) ZFNCandidate[source]ο
Public wrapper for candidate-summary construction.
- score_manufacturability(params: ZFNDesignParameters) float[source]ο
Public wrapper for manufacturability scoring logic.
ZFN Searchο
Exhaustive ZFN off-target search implementation for provided half-sites.
- sirnaforge.zfn.search.build_zfn_search_index(*, backend: ZFNSearchBackend, genome_fasta: Path, output_dir: Path | None = None) dict[str, Any][source]ο
Build a persisted search-space index bundle for indexed ZFN backends.
- sirnaforge.zfn.search.resolve_target_contigs(contig_names: list[str], requested: list[str]) list[str][source]ο
Resolve requested chromosome filters against loaded contig names.
- sirnaforge.zfn.search.build_zfn_shard_specs(contig_lengths: dict[str, int], params: ZFNDesignParameters) list[_ShardSpec][source]ο
Build chromosome/chunk shard specs from contig lengths.
This is the authoritative shard planning logic shared by the direct Python searcher and external orchestration layers such as Nextflow.
- class sirnaforge.zfn.search.ExhaustiveZFNOffTargetSearcher(annotation_provider: ZFNAnnotationProvider | None = None)[source]ο
Bases:
objectExhaustive sliding-window off-target search for a provided ZFN pair.
- __init__(annotation_provider: ZFNAnnotationProvider | None = None) None[source]ο
Initialize searcher with optional annotation provider.
- search(params: ZFNDesignParameters, annotation: GenomicAnnotationConfig | None = None) list[ZFNOffTargetSite][source]ο
Search all predicted cut sites with explicit mismatch + spacer constraints.
- search_region(params: ZFNDesignParameters, chrom: str, scan_start0: int, scan_end0: int, core_start0: int | None = None, core_end0: int | None = None, annotation: GenomicAnnotationConfig | None = None, top_n_sites: int | None = None) list[ZFNOffTargetSite][source]ο
Search one bounded genomic region using the same core engine as full search.
The region is scanned across
scan_start0..scan_end0and then filtered to the optional core window so overlapping shards can share context without double-reporting the same site.
ZFN Rankingο
Ranking utilities for ZFN off-target sites.
This module centralizes deterministic site ordering for reporting/regression use. The tie-break behavior follows the PROGNOS-inspired policy used in tests:
Higher score first.
Region priority for equal scores: Exon > Promoter > Intron > Intergenic > Unknown.
Chromosomal location ordering.
- sirnaforge.zfn.rank.rank_sites(sites: Sequence[ZFNOffTargetSite], params: ZFNDesignParameters | None = None) list[ZFNOffTargetSite][source]ο
Rank off-target sites with score-first ordering and deterministic tie-breaks.
- Parameters:
sites β Candidate sites to rank.
params β Optional design parameters. Currently only used to keep a typed, future-proof API for algorithm-specific ranking extensions.
- Returns:
A new sorted list of sites.
ZFN Annotationο
GTF/GFF-backed annotation provider for ZFN off-target sites.
- class sirnaforge.zfn.annotation.GTFZFNAnnotationProvider[source]ο
Bases:
objectAnnotate predicted ZFN sites using local GTF/GFF intervals.
- annotate(sites: list[ZFNOffTargetSite], config: GenomicAnnotationConfig) list[ZFNOffTargetSite][source]ο
Attach region and nearest gene labels to each site.
ZFN Interfacesο
Interfaces for ZFN off-target search and annotation engines.
- class sirnaforge.zfn.interfaces.ZFNOffTargetSearcher(*args, **kwargs)[source]ο
Bases:
ProtocolProtocol for ZFN off-target site searchers.
- search(params: ZFNDesignParameters, annotation: GenomicAnnotationConfig | None = None) list[ZFNOffTargetSite][source]ο
Return predicted off-target cut sites for a provided ZFN pair.
- __init__(*args, **kwargs)ο
- class sirnaforge.zfn.interfaces.ZFNAnnotationProvider(*args, **kwargs)[source]ο
Bases:
ProtocolOptional protocol for site-level region annotation.
- annotate(sites: list[ZFNOffTargetSite], config: GenomicAnnotationConfig) list[ZFNOffTargetSite][source]ο
Attach region and nearest-gene annotation to predicted sites.
- __init__(*args, **kwargs)ο
ZFN Nextflow Bridgeο
Typed Python bridge for ZFN Nextflow modules.
These helpers keep domain logic in Python while Nextflow handles process orchestration.
- class sirnaforge.zfn.nextflow_bridge.ZFNShardRow(shard_id: str, chrom: str, core_start_1: int, core_end_1: int, scan_start_1: int, scan_end_1: int, max_mismatches: int)[source]ο
Bases:
objectOne row in the ZFN shard manifest.
- sirnaforge.zfn.nextflow_bridge.make_zfn_shard_manifest(*, genome_fasta: Path, left_half_site: str, right_half_site: str, spacer_lengths: str, max_mismatches: int, sharding_enabled: str | bool, shard_chunk_mb: float, shard_overlap_bp: int, shard_chromosomes: str, output_tsv: Path) dict[str, int | bool][source]ο
Build shard TSV for ZFN search.
Sharding is applied whenever enabled, including for single-contig references. The direct Python searcher remains authoritative for overlap and chunk planning.
- sirnaforge.zfn.nextflow_bridge.run_zfn_shard_search(*, shard_id: str, shard_chrom: str, scan_start_1: int, scan_end_1: int, core_start_1: int | None = None, core_end_1: int | None = None, shard_max_mismatches: int, left_half_site: str, right_half_site: str, genome_fasta: Path, search_backend: ZFNSearchBackend, search_space_index: Path | None, algorithm: ZFNAlgorithm, dimer_mode: DimerMode, spacer_lengths: str, annotation_file: Path | None, output_sites_csv: Path, output_summary_json: Path) dict[str, int | str][source]ο
Execute one shard search and persist shard-scoped outputs.
The search scans
scan_start_1..scan_end_1(1-based, inclusive) for sequence context, but only sites whose coordinates fall entirely within the core window (core_start_1..core_end_1) are written to output. This prevents duplicate sites across overlapping shards. Whencore_start_1orcore_end_1are not provided they default to the scan boundaries.
ZFN Benchmark Dataο
Typed ingestion helpers for CCR5 ZFN benchmark tables (PROGNOS supplementary extracts).
- class sirnaforge.zfn.benchmark_data.CCR5S10VisibleRow(closest_gene: str, match_type: MatchType, chrom: str, pos_hg19: int, plus_half_site: str, minus_half_site: str, empty_indels: int | None, empty_total: int | None, active_indels: int | None, active_total: int | None, active_mutation_freq_percent: float | None, p_value: float | None, notes: str, sequencing_failure: bool)[source]ο
Bases:
objectOne visible row from the extracted S10 CCR5 off-target validation table.
- __init__(closest_gene: str, match_type: MatchType, chrom: str, pos_hg19: int, plus_half_site: str, minus_half_site: str, empty_indels: int | None, empty_total: int | None, active_indels: int | None, active_total: int | None, active_mutation_freq_percent: float | None, p_value: float | None, notes: str, sequencing_failure: bool) Noneο
- class sirnaforge.zfn.benchmark_data.CCR5S11HomologyRow(homology_rank: int, t_mismatches: int, plus_mismatches: int, minus_mismatches: int, interrogated_by: str, closest_gene: str, match_type: MatchType, chrom: str, pos_hg19: int, plus_half_site: str, minus_half_site: str)[source]ο
Bases:
objectOne visible row from the S11 homology ranking extract.
- class sirnaforge.zfn.benchmark_data.MatchType(left: Literal['L', 'R'], spacer_len: int, right: Literal['L', 'R'])[source]ο
Bases:
objectStructured representation of PROGNOS match type, e.g.
L-5-R.
- sirnaforge.zfn.benchmark_data.load_ccr5_s10_visible_rows(path: str | Path) list[CCR5S10VisibleRow][source]ο
Load visible S10 rows from CSV into typed records.
- sirnaforge.zfn.benchmark_data.load_ccr5_s11_homology_rows(path: str | Path) list[CCR5S11HomologyRow][source]ο
Load visible S11 homology rows from CSV into typed records.
Data Modelsο
SiRNA Modelsο
Pydantic models for siRNA design data structures.
- class sirnaforge.models.sirna.FilterCriteria(*, gc_min: Annotated[float, Ge(ge=0), Le(le=100)] = 35.0, gc_max: Annotated[float, Ge(ge=0), Le(le=100)] = 60.0, max_poly_runs: Annotated[int, Ge(ge=1)] = 3, max_paired_fraction: Annotated[float, Ge(ge=0), Le(le=1)] = 0.6, min_asymmetry_score: Annotated[float, Ge(ge=0.3), Le(le=1)] = 0.65, min_empirical_score: Annotated[float, Ge(ge=0.4), Le(le=0.7)] = 0.5)[source]ο
Bases:
BaseModelQuality filters for siRNA candidate selection based on thermodynamic and empirical criteria.
- classmethod gc_max_greater_than_min(v: float, info: ValidationInfo) float[source]ο
Validate that gc_max is greater than or equal to gc_min.
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.sirna.OffTargetFilterCriteria(*, max_off_target_count: Annotated[int | None, Ge(ge=0)] = 15, max_transcriptome_hits_0mm: Annotated[int | None, Ge(ge=0)] = 1, max_transcriptome_hits_1mm: Annotated[int | None, Ge(ge=0)] = 10, max_transcriptome_hits_2mm: Annotated[int | None, Ge(ge=0)] = 50, max_transcriptome_seed_perfect: Annotated[int | None, Ge(ge=0)] = None, max_mirna_perfect_seed: Annotated[int | None, Ge(ge=0)] = 0, max_mirna_1mm_seed: Annotated[int | None, Ge(ge=0)] = 10, fail_on_high_risk_mirna: bool = True, max_total_offtarget_hits: Annotated[int | None, Ge(ge=0)] = None)[source]ο
Bases:
BaseModelFiltering criteria for off-target analysis results.
Controls which siRNA candidates fail due to excessive off-target potential.
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.sirna.ScoringWeights(*, asymmetry: Annotated[float, Ge(ge=0), Le(le=1)] = 0.12, gc_content: Annotated[float, Ge(ge=0), Le(le=1)] = 0.1, accessibility: Annotated[float, Ge(ge=0), Le(le=1)] = 0.13, empirical: Annotated[float, Ge(ge=0), Le(le=1)] = 0.15, off_target: Annotated[float, Ge(ge=0), Le(le=1)] = 0.25, isoform_coverage: Annotated[float, Ge(ge=0), Le(le=1)] = 0.15, conservation: Annotated[float, Ge(ge=0), Le(le=1)] = 0.1)[source]ο
Bases:
BaseModelRelative weights for composite siRNA scoring components.
- weights_sum_to_one() ScoringWeights[source]ο
Validate that scoring weights sum to approximately 1.0.
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.sirna.DesignMode(*values)[source]ο
-
Design mode for siRNA/miRNA-biogenesis-aware workflows.
- SIRNA = 'sirna'ο
- MIRNA = 'mirna'ο
- ZFN = 'zfn'ο
- class sirnaforge.models.sirna.MiRNADesignConfig(*, gc_min: Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = 30.0, gc_max: Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = 52.0, asymmetry_min: Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = 0.65, max_homopolymer: Annotated[int, ~annotated_types.Ge(ge=1)] = 3, overhang: str = 'UU', modifications: str = 'standard_2ome', off_target_preset: str = 'MIRNA_SEED_7_8', scoring_weights: dict[str, float]=<factory>, enable_pri_hairpin_validation: bool = False)[source]ο
Bases:
BaseModelConfiguration preset for miRNA-biogenesis-aware siRNA design.
This config encapsulates thresholds, defaults, and scoring weights optimized for miRNA-like processing (Drosha/Dicer recognition, Argonaute loading preferences, seed-based off-target analysis).
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.sirna.DesignParameters(*, design_mode: DesignMode = DesignMode.SIRNA, sirna_length: Annotated[int, ~annotated_types.Ge(ge=19), ~annotated_types.Le(le=23)] = 21, top_n: Annotated[int | None, ~annotated_types.Ge(ge=1)] = None, filters: FilterCriteria = <factory>, offtarget_filters: OffTargetFilterCriteria = <factory>, scoring: ScoringWeights = <factory>, avoid_snps: bool = True, check_off_targets: bool = True, predict_structure: bool = True, apply_modifications: bool = True, modification_pattern: str = 'standard_2ome', default_overhang: str = 'dTdT', snp_file: str | None = None, genome_index: str | None = None)[source]ο
Bases:
BaseModelComplete configuration parameters for siRNA design workflow.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- design_mode: DesignModeο
- filters: FilterCriteriaο
- offtarget_filters: OffTargetFilterCriteriaο
- scoring: ScoringWeightsο
- class sirnaforge.models.sirna.SequenceType(*values)[source]ο
-
Categories of input sequence types for siRNA design.
- TRANSCRIPT = 'transcript'ο
- GENOMIC = 'genomic'ο
- CDS = 'cds'ο
- UTR = 'utr'ο
- class sirnaforge.models.sirna.SiRNACandidate(*, id: str, transcript_id: str, position: ~typing.Annotated[int, ~annotated_types.Ge(ge=1)], guide_sequence: ~typing.Annotated[str, ~annotated_types.MinLen(min_length=19), ~annotated_types.MaxLen(max_length=40)], passenger_sequence: ~typing.Annotated[str, ~annotated_types.MinLen(min_length=19), ~annotated_types.MaxLen(max_length=40)], gc_content: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)], length: ~typing.Annotated[int, ~annotated_types.Ge(ge=19), ~annotated_types.Le(le=40)], asymmetry_score: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)], duplex_stability: float | None = None, structure: str | None = None, mfe: float | None = None, paired_fraction: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = 0.0, off_target_screened: bool = False, off_target_count: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, off_target_penalty: ~typing.Annotated[float, ~annotated_types.Ge(ge=0)] = 0.0, transcriptome_hits_total: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, transcriptome_hits_0mm: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, transcriptome_hits_1mm: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, transcriptome_hits_2mm: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, transcriptome_hits_seed_0mm: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, on_target_confirmed: bool = False, on_target_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, ortholog_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, repeat_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, ortholog_species: str = '', repeat_flagged: bool = False, repeat_transcript_fraction: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = 0.0, mirna_hits_total: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, mirna_hits_0mm_seed: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, mirna_hits_1mm_seed: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, mirna_hits_high_risk: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, guide_pos1_base: str | None = None, pos1_pairing_state: str | None = None, seed_class: str | None = None, supp_13_16_score: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = None, seed_7mer_hits: ~typing.Annotated[int | None, ~annotated_types.Ge(ge=0)] = None, seed_8mer_hits: ~typing.Annotated[int | None, ~annotated_types.Ge(ge=0)] = None, seed_hits_weighted: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0)] = None, off_target_seed_risk_class: str | None = None, transcript_hit_count: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 1, transcript_hit_fraction: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = 1.0, isoform_coverage: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = None, conservation_score: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = None, component_scores: dict[str, float] = <factory>, composite_score: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)], score_asymmetry: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, score_gc_content: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, score_accessibility: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, score_empirical: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, score_off_target: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, score_isoform_coverage: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, score_conservation: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, scored_after_screening: bool = False, weight_set_version: str = '', passes_filters: bool | ~sirnaforge.models.sirna.SiRNACandidate.FilterStatus = True, quality_issues: list[str] = <factory>, overlapped_variants: list[dict[str, ~typing.Any]] = <factory>, allele_specific: bool = False, targeted_alleles: list[str] = <factory>, variant_mode: str | None = None, guide_metadata: ~sirnaforge.models.modifications.StrandMetadata | None = None, passenger_metadata: ~sirnaforge.models.modifications.StrandMetadata | None = None)[source]ο
Bases:
BaseModelIndividual siRNA candidate with computed thermodynamic and efficacy properties.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class FilterStatus(*values)[source]ο
-
Filter status codes for quality control.
- PASS = 'PASS'ο
- GC_OUT_OF_RANGE = 'GC_OUT_OF_RANGE'ο
- POLY_RUNS = 'POLY_RUNS'ο
- EXCESS_PAIRING = 'EXCESS_PAIRING'ο
- LOW_ASYMMETRY = 'LOW_ASYMMETRY'ο
- LOW_EMPIRICAL_SCORE = 'LOW_EMPIRICAL_SCORE'ο
- DIRTY_CONTROL = 'DIRTY_CONTROL'ο
- REPEAT_ELEMENT = 'REPEAT_ELEMENT'ο
- EXCESS_OFF_TARGETS = 'EXCESS_OFF_TARGETS'ο
- TRANSCRIPTOME_PERFECT_MATCH = 'TRANSCRIPTOME_PERFECT_MATCH'ο
- TRANSCRIPTOME_1MM = 'TRANSCRIPTOME_1MM'ο
- TRANSCRIPTOME_2MM = 'TRANSCRIPTOME_2MM'ο
- TRANSCRIPTOME_SEED_PERFECT = 'TRANSCRIPTOME_SEED_PERFECT'ο
- MIRNA_PERFECT_SEED = 'MIRNA_PERFECT_SEED'ο
- HIGH_RISK_MIRNA = 'HIGH_RISK_MIRNA'ο
- TOTAL_OFFTARGETS = 'TOTAL_OFFTARGETS'ο
- passes_filters: bool | FilterStatusο
- guide_metadata: StrandMetadata | Noneο
- passenger_metadata: StrandMetadata | Noneο
- classmethod validate_nucleotide_sequence(v: str) str[source]ο
Validate that sequence contains only valid nucleotides.
- classmethod warn_beyond_recommended_length(v: str) str[source]ο
Warn (do not fail) when a sequence exceeds the recommended biological max.
19-23 nt is the recommended siRNA range; longer sequences (e.g. Dicer 3β read-through isoforms) are still analyzed up to ENGINE_MAX_GUIDE_LEN.
- sirnaforge.models.sirna.build_candidate_row(candidate: SiRNACandidate) dict[str, Any][source]ο
Map one SiRNACandidate to its canonical output-row dict.
The single source of truth for candidate CSV columns, shared by DesignResult.save_csv (the sirnaforge design path) and SiRNAWorkflow.step6_generate_reports (the sirnaforge workflow path) so the two writers cannot drift on which columns they emit. Optional attributes use a tolerant getattr since the workflow path feeds candidates from several producers.
- class sirnaforge.models.sirna.DesignResult(*, input_file: str, parameters: ~sirnaforge.models.sirna.DesignParameters, candidates: list[~sirnaforge.models.sirna.SiRNACandidate], top_candidates: list[~sirnaforge.models.sirna.SiRNACandidate], total_sequences: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], total_candidates: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], filtered_candidates: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], processing_time: ~typing.Annotated[float, ~annotated_types.Ge(ge=0)], tool_versions: dict[str, str] = <factory>, rejected_candidates: list[~sirnaforge.models.sirna.SiRNACandidate] = <factory>)[source]ο
Bases:
BaseModelComplete results from siRNA design workflow with metadata and statistics.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- parameters: DesignParametersο
- candidates: list[SiRNACandidate]ο
- top_candidates: list[SiRNACandidate]ο
- rejected_candidates: list[SiRNACandidate]ο
- save_csv(filepath: str) DataFrame[SiRNACandidateSchema][source]ο
Save siRNA candidates to CSV file with comprehensive validation.
Exports all candidates to CSV format with full thermodynamic metrics. The DataFrame is validated against SiRNACandidateSchema before saving to ensure data integrity and proper column types.
- Parameters:
filepath β Output CSV file path
- Returns:
Validated DataFrame conforming to SiRNACandidateSchema
- Raises:
pandera.errors.SchemaError β If data validation fails
Chemical Modificationsο
Data models for siRNA chemical modifications and metadata.
This module provides structured representations for chemical modifications, overhangs, and provenance metadata associated with siRNA strands.
- class sirnaforge.models.modifications.ConfirmationStatus(*values)[source]ο
-
Confirmation status for siRNA sequence data.
- PENDING = 'pending'ο
- CONFIRMED = 'confirmed'ο
- class sirnaforge.models.modifications.SourceType(*values)[source]ο
-
Source type for siRNA provenance.
- PATENT = 'patent'ο
- PUBLICATION = 'publication'ο
- CLINICAL_TRIAL = 'clinical_trial'ο
- DATABASE = 'database'ο
- DESIGNED = 'designed'ο
- OTHER = 'other'ο
- class sirnaforge.models.modifications.Provenance(*, source_type: SourceType, identifier: str, url: str | None = None)[source]ο
Bases:
BaseModelProvenance information for siRNA sequences.
Tracks the origin and validation status of siRNA sequences.
- source_type: SourceTypeο
- to_header_string() str[source]ο
Convert provenance to FASTA header format.
- Returns:
US10060921B2β
- Return type:
Formatted string like βPatent
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.modifications.ChemicalModification(*, type: str, positions: list[int] = <factory>)[source]ο
Bases:
BaseModelChemical modification annotation for siRNA strands.
Represents a specific type of chemical modification and the positions where it occurs in the sequence.
- classmethod validate_positions(v: list[int]) list[int][source]ο
Validate positions are positive integers.
- to_header_string() str[source]ο
Convert modification to FASTA header format.
- Returns:
Formatted string like β2OMe(1,4,6,11,13,16,19)β or β2F()β for no positions
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.modifications.StrandRole(*values)[source]ο
-
Role of the siRNA strand in the duplex.
- GUIDE = 'guide'ο
- SENSE = 'sense'ο
- ANTISENSE = 'antisense'ο
- PASSENGER = 'passenger'ο
- class sirnaforge.models.modifications.StrandMetadata(*, id: str, sequence: str, overhang: str | None = None, chem_mods: list[ChemicalModification] = <factory>, notes: str | None = None, provenance: Provenance | None = None, confirmation_status: ConfirmationStatus = ConfirmationStatus.PENDING)[source]ο
Bases:
BaseModelComplete metadata for a single siRNA strand.
This model captures all relevant information about a siRNA strand including sequence, modifications, overhangs, and provenance.
- chem_mods: list[ChemicalModification]ο
- provenance: Provenance | Noneο
- confirmation_status: ConfirmationStatusο
- classmethod validate_sequence(v: str) str[source]ο
Validate sequence contains only valid nucleotides.
- validate_modification_positions() StrandMetadata[source]ο
Validate that modification positions donβt exceed sequence length.
- to_fasta_header(target_gene: str | None = None, strand_role: StrandRole | None = None) str[source]ο
Generate FASTA header with embedded metadata.
- Parameters:
target_gene β Target gene name
strand_role β Role of this strand in the duplex
- Returns:
FASTA header string with key-value pairs
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.modifications.SequenceRecord(*, target_gene: str, strand_role: StrandRole, metadata: StrandMetadata)[source]ο
Bases:
BaseModelComplete sequence record with strand metadata.
Associates a strand with its target and role information.
- strand_role: StrandRoleο
- metadata: StrandMetadataο
- to_fasta() str[source]ο
Generate complete FASTA record.
- Returns:
Multi-line FASTA string with header and sequence
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Off-Target Modelsο
Pydantic models for off-target analysis data structures.
This module provides validated data models for: - BWA alignment results (both genome and miRNA) - Aggregated off-target summaries - Analysis metadata and statistics
Using Pydantic ensures type safety, automatic validation, and clean serialization to JSON/TSV formats.
- class sirnaforge.models.off_target.AlignmentStrand(*values)[source]ο
-
Genomic strand orientation.
- FORWARD = '+'ο
- REVERSE = '-'ο
- class sirnaforge.models.off_target.AnalysisMode(*values)[source]ο
-
BWA alignment analysis mode.
- MIRNA_SEED = 'mirna_seed'ο
- TRANSCRIPTOME = 'transcriptome'ο
- class sirnaforge.models.off_target.MiRNADatabase(*values)[source]ο
-
Supported miRNA database sources.
Values correspond to database identifiers used by MiRNADatabaseManager. Using str enum allows seamless string comparison while providing validation.
- MIRGENEDB = 'mirgenedb'ο
- MIRBASE = 'mirbase'ο
- MIRBASE_HIGH_CONF = 'mirbase_high_conf'ο
- MIRBASE_HAIRPIN = 'mirbase_hairpin'ο
- TARGETSCAN = 'targetscan'ο
- class sirnaforge.models.off_target.BaseAlignmentHit(*, qname: str, qseq: str, coord: Annotated[int, Ge(ge=0)], strand: AlignmentStrand, cigar: str, mapq: Annotated[int, Ge(ge=0), Le(le=255)], as_score: int | None = None, nm: Annotated[int, Ge(ge=0)], seed_mismatches: Annotated[int, Ge(ge=0)], offtarget_score: Annotated[float, Ge(ge=0)])[source]ο
Bases:
BaseModel,ABCBase class for alignment hits with common fields and validators.
This abstract base class contains all shared fields and validation logic for both off-target and miRNA alignment hits.
- model_config = {'frozen': False, 'validate_assignment': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- strand: AlignmentStrandο
- classmethod validate_sequence(v: str) str[source]ο
Ensure sequence contains only valid nucleotide characters.
- class sirnaforge.models.off_target.OffTargetHit(*, qname: str, qseq: str, coord: Annotated[int, Ge(ge=0)], strand: AlignmentStrand, cigar: str, mapq: Annotated[int, Ge(ge=0), Le(le=255)], as_score: int | None = None, nm: Annotated[int, Ge(ge=0)], seed_mismatches: Annotated[int, Ge(ge=0)], offtarget_score: Annotated[float, Ge(ge=0)], species: str, rname: str)[source]ο
Bases:
BaseAlignmentHitSingle off-target alignment hit from BWA analysis.
Represents one potential off-target binding site identified by sequence alignment against a reference genome or transcriptome.
- model_config = {'frozen': False, 'validate_assignment': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.off_target.MiRNAHit(*, qname: str, qseq: str, coord: Annotated[int, Ge(ge=0)], strand: AlignmentStrand, cigar: str, mapq: Annotated[int, Ge(ge=0), Le(le=255)], as_score: int | None = None, nm: Annotated[int, Ge(ge=0)], seed_mismatches: Annotated[int, Ge(ge=0)], offtarget_score: Annotated[float, Ge(ge=0)], species: str, database: MiRNADatabase | str, mirna_id: str)[source]ο
Bases:
BaseAlignmentHitSingle miRNA seed match hit from BWA analysis.
Represents a potential miRNA-like seed match identified by alignment against miRNA databases.
- database: MiRNADatabase | strο
- model_config = {'frozen': False, 'validate_assignment': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.off_target.BaseSummary(*, candidate_id: str, total_sequences: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], total_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], timestamp: str = <factory>, status: str = 'completed')[source]ο
Bases:
BaseModelBase class for analysis summary statistics with common metadata fields.
- model_config = {'frozen': False}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.off_target.AnalysisSummary(*, candidate_id: str, total_sequences: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], total_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], timestamp: str = <factory>, status: str = 'completed', species: str, mode: ~sirnaforge.models.off_target.AnalysisMode, mean_mapq: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0.0), ~annotated_types.Le(le=255.0)] = None, mean_mismatches: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0)] = None, mean_seed_mismatches: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0)] = None)[source]ο
Bases:
BaseSummarySummary statistics for a single candidateβs off-target analysis.
- mode: AnalysisModeο
- model_config = {'frozen': False}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.off_target.MiRNASummary(*, candidate_id: str, total_sequences: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], total_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], timestamp: str = <factory>, status: str = 'completed', mirna_database: ~sirnaforge.models.off_target.MiRNADatabase | str, species_analyzed: list[str], hits_per_species: dict[str, int] = <factory>, total_raw_alignments: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, parameters: dict[str, ~typing.Any] = <factory>)[source]ο
Bases:
BaseSummarySummary statistics for miRNA seed match analysis.
Note: total_hits represents validated, high-quality seed region matches. hits_per_species represents raw alignment counts (may include low-quality matches).
- mirna_database: MiRNADatabase | strο
- model_config = {'frozen': False}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.off_target.BaseAggregatedSummary(*, species_analyzed: list[str], analysis_files_processed: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], combined_tsv: ~pathlib.Path | None = None, combined_json: ~pathlib.Path | None = None, summary_file: ~pathlib.Path | None = None, timestamp: str = <factory>)[source]ο
Bases:
BaseModelBase class for aggregated analysis summaries with common fields.
- model_config = {'frozen': False}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.off_target.AggregatedOffTargetSummary(*, species_analyzed: list[str], analysis_files_processed: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], combined_tsv: ~pathlib.Path | None = None, combined_json: ~pathlib.Path | None = None, summary_file: ~pathlib.Path | None = None, timestamp: str = <factory>, total_results: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], hits_per_species: dict[str, int] = <factory>, human_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, other_species_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, species_file_counts: dict[str, int] = <factory>, missing_species: list[str] = <factory>, status: str = 'completed')[source]ο
Bases:
BaseAggregatedSummarySummary of aggregated off-target results across multiple candidates and genomes.
- model_config = {'frozen': False}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.off_target.AggregatedMiRNASummary(*, species_analyzed: list[str], analysis_files_processed: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], combined_tsv: ~pathlib.Path | None = None, combined_json: ~pathlib.Path | None = None, summary_file: ~pathlib.Path | None = None, timestamp: str = <factory>, total_mirna_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], mirna_database: ~sirnaforge.models.off_target.MiRNADatabase | str, hits_per_species: dict[str, int] = <factory>, hits_per_candidate: dict[str, int] = <factory>, human_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, other_species_hits: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, total_candidates: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)])[source]ο
Bases:
BaseAggregatedSummarySummary of aggregated miRNA results across multiple candidates.
- mirna_database: MiRNADatabase | strο
- model_config = {'frozen': False}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
ZFN Modelsο
Pydantic models for Zinc Finger Nuclease (ZFN) design and off-target search.
- class sirnaforge.models.zfn.Strand(*values)[source]ο
-
Genome strand labels for reported sites.
- PLUS = '+'ο
- MINUS = '-'ο
- class sirnaforge.models.zfn.DimerMode(*values)[source]ο
-
What dimerization outcomes to consider when enumerating cut sites.
- HETERODIMER_ONLY = 'heterodimer_only'ο
- INCLUDE_HOMODIMERS = 'include_homodimers'ο
- class sirnaforge.models.zfn.ZFNAlgorithm(*values)[source]ο
-
Off-target ranking model family for ZFN sites.
- HOMOLOGY = 'homology'ο
- CONSERVED_G = 'conserved_g'ο
- ZFN_V2 = 'zfn_v2'ο
- class sirnaforge.models.zfn.MatchOrientation(*values)[source]ο
-
Orientation/ordering of half-sites at a genomic locus.
- LR = 'L...R'ο
- RL = 'R...L'ο
- LL = 'L...L'ο
- RR = 'R...R'ο
- class sirnaforge.models.zfn.IUPACMode(*values)[source]ο
-
How degenerate bases are handled in the query.
- NONE = 'none'ο
- ALLOW_IUPAC = 'allow_iupac'ο
- EXPAND_IUPAC = 'expand_iupac'ο
- class sirnaforge.models.zfn.ZFNSearchBackend(*values)[source]ο
-
Available scan backends for ZFN half-site search.
- EXHAUSTIVE_PYTHON = 'exhaustive_python'ο
- PYAHOCORASICK = 'pyahocorasick'ο
- FM_INDEX = 'fm_index'ο
- class sirnaforge.models.zfn.ZFNHalfSiteConstraints(*, min_len: Annotated[int, Ge(ge=6)] = 9, max_len: Annotated[int, Ge(ge=6)] = 18, max_mismatches: Annotated[int, Ge(ge=0), Le(le=6)] = 2, seed_len_from_fokI: Annotated[int | None, Ge(ge=1)] = 6, seed_max_mismatches: Annotated[int | None, Ge(ge=0)] = 1, iupac_mode: IUPACMode = IUPACMode.ALLOW_IUPAC, window_stride: Annotated[int, Ge(ge=1), Le(le=50)] = 1)[source]ο
Bases:
BaseModelConstraints on one ZFN half-site.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNSpacerConstraints(*, allowed_spacer_lengths: ~typing.Annotated[list[int], ~annotated_types.MinLen(min_length=1)] = <factory>, require_opposite_strands: bool = True)[source]ο
Bases:
BaseModelSpacer constraints between Left and Right half-sites at a cleavage site.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNOffTargetFilterCriteria(*, max_total_sites: Annotated[int | None, Ge(ge=0)] = None, max_exonic_sites: Annotated[int | None, Ge(ge=0)] = None, max_promoter_sites: Annotated[int | None, Ge(ge=0)] = None, min_site_score_to_count: Annotated[float, Ge(ge=0), Le(le=100)] = 70.0)[source]ο
Bases:
BaseModelCriteria to fail a candidate ZFN due to predicted off-target burden.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNScoringWeights(*, on_target_quality: Annotated[float, Ge(ge=0), Le(le=1)] = 0.35, off_target_specificity: Annotated[float, Ge(ge=0), Le(le=1)] = 0.45, manufacturability: Annotated[float, Ge(ge=0), Le(le=1)] = 0.2)[source]ο
Bases:
BaseModelWeights for composite ZFN candidate scoring.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNMutationType(*values)[source]ο
-
Allowed mutation categories for ZFN sub-finger constraints.
- SUBSTITUTION = 'substitution'ο
- TRANSITION = 'transition'ο
- TRANSVERSION = 'transversion'ο
- INSERTION = 'insertion'ο
- DELETION = 'deletion'ο
- class sirnaforge.models.zfn.ZFNSubfingerMutationConstraint(*, subfinger_index: Annotated[int, Ge(ge=1)], max_mutations: Annotated[int, Ge(ge=0)], mutation_types: Annotated[list[ZFNMutationType], MinLen(min_length=1)])[source]ο
Bases:
BaseModelMutation allowance definition for one ZFN sub-finger.
- mutation_types: list[ZFNMutationType]ο
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNDefaultSubfingerMutationConstraint(*, max_mutations: Annotated[int, Ge(ge=0)], mutation_types: Annotated[list[ZFNMutationType], MinLen(min_length=1)])[source]ο
Bases:
BaseModelDefault mutation allowance applied to each sub-finger.
- mutation_types: list[ZFNMutationType]ο
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNOverallMutationConstraint(*, max_mutations: Annotated[int, Ge(ge=0)], mutation_types: Annotated[list[ZFNMutationType], MinLen(min_length=1)])[source]ο
Bases:
BaseModelGlobal mutation allowance applied across all sub-fingers.
- mutation_types: list[ZFNMutationType]ο
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNMutationConstraints(*, subfinger_mutations: list[ZFNSubfingerMutationConstraint] = <factory>, default_subfinger_mutation: ZFNDefaultSubfingerMutationConstraint | None = None, overall_mutations: list[ZFNOverallMutationConstraint] = <factory>)[source]ο
Bases:
BaseModelComposite container for all ZFN sub-finger and global mutation budgets.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- subfinger_mutations: list[ZFNSubfingerMutationConstraint]ο
- default_subfinger_mutation: ZFNDefaultSubfingerMutationConstraint | Noneο
- overall_mutations: list[ZFNOverallMutationConstraint]ο
- class sirnaforge.models.zfn.ZFNShardingConfig(*, enabled: bool = True, chunk_size_bp: Annotated[int, ~annotated_types.Ge(ge=1)] = 12000000, overlap_bp: Annotated[int, ~annotated_types.Ge(ge=0)] = 50, chromosomes: list[str] = <factory>, max_workers: Annotated[int, ~annotated_types.Ge(ge=1), ~annotated_types.Le(le=128)] = 2, memory_budget_gb: Annotated[float | None, ~annotated_types.Gt(gt=0)] = None, memory_reserve_gb: Annotated[float, ~annotated_types.Ge(ge=0)] = 2.0, target_cpu_utilization: Annotated[float | None, ~annotated_types.Gt(gt=0), ~annotated_types.Le(le=1)] = None, max_cpu_workers: Annotated[int | None, ~annotated_types.Ge(ge=1), ~annotated_types.Le(le=128)] = None)[source]ο
Bases:
BaseModelOptional chromosome/chunk sharding controls for scalable ZFN search.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNDesignParameters(*, search_space_reference: str | None = 'ensembl_human_hg38_primary', search_space_fasta: str | None = None, search_space_index: str | None = None, search_backend: ZFNSearchBackend = ZFNSearchBackend.PYAHOCORASICK, left_half_site: str, right_half_site: str, half_site_constraints: ZFNHalfSiteConstraints = <factory>, spacer_constraints: ZFNSpacerConstraints = <factory>, dimer_mode: DimerMode = DimerMode.HETERODIMER_ONLY, algorithm: ZFNAlgorithm = ZFNAlgorithm.ZFN_V2, top_n_sites: Annotated[int, ~annotated_types.Ge(ge=1)] = 5000, report_n_sites: Annotated[int, ~annotated_types.Ge(ge=1)] = 200, off_target_filters: ZFNOffTargetFilterCriteria = <factory>, scoring: ZFNScoringWeights = <factory>, mutation_constraints: ZFNMutationConstraints | None = None, sharding: ZFNShardingConfig = <factory>)[source]ο
Bases:
BaseModelTop-level configuration for ZFN pair evaluation and off-target search.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- search_backend: ZFNSearchBackendο
- half_site_constraints: ZFNHalfSiteConstraintsο
- spacer_constraints: ZFNSpacerConstraintsο
- algorithm: ZFNAlgorithmο
- off_target_filters: ZFNOffTargetFilterCriteriaο
- scoring: ZFNScoringWeightsο
- mutation_constraints: ZFNMutationConstraints | Noneο
- sharding: ZFNShardingConfigο
- classmethod validate_dna_bases_and_iupac(v: str) str[source]ο
Validate half-sites as DNA/IUPAC strings.
- classmethod validate_half_site_lengths(v: str, info: ValidationInfo) str[source]ο
Validate half-site lengths against configured range.
- classmethod validate_search_space_source(v: str | None) str | None[source]ο
Normalize search-space reference keys.
- classmethod validate_search_space_fasta(v: str | None) str | None[source]ο
Normalize explicit FASTA path/URL strings.
- classmethod validate_search_space_index(v: str | None) str | None[source]ο
Normalize explicit search index path strings.
- canonical_search_contract() ZFNSearchContract[source]ο
Return canonical, JSON-serializable ZFN search contract for reports/workflows.
- class sirnaforge.models.zfn.ZFNSearchContract(*, left_half_site: str, right_half_site: str, allowed_spacer_lengths: list[int], max_mismatches_per_half_site: Annotated[int, Ge(ge=0)], seed_len_from_foki: Annotated[int | None, Ge(ge=1)] = None, seed_max_mismatches: Annotated[int | None, Ge(ge=0)] = None, dimer_mode: DimerMode, algorithm: ZFNAlgorithm, search_backend: ZFNSearchBackend, require_opposite_strands: bool, orientation_convention: str)[source]ο
Bases:
BaseModelCanonical internal contract for ZFN search/ranking behavior.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- algorithm: ZFNAlgorithmο
- search_backend: ZFNSearchBackendο
- class sirnaforge.models.zfn.GenomicAnnotationConfig(*, annotation_path: str | None = None, annotation_reference: str | None = None, cache_dir: str | None = None, promoter_upstream_bp: Annotated[int, Ge(ge=0)] = 2000, promoter_downstream_bp: Annotated[int, Ge(ge=0)] = 200)[source]ο
Bases:
BaseModelOptional annotation configuration for off-target site classification.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.zfn.ZFNOffTargetSite(*, site_id: str, chrom: str, start_1based: ~typing.Annotated[int, ~annotated_types.Ge(ge=1)], end_1based: ~typing.Annotated[int, ~annotated_types.Ge(ge=1)], strand: ~sirnaforge.models.zfn.Strand, orientation: ~sirnaforge.models.zfn.MatchOrientation, spacer_len: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], sequence: str, left_mismatches: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], right_mismatches: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], left_seed_mismatches: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, right_seed_mismatches: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, left_mismatch_positions: list[int] = <factory>, right_mismatch_positions: list[int] = <factory>, total_mismatches: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)], score: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)], score_components: dict[str, float] = <factory>, dimer_compatible: bool = True, region: ~typing.Literal['exon', 'promoter', 'intron', 'intergenic', 'unknown'] = 'unknown', nearest_gene: str | None = None, left_aligned: str, right_aligned: str)[source]ο
Bases:
BaseModelOne predicted cleavage site for a ZFN pair at a genomic locus.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- orientation: MatchOrientationο
- region: Literal['exon', 'promoter', 'intron', 'intergenic', 'unknown']ο
- class sirnaforge.models.zfn.ZFNCandidate(*, id: str, left_half_site: str, right_half_site: str, allowed_spacers: list[int], predicted_sites_total: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, predicted_sites_exonic: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, predicted_sites_promoter: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, worst_site_score: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, best_offtarget_score: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)] = None, passes_offtarget_filters: bool | str = True, component_scores: dict[str, float] = <factory>, composite_score: ~typing.Annotated[float, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=100)], top_offtargets: list[~sirnaforge.models.zfn.ZFNOffTargetSite] = <factory>)[source]ο
Bases:
BaseModelA ZFN pair candidate with summary metrics and composite score.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- top_offtargets: list[ZFNOffTargetSite]ο
- class sirnaforge.models.zfn.ZFNDesignResult(*, parameters: ~sirnaforge.models.zfn.ZFNDesignParameters, annotation: ~sirnaforge.models.zfn.GenomicAnnotationConfig | None = None, candidates: list[~sirnaforge.models.zfn.ZFNCandidate] = <factory>, off_target_sites: list[~sirnaforge.models.zfn.ZFNOffTargetSite] = <factory>, processing_time_s: ~typing.Annotated[float, ~annotated_types.Ge(ge=0)], tool_versions: dict[str, str] = <factory>)[source]ο
Bases:
BaseModelComplete results for ZFN pair evaluation and off-target search.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- parameters: ZFNDesignParametersο
- annotation: GenomicAnnotationConfig | Noneο
- candidates: list[ZFNCandidate]ο
- off_target_sites: list[ZFNOffTargetSite]ο
Transcript Annotation Modelsο
Pydantic models for transcript annotation data structures.
- class sirnaforge.models.transcript_annotation.Interval(*, seq_region_name: str, start: Annotated[int, Ge(ge=0)], end: Annotated[int, Ge(ge=0)], strand: int | None = None)[source]ο
Bases:
BaseModelGenomic interval with start, end, and optional strand information.
- model_config = {'frozen': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.transcript_annotation.TranscriptAnnotation(*, transcript_id: str, gene_id: str, symbol: str | None = None, biotype: str | None = None, seq_region_name: str, start: ~typing.Annotated[int, ~annotated_types.Ge(ge=1)], end: ~typing.Annotated[int, ~annotated_types.Ge(ge=1)], strand: int, gene_interval: ~sirnaforge.models.transcript_annotation.Interval | None = None, exons: list[~sirnaforge.models.transcript_annotation.Interval] = <factory>, cds: list[~sirnaforge.models.transcript_annotation.Interval] = <factory>, provider: str, endpoint: str | None = None, reference_choice: str | None = None)[source]ο
Bases:
BaseModelComprehensive transcript annotation from genomic databases.
Contains transcript metadata, genomic coordinates, exon/CDS structure, and source provenance for reproducibility.
- model_config = {'use_enum_values': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.transcript_annotation.TranscriptAnnotationBundle(*, transcripts: dict[str, ~sirnaforge.models.transcript_annotation.TranscriptAnnotation]=<factory>, unresolved: list[str] = <factory>, reference_choice: ReferenceChoice)[source]ο
Bases:
BaseModelCollection of transcript annotations with resolution tracking.
Bundles multiple transcript annotations from a single query, tracks which IDs were successfully resolved, and maintains reference provenance.
- transcripts: dict[str, TranscriptAnnotation]ο
- reference_choice: ReferenceChoiceο
- model_config = {'arbitrary_types_allowed': True, 'use_enum_values': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Variant Modelsο
Pydantic models for genomic variant data structures.
- class sirnaforge.models.variant.VariantMode(*values)[source]ο
-
Mode for how variants should be handled in siRNA design.
- TARGET = 'target'ο
- AVOID = 'avoid'ο
- BOTH = 'both'ο
- class sirnaforge.models.variant.VariantSource(*values)[source]ο
-
Trusted sources for variant data, ordered by priority.
- CLINVAR = 'clinvar'ο
- ENSEMBL = 'ensembl'ο
- DBSNP = 'dbsnp'ο
- LOCAL_VCF = 'local-vcf'ο
- class sirnaforge.models.variant.ClinVarSignificance(*values)[source]ο
-
ClinVar clinical significance classifications.
- PATHOGENIC = 'Pathogenic'ο
- LIKELY_PATHOGENIC = 'Likely pathogenic'ο
- UNCERTAIN_SIGNIFICANCE = 'Uncertain significance'ο
- LIKELY_BENIGN = 'Likely benign'ο
- BENIGN = 'Benign'ο
- CONFLICTING = 'Conflicting interpretations of pathogenicity'ο
- OTHER = 'Other'ο
- class sirnaforge.models.variant.EnsemblMapping(*, location: str, allele_string: str, assembly_name: str, seq_region_name: str, strand: int, start: int, end: int, coord_system: str, **extra_data: Any)[source]ο
Bases:
BaseModelEnsembl variation mapping information.
Represents genomic mapping data for a variant from the Ensembl Variation API. Contains coordinate and allele information for a specific genomic location.
- model_config = {'extra': 'allow'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.variant.EnsemblPopulationFrequency(*, population: str, frequency: Annotated[float | None, Ge(ge=0), Le(le=1)], allele_count: Annotated[int | None, Ge(ge=0)] = None, allele_number: Annotated[int | None, Ge(ge=0)] = None, allele: str | None = None, **extra_data: Any)[source]ο
Bases:
BaseModelPopulation frequency data from Ensembl.
Contains allele frequency information for a specific population from sources like 1000 Genomes, gnomAD, ExAC, etc.
- model_config = {'extra': 'allow'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.variant.EnsemblVariationResponse(*, name: str, var_class: str, source: str, most_severe_consequence: str | None, MAF: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)], minor_allele: str | None, ambiguity: str, mappings: list[~sirnaforge.models.variant.EnsemblMapping], clinical_significance: list[str] | None, synonyms: list[str] | None, evidence: list[str] | None, populations: list[~sirnaforge.models.variant.EnsemblPopulationFrequency | None] = <factory>, **extra_data: ~typing.Any)[source]ο
Bases:
BaseModelResponse model for Ensembl Variation API.
Represents the complete response from the Ensembl REST API variation endpoint. Contains variant metadata, mappings, frequencies, and clinical information.
- model_config = {'extra': 'allow'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- mappings: list[EnsemblMapping]ο
- populations: list[EnsemblPopulationFrequency | None]ο
- class sirnaforge.models.variant.ClinVarVariationResponse(*, uid: str, obj_type: str | None, accession: str | None, title: str | None, germline_classification: dict | None, clinical_impact_classification: dict | None, variation_set: list[dict] | None, genes: list[dict] | None, molecular_consequence_list: list[str] | None, **extra_data: Any)[source]ο
Bases:
BaseModelResponse model for ClinVar variation summary.
Represents the response from NCBI ClinVar E-utilities esummary endpoint. Contains clinical significance, variation details, and associated conditions.
- model_config = {'extra': 'allow'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.models.variant.VariantRecord(*, id: str | None = None, chr: str, pos: ~typing.Annotated[int, ~annotated_types.Ge(ge=1)], ref: ~typing.Annotated[str, ~annotated_types.MinLen(min_length=1)], alt: ~typing.Annotated[str, ~annotated_types.MinLen(min_length=1)], assembly: str = 'GRCh38', sources: list[~sirnaforge.models.variant.VariantSource] = <factory>, clinvar_significance: ~sirnaforge.models.variant.ClinVarSignificance | None = None, af: ~typing.Annotated[float | None, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=1)] = None, population_afs: dict[str, float] = <factory>, annotations: dict[str, ~typing.Any] = <factory>, provenance: dict[str, ~typing.Any] = <factory>)[source]ο
Bases:
BaseModelComplete variant record with annotations from multiple sources.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- sources: list[VariantSource]ο
- clinvar_significance: ClinVarSignificance | Noneο
- get_max_population_af() float | None[source]ο
Get the maximum allele frequency across all populations.
- Returns:
Maximum population-specific AF, or None if no population data available
- get_effective_af_for_mode(mode: VariantMode) float | None[source]ο
Get the effective allele frequency based on variant mode.
For βavoidβ mode: Use max population AF if available (to avoid SNPs prevalent in any geographic group), otherwise use global AF.
For βtargetβ or βbothβ modes: Use global AF (targets most common alleles).
- Parameters:
mode β Variant mode (target/avoid/both)
- Returns:
Effective allele frequency for filtering, or None if no AF data
- get_primary_source() VariantSource | None[source]ο
Get the highest priority source for this variant.
- class sirnaforge.models.variant.VariantQueryType(*values)[source]ο
-
Types of variant query identifiers.
- RSID = 'rsid'ο
- COORDINATE = 'coordinate'ο
- HGVS = 'hgvs'ο
- class sirnaforge.models.variant.VariantQuery(*, raw_input: str, query_type: VariantQueryType, rsid: str | None = None, chr: str | None = None, pos: Annotated[int | None, Ge(ge=1)] = None, ref: str | None = None, alt: str | None = None, hgvs: str | None = None, assembly: str = 'GRCh38')[source]ο
Bases:
BaseModelParsed variant query with normalized components.
- model_config = {'extra': 'forbid'}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- query_type: VariantQueryTypeο
Validation Schemasο
Pandera schemas for siRNAforge data validation.
This module defines pandera schemas for validating the structure and content of various table-like outputs from the siRNAforge pipeline.
Modern schemas using class-based approach with type annotations for improved type safety, error reporting, and maintainability.
Use schemas: MySchema.validate(df) - validation errors provide detailed feedback.
- class sirnaforge.models.schemas.SchemaConfig[source]ο
Bases:
objectCommon configuration settings for all pandera schemas.
Provides consistent validation behavior across all siRNAforge data schemas with type coercion, strict column checking, and flexible column ordering.
- coerce = Trueο
- strict = Trueο
- ordered = Falseο
- class sirnaforge.models.schemas.SiRNACandidateSchema(*args, **kwargs)[source]ο
Bases:
DataFrameModelValidation schema for siRNA candidate results (CSV output).
Ensures data integrity and biological validity of siRNA design results with comprehensive checks for sequence composition, thermodynamic parameters, and scoring metrics. Includes optimal value ranges for key metrics based on research-backed thermodynamic principles.
Expected columns include sequences, thermodynamic scores (asymmetry, MFE, duplex stability), off-target counts, and composite quality scores.
- class Config[source]ο
Bases:
SchemaConfigSchema configuration with improved error reporting.
- description = 'siRNA candidate validation schema'ο
- title = 'SiRNA Design Results'ο
- add_missing_columns = Trueο
- strict = Falseο
- name = 'SiRNACandidateSchema'ο
- on_target_hits: Series[Int64Dtype] = 'on_target_hits'ο
- ortholog_hits: Series[Int64Dtype] = 'ortholog_hits'ο
- repeat_hits: Series[Int64Dtype] = 'repeat_hits'ο
- repeat_flagged: Series[BooleanDtype] = 'repeat_flagged'ο
- seed_7mer_hits: Series[Int64Dtype] = 'seed_7mer_hits'ο
- seed_8mer_hits: Series[Int64Dtype] = 'seed_8mer_hits'ο
- scored_after_screening: Series[BooleanDtype] = 'scored_after_screening'ο
- classmethod check_passes_filters_values(df: DataFrame) bool[source]ο
Ensure passes_filters contains allowed filter status values.
Derives the allow-list from SiRNACandidate.FilterStatus enum to prevent drift.
- class sirnaforge.models.schemas.ORFValidationSchema(*args, **kwargs)[source]ο
Bases:
DataFrameModelValidation schema for open reading frame analysis results (tab-delimited output).
Validates ORF detection and characterization results with proper handling of nullable fields for cases where no valid ORF is found. Includes metrics for transcript composition, ORF boundaries, codon usage, and GC content within coding regions.
Used to validate outputs from ORF analysis tools and ensure data consistency for downstream siRNA target validation.
- class sirnaforge.models.schemas.OffTargetHitsSchema(*args, **kwargs)[source]ο
Bases:
DataFrameModelDEPRECATED: Use MiRNAAlignmentSchema or GenomeAlignmentSchema instead.
Legacy validation schema for off-target analysis results (TSV output). This schema is too generic and doesnβt match actual BWA output format.
Migration Guide: - For miRNA seed analysis β Use MiRNAAlignmentSchema - For genome/transcriptome β Use GenomeAlignmentSchema
Will be removed in v0.3.0.
- class sirnaforge.models.schemas.MiRNAAlignmentSchema(*args, **kwargs)[source]ο
Bases:
DataFrameModelPandera schema for miRNA seed match alignment results (TSV/DataFrame).
Validates tabular data from BWA-MEM2 miRNA seed analysis. Each row represents one alignment between an siRNA candidate and a miRNA seed region.
Use this for: - Reading *_mirna_analysis.tsv files - Validating pandas DataFrames from miRNA analysis - Bulk operations on miRNA alignment results
Corresponding Pydantic model: models.off_target.MiRNAHit (for single rows)
- class Config[source]ο
Bases:
SchemaConfigSchema configuration.
- description = 'miRNA seed match alignment results'ο
- title = 'miRNA Alignment DataFrame'ο
- strict = Trueο
- coerce = Trueο
- name = 'MiRNAAlignmentSchema'ο
- as_score: Series[Int64Dtype] = 'as_score'ο
- class sirnaforge.models.schemas.GenomeAlignmentSchema(*args, **kwargs)[source]ο
Bases:
DataFrameModelPandera schema for genome/transcriptome off-target alignment results (TSV/DataFrame).
Validates tabular data from BWA-MEM2 genome/transcriptome analysis. Each row represents one potential off-target alignment in the genome.
Use this for: - Reading *_analysis.tsv files from genome alignment - Validating pandas DataFrames from transcriptome off-target analysis - Bulk operations on genome alignment results
Corresponding Pydantic model: models.off_target.OffTargetHit (for single rows)
- class Config[source]ο
Bases:
SchemaConfigSchema configuration.
- description = 'Genome/transcriptome off-target alignment results'ο
- title = 'Genome Alignment DataFrame'ο
- strict = Trueο
- coerce = Trueο
- name = 'GenomeAlignmentSchema'ο
- as_score: Series[Int64Dtype] = 'as_score'ο
Data Accessο
Base Data Classesο
Shared base classes and utilities for genomic data analysis.
- exception sirnaforge.data.base.DatabaseError(message: str, database: str | None = None)[source]ο
Bases:
ExceptionBase exception for database-related errors.
- exception sirnaforge.data.base.DatabaseAccessError(message: str, database: str | None = None)[source]ο
Bases:
DatabaseErrorException for network/access issues (firewall, timeout, server down).
- exception sirnaforge.data.base.GeneNotFoundError(query: str, database: str | None = None)[source]ο
Bases:
DatabaseErrorException for when a gene is not found in the database.
- class sirnaforge.data.base.DatabaseType(*values)[source]ο
-
Supported genomic databases.
- ENSEMBL = 'ensembl'ο
- REFSEQ = 'refseq'ο
- GENCODE = 'gencode'ο
- class sirnaforge.data.base.SequenceType(*values)[source]ο
-
Types of sequence data that can be retrieved.
- CDNA = 'cdna'ο
- CDS = 'cds'ο
- PROTEIN = 'protein'ο
- GENOMIC = 'genomic'ο
- class sirnaforge.data.base.GeneInfo(*, gene_id: str, gene_name: str | None = None, gene_type: str | None = None, chromosome: str | None = None, start: int | None = None, end: int | None = None, strand: int | None = None, description: str | None = None, database: DatabaseType)[source]ο
Bases:
BaseModelGene information model.
- database: DatabaseTypeο
- model_config = {'use_enum_values': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.data.base.TranscriptInfo(*, transcript_id: str, transcript_name: str | None = None, transcript_type: str | None = None, gene_id: str, gene_name: str | None = None, sequence: str | None = None, length: int | None = None, database: DatabaseType, is_canonical: bool = False)[source]ο
Bases:
BaseModelTranscript information model.
- database: DatabaseTypeο
- model_config = {'use_enum_values': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.data.base.AbstractDatabaseClient(timeout: int = 30)[source]ο
Bases:
ABCAbstract base class for database clients.
- abstractmethod async search_gene(query: str, include_sequence: bool = True) tuple[GeneInfo | None, list[TranscriptInfo]][source]ο
Search for a gene and return gene info and transcripts.
- Parameters:
query β Gene ID, gene name, or transcript ID
include_sequence β Whether to fetch transcript sequences
- Returns:
Tuple of (gene_info, transcripts)
- Raises:
DatabaseAccessError β For network/server access issues
GeneNotFoundError β When gene is not found in database
- abstractmethod async get_sequence(identifier: str, sequence_type: SequenceType = SequenceType.CDNA) str[source]ο
Get sequence for a specific identifier.
- Parameters:
identifier β Gene ID, transcript ID, etc.
sequence_type β Type of sequence to retrieve
- Returns:
Sequence string
- Raises:
DatabaseAccessError β For network/server access issues
GeneNotFoundError β When identifier is not found in database
- abstract property database_type: DatabaseTypeο
Return the database type this client handles.
- property query_species: strο
Canonical organism whose transcripts a gene query against this database returns.
Every concrete client here is wired to exactly one organism β
EnsemblClientpinsspecies=homo_sapienson every lookup,RefSeqClientappendsAND Homo sapiens[Organism]to every esearch term, andGencodeClienttargets the human GENCODE release β so the organism of a retrieved transcript set is a property of where the transcripts came from. Callers that need the βquery speciesβ must read it from here rather than infer it from the off-target species list, which is an unordered set of genomes to screen against and says nothing about the target.
- class sirnaforge.data.base.AbstractTranscriptAnnotationClient(timeout: int = 30)[source]ο
Bases:
ABCAbstract base class for transcript annotation clients.
Purpose and Scope: Provides genomic annotation metadata (exon/CDS structure, coordinates, biotype) WITHOUT fetching full transcript sequences. This is complementary to, not overlapping with, AbstractDatabaseClient which focuses on sequence retrieval.
Key Differences from GeneSearcher/AbstractDatabaseClient:
Focus: Structural annotations (exons, CDS intervals, genomic coordinates) vs. sequence data (cDNA, CDS, protein sequences)
Use Case: Enriching existing transcript metadata with genomic context vs. discovering and retrieving transcripts with sequences
Query Patterns: - By stable IDs: fetch_by_ids([βENST00000269305β]) - By genomic regions: fetch_by_regions([β17:7661779-7687550β]) vs. GeneSearcher which queries by gene name/symbol
Caching Strategy: In-memory LRU cache with TTL for transient annotation data vs. ReferenceManagerβs persistent file cache for large sequence datasets
When to Use: - Need exon/CDS boundaries for visualization or analysis - Need genomic coordinates for variant mapping - Need biotype information without full sequence download - Need to query multiple transcripts in a genomic region
When to Use GeneSearcher Instead: - Need transcript sequences for siRNA design - Need to discover transcripts by gene name/symbol - Need protein sequences or translations
- __init__(timeout: int = 30)[source]ο
Initialize transcript annotation client.
- Parameters:
timeout β Request timeout in seconds
- abstractmethod async fetch_by_ids(ids: list[str], *, species: str, reference: ReferenceChoice) TranscriptAnnotationBundle[source]ο
Fetch transcript annotations by stable IDs.
- Parameters:
ids β List of transcript or gene IDs (e.g., ENST00000269305, TP53)
species β Species name (e.g., βhomo_sapiensβ, βhumanβ)
reference β Reference assembly/release choice
- Returns:
TranscriptAnnotationBundle containing resolved annotations
- Raises:
DatabaseAccessError β For network/server access issues
- abstractmethod async fetch_by_regions(regions: list[str], *, species: str, reference: ReferenceChoice) TranscriptAnnotationBundle[source]ο
Fetch transcript annotations by genomic regions.
- Parameters:
regions β List of genomic regions in format βchr:start-endβ (e.g., β17:7661779-7687550β)
species β Species name (e.g., βhomo_sapiensβ, βhumanβ)
reference β Reference assembly/release choice
- Returns:
TranscriptAnnotationBundle containing all transcripts overlapping regions
- Raises:
DatabaseAccessError β For network/server access issues
- class sirnaforge.data.base.EnsemblClient(timeout: int = 30, base_url: str = 'https://rest.ensembl.org')[source]ο
Bases:
AbstractDatabaseClientClient for Ensembl REST API interactions.
- __init__(timeout: int = 30, base_url: str = 'https://rest.ensembl.org')[source]ο
Initialize Ensembl client.
- property database_type: DatabaseTypeο
Return the database type this client handles.
- async search_gene(query: str, include_sequence: bool = True) tuple[GeneInfo | None, list[TranscriptInfo]][source]ο
Search for a gene and return gene info and transcripts.
- async get_sequence(identifier: str, sequence_type: SequenceType = SequenceType.CDNA, headers: dict | None = None) str[source]ο
Get sequence from Ensembl REST API.
- Parameters:
identifier β Gene ID, transcript ID, etc.
sequence_type β Type of sequence to retrieve
headers β Optional HTTP headers
- Returns:
Sequence string
- Raises:
DatabaseAccessError β For network/server access issues
GeneNotFoundError β When identifier is not found in database
- class sirnaforge.data.base.RefSeqClient(timeout: int = 30, base_url: str = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils')[source]ο
Bases:
AbstractDatabaseClientClient for RefSeq database via NCBI E-utilities API.
- __init__(timeout: int = 30, base_url: str = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils')[source]ο
Initialize RefSeq client.
- property database_type: DatabaseTypeο
Return the database type this client handles.
- async search_gene(query: str, include_sequence: bool = True) tuple[GeneInfo | None, list[TranscriptInfo]][source]ο
Search for a gene and return gene info and transcripts.
- async get_sequence(identifier: str, _sequence_type: SequenceType = SequenceType.CDNA) str[source]ο
Get sequence for a specific identifier from NCBI.
- class sirnaforge.data.base.GencodeClient(timeout: int = 30)[source]ο
Bases:
AbstractDatabaseClientClient for GENCODE database.
- property database_type: DatabaseTypeο
Return the database type this client handles.
- async search_gene(query: str, include_sequence: bool = True) tuple[GeneInfo | None, list[TranscriptInfo]][source]ο
Search for a gene and return gene info and transcripts.
- async get_sequence(_identifier: str, _sequence_type: SequenceType = SequenceType.CDNA) str[source]ο
Get sequence for a specific identifier from GENCODE.
- class sirnaforge.data.base.SequenceUtils[source]ο
Bases:
objectUtility functions for sequence analysis.
- class sirnaforge.data.base.FastaUtils[source]ο
Bases:
objectUtility functions for FASTA file operations.
- static save_sequences_fasta(sequences: list[tuple[str, str]], output_path: str | Path, line_length: int = 80) None[source]ο
Save sequences to FASTA format.
- Parameters:
sequences β List of (header, sequence) tuples
output_path β Output file path
line_length β Maximum line length for sequence
- static read_fasta(file_path: str | Path) list[tuple[str, str]][source]ο
Read sequences from FASTA file.
- Parameters:
file_path β Path to FASTA file
- Returns:
List of (header, sequence) tuples
- static parse_fasta_to_dict(file_path: str | Path) dict[str, str][source]ο
Parse FASTA file into a dictionary.
- Parameters:
file_path β Path to FASTA file
- Returns:
Dictionary mapping sequence names to sequences
- static write_dict_to_fasta(sequences: dict[str, str], output_path: str | Path) None[source]ο
Write sequences dictionary to FASTA format.
- Parameters:
sequences β Dictionary of sequence name -> sequence
output_path β Output file path
- static validate_sirna_sequences(sequences: dict[str, str], expected_length: int = 21) dict[str, str][source]ο
Validate siRNA sequences for correct length and nucleotide content.
- Parameters:
sequences β Dictionary of sequence name -> sequence
expected_length β Expected siRNA length
- Returns:
Dictionary of valid sequences
- sirnaforge.data.base.get_database_display_name(database: DatabaseType) str[source]ο
Get display name for database, handling both enum and string values.
Annotation Managerο
Genomic annotation manager built on the transcriptome/reference cache pipeline.
- class sirnaforge.data.annotation_manager.AnnotationSource(name: str, url: str, species: str, format: str = 'fasta', compressed: bool = False, description: str = '')[source]ο
Bases:
TranscriptomeSourceAnnotation-specific source model.
- class sirnaforge.data.annotation_manager.AnnotationManager(cache_dir: str | Path | None = None, cache_ttl_days: int = 30)[source]ο
Bases:
TranscriptomeManagerAnnotation manager with caching and no index-building side effects.
- SOURCE_LABEL = 'annotation'ο
Gene Searchο
Gene search and sequence retrieval from multiple databases.
- class sirnaforge.data.gene_search.GeneSearchResult(*, query: str, database: DatabaseType, gene_info: GeneInfo | None = None, transcripts: list[TranscriptInfo] = <factory>, error: str | None = None, is_access_error: bool = False)[source]ο
Bases:
BaseModelComplete gene search result.
- database: DatabaseTypeο
- transcripts: list[TranscriptInfo]ο
- model_config = {'use_enum_values': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.data.gene_search.GeneSearcher(timeout: int = 30, max_retries: int = 3)[source]ο
Bases:
objectSearch genes and retrieve sequences from genomic databases using multiple clients.
- __init__(timeout: int = 30, max_retries: int = 3)[source]ο
Initialize gene searcher with database clients.
- Parameters:
timeout β Request timeout in seconds
max_retries β Maximum retry attempts
- clients: dict[DatabaseType, AbstractDatabaseClient]ο
- get_client(database: DatabaseType) AbstractDatabaseClient[source]ο
Get the client for a specific database.
- query_species(database: DatabaseType | None = None) str[source]ο
Canonical organism whose transcripts a gene query returns.
This is the authoritative βquery speciesβ: the organism the retrieved target transcripts belong to, read off the database that retrieved them rather than guessed from the off-target species list.
database=Noneasks the questionsearch_gene_with_fallbackasks β any of the clients may serve the query. Every client is single-organism and they all agree today, so the fallback cannot change the answer; if that ever stops being true the disagreement surfaces here (the requested databaseβs answer wins and a warning is logged) instead of silently mislabelling the target.- Parameters:
database β Database the caller intends to query, or None for the fallback chain.
- Returns:
Canonical species name (e.g.
"human").
- async search_gene_with_fallback(query: str, include_sequence: bool = True) GeneSearchResult[source]ο
Search for a gene with automatic fallback to other databases.
Tries databases in order: Ensembl -> RefSeq -> GENCODE Falls back to next database only if access is blocked (not if gene is not found).
- Parameters:
query β Gene ID, gene name, or transcript ID
include_sequence β Whether to fetch transcript sequences
- Returns:
GeneSearchResult from the first accessible database
- async search_gene(query: str, database: DatabaseType | None = None, include_sequence: bool = True) GeneSearchResult[source]ο
Search for a gene and retrieve its isoforms.
- Parameters:
query β Gene ID, gene name, or transcript ID
database β Database to search (defaults to Ensembl)
include_sequence β Whether to fetch transcript sequences
- Returns:
GeneSearchResult with gene info and transcripts
- async search_multiple_databases(query: str, databases: list[DatabaseType] | None = None, include_sequence: bool = True) list[GeneSearchResult][source]ο
Search across multiple databases.
- Parameters:
query β Gene ID, gene name, or transcript ID
databases β List of databases to search
include_sequence β Whether to fetch sequences
- Returns:
List of search results from each database
- save_transcripts_fasta(transcripts: list[TranscriptInfo], output_path: str | Path, include_metadata: bool = True) None[source]ο
Save transcripts to FASTA format using shared utility.
- Parameters:
transcripts β List of transcript information
output_path β Output file path
include_metadata β Include metadata in FASTA headers
- sirnaforge.data.gene_search.search_gene_sync(query: str, database: DatabaseType = DatabaseType.ENSEMBL, include_sequence: bool = True) GeneSearchResult[source]ο
Synchronous wrapper for gene search.
- sirnaforge.data.gene_search.search_gene_with_fallback_sync(query: str, include_sequence: bool = True) GeneSearchResult[source]ο
Synchronous wrapper for gene search with fallback.
- sirnaforge.data.gene_search.search_multiple_databases_sync(query: str, databases: list[DatabaseType] | None = None, include_sequence: bool = True) list[GeneSearchResult][source]ο
Synchronous wrapper for multi-database search.
ORF Analysisο
ORF analysis and sequence validation for transcript sequences.
- class sirnaforge.data.orf_analysis.ORFInfo(*, start_pos: int, end_pos: int, length: int, reading_frame: int, start_codon: str, stop_codon: str, has_valid_start: bool, has_valid_stop: bool, is_complete: bool, gc_content: float)[source]ο
Bases:
BaseModelInformation about an Open Reading Frame.
- model_config = {'frozen': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.data.orf_analysis.SequenceAnalysis(*, transcript_id: str, sequence_type: SequenceType, sequence_length: int, gc_content: float, orfs: list[ORFInfo], longest_orf: ORFInfo | None = None, has_valid_orf: bool = False, cds_sequence: str | None = None, protein_sequence: str | None = None, cds_start: int | None = None, cds_end: int | None = None, utr5_length: int | None = None, utr3_length: int | None = None, sequence_region: str | None = None)[source]ο
Bases:
BaseModelComplete sequence analysis including ORF information.
- sequence_type: SequenceTypeο
- model_config = {'use_enum_values': True}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.data.orf_analysis.ORFAnalyzer(database_client: AbstractDatabaseClient | None = None)[source]ο
Bases:
objectAnalyze ORFs in transcript sequences and validate sequence types.
- __init__(database_client: AbstractDatabaseClient | None = None)[source]ο
Initialize ORF analyzer.
- Parameters:
database_client β Optional database client for retrieving additional sequence types
- find_orfs(sequence: str, min_length: int = 150) list[ORFInfo][source]ο
Find all ORFs in a sequence (all 3 reading frames).
- async get_additional_sequence(transcript_id: str, sequence_type: SequenceType) str | None[source]ο
Retrieve specific sequence type using the database client if available.
- Parameters:
transcript_id β Transcript identifier
sequence_type β Type of sequence to retrieve
- Returns:
Sequence string or None if not available or client not provided
- async analyze_transcript(transcript: TranscriptInfo) SequenceAnalysis[source]ο
Perform complete ORF analysis of a transcript.
- async analyze_transcripts(transcripts: list[TranscriptInfo]) dict[str, SequenceAnalysis][source]ο
Analyze multiple transcripts.
- sirnaforge.data.orf_analysis.create_orf_analyzer(database_client: AbstractDatabaseClient | None = None) ORFAnalyzer[source]ο
Create an ORF analyzer with optional database client.
- Parameters:
database_client β Optional database client for retrieving additional sequence types
- Returns:
ORFAnalyzer instance
- async sirnaforge.data.orf_analysis.analyze_multiple_transcript_orfs(transcripts: list[TranscriptInfo], database_client: AbstractDatabaseClient | None = None) dict[str, SequenceAnalysis][source]ο
Analyze ORFs in multiple transcripts.
- Parameters:
transcripts β List of transcripts to analyze
database_client β Optional database client for additional sequence retrieval
- Returns:
Dictionary mapping transcript IDs to SequenceAnalysis results
Genome Managerο
Genome reference manager built on the composable transcriptome manager core.
- class sirnaforge.data.genome_manager.GenomeManager(cache_dir: str | Path | None = None, cache_ttl_days: int = 30, auto_build_indices: bool = True)[source]ο
Bases:
TranscriptomeManagerGenome FASTA manager with caching and optional BWA-MEM2 index building.
- SOURCE_LABEL = 'genome'ο
- SOURCES = {'ensembl_human_hg38_primary': TranscriptomeSource(name='ensembl_human_hg38_primary', url='https://ftp.ensembl.org/pub/current_fasta/homo_sapiens/dna/Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz', species='human', format='fasta', compressed=True, description='Ensembl human GRCh38 primary assembly genomic reference'), 'ensembl_macaque_mmul10_toplevel': TranscriptomeSource(name='ensembl_macaque_mmul10_toplevel', url='https://ftp.ensembl.org/pub/current_fasta/macaca_mulatta/dna/Macaca_mulatta.Mmul_10.dna.toplevel.fa.gz', species='macaque', format='fasta', compressed=True, description='Ensembl rhesus macaque Mmul_10 toplevel assembly genomic reference'), 'ensembl_mouse_grcm39_primary': TranscriptomeSource(name='ensembl_mouse_grcm39_primary', url='https://ftp.ensembl.org/pub/current_fasta/mus_musculus/dna/Mus_musculus.GRCm39.dna.primary_assembly.fa.gz', species='mouse', format='fasta', compressed=True, description='Ensembl mouse GRCm39 primary assembly genomic reference'), 'ensembl_rat_grcr8_toplevel': TranscriptomeSource(name='ensembl_rat_grcr8_toplevel', url='https://ftp.ensembl.org/pub/current_fasta/rattus_norvegicus/dna/Rattus_norvegicus.GRCr8.dna.toplevel.fa.gz', species='rat', format='fasta', compressed=True, description='Ensembl rat GRCr8 toplevel assembly genomic reference')}ο
- __init__(cache_dir: str | Path | None = None, cache_ttl_days: int = 30, auto_build_indices: bool = True)[source]ο
Initialize genome manager.
- Parameters:
cache_dir β Directory for genome cache
cache_ttl_days β Cache time-to-live in days
auto_build_indices β Automatically build BWA-MEM2 indices when missing
Reference Managerο
Base Reference Database Manager for shared caching functionality.
This module provides the foundation for managing reference databases (miRNA, transcriptome, genome) with automatic caching, download management, and integrity validation.
- class sirnaforge.data.reference_manager.ReferenceSource(name: str, url: str, species: str, format: str = 'fasta', compressed: bool = False, description: str = '')[source]ο
Bases:
objectBase configuration for a reference database source.
- class sirnaforge.data.reference_manager.CacheMetadata(source: ReferenceSource, downloaded_at: str, file_size: int, checksum: str, file_path: str, version: str = '1.0', extra: dict[str, Any] | None = None)[source]ο
Bases:
objectMetadata for cached reference files.
- source: ReferenceSourceο
- classmethod from_dict(data: dict[str, ~typing.Any], source_class: type[~sirnaforge.data.reference_manager.ReferenceSource] = <class 'sirnaforge.data.reference_manager.ReferenceSource'>) CacheMetadata[source]ο
Create CacheMetadata from dictionary.
- Parameters:
data β Dictionary containing metadata
source_class β Class to use for source (allows subclasses)
- class sirnaforge.data.reference_manager.ReferenceManager(cache_subdir: str, cache_dir: str | Path | None = None, cache_ttl_days: int = 30, artifact_class: str | None = None)[source]ο
-
Base class for reference database managers with caching support.
This provides common functionality for: - Cache directory management with multiple fallback locations - File downloading with retry and progress - Checksum validation - TTL-based cache invalidation - Metadata persistence
Subclasses should implement source-specific operations like filtering, indexing, or multi-source aggregation.
- __init__(cache_subdir: str, cache_dir: str | Path | None = None, cache_ttl_days: int = 30, artifact_class: str | None = None)[source]ο
Initialize the reference manager.
- Parameters:
cache_subdir β Subdirectory name under cache root (e.g., βmirnaβ, βtranscriptomesβ)
cache_dir β Directory for caching databases (default: ~/.cache/sirnaforge/{cache_subdir})
cache_ttl_days β Cache time-to-live in days
artifact_class β Producer-version scope for this cache (default: cache_subdir). One subdirectory holds one kind of artifact, so the subdirectory name is also the natural invalidation scope; override only when two managers share a directory but not a producer.
- clear_cache(confirm: bool = False) dict[str, Any][source]ο
Clear all cached files for this manager.
By default this only reports what would be removed. Set confirm=True to actually delete files.
- is_producer_version_current(meta: CacheMetadata) bool[source]ο
Whether meta was written by the producer version this build ships.
Public because it is the one question every cache consumer needs to be able to ask (and test) directly, independently of TTL and checksums.
- stale_producer_entries() list[str][source]ο
Cache keys whose recorded producer version is no longer current.
Transcriptome Managerο
Transcriptome Database Manager with local caching and automatic index building.
This module provides a clean interface for downloading, caching, and managing transcriptome FASTA files with automatic BWA-MEM2 index building and cache management.
- class sirnaforge.data.transcriptome_manager.TranscriptomeSource(name: str, url: str, species: str, format: str = 'fasta', compressed: bool = False, description: str = '')[source]ο
Bases:
ReferenceSourceTranscriptome-specific database source configuration.
Inherits from ReferenceSource with transcriptome-specific extensions.
- class sirnaforge.data.transcriptome_manager.TranscriptomeManager(cache_dir: str | Path | None = None, cache_ttl_days: int = 90, auto_build_indices: bool = True, local_content_dedupe: bool = True, cache_subdir: str = 'transcriptomes', sources: dict[str, TranscriptomeSource] | None = None, source_label: str | None = None)[source]ο
Bases:
ReferenceManager[TranscriptomeSource]Transcriptome database manager with caching and automatic BWA-MEM2 index building.
- SOURCE_LABEL = 'transcriptome'ο
- INDEX_SUFFIXES = ('.0123', '.amb', '.ann', '.bwt.2bit.64', '.pac')ο
- FILTER_URI_FRAGMENT = '#filters='ο
- UNREMOVABLE_INDEX_KEY = 'unremovable_stale_index'ο
- SOURCES = {'ensembl_human_cdna': TranscriptomeSource(name='ensembl_cdna', url='https://ftp.ensembl.org/pub/current_fasta/homo_sapiens/cdna/Homo_sapiens.GRCh38.cdna.all.fa.gz', species='human', format='fasta', compressed=True, description='Ensembl human cDNA sequences (GRCh38)'), 'ensembl_macaque_cdna': TranscriptomeSource(name='ensembl_cdna', url='https://ftp.ensembl.org/pub/current_fasta/macaca_mulatta/cdna/Macaca_mulatta.Mmul_10.cdna.all.fa.gz', species='macaque', format='fasta', compressed=True, description='Ensembl rhesus macaque cDNA sequences (Mmul_10)'), 'ensembl_mouse_cdna': TranscriptomeSource(name='ensembl_cdna', url='https://ftp.ensembl.org/pub/current_fasta/mus_musculus/cdna/Mus_musculus.GRCm39.cdna.all.fa.gz', species='mouse', format='fasta', compressed=True, description='Ensembl mouse cDNA sequences (GRCm39)'), 'ensembl_rat_cdna': TranscriptomeSource(name='ensembl_cdna', url='https://ftp.ensembl.org/pub/current_fasta/rattus_norvegicus/cdna/Rattus_norvegicus.GRCr8.cdna.all.fa.gz', species='rat', format='fasta', compressed=True, description='Ensembl rat cDNA sequences (GRCr8)')}ο
- __init__(cache_dir: str | Path | None = None, cache_ttl_days: int = 90, auto_build_indices: bool = True, local_content_dedupe: bool = True, cache_subdir: str = 'transcriptomes', sources: dict[str, TranscriptomeSource] | None = None, source_label: str | None = None)[source]ο
Initialize the transcriptome database manager.
- Parameters:
cache_dir β Directory for caching transcriptomes (default: ~/.cache/sirnaforge/transcriptomes)
cache_ttl_days β Cache time-to-live in days (default: 90 days for large files)
auto_build_indices β Automatically build BWA-MEM2 indices when missing
local_content_dedupe β Reuse cached local files by content hash across different input paths
cache_subdir β Cache subdirectory override for composable manager reuse
sources β Optional source dictionary override
source_label β Optional source label used in status/error reporting
- sources: dict[str, TranscriptomeSource]ο
- describe_source_status(source_name: str) dict[str, Any][source]ο
Return cache metadata for a configured source.
- describe_sources_status(source_names: list[str] | tuple[str, ...] | None = None) list[dict[str, Any]][source]ο
Return cache statuses for multiple transcriptome sources.
- get_transcriptome(source_name: str, force_refresh: bool = False, build_index: bool = True) dict[str, Path] | None[source]ο
Get transcriptome database, downloading and building index if needed.
- Parameters:
source_name β Pre-configured source name (e.g., βensembl_human_cdnaβ)
force_refresh β Force re-download even if cached
build_index β Build BWA-MEM2 index if missing
- Returns:
Dictionary with βfastaβ and optionally βindexβ paths, or None if failed
- get_custom_transcriptome(fasta_path: str | Path, build_index: bool = True, cache_name: str | None = None) dict[str, Path] | None[source]ο
Process a custom transcriptome FASTA with caching and index building.
- Parameters:
fasta_path β Path or URL to transcriptome FASTA file
build_index β Build BWA-MEM2 index if missing
cache_name β Custom cache name (default: derived from filename)
- Returns:
Dictionary with βfastaβ and optionally βindexβ paths, or None if failed
- get_filtered_transcriptome(source_name: str, filters: list[str], force_refresh: bool = False, build_index: bool = True) dict[str, Path] | None[source]ο
Get a filtered transcriptome with caching.
- Parameters:
source_name β Pre-configured source name (e.g., βensembl_human_cdnaβ)
filters β List of filter names (e.g., [βprotein_codingβ, βcanonical_onlyβ])
force_refresh β Force re-download and re-filter
build_index β Build BWA-MEM2 index if missing
- Returns:
Dictionary with βfastaβ and optionally βindexβ paths, or None if failed
- list_available_sources() dict[str, TranscriptomeSource][source]ο
List all pre-configured transcriptome sources.
Transcriptome Filterο
Transcriptome filtering utilities for reducing reference size.
Provides functions to filter transcriptome FASTA files based on: - Biotype (protein_coding, etc.) - Canonical transcript status - Specific regions (e.g., 3β UTR)
This helps reduce memory requirements for BWA-MEM2 indexing on low-RAM machines.
- class sirnaforge.data.transcriptome_filter.TranscriptFilter[source]ο
Bases:
objectFilter transcripts based on header metadata and biotype.
- static parse_ensembl_header(description: str) dict[str, str][source]ο
Parse Ensembl FASTA header to extract metadata.
- Parameters:
description β Full FASTA description line (without β>β)
- Returns:
Dictionary of parsed fields (gene_biotype, transcript_biotype, gene_symbol, etc.)
- static is_protein_coding(record: SeqRecord) bool[source]ο
Check if transcript is protein coding.
- Parameters:
record β SeqRecord from FASTA
- Returns:
True if protein_coding, False otherwise
- static is_canonical(record: SeqRecord) bool[source]ο
Check if transcript is canonical (MANE Select or Ensembl canonical).
- Parameters:
record β SeqRecord from FASTA
- Returns:
True if canonical, False otherwise
- static filter_fasta(input_fasta: Path, output_fasta: Path, filter_func: Callable[[SeqRecord], bool], filter_name: str = 'custom') int[source]ο
Filter FASTA file using a custom filter function.
- Parameters:
input_fasta β Path to input FASTA file
output_fasta β Path to output FASTA file
filter_func β Function that returns True for records to keep
filter_name β Name of filter for logging
- Returns:
Number of sequences kept
- static apply_protein_coding_filter(input_fasta: Path, output_fasta: Path) int[source]ο
Filter to protein-coding transcripts only.
- Parameters:
input_fasta β Path to input FASTA file
output_fasta β Path to output FASTA file
- Returns:
Number of sequences kept
- static apply_canonical_filter(input_fasta: Path, output_fasta: Path) int[source]ο
Filter to canonical transcripts only.
- Parameters:
input_fasta β Path to input FASTA file
output_fasta β Path to output FASTA file
- Returns:
Number of sequences kept
- static apply_combined_filter(input_fasta: Path, output_fasta: Path, filters: list[str]) int[source]ο
Apply multiple filters in sequence.
- Parameters:
input_fasta β Path to input FASTA file
output_fasta β Path to output FASTA file
filters β List of filter names (e.g., [βprotein_codingβ, βcanonical_onlyβ])
- Returns:
Number of sequences kept
- sirnaforge.data.transcriptome_filter.get_filter_spec(filter_string: str | None) list[str][source]ο
Parse filter specification string into list of filter names.
- Parameters:
filter_string β Comma-separated filter names (e.g., βprotein_coding,canonical_onlyβ)
- Returns:
List of filter names, or empty list if None
Transcript Annotationsο
Transcript annotation providers using Ensembl REST and optional VEP enrichment.
This module provides clients for fetching genomic transcript annotations (exon/CDS structure, coordinates, biotype) separate from sequence retrieval.
Architecture Overview:
EnsemblTranscriptModelClient: Primary implementation using Ensembl REST API
VepConsequenceClient: Optional enrichment client (placeholder for future development)
Caching Strategy:
Uses in-memory LRU cache with TTL rather than ReferenceManagerβs persistent file cache. This design choice is intentional because:
Data Size: Annotation JSON responses are small (KB) vs. sequence files (GB)
Volatility: Annotations may update with new releases; TTL provides freshness
Access Pattern: High frequency, low latency requirements during workflow execution
Scope: Transient metadata enrichment vs. permanent reference datasets
The cache automatically evicts oldest entries when reaching max_cache_entries, and entries expire after cache_ttl seconds.
Relationship to GeneSearcher:
GeneSearcher: Discovers transcripts by gene name, fetches cDNA/protein sequences
This module: Enriches known transcript IDs with genomic structural metadata
Both can use Ensembl, but query different API endpoints for different purposes
No redundancy: complementary data types that donβt overlap
- class sirnaforge.data.transcript_annotation.EnsemblTranscriptModelClient(timeout: int = 30, base_url: str = 'https://rest.ensembl.org', cache_ttl: int = 3600, max_cache_entries: int = 1000)[source]ο
Bases:
AbstractTranscriptAnnotationClientEnsembl REST-based transcript annotation client.
Retrieves transcript metadata including genomic coordinates, exon/CDS structure, and biotype information using Ensemblβs public REST API.
API Endpoints Used:
Lookup by ID (/lookup/id/:id?expand=1): - Fetches detailed annotation for single transcript/gene ID - Returns exon coordinates, CDS intervals, biotype - Example: /lookup/id/ENST00000269305?expand=1
Overlap by Region (/overlap/region/:species/:region): - Fetches all transcripts overlapping genomic region - Useful for region-based queries - Example: /overlap/region/human/17:7661779-7687550?feature=transcript
Caching Implementation:
Cache key format: βid:{species}:{identifier}:{reference}β or βregion:{species}:{region}:{reference}β
TTL: Configurable, default 1 hour (3600 seconds)
Eviction: LRU when max_cache_entries reached (default 1000)
Thread-safe: Single-process use only (workflow orchestration context)
Error Handling:
404: ID not found β added to unresolved list, no exception raised
403/503: Server unavailable β DatabaseAccessError raised
Network errors: Wrapped in DatabaseAccessError with context
Timeout: Configurable via timeout parameter
Example Usage:
>>> client = EnsemblTranscriptModelClient() >>> reference = ReferenceChoice.explicit("GRCh38", reason="user-specified") >>> bundle = await client.fetch_by_ids( ... ids=["ENST00000269305"], ... species="human", ... reference=reference ... ) >>> print(f"Resolved: {bundle.resolved_count}, Unresolved: {bundle.unresolved_count}")
- __init__(timeout: int = 30, base_url: str = 'https://rest.ensembl.org', cache_ttl: int = 3600, max_cache_entries: int = 1000)[source]ο
Initialize Ensembl transcript annotation client.
- Parameters:
timeout β Request timeout in seconds
base_url β Ensembl REST API base URL
cache_ttl β Cache time-to-live in seconds (default: 1 hour)
max_cache_entries β Maximum number of cached entries (default: 1000)
- async fetch_by_ids(ids: list[str], *, species: str, reference: ReferenceChoice) TranscriptAnnotationBundle[source]ο
Fetch transcript annotations by stable IDs using Ensembl lookup endpoint.
- Parameters:
ids β List of transcript or gene IDs
species β Species name (e.g., βhomo_sapiensβ, βhumanβ)
reference β Reference assembly/release choice
- Returns:
TranscriptAnnotationBundle with resolved annotations
- async fetch_by_regions(regions: list[str], *, species: str, reference: ReferenceChoice) TranscriptAnnotationBundle[source]ο
Fetch transcript annotations by genomic regions using Ensembl overlap endpoint.
- Parameters:
regions β List of regions in format βchr:start-endβ (e.g., β17:7661779-7687550β)
species β Species name (e.g., βhomo_sapiensβ, βhumanβ)
reference β Reference assembly/release choice
- Returns:
TranscriptAnnotationBundle with all transcripts overlapping regions
- class sirnaforge.data.transcript_annotation.VepConsequenceClient(timeout: int = 30, base_url: str = 'https://rest.ensembl.org')[source]ο
Bases:
objectOptional VEP (Variant Effect Predictor) consequence enrichment client.
Provides additional functional annotation for transcript variants. This is an optional enhancement and not required for base functionality.
Current Status: PLACEHOLDER
This client exists as a stub for future VEP integration. The enrich_annotations method currently returns the input bundle unchanged.
Future Implementation:
When activated (via config flag), this client will:
Query Ensembl VEP REST API for consequence predictions
Enrich TranscriptAnnotation objects with variant consequence types (missense, nonsense, etc.), conservation scores, regulatory feature overlaps, and population frequency data
Maintain consistent caching strategy with EnsemblTranscriptModelClient
Design Rationale:
Separated from EnsemblTranscriptModelClient because:
VEP queries are expensive (rate-limited, slower)
Not all workflows need consequence predictions
Allows independent caching strategies
Can be enabled/disabled via configuration
- __init__(timeout: int = 30, base_url: str = 'https://rest.ensembl.org')[source]ο
Initialize VEP client.
- Parameters:
timeout β Request timeout in seconds
base_url β Ensembl REST API base URL
- async enrich_annotations(bundle: TranscriptAnnotationBundle, _species: str = 'homo_sapiens') TranscriptAnnotationBundle[source]ο
Enrich transcript annotations with VEP consequence data.
- Parameters:
bundle β Existing transcript annotation bundle
species β Species name for VEP queries
- Returns:
Enriched bundle (currently returns input unchanged - placeholder for future VEP integration)
miRNA Managementο
miRNA Database Manager with multi-species support.
This module provides a clean interface for downloading, caching, and managing miRNA databases from multiple sources (MirGeneDB, miRBase, TargetScan) with automatic cache management and species-specific organization.
- class sirnaforge.data.mirna_manager.MiRNASource(name: str, url: str, species: str, format: str = 'fasta', compressed: bool = False, description: str = '')[source]ο
Bases:
ReferenceSourcemiRNA-specific database source configuration.
Inherits from ReferenceSource and can add miRNA-specific fields if needed.
- class sirnaforge.data.mirna_manager.MiRNADatabaseManager(cache_dir: str | Path | None = None, cache_ttl_days: int = 30)[source]ο
Bases:
ReferenceManager[MiRNASource]Elegant miRNA database manager with caching and multi-species support.
- SOURCES = {'mirbase': {'human': MiRNASource(name='mirbase_mature', url='https://www.mirbase.org/download/CURRENT/mature.fa', species='human', format='fasta', compressed=False, description='miRBase mature miRNA sequences (all species, filtered for Homo sapiens - hsa)'), 'mouse': MiRNASource(name='mirbase_mature', url='https://www.mirbase.org/download/CURRENT/mature.fa', species='mouse', format='fasta', compressed=False, description='miRBase mature miRNA sequences (all species, filtered for Mus musculus - mmu)'), 'rat': MiRNASource(name='mirbase_mature', url='https://www.mirbase.org/download/CURRENT/mature.fa', species='rat', format='fasta', compressed=False, description='miRBase mature miRNA sequences (all species, filtered for Rattus norvegicus - rno)')}, 'mirbase_hairpin': {'human': MiRNASource(name='mirbase_hairpin', url='https://www.mirbase.org/download/CURRENT/hairpin.fa', species='human', format='fasta', compressed=False, description='miRBase hairpin precursor miRNA sequences (Homo sapiens - hsa)'), 'mouse': MiRNASource(name='mirbase_hairpin', url='https://www.mirbase.org/download/CURRENT/hairpin.fa', species='mouse', format='fasta', compressed=False, description='miRBase hairpin precursor miRNA sequences (Mus musculus - mmu)'), 'rat': MiRNASource(name='mirbase_hairpin', url='https://www.mirbase.org/download/CURRENT/hairpin.fa', species='rat', format='fasta', compressed=False, description='miRBase hairpin precursor miRNA sequences (Rattus norvegicus - rno)')}, 'mirbase_high_conf': {'human': MiRNASource(name='mirbase_mature_hc', url='https://www.mirbase.org/download/CURRENT/mature_high_conf.fa', species='human', format='fasta', compressed=False, description='miRBase high-confidence mature miRNA sequences (Homo sapiens - hsa)'), 'mouse': MiRNASource(name='mirbase_mature_hc', url='https://www.mirbase.org/download/CURRENT/mature_high_conf.fa', species='mouse', format='fasta', compressed=False, description='miRBase high-confidence mature miRNA sequences (Mus musculus - mmu)'), 'rat': MiRNASource(name='mirbase_mature_hc', url='https://www.mirbase.org/download/CURRENT/mature_high_conf.fa', species='rat', format='fasta', compressed=False, description='miRBase high-confidence mature miRNA sequences (Rattus norvegicus - rno)')}, 'mirgenedb': {'aga': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/aga?mat=1', species='aga', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Anopheles gambiae, NCBI:7165) [Mosquito]'), 'bta': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/bta?mat=1', species='bta', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Bos taurus, NCBI:9913) [Cow]'), 'cel': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/cel?mat=1', species='cel', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Caenorhabditis elegans, NCBI:6239) [C. elegans]'), 'cfa': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/cfa?mat=1', species='cfa', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Canis lupus familiaris, NCBI:9615) [Dog]'), 'dme': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/dme?mat=1', species='dme', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Drosophila melanogaster, NCBI:7227) [Fruit fly]'), 'dre': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/dre?mat=1', species='dre', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Danio rerio, NCBI:7955) [Zebrafish]'), 'eca': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/eca?mat=1', species='eca', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Equus caballus, NCBI:9796) [Horse]'), 'fca': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/fca?mat=1', species='fca', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Felis catus, NCBI:9685)'), 'gac': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/gac?mat=1', species='gac', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Gasterosteus aculeatus, NCBI:69293) [Stickleback]'), 'gga': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/gga?mat=1', species='gga', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Gallus gallus, NCBI:9031) [Chicken]'), 'ggo': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/ggo?mat=1', species='ggo', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Gorilla gorilla, NCBI:9593)'), 'hsa': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/hsa?mat=1', species='hsa', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Homo sapiens, NCBI:9606) [Human]'), 'mml': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/mml?mat=1', species='mml', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Macaca mulatta, NCBI:9544) [Rhesus macaque]'), 'mmu': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/mmu?mat=1', species='mmu', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Mus musculus, NCBI:10090) [Mouse]'), 'oar': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/oar?mat=1', species='oar', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Ovis aries, NCBI:9940) [Sheep]'), 'ola': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/ola?mat=1', species='ola', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Oryzias latipes, NCBI:8090) [Medaka]'), 'pma': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/pma?mat=1', species='pma', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Petromyzon marinus, NCBI:7757) [Sea lamprey]'), 'ptr': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/ptr?mat=1', species='ptr', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Pan troglodytes, NCBI:9598) [Chimpanzee]'), 'rno': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/rno?mat=1', species='rno', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Rattus norvegicus, NCBI:10116)'), 'spur': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/spur?mat=1', species='spur', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Strongylocentrotus purpuratus, NCBI:7668) [Purple sea urchin]'), 'ssc': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/ssc?mat=1', species='ssc', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Sus scrofa, NCBI:9823) [Pig]'), 'tgu': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/tgu?mat=1', species='tgu', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Meleagris gallopavo, NCBI:9103) [Turkey]'), 'xla': MiRNASource(name='mirgenedb', url='https://www.mirgenedb.org/fasta/xla?mat=1', species='xla', format='fasta', compressed=False, description='MirGeneDB high-confidence miRNAs (Xenopus laevis, NCBI:8355) [African clawed frog]')}, 'targetscan': {'human': MiRNASource(name='targetscan', url='https://www.targetscan.org/vert_80/vert_80_data_download/miR_Family_Info.txt.zip', species='human', format='tsv', compressed=True, description='TargetScan miRNA family data')}}ο
- classmethod get_available_sources() list[str][source]ο
Return sorted list of supported database sources.
- classmethod get_all_species() list[str][source]ο
Return sorted list of all species across sources.
- classmethod get_species_for_source(source_name: str) list[str][source]ο
Return sorted list of species supported by a given source.
- classmethod get_species_aliases(source_name: str) dict[str, list[str]][source]ο
Return mapping of canonical species identifiers to their known aliases.
- classmethod get_canonical_species() list[str][source]ο
Return sorted list of canonical species keys.
- classmethod canonicalize_species_name(species: str) str | None[source]ο
Normalize a raw species identifier to a canonical key.
- classmethod canonicalize_species_list(species_list: Sequence[str]) list[str][source]ο
Normalize a list of species identifiers to canonical keys, preserving order.
- classmethod get_genome_species_for_canonical(canonical_species: Sequence[str]) list[str][source]ο
Return genome species identifiers for canonical species keys.
Note: These are used for miRNA database lookups, not genomic DNA alignment. The term βgenomeβ here refers to the organismβs miRNA annotation set.
- classmethod get_mirna_slugs_for_canonical(canonical_species: Sequence[str], source_name: str) list[str][source]ο
Return normalized miRNA identifiers for canonical species.
- classmethod get_supported_canonical_species_for_source(source_name: str) list[str][source]ο
Return canonical species supported by a given source.
- classmethod resolve_species_selection(requested_species: Sequence[str], source_name: str, mirna_overrides: Sequence[str] | None = None) dict[str, list[str]][source]ο
Resolve canonical, genome, and miRNA identifiers for the requested species.
- classmethod normalize_species(source_name: str, species: str) str | None[source]ο
Normalize user-provided species identifiers to canonical keys.
- classmethod get_source_configuration(source_name: str, species: str) MiRNASource | None[source]ο
Retrieve the MiRNASource configuration for a given source/species.
- classmethod is_supported_species(source_name: str, species: str) bool[source]ο
Check if a species is supported for the given source.
- classmethod get_mirgenedb_species_metadata() dict[str, dict[str, Any]][source]ο
Expose the MirGeneDB species metadata table.
- __init__(cache_dir: str | Path | None = None, cache_ttl_days: int = 30)[source]ο
Initialize the miRNA database manager.
- Parameters:
cache_dir β Directory for caching databases (default: ~/.cache/sirnaforge/mirna)
cache_ttl_days β Cache time-to-live in days
- get_database(source_name: str, species: str, force_refresh: bool = False) Path | None[source]ο
Get miRNA database, downloading and filtering if needed.
Simplified caching: each species+source combination gets its own cache file.
- Parameters:
source_name β Database source (βmirbaseβ, βmirbase_high_confβ, etc.)
species β Species name (βhumanβ, βmouseβ, βratβ)
force_refresh β Force re-download even if cached
- Returns:
Path to cached FASTA file, or None if failed
- get_combined_database(sources: list[str], species: str, output_name: str | None = None) Path | None[source]ο
Combine multiple databases into a single file.
- Parameters:
sources β List of source names to combine
species β Target species
output_name β Custom output filename (default: auto-generated)
- Returns:
Path to combined FASTA file
Species Registryο
Canonical species registry and metadata for miRNA and genome mappings.
- sirnaforge.data.species_registry.normalize_species_name(species: str) str[source]ο
Normalize species name to canonical form.
- Parameters:
species β Species name in any recognized form (e.g., βhsaβ, βhumanβ, βHomo sapiensβ)
- Returns:
Canonical species name (e.g., βhumanβ), or original string if not recognized
Examples
>>> normalize_species_name('hsa') 'human' >>> normalize_species_name('Mus musculus') 'mouse' >>> normalize_species_name('macaque') 'macaque' >>> normalize_species_name('unknown') 'unknown'
Variant Resolverο
Variant resolution from multiple databases (ClinVar, Ensembl, dbSNP) with caching.
- class sirnaforge.data.variant_resolver.VariantResolver(min_af: float = 0.01, clinvar_filters: list[ClinVarSignificance] | None = None, assembly: str = 'GRCh38', source_priority: list[VariantSource] | None = None, cache_dir: Path | None = None, timeout: int = 30, variant_mode: str | None = None)[source]ο
Bases:
objectResolve variant identifiers to VariantRecord using multiple databases with priority ordering.
Priority order: ClinVar > Ensembl > dbSNP Supports caching and local VCF files. Only supports GRCh38 assembly.
- __init__(min_af: float = 0.01, clinvar_filters: list[ClinVarSignificance] | None = None, assembly: str = 'GRCh38', source_priority: list[VariantSource] | None = None, cache_dir: Path | None = None, timeout: int = 30, variant_mode: str | None = None)[source]ο
Initialize variant resolver.
- Parameters:
min_af β Minimum allele frequency threshold (default: 0.01)
clinvar_filters β Allowed ClinVar significance levels (default: Pathogenic, Likely pathogenic)
assembly β Reference genome assembly (only GRCh38 supported)
source_priority β Source priority list (default: ClinVar > Ensembl > dbSNP)
cache_dir β Cache directory for variant data
timeout β HTTP request timeout in seconds
variant_mode β Variant mode for AF filtering (βavoidβ, βtargetβ, βbothβ). In βavoidβ mode, uses max population AF if available to avoid SNPs prevalent in any geographic group (e.g., >10% in one population).
- parse_identifier(input_str: str) VariantQuery[source]ο
Parse variant identifier string into VariantQuery.
Accepts: - rsID: rs12345 - VCF-style coordinate: chr17:7577121:G:A or 17:7577121:G:A - HGVS: NM_000546.6:c.215C>G (basic support)
- Parameters:
input_str β User-provided variant identifier
- Returns:
VariantQuery with parsed components
- Raises:
ValueError β If input format is not recognized
- async resolve_variant(query: VariantQuery) VariantRecord | None[source]ο
Resolve a variant query to a VariantRecord.
Tries sources in priority order: ClinVar -> Ensembl -> dbSNP Applies AF and ClinVar filters. Uses cache when available.
- Parameters:
query β Parsed variant query
- Returns:
VariantRecord if found and passes filters, None otherwise
- read_vcf(vcf_path: Path) list[VariantRecord][source]ο
Read variants from VCF file (supports bgzip+tabix).
- Parameters:
vcf_path β Path to VCF file
- Returns:
List of VariantRecord objects passing filters
- Raises:
FileNotFoundError β If VCF file doesnβt exist
- sirnaforge.data.variant_resolver.resolve_variant_sync(variant_id: str, min_af: float = 0.01, clinvar_filters: list[ClinVarSignificance] | None = None, cache_dir: Path | None = None, variant_mode: str | None = None) VariantRecord | None[source]ο
Synchronous wrapper for variant resolution.
- Parameters:
variant_id β Variant identifier (rsID, coordinate, or HGVS)
min_af β Minimum allele frequency
clinvar_filters β Allowed ClinVar significance levels
cache_dir β Cache directory
variant_mode β Variant mode for AF filtering (βavoidβ, βtargetβ, βbothβ)
- Returns:
VariantRecord if found and passes filters, None otherwise
Variant Cacheο
Improved variant caching using Parquet for efficient storage and retrieval.
- class sirnaforge.data.variant_cache.VariantParquetCache(cache_dir: Path, ttl_days: int = 90)[source]ο
Bases:
objectEfficient variant cache using Parquet files for better performance than JSON.
Benefits over JSON: - Columnar storage format is much more efficient for variant data - Built-in compression reduces disk usage - Fast filtering and querying with pandas - Batch operations instead of individual file I/O
- __init__(cache_dir: Path, ttl_days: int = 90)[source]ο
Initialize the Parquet-based variant cache.
- Parameters:
cache_dir β Directory for cache storage
ttl_days β Time-to-live for cached entries in days (default: 90)
- get(cache_key: str) VariantRecord | None[source]ο
Retrieve a variant from cache by key.
- Parameters:
cache_key β Cache key for the variant
- Returns:
VariantRecord if found and not stale, None otherwise
- put(cache_key: str, variant: VariantRecord) None[source]ο
Store a variant in the cache.
- Parameters:
cache_key β Cache key for storage
variant β VariantRecord to cache
- cleanup_stale_entries() int[source]ο
Remove entries older than TTL.
- Returns:
Number of entries removed
Variant Helpersο
Helper functions for generating sequence contexts with variant alleles.
- sirnaforge.data.variant_helpers.generate_contexts_for_variant(variant: VariantRecord, reference_sequence: str, transcript_start: int, transcript_id: str, flank_size: int = 50) dict[str, tuple[str, int, int]][source]ο
Generate reference and alternate sequence contexts for a variant.
- Parameters:
variant β Variant record with position and alleles
reference_sequence β Full reference transcript sequence
transcript_start β Genomic start position of the transcript (1-based)
transcript_id β Transcript identifier
flank_size β Number of nucleotides to include on each side of variant (default: 50)
- Returns:
sequence context (str)
relative position of variant in context (int, 0-based)
length of the allele (int)
- Return type:
Dictionary with βrefβ and βaltβ keys, each containing
- Raises:
ValueError β If variant position is outside transcript boundaries
- sirnaforge.data.variant_helpers.check_candidate_overlaps_variant(candidate_pos: int, candidate_length: int, variant: VariantRecord, transcript_start: int) bool[source]ο
Check if a siRNA candidate overlaps with a variant position.
- Parameters:
candidate_pos β 1-based start position of candidate in transcript
candidate_length β Length of the siRNA candidate
variant β Variant record to check
transcript_start β 1-based genomic start position of transcript
- Returns:
True if candidate overlaps the variant, False otherwise
- sirnaforge.data.variant_helpers.annotate_candidate_with_variant(candidate: SiRNACandidate, variant: VariantRecord, allele: str, variant_mode: str) None[source]ο
Annotate a siRNA candidate with variant information.
Modifies the candidate in place to add variant-specific metadata.
- Parameters:
candidate β SiRNACandidate to annotate
variant β Variant record that overlaps the candidate
allele β Which allele the candidate targets (βrefβ or βaltβ)
variant_mode β Variant handling mode (βtargetβ, βavoidβ, βbothβ)
- sirnaforge.data.variant_helpers.apply_variant_to_sequence(sequence: str, variant: VariantRecord, transcript_start: int, allele: str = 'alt') str[source]ο
Apply a variant to a reference sequence to generate an alternate sequence.
- Parameters:
sequence β Reference sequence
variant β Variant record with position and alleles
transcript_start β 1-based genomic start position of transcript
allele β Which allele to apply (βrefβ returns unchanged sequence, βaltβ applies variant)
- Returns:
Modified sequence with variant applied
- Raises:
ValueError β If variant position is outside sequence boundaries or allele is invalid
- sirnaforge.data.variant_helpers.get_variant_position_in_transcript(variant: VariantRecord, transcript_start: int) int[source]ο
Calculate the 0-based position of a variant within a transcript.
- Parameters:
variant β Variant record
transcript_start β 1-based genomic start position of transcript
- Returns:
0-based position of variant within transcript
Pipeline Integrationο
Nextflow CLIο
Command-line entry points used by embedded Nextflow modules.
- sirnaforge.pipeline.nextflow_cli.build_bwa_index_cli(fasta_file: str, species: str, output_dir: str = '.') dict[str, Any][source]ο
Build BWA-MEM2 index for genome/transcriptome.
- Parameters:
fasta_file β Path to input FASTA file
species β Species identifier
output_dir β Directory to write index files
- Returns:
Dictionary with index prefix path
- sirnaforge.pipeline.nextflow_cli.aggregate_results_cli(genome_species: str, output_dir: str = '.', mirna_db: str | None = None, mirna_species: str | None = None, analysis_files: list[str] | None = None, summary_files: list[str] | None = None) dict[str, Any][source]ο
Aggregate off-target analysis results from multiple candidates and genomes.
- Parameters:
genome_species β Comma-separated list of species
output_dir β Directory to write aggregated results
mirna_db β The database that provided the reference
mirna_species β The species code for the matching miRNA
analysis_files β Optional explicit list of staged analysis files to aggregate
summary_files β Optional explicit list of staged summary files to aggregate
- Returns:
Dictionary with aggregation statistics
- sirnaforge.pipeline.nextflow_cli.aggregate_mirna_results_cli(mirna_db: str, mirna_species: str, results_dir: str = '.', output_dir: str = '.') dict[str, Any][source]ο
Aggregate miRNA seed analysis results from multiple candidates.
- Parameters:
mirna_db β miRNA database name used for analysis
mirna_species β Comma-separated list of species analyzed
results_dir β Directory containing individual miRNA results
output_dir β Directory to write aggregated results
- Returns:
Dictionary with aggregation statistics
Nextflow Configurationο
Nextflow Configuration Management.
This module handles configuration for Nextflow workflows, including Docker settings, resource management, and parameter validation.
Simple Usage Examples:
# Auto-configure based on environment (easiest) config = NextflowConfig.auto_configure()
# Production settings config = NextflowConfig.for_production()
# Testing settings config = NextflowConfig.for_testing()
# Local Docker testing (uses local image built by βmake dockerβ) config = NextflowConfig.for_local_docker_testing()
- class sirnaforge.pipeline.nextflow.config.EnvironmentInfo(*, running_in_docker: bool, docker_available: bool, requested_profile: str, recommended_profile: str, docker_image: str | None = None, profile_override_reason: str | None = None)[source]ο
Bases:
BaseModelInformation about the current execution environment.
- is_profile_overridden() bool[source]ο
Check if the recommended profile differs from the requested profile.
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.pipeline.nextflow.config.NextflowConfig(docker_image: str = 'ghcr.io/austin-s-h/sirnaforge:latest', profile: str = 'docker', work_dir: Path | None = None, nxf_home: Path | None = None, max_cpus: int = 16, max_memory: str = '128.GB', max_time: str = '240.h', **kwargs: Any)[source]ο
Bases:
objectConfiguration manager for Nextflow workflows.
- DEFAULT_SIRNAFORGE_DOCKER_IMAGE = 'ghcr.io/austin-s-h/sirnaforge:latest'ο
- MEMORY_BUFFER_GB = 0.5ο
- MIN_MEMORY_GB = 1ο
- __init__(docker_image: str = 'ghcr.io/austin-s-h/sirnaforge:latest', profile: str = 'docker', work_dir: Path | None = None, nxf_home: Path | None = None, max_cpus: int = 16, max_memory: str = '128.GB', max_time: str = '240.h', **kwargs: Any) None[source]ο
Initialize Nextflow configuration.
- Parameters:
docker_image β Docker container image to use
profile β Nextflow profile (docker, singularity, conda, local)
work_dir β Working directory for Nextflow execution
nxf_home β Nextflow home cache
max_cpus β Maximum CPU cores
max_memory β Maximum memory allocation
max_time β Maximum execution time
**kwargs β Additional configuration parameters
- get_nextflow_args(input_file: Path, output_dir: Path, genome_species: list[str], additional_params: dict[str, Any] | None = None, include_test_profile: bool = False) list[str][source]ο
Generate Nextflow command arguments.
- Parameters:
input_file β Input FASTA file path
output_dir β Output directory
genome_species β List of species for miRNA genome lookups (not genomic DNA)
additional_params β Additional parameters to pass
include_test_profile β Whether to include βtestβ profile for integration testing
- Returns:
List of command arguments for Nextflow
- create_config_file(config_path: Path) Path[source]ο
Create a custom Nextflow configuration file.
- Parameters:
config_path β Path where to create the config file
- Returns:
Path to the created configuration file
- validate_docker_available() bool[source]ο
Check if Docker is available for Nextflow execution.
This checks if Docker can be used by Nextflow to run containers. Note: This is different from running tests inside Docker containers.
- Returns:
True if Docker is available and accessible for Nextflow
- is_running_in_docker() bool[source]ο
Check if weβre currently running inside a Docker container.
This is useful for determining the appropriate execution profile when running tests or workflows.
- Returns:
True if running inside a Docker container
- get_execution_profile() str[source]ο
Get the appropriate execution profile based on available tools and environment.
This method considers: 1. Environment variables (SIRNAFORGE_USE_LOCAL_EXECUTION) 2. Whether weβre running inside a Docker container (for testing) 3. Whether Docker is available for Nextflow execution 4. Availability of Singularity or Conda as fallbacks 5. The requested profile
- Returns:
Recommended execution profile
- get_environment_info() EnvironmentInfo[source]ο
Get information about the current execution environment.
This provides structured information about Docker availability, profile selection, and environment detection.
- Returns:
EnvironmentInfo model with environment details
- classmethod for_testing() NextflowConfig[source]ο
Create a configuration optimized for testing.
This automatically detects if weβre running in Docker and adjusts accordingly. Uses uv/conda for environment management when available.
- Returns:
NextflowConfig instance with test-friendly settings
- classmethod for_production(**kwargs: Any) NextflowConfig[source]ο
Create a configuration optimized for production use.
This uses Docker by default for reproducible execution with full resources.
- Parameters:
**kwargs β Additional configuration parameters to override defaults
- Returns:
NextflowConfig instance with production settings
- classmethod auto_configure(**kwargs: Any) NextflowConfig[source]ο
Auto-configure Nextflow settings based on environment detection.
This method automatically detects available tools and selects the best profile.
- Parameters:
**kwargs β Additional configuration parameters to override defaults
- Returns:
NextflowConfig instance with auto-detected settings
Nextflow Runnerο
Nextflow Pipeline Runner.
This module provides a Python interface to execute Nextflow workflows for siRNA off-target analysis with proper Docker integration.
- class sirnaforge.pipeline.nextflow.runner.NextflowRunner(config: NextflowConfig | None = None)[source]ο
Bases:
objectExecute Nextflow workflows from Python with proper error handling.
- __init__(config: NextflowConfig | None = None)[source]ο
Initialize Nextflow runner.
- Parameters:
config β NextflowConfig instance, creates auto-configured if None
- async run(input_file: Path, output_dir: Path, genome_species: list[str] | None = None, **kwargs: Any) dict[str, Any][source]ο
Simple method to run Nextflow workflow with auto-validation and defaults.
- Parameters:
input_file β Path to input FASTA file
output_dir β Output directory for results
genome_species β List of species for miRNA genome lookups (defaults to [βhumanβ, βratβ, βrhesusβ])
**kwargs β Additional parameters passed to run_offtarget_analysis
- Returns:
Dictionary containing execution results and metadata
- Raises:
NextflowExecutionError β If workflow execution fails
- run_sync(input_file: Path, output_dir: Path, genome_species: list[str] | None = None, **kwargs: Any) dict[str, Any][source]ο
Synchronous version of run() for simpler usage without async/await.
- Parameters:
input_file β Path to input FASTA file
output_dir β Output directory for results
genome_species β List of species for miRNA genome lookups (defaults to [βhumanβ, βratβ, βrhesusβ])
**kwargs β Additional parameters passed to run_offtarget_analysis
- Returns:
Dictionary containing execution results and metadata
- async run_offtarget_analysis(input_file: Path, output_dir: Path, genome_species: list[str], additional_params: dict[str, Any] | None = None, show_progress: bool = True) dict[str, Any][source]ο
Run the off-target analysis Nextflow workflow.
- Parameters:
input_file β Path to siRNA candidates FASTA file
output_dir β Output directory for results
genome_species β List of species for miRNA genome lookups
additional_params β Additional parameters for the workflow
show_progress β Whether to show progress indicators
- Returns:
Dictionary containing execution results and metadata
- Raises:
NextflowExecutionError β If workflow execution fails
- validate_installation() dict[str, bool | str][source]ο
Validate that Nextflow and required tools are available.
- Returns:
Dictionary of tool availability status
- classmethod for_testing() NextflowRunner[source]ο
Create a runner configured for testing.
This uses the test configuration which automatically detects if weβre running in Docker and adjusts accordingly.
- Returns:
NextflowRunner configured for testing
- classmethod create(**config_kwargs: Any) NextflowRunner[source]ο
Create a NextflowRunner with auto-configured settings.
- Parameters:
**config_kwargs β Configuration parameters for NextflowConfig
- Returns:
NextflowRunner with auto-configured NextflowConfig
- exception sirnaforge.pipeline.nextflow.runner.NextflowExecutionError(message: str, stdout: str = '', stderr: str = '')[source]ο
Bases:
ExceptionException raised when Nextflow execution fails.
- __init__(message: str, stdout: str = '', stderr: str = '')[source]ο
Initialize the exception with message and optional stdout/stderr.
- Parameters:
message β Error message describing what went wrong
stdout β Standard output from the failed command
stderr β Standard error from the failed command
Pipeline Resourcesο
Resource Management for siRNAforge Pipeline.
This module provides utilities for managing test data and pipeline resources.
- sirnaforge.pipeline.resources.resources.get_resource_path(resource_name: str) Path[source]ο
Get path to a pipeline resource file.
- Parameters:
resource_name β Name of the resource file
- Returns:
Path to the resource file
- Raises:
FileNotFoundError β If resource is not found
- sirnaforge.pipeline.resources.resources.get_test_data_path(filename: str) Path[source]ο
Get path to test data file.
- Parameters:
filename β Name of the test data file
- Returns:
Path to the test data file
- Raises:
FileNotFoundError β If test data file is not found
- sirnaforge.pipeline.resources.resources.validate_test_data() dict[str, bool][source]ο
Validate that required test data files are present.
- Returns:
Dictionary mapping filenames to availability status
Workflow Orchestrationο
siRNAforge Workflow Orchestrator.
Coordinates the complete siRNA design pipeline: 1. Transcript retrieval and validation 2. ORF validation and reporting 3. siRNA candidate generation and scoring 4. Top-N candidate selection and reporting 5. Off-target analysis with Nextflow pipeline
- class sirnaforge.workflow.WorkflowConfig(output_dir: Path, gene_query: str, input_fasta: Path | None = None, database: DatabaseType = DatabaseType.ENSEMBL, design_params: DesignParameters | None = None, nextflow_config: Mapping[str, Any] | None = None, genome_indices_override: str | None = None, genome_species: list[str] | None = None, query_species: str | None = None, mirna_database: str = 'mirgenedb', mirna_species: Sequence[str] | None = None, transcriptome_fasta: str | None = None, transcriptome_filter: str | None = None, transcriptome_selection: ReferenceSelection | None = None, validation_config: ValidationConfig | None = None, log_file: str | None = None, write_json_summary: bool = True, num_threads: int | None = None, input_source: InputSource | None = None, keep_nextflow_work: bool = False, variant_config: VariantWorkflowConfig | None = None, zfn_config: ZFNWorkflowConfig | None = None)[source]ο
Bases:
objectConfiguration for the complete siRNA design workflow.
- __init__(output_dir: Path, gene_query: str, input_fasta: Path | None = None, database: DatabaseType = DatabaseType.ENSEMBL, design_params: DesignParameters | None = None, nextflow_config: Mapping[str, Any] | None = None, genome_indices_override: str | None = None, genome_species: list[str] | None = None, query_species: str | None = None, mirna_database: str = 'mirgenedb', mirna_species: Sequence[str] | None = None, transcriptome_fasta: str | None = None, transcriptome_filter: str | None = None, transcriptome_selection: ReferenceSelection | None = None, validation_config: ValidationConfig | None = None, log_file: str | None = None, write_json_summary: bool = True, num_threads: int | None = None, input_source: InputSource | None = None, keep_nextflow_work: bool = False, variant_config: VariantWorkflowConfig | None = None, zfn_config: ZFNWorkflowConfig | None = None)[source]ο
Initialize workflow configuration.
- class sirnaforge.workflow.ZFNWorkflowConfig(zfn_params: ZFNDesignParameters, annotation: GenomicAnnotationConfig | None = None)[source]ο
Bases:
objectConfiguration for ZFN pair evaluation and off-target search workflow.
This carries the scientifically distinct ZFN parameters: - Left/right half-site sequences (IUPAC-validated, 9-18 bp) - Genomic search space (whole-genome FASTA) - Algorithm choice (homology / conserved_g / zfn_v2) - Spacer/dimer/mismatch constraints - Optional genomic annotation for region classification
- __init__(zfn_params: ZFNDesignParameters, annotation: GenomicAnnotationConfig | None = None)[source]ο
Initialize ZFN workflow configuration.
- class sirnaforge.workflow.SiRNAWorkflow(config: WorkflowConfig)[source]ο
Bases:
objectMain workflow orchestrator for siRNA/miRNA/ZFN design pipeline.
- __init__(config: WorkflowConfig)[source]ο
Initialize the workflow orchestrator.
- async run_complete_workflow() dict[str, Any][source]ο
Run the complete design workflow (siRNA/miRNA or ZFN).
- async step1_retrieve_transcripts(progress: Progress) list[TranscriptInfo][source]ο
Step 1: Retrieve and validate transcript sequences.
- async resolve_variants_step(progress: Progress) list[VariantRecord][source]ο
Resolve variants for targeting or avoidance (optional workflow step).
This step runs after transcript retrieval and before siRNA design, resolving and filtering variants based on the workflow configuration.
This step is run after transcript retrieval and before ORF validation and siRNA design. Variants are resolved using ClinVar, Ensembl Variation, and/or VCF files.
- Parameters:
progress β Rich progress tracker
- Returns:
List of resolved VariantRecords that passed filters
- async step2_validate_orfs(transcripts: list[TranscriptInfo], progress: Progress) dict[str, Any][source]ο
Step 2: Validate ORFs and generate validation report.
- async step3_design_sirnas(transcripts: list[TranscriptInfo], progress: Progress) DesignResult[source]ο
Step 3: Design siRNA candidates for valid transcripts.
Parallelizes per-transcript design when not running from a user-provided input FASTA, to preserve backward-compatibility with tests and monkeypatching of design_from_file. Set env SIRNAFORGE_PARALLEL_DESIGN=1 to force parallel mode.
- async step6_generate_reports(design_results: DesignResult) None[source]ο
Step 6: Generate comprehensive reports.
- async step5_offtarget_analysis(design_results: DesignResult) dict[str, Any][source]ο
Step 5: Detect repeat elements, then run off-target analysis via the Nextflow pipeline.
Repeat detection runs here rather than as its own workflow step so it can reuse the transcriptome reference this step already materializes for screening, instead of fetching it a second time just to locate the query speciesβ FASTA. The corollary is that
check_off_targets=False(--skip-off-targets) skips repeat detection as well: both are reference-based scans, and the reference is what the flag exists to avoid paying for.
- sirnaforge.workflow.apply_zfn_runtime_overrides(zfn_design_params: ZFNDesignParameters, nextflow_config_overrides: dict[str, Any]) ZFNDesignParameters[source]ο
Apply non-CLI ZFN sharding/runtime overrides and project Nextflow params.
Starts from
zfn_design_params.sharding(typed defaults are authoritative), merges optional JSON overrides fromSIRNAFORGE_ZFN_SHARDING_JSON, and mirrors the resolved sharding values intonextflow_config_overridesso the Nextflow route and direct Python route share the same effective config.The runtime search implementation remains generic and contig-aware, including chunk sharding on single-contig inputs when sharding is enabled.
- async sirnaforge.workflow.run_sirna_workflow(gene_query: str, output_dir: str, input_fasta: str | None = None, database: str = 'ensembl', design_mode: str = 'sirna', top_n_candidates: int | None = None, genome_species: list[str] | None = None, query_species: str | None = None, genome_indices_override: str | None = None, mirna_database: str = 'mirgenedb', mirna_species: Sequence[str] | None = None, transcriptome_fasta: str | None = None, transcriptome_filter: str | None = None, transcriptome_selection: ReferenceSelection | None = None, gc_min: float = 30.0, gc_max: float = 52.0, sirna_length: int = 21, modification_pattern: str = 'standard_2ome', overhang: str = 'dTdT', zfn_design_params: ZFNDesignParameters | None = None, zfn_annotation: GenomicAnnotationConfig | None = None, check_off_targets: bool = True, variant_ids: list[str] | None = None, variant_vcf_file: Path | None = None, variant_mode: str = 'avoid', variant_min_af: float = 0.01, variant_clinvar_filters: str = 'Pathogenic,Likely pathogenic', variant_assembly: str = 'GRCh38', log_file: str | None = None, write_json_summary: bool = True, num_threads: int | None = None, allow_transcriptome_with_input_fasta: bool = False, default_transcriptome_sources: Sequence[str] = ('ensembl_human_cdna', 'ensembl_mouse_cdna', 'ensembl_rat_cdna', 'ensembl_macaque_cdna'), keep_nextflow_work: bool = False, nextflow_docker_image: str | None = None, max_hits: int | None = None, max_off_targets: int | None = None) dict[str, Any][source]ο
Run complete siRNA design workflow.
- Parameters:
gene_query β Gene name or ID to search for
output_dir β Directory for output files
input_fasta β Local path or remote URI to an input FASTA file
database β Database to search (ensembl, refseq, gencode)
design_mode β Design mode (sirna, mirna, or zfn)
top_n_candidates β Cap on how many top-ranked candidates are reported (None = no cap, the default). Enumeration and screening always cover every candidate.
genome_species β Species genomes for off-target analysis
query_species β Organism the TARGET transcripts belong to. Defaults to the organism the gene-query database serves (human), which is also the species of the default transcriptome; set it when designing against an input FASTA from another organism.
genome_indices_override β Comma-separated species:/index_prefix overrides for off-target analysis
mirna_database β miRNA reference database identifier
mirna_species β miRNA reference species identifiers
transcriptome_fasta β Path or URL to transcriptome FASTA for off-target analysis
transcriptome_filter β Comma-separated filter names (protein_coding, canonical_only)
transcriptome_selection β Pre-resolved transcriptome selection metadata
gc_min β Minimum GC content percentage
gc_max β Maximum GC content percentage
sirna_length β siRNA length in nucleotides
modification_pattern β Chemical modification pattern
overhang β Overhang sequence (dTdT for DNA, UU for RNA)
zfn_design_params β Optional ZFN design parameters for ZFN mode workflow
zfn_annotation β Optional genomic annotation config for ZFN off-target classification
check_off_targets β Perform off-target analysis stage (default: True)
variant_ids β List of variant identifiers (rsID, chr:pos:ref:alt, or HGVS) to target or avoid
variant_vcf_file β Path to VCF file containing variants to target or avoid
variant_mode β How to handle variants (avoid/target/both) - default is avoid
variant_min_af β Minimum allele frequency threshold for variant filtering (default: 0.01)
variant_clinvar_filters β Comma-separated ClinVar significance levels to include (default: Pathogenic,Likely pathogenic)
variant_assembly β Reference genome assembly for variants (only GRCh38 supported)
log_file β Path to centralized log file
write_json_summary β Write logs/workflow_summary.json
num_threads β Optional override for design parallelism
allow_transcriptome_with_input_fasta β Opt in to resolving
default_transcriptome_sourceswheninput_fastais supplied (default: False). Left False, an input-FASTA run is design-only unlesstranscriptome_fastanames a reference explicitly: supplying your own sequences should never trigger a multi-gigabyte reference download you did not ask for. Set True to screen an input-FASTA run against the bundled defaults.default_transcriptome_sources β Ordered list of transcriptome identifiers evaluated by default
keep_nextflow_work β Keep Nextflow work directory symlink in output
nextflow_docker_image β Override Docker image used by the embedded Nextflow pipeline
max_hits β Override the pipelineβs per-candidate off-target hit cap (None keeps the pipelineβs exhaustive default; set a lower value, e.g. 10000, to speed up large gene-family searches)
max_off_targets β Override the genuine off-target ceiling that gates PASS vs EXCESS_OFF_TARGETS (None keeps OffTargetFilterCriteriaβs default of 15). Unlike max_hits this changes the verdict, not how many hits are recorded.
- Returns:
Dictionary with complete workflow results
- async sirnaforge.workflow.run_offtarget_only_workflow(input_candidates_fasta: str, output_dir: str, genome_species: list[str] | None = None, query_species: str | None = None, genome_indices_override: str | None = None, mirna_database: str = 'mirgenedb', mirna_species: Sequence[str] | None = None, transcriptome_fasta: str | None = None, transcriptome_filter: str | None = None, transcriptome_selection: ReferenceSelection | None = None, log_file: str | None = None, nextflow_docker_image: str | None = None) dict[str, Any][source]ο
Run off-target-only workflow for pre-designed siRNA candidates.
This is a simplified workflow that only runs the off-target analysis stage without transcript retrieval, ORF validation, or siRNA design. It accepts pre-designed 21-nt siRNA guide sequences and runs comprehensive off-target analysis using the embedded Nextflow pipeline.
- Parameters:
input_candidates_fasta β Path to FASTA file with 21-nt siRNA guide sequences
output_dir β Directory for output files
genome_species β Species genomes for off-target analysis
query_species β Organism the input guides were designed against (defaults to human)
genome_indices_override β Comma-separated species:/index_prefix overrides
mirna_database β miRNA reference database identifier
mirna_species β miRNA reference species identifiers
transcriptome_fasta β Path or URL to transcriptome FASTA for off-target analysis
transcriptome_filter β Comma-separated filter names (protein_coding, canonical_only)
transcriptome_selection β Pre-resolved transcriptome selection metadata
log_file β Path to centralized log file
nextflow_docker_image β Override Docker image used by the embedded Nextflow pipeline
- Returns:
Dictionary with off-target analysis results
Variant Workflow Integrationο
Workflow integration for variant targeting.
- class sirnaforge.workflow_variant.VariantWorkflowConfig(variant_ids: list[str] | None = None, vcf_file: Path | None = None, variant_mode: VariantMode = VariantMode.AVOID, min_af: float = 0.01, clinvar_filter_levels: list[ClinVarSignificance] | None = None, assembly: str = 'GRCh38', cache_dir: Path | None = None)[source]ο
Bases:
objectConfiguration for variant targeting in the workflow.
- __init__(variant_ids: list[str] | None = None, vcf_file: Path | None = None, variant_mode: VariantMode = VariantMode.AVOID, min_af: float = 0.01, clinvar_filter_levels: list[ClinVarSignificance] | None = None, assembly: str = 'GRCh38', cache_dir: Path | None = None)[source]ο
Initialize variant workflow configuration.
- Parameters:
variant_ids β List of variant identifiers (rsID, coordinate, HGVS)
vcf_file β Path to VCF file with variants
variant_mode β How to handle variants (avoid/target/both)
min_af β Minimum allele frequency threshold
clinvar_filter_levels β Allowed ClinVar significance levels
assembly β Reference genome assembly (only GRCh38 supported)
cache_dir β Cache directory for variant data
- async sirnaforge.workflow_variant.resolve_workflow_variants(config: VariantWorkflowConfig, gene_name: str, output_dir: Path) list[VariantRecord][source]ο
Resolve all variants for the workflow.
This is an optional workflow step that runs after gene/transcript selection and before siRNA candidate design.
- Parameters:
config β Variant workflow configuration
gene_name β Gene name for logging/reporting
output_dir β Output directory for reports
- Returns:
List of resolved VariantRecords passing filters
- sirnaforge.workflow_variant.normalize_variant_mode(mode: str | VariantMode) VariantMode[source]ο
Normalize variant mode to enum, handling string input.
- Parameters:
mode β Variant mode as string or enum
- Returns:
VariantMode enum
- Raises:
ValueError β If mode string is invalid
- sirnaforge.workflow_variant.parse_clinvar_filter_string(filter_string: str) list[ClinVarSignificance][source]ο
Parse comma-separated ClinVar filter string to enum list.
- Parameters:
filter_string β Comma-separated string of significance levels
- Returns:
List of ClinVarSignificance enums
- Raises:
ValueError β If any significance level is invalid
Validationο
Validation Configurationο
Validation configuration and settings.
- class sirnaforge.validation.config.ValidationLevel(*values)[source]ο
-
Validation strictness levels.
- STRICT = 'strict'ο
- WARNING = 'warning'ο
- DISABLED = 'disabled'ο
- class sirnaforge.validation.config.ValidationStage(*values)[source]ο
-
Pipeline stages where validation can be applied.
- INPUT = 'input'ο
- TRANSCRIPT_RETRIEVAL = 'transcript_retrieval'ο
- ORF_ANALYSIS = 'orf_analysis'ο
- DESIGN = 'design'ο
- FILTERING = 'filtering'ο
- SCORING = 'scoring'ο
- OFF_TARGET = 'off_target'ο
- OUTPUT = 'output'ο
- class sirnaforge.validation.config.ValidationConfig(*, default_level: ValidationLevel = ValidationLevel.STRICT, stage_levels: dict[~sirnaforge.validation.config.ValidationStage, ~sirnaforge.validation.config.ValidationLevel]=<factory>, validate_sequences: bool = True, validate_ranges: bool = True, validate_consistency: bool = True, validate_biology: bool = True, max_validation_errors: Annotated[int, ~annotated_types.Ge(ge=1)] = 100, collect_all_errors: bool = False, batch_size: Annotated[int, ~annotated_types.Ge(ge=1)] = 1000, enable_caching: bool = True)[source]ο
Bases:
BaseModelConfiguration for validation system.
- default_level: ValidationLevelο
- stage_levels: dict[ValidationStage, ValidationLevel]ο
- get_level_for_stage(stage: ValidationStage) ValidationLevel[source]ο
Get validation level for a specific stage.
- is_enabled_for_stage(stage: ValidationStage) bool[source]ο
Check if validation is enabled for a stage.
- should_fail_on_error(stage: ValidationStage) bool[source]ο
Check if validation errors should cause failures.
- model_config = {}ο
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class sirnaforge.validation.config.ValidationPresets[source]ο
Bases:
objectPredefined validation configurations.
- static development() ValidationConfig[source]ο
Configuration for development environment.
- static production() ValidationConfig[source]ο
Configuration for production environment.
- static testing() ValidationConfig[source]ο
Configuration for testing environment.
- static performance() ValidationConfig[source]ο
Configuration optimized for performance.
Validation Middlewareο
Validation middleware for integrating validation into the siRNA design workflow.
- class sirnaforge.validation.middleware.ValidationReport(stage: ValidationStage)[source]ο
Bases:
objectComprehensive validation report for a workflow stage.
- __init__(stage: ValidationStage)[source]ο
Initialize validation report.
- add_item_result(result: ValidationResult) None[source]ο
Add validation result for an individual item.
- class sirnaforge.validation.middleware.ValidationMiddleware(config: ValidationConfig)[source]ο
Bases:
objectMiddleware for integrating validation throughout the workflow.
- __init__(config: ValidationConfig)[source]ο
Initialize validation middleware.
- validate_input_parameters(params: DesignParameters) ValidationReport[source]ο
Validate input design parameters.
- validate_transcripts(transcripts: list[TranscriptInfo]) ValidationReport[source]ο
Validate transcript data after retrieval.
- validate_design_results(design_result: DesignResult) ValidationReport[source]ο
Validate siRNA design results.
- validate_dataframe_output(df: DataFrame, schema_type: str) ValidationReport[source]ο
Validate DataFrame output against pandera schemas.
- validate_transcript_id_consistency(transcripts: list[TranscriptInfo], candidates: list[SiRNACandidate], orf_data: DataFrame | None = None) ValidationReport[source]ο
Validate consistency of transcript IDs across datasets.
Validation Utilitiesο
Validation utilities for data consistency and cross-validation.
- class sirnaforge.validation.utils.ValidationResult(is_valid: bool = True)[source]ο
Bases:
objectContainer for validation results.
- merge(other: ValidationResult) None[source]ο
Merge another validation result into this one.
- class sirnaforge.validation.utils.ValidationUtils[source]ο
Bases:
objectUtility functions for data validation.
- static validate_nucleotide_sequence(sequence: str, allow_ambiguous: bool = True) ValidationResult[source]ο
Validate nucleotide sequence composition.
- static validate_sirna_length(sequence: str) ValidationResult[source]ο
Validate siRNA sequence length.
- static validate_parameter_consistency(params: DesignParameters) ValidationResult[source]ο
Validate design parameter consistency.
- static validate_candidate_consistency(candidate: SiRNACandidate) ValidationResult[source]ο
Validate siRNA candidate internal consistency.
- static validate_dataframe_schema(df: DataFrame, schema_type: str) ValidationResult[source]ο
Validate DataFrame against appropriate pandera schema.
- static validate_transcript_ids_consistency(candidate_ids: set[str], orf_ids: set[str], transcript_ids: set[str]) ValidationResult[source]ο
Validate consistency of transcript IDs across datasets.
- static validate_biological_constraints(candidate: SiRNACandidate) ValidationResult[source]ο
Validate bioinformatics-specific constraints.
- static cross_validate_pydantic_pandera() ValidationResult[source]ο
Cross-validate Pydantic model constraints with Pandera schema constraints.
Utilitiesο
Logging Utilitiesο
Logging utilities for siRNAforge toolkit.
This module provides a single point to configure logging for both console and an optional centralized log file. Call configure_logging once at application startup (CLI entrypoint) to enable file logging. Individual modules should use get_logger(__name__) to obtain a configured logger.
- sirnaforge.utils.logging_utils.configure_logging(level: str | None = None, log_file: str | None = None) None[source]ο
Configure root logger: console + optional rotating file handler.
- Parameters:
level β Logging level name (DEBUG/INFO/WARNING/ERROR). If None, uses INFO.
log_file β Path to central log file. If None, will read env var SIRNAFORGE_LOG_FILE. If still None, no file handler is added.
- sirnaforge.utils.logging_utils.get_logger(name: str, level: str | None = None) Logger[source]ο
Get a logger with standard configuration.
This will return a child logger of the root logger configured by configure_logging. For scripts that donβt call configure_logging, get_logger will still set a console handler on first use.
Cache Utilitiesο
Shared cache helpers for siRNAforge.
Centralizes cache path resolution so every subsystem honors the same SIRNAFORGE_CACHE_DIR / XDG cache layout, and the producer-version stamping that lets us discard artifacts a known-bad writer left on disk.
- sirnaforge.utils.cache_utils.resolve_cache_subdir(subdir: str, *, override: str | PathLike[str] | None = None) Path[source]ο
Resolve a writable cache directory for the requested subdir.
The lookup order matches ReferenceManager: explicit override, env vars, XDG, $HOME/.cache, workspace-local fallback, then temp dir.
- sirnaforge.utils.cache_utils.stable_cache_key(payload: Mapping[str, Any]) str[source]ο
Create a deterministic sha256 digest for arbitrary JSON-serializable data.
- sirnaforge.utils.cache_utils.LEGACY_PRODUCER_VERSION = '1.0'ο
Version attributed to artifacts written before producer stamping existed.
CacheMetadata.version has always defaulted to this string, so pre-existing metadata reads back as βproduced by the pre-versioning writerβ without needing a migration step.
- sirnaforge.utils.cache_utils.PRODUCER_VERSION_FIELD = 'producer_version'ο
Key under which an artifact stamp records the version that produced it.
Manager-backed caches keep the same value in CacheMetadata.version; sidecar stamps have no such document, so they carry this field. Naming it once keeps the writer (write_artifact_stamp) and the reader (is_artifact_stamp_current) from drifting apart. Only artifact classes that are actually validated somewhere are registered below - a constant nobody checks would read as a guarantee we do not give.
- sirnaforge.utils.cache_utils.current_producer_version(artifact_class: str) str[source]ο
Return the producer version to record for artifact_class.
Unregistered classes report the legacy version: registering a class is what opts it in, so a new cache namespace can never invalidate itself by accident.
- sirnaforge.utils.cache_utils.normalize_producer_version(recorded: object) str[source]ο
Coerce a recorded producer version into a comparable string.
Missing values (None, NaN from a parquet column that did not exist yet, an empty string) all mean the same thing: the artifact predates stamping.
- sirnaforge.utils.cache_utils.is_producer_version_current(artifact_class: str, recorded: object) bool[source]ο
Whether an artifactβs recorded producer version is the current one.
- sirnaforge.utils.cache_utils.log_discarded_artifact(artifact_class: str, artifact: Path | str, reason: str) None[source]ο
Warn that a stale cache artifact is being dropped.
Deliberately WARNING, not DEBUG: this is the one line that explains why a run suddenly spends time regenerating or re-downloading a reference.
- sirnaforge.utils.cache_utils.STAMP_FULL_DIGEST_MAX_BYTES = 67108864ο
Largest output we are willing to read end-to-end on every cache hit.
A combined miRNA FASTA is a few MB, so it is digested whole for a few milliseconds. A BWA-MEM2 index or a transcriptome is gigabytes: reading it in full on every hit would cost more than the cache saves, so those fall back to DIGEST_MODE_SAMPLED.
- sirnaforge.utils.cache_utils.STAMP_SAMPLE_BYTES = 4194304ο
Head/tail window digested for outputs above the full-digest budget.
- sirnaforge.utils.cache_utils.artifact_stamp_path(artifact: Path) Path[source]ο
Return the sidecar stamp path for a derived artifact or index prefix.
- sirnaforge.utils.cache_utils.fingerprint_outputs(outputs: Sequence[Path], *, full_digest_max_bytes: int | None = None) dict[str, dict[str, Any]][source]ο
Fingerprint the bytes an artifact is actually made of.
Keyed by basename so the fingerprint survives a re-homed cache directory, and so a multi-file artifact (a BWA index prefix has four members) records one entry per member and therefore proves its own completeness on read.
Every member records its exact size; the digest is full below STAMP_FULL_DIGEST_MAX_BYTES and sampled above it. Size alone already catches every truncation, which is the failure mode that actually happens.
- sirnaforge.utils.cache_utils.fingerprint_inputs(inputs: Sequence[Path]) dict[str, str][source]ο
MD5 each input file, keyed by position and basename.
Position keeps duplicate basenames distinct; basenames rather than full paths keep the fingerprint stable when a cache directory is re-homed (containers mount it elsewhere). Callers that already hold a digest for a large file should pass it directly rather than paying for a second full read.
- sirnaforge.utils.cache_utils.write_artifact_stamp(artifact_class: str, artifact: Path, *, inputs: Mapping[str, str] | None = None, outputs: Sequence[Path] | None = None, extra: Mapping[str, Any] | None = None) Path[source]ο
Record the producer version, input fingerprint and output bytes of an artifact.
outputs lists the files the artifact consists of, and defaults to the artifact itself. Multi-file artifacts must pass their members explicitly: a BWA index prefix is not a file, and the four files behind it are what has to be verified.
- sirnaforge.utils.cache_utils.read_artifact_stamp(artifact: Path) dict[str, Any] | None[source]ο
Read a derived artifactβs stamp, or None when it is absent/unreadable.
- sirnaforge.utils.cache_utils.discard_artifact_stamp(artifact: Path) None[source]ο
Remove a derived artifactβs stamp so it cannot vouch for a rebuilt file.
- sirnaforge.utils.cache_utils.is_artifact_stamp_current(artifact_class: str, artifact: Path, *, inputs: Mapping[str, str] | None = None, max_age_days: int | None = None) bool[source]ο
Whether a derived artifact may be reused.
Answers βwas it produced by the current code, from exactly these inputs, recently enough - and are its own bytes still the bytes we stampedβ. The last clause is what makes a stamp unable to vouch for an artifact that was truncated or corrupted after it was written, so callers may reuse on a True answer alone.
CLI Input Helpersο
Shared CLI input parsing and validation helpers.
These helpers are intentionally small and side-effect free so that Typer/Rich commands can stay focused on orchestration and UX.
- sirnaforge.utils.cli_inputs.parse_csv(value: str) list[str][source]ο
Split a comma-separated string into normalized non-empty tokens.
- sirnaforge.utils.cli_inputs.parse_required_csv(value: str, *, error_message: str) list[str][source]ο
Parse a required CSV argument, raising ValueError when empty.
- sirnaforge.utils.cli_inputs.parse_optional_csv(value: str | None, *, error_message: str) list[str] | None[source]ο
Parse an optional CSV argument.
Returns None when value is None, otherwise returns a list of tokens. Raises ValueError when the provided string contains no usable tokens.
- sirnaforge.utils.cli_inputs.extract_override_species_from_offtarget_indices(offtarget_indices: str | None) list[str] | None[source]ο
Extract unique species tokens from an offtarget indices override string.
Validates the expected
species:/index_prefixformat for each entry. Returns None when no override is provided.
Control Candidatesο
Helpers for injecting control candidates into design results.
- sirnaforge.utils.control_candidates.inject_dirty_controls(design_result: DesignResult, count: int = 2) list[SiRNACandidate][source]ο
Append clearly labelled βdirtyβ control candidates to a design result.
βDirtyβ controls are not synthetic sequences. We intentionally reuse the lowest-scoring rejected candidates from the same run so every control is a plausible design that simply failed QC (GC range, off-target score, etc.). Carrying these borderline guides forward guarantees that the downstream off-target pipeline receives at least a couple of sequences that should light up in the reports, making it easier for users to confirm the workflow is wired correctly.
The clones retain their original guide/passenger sequences and metadata but are marked with
DIRTY_CONTROL. They are appended to bothcandidatesandtop_candidatesso that subsequent stages (CSV export, Nextflow off-target analysis, etc.) see the controls exactly where they expect normal guides. IDs are suffixed with__DIRTY_CONTROL_<n>for clarity.- Parameters:
design_result β Aggregated design result to augment in-place.
count β Number of controls to add (default: 2).
- Returns:
List of control candidates that were appended. Returns an empty list if the design result already contains controls or there are no candidates to copy.
FASTA Utilitiesο
Shared FASTA parsing helpers used across siRNAforge modules.
Modification Patternsο
Utility functions for applying chemical modification patterns to siRNA candidates.
This module provides functions to apply standard modification patterns to siRNA candidates during the design workflow, enabling automated annotation of chemical modifications for downstream synthesis and analysis.
- sirnaforge.utils.modification_patterns.apply_standard_2ome_pattern(sequence: str) list[ChemicalModification][source]ο
Apply standard alternating 2β-O-methyl pattern.
This is the industry-standard pattern providing balanced nuclease resistance and RISC loading efficiency.
- Parameters:
sequence β RNA sequence to modify
- Returns:
List containing one ChemicalModification with alternating positions
- sirnaforge.utils.modification_patterns.apply_minimal_terminal_pattern(sequence: str) list[ChemicalModification][source]ο
Apply minimal terminal modifications for cost-effective protection.
Modifies only the 3β terminal positions to provide basic nuclease resistance while minimizing synthesis cost.
- Parameters:
sequence β RNA sequence to modify
- Returns:
List containing one ChemicalModification with terminal positions
- sirnaforge.utils.modification_patterns.apply_maximal_stability_pattern(sequence: str) list[ChemicalModification][source]ο
Apply maximal stability pattern for in vivo applications.
Fully modified pattern similar to FDA-approved therapeutics, providing maximum nuclease resistance and extended serum half-life.
- Parameters:
sequence β RNA sequence to modify
- Returns:
List containing ChemicalModifications (2OMe on all positions, PS at terminals)
- sirnaforge.utils.modification_patterns.get_modification_pattern(pattern_name: str, sequence: str) list[ChemicalModification][source]ο
Get modification pattern by name.
- Parameters:
pattern_name β Name of the pattern (standard_2ome, minimal_terminal, maximal_stability, none)
sequence β RNA sequence to apply pattern to
- Returns:
List of ChemicalModification objects
- Raises:
ValueError β If pattern_name is not recognized
- sirnaforge.utils.modification_patterns.apply_modifications_to_candidate(candidate: SiRNACandidate, pattern_name: str = 'standard_2ome', overhang: str = 'dTdT', target_gene: str | None = None) SiRNACandidate[source]ο
Apply chemical modifications to a siRNA candidate.
This function annotates both guide and passenger strands with the specified modification pattern and overhang, updating the candidateβs metadata fields.
- Parameters:
candidate β SiRNACandidate to annotate
pattern_name β Modification pattern to apply (default: standard_2ome)
overhang β Overhang sequence (default: dTdT)
target_gene β Optional target gene name for metadata
- Returns:
Updated SiRNACandidate with modification metadata
Resource Resolverο
Utilities for resolving user-provided input resources.
Supports downloading transcript FASTA files from remote locations and normalises them into local paths that the workflow can consume.
- class sirnaforge.utils.resource_resolver.InputSource(original: str, local_path: Path, source_type: str, downloaded: bool, size_bytes: int, sha256: str | None = None)[source]ο
Bases:
objectNormalized representation of a workflow input resource.
- sirnaforge.utils.resource_resolver.resolve_input_source(input_location: str, destination_root: Path, *, timeout: float = 30.0) InputSource[source]ο
Resolve a workflow input location into a local path.
- Parameters:
input_location β Raw string provided by the user (path or URI).
destination_root β Directory where downloaded inputs should be stored.
timeout β Timeout for remote downloads in seconds.
- Returns:
InputSource describing the normalized local resource.
- Raises:
FileNotFoundError β If a local file doesnβt exist.
ValueError β If the URI scheme is unsupported.
httpx.HTTPStatusError β If the remote download fails with non-2xx status.
Species Utilitiesο
Shared helpers for reasoning about species labels.
These utilities centralize the normalization and categorization rules we use when aggregating off-target hits across genome/transcriptome and miRNA pipelines. The helpers intentionally accept very loose inputs (common names, scientific labels, assembly identifiers) so downstream callers can rely on a single implementation when deciding whether a hit should be treated as human-specific.
- sirnaforge.utils.species.bucket_species(label: str | None) str[source]ο
Map an arbitrary label to
"human"or"other".
- sirnaforge.utils.species.human_vs_other_totals(counts: Mapping[str, int]) tuple[int, int][source]ο
Collapse per-species hit counts into
(human, other)totals.
- sirnaforge.utils.species.is_human_species(label: str | None) bool[source]ο
Return
Truewhen the provided label should be bucketed as human.
- sirnaforge.utils.species.normalize_species_label(label: str | None) str[source]ο
Normalize a species label to a lowercase slug.
The transformation removes punctuation, collapses whitespace, and replaces runs of non-alphanumeric characters with a single underscore so strings like
"Homo sapiens (GRCh38)"become"homo_sapiens_grch38".
Typed Decoratorsο
Typed wrappers for third-party decorators used across models.
These wrappers preserve runtime behavior while helping static analyzers (mypy/Pylance) keep function signatures precise when decorator stubs are insufficiently typed.
- sirnaforge.utils.typed_decorators.field_validator_typed(*field_names: str, **kwargs: Any) Callable[[F], F][source]ο
Typed wrapper around pydantic
field_validator.
- sirnaforge.utils.typed_decorators.field_serializer_typed(*field_names: str, **kwargs: Any) Callable[[F], F][source]ο
Typed wrapper around pydantic
field_serializer.
- sirnaforge.utils.typed_decorators.check_types_typed(func: F) F[source]ο
Typed wrapper around pandera
check_types.
Unified Cacheο
Unified cache manager for all sirnaforge reference databases.
Provides a single interface to manage miRNA databases, transcriptomes, and indices using composition and protocol-based design.
- class sirnaforge.utils.unified_cache.CacheStats[source]ο
Bases:
TypedDictStatistics for a cache component.
- class sirnaforge.utils.unified_cache.ClearResult[source]ο
Bases:
TypedDictResult of a cache clear operation.
- class sirnaforge.utils.unified_cache.CacheComponent(*args, **kwargs)[source]ο
Bases:
ProtocolProtocol for cache components.
- cache_info() CacheStats[source]ο
Get cache statistics.
- clear_cache(confirm: bool = False) ClearResult[source]ο
Clear the cache.
- __init__(*args, **kwargs)ο
- class sirnaforge.utils.unified_cache.UnifiedCacheManager[source]ο
Bases:
objectUnified manager for all sirnaforge caches.
Uses composition to combine miRNA and transcriptome caches into a single, easy-to-use interface.
- get_info(include_mirna: bool = True, include_transcriptome: bool = True) dict[str, CacheStats][source]ο
Get cache info for selected components.
- Parameters:
include_mirna β Include miRNA cache stats
include_transcriptome β Include transcriptome cache stats
- Returns:
Dictionary mapping component name to cache stats
- clear(clear_mirna: bool = False, clear_transcriptome: bool = False, dry_run: bool = False) dict[str, ClearResult][source]ο
Clear selected cache components.
- Parameters:
clear_mirna β Clear miRNA databases
clear_transcriptome β Clear transcriptomes and indices
dry_run β Show what would be deleted without deleting
- Returns:
Dictionary mapping component name to clear results
Chemical Modificationsο
Helper functions for working with siRNA chemical modifications metadata.
This module provides utilities for: - Parsing FASTA headers to extract modification metadata - Loading metadata from JSON sidecar files - Encoding/decoding modification annotations
- sirnaforge.modifications.parse_chem_mods(chem_mods_str: str) list[ChemicalModification][source]ο
Parse ChemMods field from FASTA header.
- Parameters:
chem_mods_str β String like β2OMe(1,4,6,11)+2F()β
- Returns:
List of ChemicalModification objects
- sirnaforge.modifications.parse_provenance(prov_str: str, url: str | None = None) Provenance | None[source]ο
Parse Provenance field from FASTA header.
- Parameters:
prov_str β String like βPatent:US10060921B2β
url β Optional URL string
- Returns:
Provenance object or None
- sirnaforge.modifications.parse_header(record: SeqRecord) dict[str, Any][source]ο
Parse FASTA header to extract metadata.
- Parameters:
record β BioPython SeqRecord from FASTA file
- Returns:
Dictionary with parsed metadata fields
- sirnaforge.modifications.load_metadata(json_path: str | Path) dict[str, StrandMetadata][source]ο
Load and validate metadata from JSON sidecar file using Pydantic.
- Parameters:
json_path β Path to JSON file containing metadata
- Returns:
Dictionary mapping strand IDs to StrandMetadata objects
- Raises:
ValidationError β If JSON data doesnβt match StrandMetadata schema
- sirnaforge.modifications.merge_metadata_into_fasta(fasta_path: str | Path, metadata_path: str | Path, output_path: str | Path) int[source]ο
Merge metadata from JSON into FASTA headers.
Uses Pydantic for automatic validation of metadata.
- Parameters:
fasta_path β Input FASTA file
metadata_path β JSON file with metadata
output_path β Output FASTA file with updated headers
- Returns:
Number of sequences with metadata applied
- Raises:
ValidationError β If metadata doesnβt match StrandMetadata schema
- sirnaforge.modifications.save_metadata_json(metadata_dict: dict[str, StrandMetadata], output_path: str | Path) None[source]ο
Save strand metadata to JSON file using Pydantic serialization.
- Parameters:
metadata_dict β Dictionary mapping strand IDs to StrandMetadata objects
output_path β Path to output JSON file