mantispy.pp.detect_plate_position#
- mantispy.pp.detect_plate_position(adata, by='Metadata_Plate', reference='negcon', n_splits=5, min_controls=20, max_iter=10, tol=0.0001, seed=0, key_added='plate_position_detection', copy=False)[source]#
Test whether the plate-position correction generalizes, to gate it per plate.
A per-plate row and column effect is often mis-estimated rather than a real artifact: with few controls on a large grid, the apparent gradient is the controls’ own scatter, and
correct_plate_position()would then subtract signal. This is a correctability gate, not an artifact detector: it cross-validates the very model the corrector applies – the additive row and column median polish – and reports whether it predicts held-out controls better than their plate level. A plate is worth correcting only when that model generalizes.Per plate, on the control wells selected by
reference, each well is reduced to one value per grid position. Across cross-validation folds the row and column effects are fitted on the training controls by the same median polish ascorrect_plate_position(), and a plate level is taken as the median of the training controls once their effects are removed. Each held-out control is predicted from that level plus its own row and column effect, and a cross-validated coefficient of determination is formed per feature from the held-out residuals against the level alone, then summarized per plate.- Parameters:
adata (
AnnData) – Object to inspect, at cell or well resolution.by (
str(default:'Metadata_Plate')) – Column identifying the plate.reference (
str|None(default:'negcon')) – Wells to fit and score on, defaulting to the controls ("negcon"), unlikecorrect_plate_position(), which fits on every well by default; see there. Pass the samereferenceto both so the gate validates what the correction will remove.n_splits (
int(default:5)) – Number of cross-validation folds over the control wells.min_controls (
int(default:20)) – Fewest control wells a plate needs to be scored; a plate below it is recorded unscored.max_iter (
int(default:10)) – Maximum number of median-polish iterations, as incorrect_plate_position().tol (
float(default:0.0001)) – Convergence tolerance of the median polish, as incorrect_plate_position().seed (
int(default:0)) – Seed for the fold assignment.key_added (
str(default:'plate_position_detection')) – Key underuns["mantispy"]for the result table.copy (
bool(default:False)) – Return a modified copy instead of writing in place.
- Return type:
- Returns:
None, or the modified copy. Writes a per-plate table touns["mantispy"][key_added]with one row per plate and the columnsplate,n_controls,cv_r2_median,frac_features_positiveandreason. A positivecv_r2_medianmeans the correction generalizes to held-out controls and the plate is worth correcting; a value at or below zero means it predicts them no better than their plate level, socorrect_plate_position()would remove scatter and should be skipped. A value at or below zero is a decision to skip, not a verdict that the plate is clean, and a real but non-additive or weakly-estimated effect can score this way. A plate with too few controls is recorded with missing scores and areason; unscored means unknown, so inspect it rather than read it as negative.- Raises:
KeyError – If
referencenames a column that is not present.ValueError – If the reference column has missing values.
TypeError – If the reference column is not boolean.
Notes
This pairs with
correct_plate_position()as its gate: detect first, then pass the passing plates to the corrector’splatesargument so only they are corrected. It is also a quality-control signal on its own: a plate whose position structure is strong and generalizing can be excluded or inspected rather than corrected, which on multivariate profiles, where correcting rarely helps, is often the better choice. Whether correcting helps is a question for the downstream metric, not for this score.