mantispy.metrics.diagnose_testing#
- mantispy.metrics.diagnose_testing(adata, groupby='Metadata_Perturbation', reference='negcon', block='Metadata_Plate', n_draws=8, alpha=0.05, seed=0, n_permutations=200, *, method='ks')[source]#
Check whether differential testing is calibrated on this screen.
- Parameters:
adata (
AnnData) – Well-level profiles after the normalization and transform you plan to test with, since the results depend on both.groupby (
str(default:'Metadata_Perturbation')) – As indifferential_features().reference (
str|None(default:'negcon')) – As indifferential_features().block (
str|None(default:'Metadata_Plate')) – At well resolution, as indifferential_features(). At cell resolution it names the exchangeable unit for the permutation null, normally the well; the well-level default"Metadata_Plate"is read there as the physical well, and any other column is honored so the diagnosed null equals the null your test would run.n_draws (
int(default:8)) – Pseudo-treatments drawn from the controls for the empirical null. More draws resolve the false positive rate better and take longer.alpha (
float(default:0.05)) – Nominal rate the null is compared against.seed (
int(default:0)) – Seed for choosing which control wells stand in for a treatment. The two hit callers’ permutation nulls are seeded by the draw index instead, so they are identical across calls that differ only inseed.n_permutations (
int(default:200)) – Null size for the two hit callers; smaller is faster and coarser.method (
str(default:'ks')) – Keyword-only. Thehit_calling()method the cell-resolution checks measure,"ks"by default because the diagnostic is about pseudoreplication."mahalanobis"whitens the distances, which divides out the between-well signal the cell-shuffle null exists to expose, so it cannot show that inflation. It is not used at well resolution, which keeps each caller’s own default.
- Return type:
- Returns:
A frame with columns
check,value,expected,verdictandnote, one row per check that ran, where aFAILverdict means the check does not hold on this data. The empirical-null rows are absent when every null p-value came back non-finite, and the two hit-caller rows need at least eight reference wells.- Raises:
ValueError – At well resolution, no treatment has two wells, or there are fewer than four reference wells, leaving nothing to measure a null against. At cell resolution, the object is not stamped a known resolution (stamp it with
mantispy.io.stamp(), or aggregate to wells withaggregate()); or it has no complete, replicated well column, or ablocknaming noobscolumn, to draw the well-block null from; or fewer than six reference wells, too few to leave four for the null after a two-well pseudo-treatment.
Notes
At cell resolution the checks change, because cells within a well are not independent replicates and the well-level checks describe well-level testing. Control cells are relabeled as pseudo-treatments of whole control wells and put through the two cell-resolution hit callers under two nulls. Each row’s
notenames the block the null draws whole, and thehit_callingrows namemethodtoo, so there is no silent substitution of the test you meant:hit_calling well-block null rate/edistance well-block null rateThe caller drawing whole wells for its null, the design’s exchangeable unit. The count is compared against the upper tail of
Binomial(n_draws, alpha)as the well-level hit-caller rows are. This is the rate to trust.hit_calling cell-shuffle null rate/edistance cell-shuffle null rateThe same caller with the null permuting single cells instead of whole wells. Cells within a well share the well, so this shrinks the null spread by the cell count rather than the well count and runs above the well-block rate when cells are not exchangeable. The verdict compares the two: it fails when the cell-shuffle count exceeds both the well-block rate and the chance cutoff, the signature of pseudoreplication, and passes when the two rates agree.
At well resolution the checks and what each one detects:
null p < 0.05/null p < 0.01Control wells relabeled as treatments of the size yours have. The rate should match the nominal one. Heavy tails distort small p-values first, so a test can be calibrated at 0.05 and not at 0.01, which is closer to the range a false discovery rate works in.
null discoveriesHow many of those null p-values survive Benjamini-Hochberg. A count above zero means the q-values on the real data are optimistic by roughly that much.
hit_calling null rate/edistance null rateThe same relabeling applied to the two hit callers, counted over
n_drawsdraws. Both are permutation tests that are not fully calibrated at small control counts, so the count is compared against the upper tail ofBinomial(n_draws, alpha)instead of a fixed rate. At eight draws the smallest non-zero rate is 0.125, and a threshold below that would fail a calibrated screen a third of the time. Raisingn_drawssharpens the answer and moves the cutoff with it.rank test resolutionThe smallest p-value a Mann-Whitney test can return at your replication, compared with what multiple-testing correction requires. With three wells against 14 reference wells the floor is 2.9e-03 whatever the effect size, and
effect_size()then silently calls nothing.excess kurtosisHow far the features are from the normality a t-test assumes. It predicts the null checks above but is not a verdict on its own, since heavy tails matter less with enough wells per group.
wells per treatmentandtreatments sharing a {block} with the referenceThe replicate structure the other checks depend on. A treatment whose wells share no block with the reference cannot be tested.