.proteoform_group_simulator

proteopy.utils.proteoform_group_simulator(adata, *, n_iterations=1, n_mixed=1000, n_unmixed=1000, n_mixed_peptides=2, random_state=None, verbose=False)[source]

Iterate over peptide-level datasets with planted proteoform groups.

Each iteration draws proteins from adata and builds a new AnnData from their peptides:

  • mixed proteins: all peptides of a background protein plus n_mixed_peptides peptides of a donor protein, relabelled with the protein ID "{background}_{donor}". The two source proteins form two known proteoform groups.

  • unmixed proteins: all peptides of a protein, unchanged.

Background and unmixed proteins have at least two peptides; donor proteins at least n_mixed_peptides. All drawn proteins within an iteration are distinct.

Unmixed proteins are real proteins and may carry real proteoform groups.

Running a proteoform inference method on each yielded object and passing it to proteoform_simulation_metrics() estimates how well the method recovers proteoform groups in this dataset.

Parameters:
  • adata (AnnData) – Peptide-level AnnData with .var columns peptide_id and protein_id.

  • n_iterations (int) – Number of simulated datasets to yield.

  • n_mixed (int | Sequence[int]) – Number of mixed proteins per iteration.

  • n_unmixed (int | Sequence[int]) – Number of unmixed proteins per iteration.

  • n_mixed_peptides (int | Sequence[int]) – Number of donor peptides added to each mixed protein.

  • random_state (int | None) – Seed for the simulation. Iteration i depends only on adata, its parameters, random_state and i, not on n_iterations, so it is identical whether 5 or 50 iterations are requested. If None, a random seed is drawn and stored in .uns['proteoform_simulation'] so the run can be repeated.

  • verbose (bool) – If True, print the parameters of each iteration.

  • n_mixed

  • a (n_unmixed and n_mixed_peptides accept)

  • int (single)

  • iteration (n_iterations elements whose i-th element is used in)

  • exactly (or a sequence with)

  • iteration

  • mixed (unmixed ratio at a fixed n_mixed_peptides.)

  • the (e.g. to sweep)

  • mixed

Returns:

A single-pass generator of n_iterations peptide-level AnnData objects. .X is dense. Each object has, in addition to the columns of adata:

  • .var['protein_id']: simulated protein ID

  • .var['source_protein_id']: the peptide’s original protein

  • .var['simulation_type']: "mixed" or "unmixed"

  • .uns['proteoform_simulation']: iteration, random_state, n_mixed, n_unmixed and n_mixed_peptides of this iteration

Return type:

Iterator[AnnData]

Raises:

ValueError – If adata is not peptide-level, a sequence parameter does not have n_iterations elements, or adata has too few eligible proteins for any iteration.

Warns:

UserWarning – If .X is sparse (the simulated objects are dense), or if adata already holds proteoform inference results. These are copied into the simulated objects unchanged and must be recomputed.

Examples

>>> import pandas as pd
>>> import proteopy as pr
>>> records = []
>>> for sim in pr.utils.proteoform_group_simulator(
...     adata,
...     n_iterations=10,
...     n_mixed=500,
...     n_unmixed=500,
...     n_mixed_peptides=2,
...     random_state=42,
... ):
...     pr.tl.proteoform_group_inference(sim, method="copf")
...     metrics, _ = pr.utils.proteoform_simulation_metrics(sim)
...     records.append({**sim.uns["proteoform_simulation"], **metrics})
>>> results = pd.DataFrame(records)

Sweep the mixed:unmixed ratio in one call:

>>> sims = pr.utils.proteoform_group_simulator(
...     adata,
...     n_iterations=3,
...     n_mixed=[100, 250, 500],
...     n_unmixed=[900, 750, 500],
...     random_state=42,
... )

A single simulated dataset:

>>> sim = next(pr.utils.proteoform_group_simulator(adata))