Skip to content

SimulationResult

SimulationResult is the output wrapper returned by Experiment.run_records(...). It holds the list of AIRR record dicts, the underlying engine Outcome objects (for trace / replay / validation), legacy parent Outcomes when expand_clones produced fixed-size families, and lineage trees when clonal_lineage produced BCR tree output. Treat it as a list-like view of records plus the typed validators and export helpers below.

Common methods

The eight methods you'll reach for in real pipelines:

Method Purpose
.validate_records(refdata) Per-record AIRR-output correctness gate
.validate_families() Clonal family consistency gate (groups by clone_id)
.validate_families_with_parents(refdata=None) Parent-aware family validator
.to_dataframe(*, airr_strict=False) Return a pandas DataFrame with canonical AIRR columns
.to_tsv(path, *, airr_strict=True) Write TSV with AIRR coordinates, CIGAR placement offsets, and T / F booleans
.to_csv(path, *, airr_strict=False) Write CSV with Python record conventions by default
.to_fasta(path, *, prefix="seq") Write assembled sequences as FASTA
.to_fastq(...) / .to_paired_fastq(...) Write FASTQ; paired-end requires read_layout="paired_end"

clonal_repertoire returns ordinary SimulationResult records with clone_id and duplicate_count. clonal_lineage returns SimulationResultWithLineages, a subclass that adds .lineage_trees. Legacy expand_clones returns SimulationResult with .parents.

Record dicts, default CSV, and default DataFrames use 0-based, half-open biological coordinates and local per-segment CIGARs. airr_strict=True converts biological coordinates to 1-based closed intervals and prefixes CIGARs with query/reference offsets. Boolean conversion to T / F applies to strict TSV/CSV, not DataFrames. For reverse-strand records, biological query coordinates index the coding-oriented reverse complement of sequence; paired-read windows always index the observed sequence using 0-based, half-open intervals.

FASTQ exports (prose only)

The two FASTQ-emitting methods are documented in Export the results and Paired-end reads and FASTQ, and are intentionally omitted from the generated block below because their **quality_kwargs parameter is untyped (griffe rejects it under strict mode). Their public signatures:

result.to_fastq(
    path: str,
    *,
    quality: str = "illumina",       # "illumina" (trapezoid) or "constant"
    prefix: str = "seq",
    **quality_kwargs,                # see paired-end-fastq.md
) -> None

result.to_paired_fastq(
    r1_path: str,
    r2_path: str,
    *,
    quality: str = "illumina",
    overwrite: bool = False,
    **quality_kwargs,
) -> None

to_paired_fastq requires the experiment to have included .paired_end(r1_length=..., r2_length=..., insert_size=...) - otherwise it raises. It also refuses to overwrite an existing output file unless you pass overwrite=True.

Class reference

GenAIRR.result.SimulationResult

Bases: _ResultExport, _ResultValidation

List-like wrapper around a batch of AIRR records.

result[i] returns the i-th record dict; len(result) is the number of records; iteration yields records in order.

The original Outcome objects (with their full trace + revision history) are kept on .outcomes for advanced inspection — most users won't need them.

records property

The underlying list of record dicts. Mutation through this view propagates back into the result.

outcomes property

The underlying list of Outcome objects, or None when this :class:SimulationResult was built from records directly (e.g. loaded from a TSV).

parents property

Per-clone parent Outcome objects for clonal results; None for non-clonal results and for results built from records directly.

parents[c] is the recombination ancestor of clone c: every descendant record with record["clone_id"] == record["parent_id"] == c was produced by running the post-fork plan from this parent's :meth:final_simulation.

The parent Outcome carries the pre-fork addressed-choice .trace(), the pre-fork .events() ledger, the per-revision IR history (.revision(i)), and the final assembled IR (.final_simulation()). Use these for replay, lineage analysis, or building a parent-aware family validator (Slice 3+ scope).

The flat .outcomes list continues to carry only the descendant outcomes (one entry per AIRR record); parents live exclusively here. len(.parents) equals the clonal pipeline's n_clones; len(.outcomes) equals n_clones * per_clone.

from_outcomes(outcomes, refdata, *, id_prefix='seq', expose_provenance=False) classmethod

Build a :class:SimulationResult from a list of Rust Outcome objects + the refdata they ran against.

Each record's sequence_id is set to f"{id_prefix}{i}" (e.g. seq0, seq1, …) so AIRR-format consumers see a unique per-row identifier out of the box.

expose_provenance=True adds truth_v_call, truth_d_call, truth_j_call columns containing the originally-sampled allele names — distinct from the evidence-driven v_call / d_call / j_call fields, which reflect what an aligner would see. Pair them at the Python level to compute aligner-vs-truth accuracy without a side truth file.