pbcheck audit report

1. Header

pbcheck audit of '(no file)'

pbcheck 0.1.0, generated 2026-09-06T07:37:08Z.

Status: complete

This is a pbcheck v0.1.0 audit of one stratum of one file. It measures how a naive per-cell test and a donor-pseudobulk test behave on this data under a donor-permutation null. It is run outside pbcheck's pre-registered Phase 0 protocol, is not a Phase 0 measurement, and makes no claim about any publication or about whether any reported result is true.

2. Read-out

Under donor permutation, with no true signal to find, the naive per-cell test calls a median of 6915 genes (86.44% of the 8000-gene universe; Monte-Carlo SE 1.018) over 1000 permutations; on the real labels it calls 6892. Both counts are corrected over the whole universe on their own (solo BH).

The naive arm's inflation factor lambda is 144.7 (IQR 4.847): above the band 0.9 to 1.1, which is the donor-pseudobulk arm's band, shown here to describe the naive number and not as the naive arm's own criterion.

The donor-pseudobulk arm's lambda is 1 (inside the band 0.9 to 1.1); its permutation false-positive rate is 0.05 (MC SE 0.01541) and its floor a median of 0 genes; on the real labels it calls 0 genes, corrected across both arms together (paired BH).

8 donors in 'disease', 8 in 'ctrl'; 12868 distinct donor splits exist.

After the thin-donor filter (fewer than 10 cells or 1000 counts), 8 and 8 pseudobulk profiles remain.

Real-label calls over the permutation floor: the per-cell arm calls 0.9967 times its own floor, both counts corrected over the whole universe on their own (solo BH). The donor-pseudobulk arm calls 0 times its floor, both counts corrected across the two arms together (paired BH).

On this file, with condition labels shuffled between donors and therefore no real signal to find, the per-cell test still calls a median of 6915 of 8000 genes at FDR 0.05 (86.4%), corrected over the whole gene universe on its own (solo BH); on the real labels, corrected the same way, it calls 6892. A gene list produced by a per-cell test on this data cannot be separated from that floor. The donor is the replication unit this design supports. The donor-pseudobulk test called 0 genes on the real labels against a permutation median of 0, both corrected across the two arms together over the genes they have in common (paired BH).
Amendment 3 declares an operating envelope for the pseudobulk arm on synthetic oracles. For each donor-variance point it states the donor count per group at which the power target is reached, and each row says what the committed grid supports there: a point measured on the grid, or a count derived or extrapolated from it.
sigma_donor 0.2: at least 4 donors per group (power at least 0.6 at log2FC 1.0 in 200 genes; grid support 'not in the grid; Amendment 1 frontier only')
sigma_donor 0.35: at least 8 donors per group (power at least 0.6 at log2FC 1.0 in 200 genes; grid support 'ebayes power 0.793 at 8v8 (calibrated) -> n* <= 8')
sigma_donor 0.5: at least 13 donors per group (power at least 0.6 at log2FC 1.0 in 200 genes; grid support 'ebayes power 0.486 at 12v12, the largest n tested -> n* > 12')
sigma_donor 0.7: at least 23 donors per group (power at least 0.6 at log2FC 1.0 in 200 genes; grid support 'ebayes power 0.003 at 8v8 -> n* far above 8')
The arm's calibration was evaluated at one hard regime (sigma_donor 0.5, 8 against 8 donors) and nowhere else. pbcheck does not estimate sigma_donor for real data, so whether this stratum lies inside that envelope is not determined here.
Everything in this report is a diagnostic of this file: the naive arm's inflation factor and permutation floor, the pseudobulk arm's inflation factor, floor and false-positive rate as its negative control, and the bookkeeping of the shared gene universe. None of it is a Phase 0 result, and pbcheck does not rate this file against the Phase 0 decision rule.

3. What these words mean

lambda: the genomic inflation factor: the ratio of observed test statistics to the null expectation, with 1.0 meaning no inflation.

permutation floor: the number of genes a test calls under donor permutation, when condition labels carry no real signal; it is the test's own false-positive baseline on this data.

donor-permutation null: the null distribution built by reassigning condition labels between donors, keeping every donor's cells together, and rerunning the test on each reassignment.

gene universe: the fixed set of genes both arms are tested and corrected over, frozen before either arm sees the real labels.

replication unit: the unit whose independent draws the statistics assume; for donor data that unit is the donor, not the cell.

thin-donor filter: the rule that drops a donor's pseudobulk profile when it is built from too few cells or too few counts, rather than keeping a noisy profile.

operating envelope: the region of donor count and donor-to-donor variability that Amendment 3 declares for the pseudobulk arm on synthetic data; each of its points states the donor count per group at which the power target is reached, on the committed grid or by the derivation the grid support of that point names.

sigma_donor: a knob of pbcheck's synthetic simulator for how much donors differ from each other; it cannot be measured on your data, which is why the envelope question is left open.

Monte-Carlo SE: the standard error of a quantity estimated from a finite number of permutations; it shrinks as more permutations are drawn.

BH convention (solo vs paired): solo BH corrects an arm's p-values over the whole gene universe on its own; paired BH corrects both arms together over the genes common to both, so their real-label counts are directly comparable.

4. Design audit

Donors per group
groupdonors (pre-filter)pseudobulk profiles (post-filter)
ctrl88
disease88
Cells per donor (top 16 of 16; 0 more not shown)
donorcells
d00625
d01625
d02625
d03625
d04625
d05625
d06625
d07625
d08625
d09625
d10625
d11625
d12625
d13625
d14625
d15625

No batch columns were provided.

Design flags
FieldValue
donor nests in conditionTrue
imbalance ratio1
usable for pseudobulkTrue
flagsnone
Dropped cells
FieldValue
dropped, other condition0
dropped, other cell type0
dropped, missing donor0
dropped, missing condition0
dropped, missing cell type0

5. Counts check

Counts check
FieldValue
sourceX
passedTrue
reasonn/a
dtypeint32
values scanned80000000

Examples of the values checked: none.

6. Naive per-cell arm

Real-label counts
FieldValue
real-label calls, solo BH6892
real-label calls, paired BH6892
Top genes, naive arm
genepvalpadjlog2fcpct grouppct reference
g0232000.87650.99180.953
g050000-0.91310.9680.9938
g0636000.78210.99960.9932
g075200-0.75510.98280.9954
g128700-1.0710.82680.948
g1391001.1180.99880.9884
g162900-1.1890.83020.959
g1976000.97450.9930.961
g239800-1.0490.8880.9556
g2753000.79290.99980.9994
g3053001.1160.9970.9586
g345200-0.91930.93920.9798
g3643000.79220.99940.9984
g3779001.30.80920.5564
g3932000.94410.99960.9962
g4249001.0030.99860.9936
g4458001.4360.84920.5708
g452100-1.0330.84620.9438
g4581001.1630.91240.801
g4820000.9640.99960.996
g5247001.0190.960.8844
g5317001.0820.94360.799
g540500-1.1010.95080.9944
g584400-0.81060.99861
g6185000.96390.99520.9742
Naive inflation factor
FieldValue
lambda144.7
lambda IQR4.847
classabove_band
Solo permutation floor
FieldValue
median count6915
median fraction0.8644
IQR count44
bh modesolo
Monte-Carlo SE1.018
Paired permutation floor
FieldValue
median count6912
median fraction0.864
IQR count37.5
bh modepaired
Monte-Carlo SE2.3
Permutations, naive arm
FieldValue
requested1000
achieved1000
Machinery check of the permutation engine, not a criterion of any kind: the inflation factor of the empirical permutation p-values is 0.9884.

7. Donor-pseudobulk arm

Real-label counts
FieldValue
real-label calls, paired BH0
Top genes, donor-pseudobulk arm
genepvalpadjlog2fc
g44589.85e-050.69841.373
g68370.00041870.6984-1.254
g38780.00060380.6984-1.218
g68620.00063010.69841.237
g37790.00066960.69841.199
g25220.00069980.69841.219
g16290.00076390.6984-1.177
g66320.0009640.69841.184
g76230.00096810.6984-1.171
g30530.0011820.69841.15
g50030.0012050.6984-1.153
g54050.0012090.6984-1.142
g33430.0012570.6984-1.133
g12870.0013610.6984-1.141
g53170.0014550.69841.14
g12770.001470.69841.131
g11180.0014840.6984-1.142
g04850.0015980.711.121
g13910.0017010.71631.125
g34250.00220.88011.094
g17170.0023390.8911.08
g61020.0025590.93021.077
g39730.0026820.93021.067
g68080.002790.93021.057
g45810.0032560.99511.042
Pseudobulk inflation and false-positive rate
FieldValue
lambda1
lambda IQR0.03131
classin_band
false-positive rate0.05
false-positive rate Monte-Carlo SE0.01541
Pseudobulk permutation floor
FieldValue
median count0
median fraction0
bh modepaired
Monte-Carlo SE0.01765
Permutations, pseudobulk arm
FieldValue
requested200
achieved200
Machinery check of the permutation engine, not a criterion of any kind: the inflation factor of the empirical permutation p-values is 0.9884.
Moderated eBayes technical detail
quantityvaluemeaning
d0320.8moderated eBayes prior degrees of freedom
shrinkage factorn/ahow strongly a gene's own variance is pulled toward the prior
complete poolingn/awhether every gene's variance was replaced by the prior outright
residual dfn/aresidual degrees of freedom feeding the moderated test

8. Shared universe bookkeeping

Frozen gene universe
FieldValue
size8000
minimum size200
builderpseudobulk_frozen

Builder rule: A gene enters the frozen universe when its total count across the surviving donor pseudobulk profiles is at least 15 and it is detected (count greater than 0) in at least ceil(0.5 * n_profiles) of them. The rule ignores the condition labels, so the tested gene set cannot shift when the labels are permuted (pbcheck.gene_universe.frozen_universe, applied after the thin-donor filter).

Thin-donor filter
FieldValue
min_cells10
min_counts1000
n_profiles_before16
n_profiles_after16
n_dropped0
dropped_profiles[]
per_threshold{'min_cells': 0, 'min_counts': 0}
semanticsdropped, not merged (spec section 1 item 2; Amendment 2 Change 7)
Shared universe, real-label bookkeeping
FieldValue
common tested8000
dropped for fairness0
no value in naive arm0
no value in pseudobulk arm0
pseudobulk arm complete for every geneTrue
Real split against the permutation range
FieldValue
real split inside permutation rangeyes
real split percentile in permutations1
Monte-Carlo detail
FieldValue
naive_floor_median6912
naive_floor_mc_se2.3
naive_floor_median_solo6915
pb_floor_median0
pb_floor_mc_se0.01765
pb_fp_rate0.05
pb_fp_rate_mc_se0.01541
bh_modepaired (mtc.bh_both_arms) over one common tested set — spec section 5
naive_floor_median_solo_bh_modesolo (mtc.bh_over_universe) — naive arm only
floor_gap6912
floor_gap_over_mc_se3005

9. Settings and provenance

Tool settings
settingvalue
n_perm_requested1000
n_perm_pb_requested200
seed0
top_n25
design_onlyno
naive_methodwilcoxon
naive_enginefast
pseudobulk_methodmoderated_ebayes
trendno
min_donors_per_group3
universe_min_total_count15
universe_min_prop0.5
fallback_universe_min_prop0.5
fallback_universe_min_size200
min_profiles_per_group_after_thin_filter3
Protocol constants
protocol constantvalue
alpha0.05
lambda_band[0.9, 1.1]
min_universe_size200
min_cells10
min_counts1000
Operating envelope
sigma_donormin donors per groupgrid support
0.24not in the grid; Amendment 1 frontier only
0.358ebayes power 0.793 at 8v8 (calibrated) -> n* <= 8
0.513ebayes power 0.486 at 12v12, the largest n tested -> n* > 12
0.723ebayes power 0.003 at 8v8 -> n* far above 8
Package versions
packageversion
numpy2.5.2
scipy1.18.0
pandas3.0.3
anndata0.13.2
scanpy1.12.2
statsmodels0.14.6
decoupler2.2.0
pydeseq20.5.4
Platform
FieldValue
platformWindows-11-10.0.26200-SP0
python3.12.10
Runtime by stage
stageseconds
loadn/a
prepare0.2831
design0.01699
counts0.2682
pseudobulk_build2.384
universe0.02562
real_label23.35
permutation_null62.79
rendern/a
The engine was measured on one synthetic oracle point (sigma_donor 0.5, 8 against 8 donors, 1500 genes), recorded in pilot/gate/synthetic_gate_2026-08-15.json; that measurement is not repeated on this file. Of the settings below, only the ones listed as protocol constants are pre-registered values taken from pbcheck.gate_config (alpha, lambda_band, min_universe_size, min_cells, min_counts); the permutation counts, the universe filter parameters, the fallback universe rule and the display settings are the tool's own and are not protocol values.

10. Footer

Generated by pbcheck 0.1.0. Protocol: docs/PHASE0_SPEC.md and docs/AMENDMENTS.md in the pbcheck repository.