.apply_peptide_batch_effects

proteopy.utils.apply_peptide_batch_effects(adata, batch_key, batches, *, flavor='subset_shift', n_peptides=2, log2fc=-1.0, fraction=1.0, log_space=False, random_state=None, inplace=True, verbose=False)[source]

Simulate peptide-specific batch effects in peptide-level data.

With flavor="subset_shift", n_peptides peptides are drawn per protein and their intensities are changed by the same fold change 2 ** log2fc in every sample of the affected batches. The drawn peptides then move together across batches, apart from the other peptides of their protein, mimicking batch effects that act on single peptides (ionisation, digestion, retention-time drift) rather than on whole proteins.

With \(B\) the samples of the affected batches and \(P\) the shifted peptides, the "subset_shift" flavor computes, in linear space (log_space=False) and in log2 space (log_space=True) respectively:

\[X'_{s,p} = X_{s,p} \cdot 2^{\mathrm{log2fc}} \qquad X'_{s,p} = X_{s,p} + \mathrm{log2fc} \qquad \text{for } s \in B,\ p \in P\]

All other values are unchanged.

Parameters:
  • adata (AnnData) – Peptide-level AnnData.

  • batch_key (str) – .obs column defining the batches. Observations with a missing batch label are never affected.

  • batches (int | Sequence) – Batches receiving the effect. A list gives the batch labels (values of .obs[batch_key]). An int draws that many batches at random. At least one batch must stay unaffected.

  • flavor (str) – Kind of batch effect. Only "subset_shift" is available.

  • n_peptides (int) – Number of peptides shifted per affected protein. Only proteins with more than n_peptides peptides are eligible, so each keeps at least one unshifted peptide. The same peptides are shifted in all affected batches.

  • log2fc (float) – Log2 fold change applied to the drawn peptides in the affected batches, e.g. -1 halves their intensities.

  • fraction (float) – Fraction of eligible proteins, randomly selected, that receive the effect.

  • log_space (bool) – If False, .X holds linear intensities and is multiplied by 2 ** log2fc. If True, .X is assumed to be log2-transformed and log2fc is added. Data in another log base must be converted to log2 first. Missing values stay missing. In linear space zeros stay zero; in log space every finite value is shifted.

  • random_state (int | None) – Seed for drawing batches, proteins and peptides. If None, a random seed is drawn and stored in .uns['batch_effect_simulation'].

  • inplace (bool) – If True, modify adata in place; else return a new AnnData.

  • verbose (bool) – If True, print the affected batches, the number of affected proteins and peptides, and where the annotations are stored.

Returns:

None if inplace=True, else a new AnnData. .X is dense. Adds:

  • .var['batch_effect']: True for the shifted peptides

  • .uns['batch_effect_simulation']: flavor, batch_key, the affected batches, n_peptides, log2fc, fraction, log_space, random_state, n_proteins_affected and n_peptides_affected

A second call overwrites both; shifts already applied to .X are kept.

Return type:

AnnData | None

Raises:
  • ValueError – If adata is not peptide-level, .obs[batch_key] has fewer than 2 batches, batches names unknown batches or all of them, or a numeric argument is out of range.

  • KeyError – If batch_key is not in .obs.

  • TypeError – If batches is neither an int nor a list of labels, or log_space is not a bool.

Warns:

UserWarning – If .X is sparse (it is densified), or if log_space does not match whether .X looks log-transformed.

Examples

Shift specific batches of log2-transformed data:

>>> import proteopy as pr
>>> pr.utils.apply_peptide_batch_effects(
...     adata,
...     batch_key="batch",
...     batches=["batch_1"],
...     log2fc=-3,
...     log_space=True,
... )