WHAT: smooths a histogram, locates peaks above peak_frac of the maximum,
and returns the valley between the peak pair maximising depth * min(height).
Returns NA when the distribution is unimodal – the honest answer, which then
routes threshold resolution to the unstained-control fallback.
WHY: for a bimodal marker the valley is the least-arbitrary cutoff available
and adapts to each sample's own staining intensity.
Arguments
- x
A vector of values.
- bins
The bins. Default
220L.- smooth
The smooth. Default
4.- peak_frac
The peak frac. Default
0.02.- min_gap_frac
The min gap frac. Default
0.06.- range_q
The range q. Default
c(0.001, 0.999).- min_rel_depth
minimum valley depth AS A FRACTION of the smaller of the two flanking peaks. This is the parameter that makes minority positive populations findable – see the note on scoring below.
- min_upper_frac
the upper mode must hold at least this fraction of events, so a cut cannot be placed out in the extreme tail where a handful of events form a bump.
- floor
no cut is accepted at or below this value. Callers pass the transformed value of zero signal,
transform$fn(0, marker): a stained population cannot sit below zero. Without it, the small bump that compensated events form below zero, next to the negative peak, scores as a deep separation, and the cut lands under the negative peak, so every cell is called positive. On one cohort that put 87% of CD45+ cells "Vd1+" and emptied every population defined as Vd1-. Default-Inf, no floor.- prefer
which qualifying valley to return.
"deepest", the default, takes the best-separated pair of modes."lowest"takes the qualifying valley nearest the bottom of the scale, which is what a gate meant to remove only NEGATIVE events needs: in whole blood the CD45 distribution has a negative mode, a dim mode (granulocytes) and a bright one (lymphocytes), the dim/bright valley is often the deepest, and taking it removed the granulocytes from the CD45+ parent. Used for the CD45 gate. Under"lowest"a valley also needsmin_lower_fracof the events below it, so a ripple in the tail of the negative mode does not count as a separation.- min_lower_frac
see
prefer. Default0.01.- details
when TRUE return a list carrying the cut plus the relative depth of the valley and why no cut was found, instead of the bare cut. The default returns exactly what it always has: one number or
NA_real_.threshold_uncertainty()uses the list form, because how deep a valley is determines how far the cut can move under resampling, and recomputing the smoothed histogram elsewhere would let the two drift apart.- noise_alpha
the family-wise rate at which counting noise alone may pass for a slope. A valley counts only where the density falls significantly from the first peak to it and rises significantly from it to the second, each judged against Poisson noise with a two-sided Bonferroni quantile over the non-overlapping smoothing windows (a SiZer-style test, Chaudhuri and Marron 1999). Relative depth alone does not see sample size: on single modes of 3,000 simulated events it found a valley in 81 of 150 samples, most of them below 95% of the events, and on a flat shoulder of a few events per bin it split the shoulder. Default
0.05;NAturns the test off.- ceiling
no cut is accepted at or above this value. Default
Inf; the viability step passes the dye's dominant mode to look for a minimum below it (seeapply_gate_hierarchy()).
