mantispy.pp.regress_out#
- mantispy.pp.regress_out(adata, keys=('Metadata_CellCount',), by='Metadata_Plate', reference=None, key_added=None, copy=False)[source]#
Regress confounders out of every feature, within groups.
- Parameters:
adata (
AnnData) – Object to correct.keys (
Sequence[str] (default:('Metadata_CellCount',))) –obscolumns to regress out. Numeric columns enter directly; categorical ones are one-hot encoded with the first level dropped.by (
str|None(default:'Metadata_Plate')) – Fit separately within each group of this column, usually the plate, whichscanpy.pp.regress_out()cannot do.Nonefits one model globally.reference (
str|None(default:None)) – Rows to fit on:Nonefor all,"negcon"forMetadata_Control, or the name of a booleanobscolumn. With a reference, each feature is re-expressed at the reference rows’ mean covariate, and a covariate beyond the range the reference rows span is clipped to it, so no row is corrected by extrapolating the fit. Numeric covariates only.key_added (
str|None(default:None)) – Write tolayers[key_added]instead of overwritingX.copy (
bool(default:False)) – Return a modified copy instead of mutating in place.
- Return type:
- Returns:
None, or the modified copy. WritesXorlayers[key_added], where each feature is replaced by its residual plus the fitted value at an anchor: the mean over the whole object for a numeric covariate, and the group’s own mean for a categorical one, which keeps the units of the data. Withreference, the anchor is the reference rows’ mean within each group.- Raises:
KeyError – If any of
keysis not anobscolumn.ValueError – If a categorical covariate has missing values, or
referenceselects no rows or is given with a categorical covariate.
Notes
Missing and infinite values stay as they are, and a feature holding one is fitted on its finite rows. A group with no more rows than design columns is left uncorrected and logged.
Without a reference, every group is re-expressed at the pooled mean covariate, which removes a density difference between plates when every plate spans that value. A plate that does not span it is corrected by extrapolating its own fit, and a warning names it.
With
reference="negcon"the slope is estimated where density varies for technical reasons only. Fitted on every well of a screen whose treatments change density, the slope also carries the treatments’ own effects, so the correction erodes their phenotypes and moves the controls away from the centre a control-referenced normalization put them at. With few control wells per plate, pool them withby=Noneand a covariate that is comparable between plates, such as the log of each well’s cell count over its plate’s control median.Whether the cell count is a confounder at all depends on the screen. In the ORF and CRISPR arms of JUMP, whose plate layouts were not randomized, it is largely technical, and the recipe regresses it out [Chandrasekaran et al., 2023]. In a compound screen it is partly a treatment effect (a compound that kills cells is supposed to lower it), so regressing it out removes part of the phenotype along with the nuisance, and the recipe does not. Measure both ways before adopting either;
evaluate_correction()takes acovariatesargument for exactly this, andcytotoxicity()asks the question directly.A numeric covariate with a missing or infinite value is dropped from that group’s design and nothing is regressed out for it there, with a warning. A categorical covariate with a missing label is refused instead: the all-zero encoding of a missing category is also the encoding of the level
drop_firstremoved, so those rows would be corrected as the reference level and take every other row with them.