Estimates the two parameters of the detector noise model used by
unmix.gls(): a per-detector additive variance floor (read noise plus
any residual dark-offset contribution) and a per-detector photon
conversion factor counts.per.unit, such that
$$Var(y_d) = read.var_d + \mu_d / \kappa_d$$
Estimation uses the mean-variance relationship of the residual after
least-squares projection onto spectra (optionally augmented with
af.spectra). Residuals are orthogonal to the fitted values by
construction, so binning on the fitted value does not bias the variance
estimate. A degrees-of-freedom correction accounts for the variance
removed by the projection.
Best estimated on bead controls (no autofluorescence, no biological spread) or on an unstained cell control together with its AF dictionary. On fully stained samples, unmodelled spectral variation inflates both parameters; that is not necessarily wrong (it reflects true predictive uncertainty) but it is no longer a pure instrument measurement.
Usage
estimate.noise.model(
raw.data,
spectra,
af.spectra = NULL,
n.bins = 40L,
min.bin.n = 50L,
trim.quantile = 0.999,
verbose = TRUE,
af.pc.n = 5L,
af.raw.data = NULL,
af.basis.n.cells = 20000L,
read.var.floor = NULL,
file.id = NULL,
unstained.data = NULL,
dark.quantile = 0.95,
n.tranche = 10L
)Arguments
- raw.data
Numeric matrix (events x detectors), or a path to an FCS file. Detector columns must include all columns of
spectra.- spectra
Numeric matrix (fluorophores x detectors).
- af.spectra
Optional AF dictionary (AF components x detectors), as returned by
get.af.spectra(). Strongly recommended for cell controls.- n.bins
Integer, number of quantile bins per detector. Default
40.- min.bin.n
Integer, minimum events per bin. Default
50.- trim.quantile
Numeric, upper quantile of each detector discarded before binning, to exclude saturation. Default
0.999.- verbose
Logical. Default
TRUE.- af.pc.n
Integer, number of principal components to use to describe
af.spectra. Default is5.- af.raw.data
Optional numeric matrix, or a path to an FCS file, of individual autofluorescence-only events – typically the same unstained sample
af.spectrawas built from. When supplied, the AF shape basis is fit by PCA on these per-cell events (L-infinity normalised per event, matchingget.af.spectra()'s own convention) instead of on the rows ofaf.spectra.af.spectrarows are SOM node centroids, already compressed from the underlying cells; if within-node AF spread is substantially real rather than noise (checkshape.fracinattr(af.spectra, "af.model")), the centroids alone understate true per-cell AF shape diversity, and the basis fit here from raw events will need more components to reach the same variance-explained target. Ignored whenaf.spectraisNULL. DefaultNULL, which fits the basis onaf.spectraas before.- af.basis.n.cells
Integer, default
20000. Maximum events fromaf.raw.dataused for the PCA; downsampled if more are supplied. Only used whenaf.raw.datais supplied.- read.var.floor
Optional named numeric vector, per-detector additive
- file.id
Optional vector (character or factor), length
nrow(raw.data), identifying which source file/acquisition each row came from. When supplied, per-file residual means are subtracted before the mean-variance regression, so between-file offsets (gain drift, voltage differences across acquisition days) are not counted as photon-driven variance. Recommended wheneverraw.datawas pooled across multiple control files, e.g. frompool.scc.for.noise.model(). DefaultNULL.- unstained.data
Optional numeric matrix (events x detectors) of an unstained/AF-only control, used only to anchor the lower tranche of the linearity check at
dark.quantileof the true-dark distribution. WhenNULL, falls back todark.quantileofraw.dataitself, which is a weaker proxy since it is not a genuinely dark reference. DefaultNULL.- dark.quantile
Numeric in (0, 1), the quantile of
unstained.data(or ofraw.datawhenunstained.dataisNULL) used as the upper bound of the lowest linearity tranche. Default0.95.- n.tranche
Integer, number of intensity tranches for the linearity check. Default
10L.
Value
A named list:
read.varNamed numeric vector, additive variance floor per detector, in squared instrument units.
counts.per.unitNamed numeric vector, \(\kappa_d\).
kappa.pooledNumeric scalar, median of
counts.per.unit.fit.tableData frame of per-bin means and variances, for QC plotting.
r.squaredNamed numeric vector, per-detector regression fit.
curvature.coefNamed numeric vector, the quadratic coefficient of
variance ~ mean + mean^2fitted acrossn.trancheintensity tranches per detector. Negative indicates variance growing more slowly than linear at high signal (compression, e.g. approaching saturation); positive indicates faster-than-linear growth.curvature.pNamed numeric vector, the p-value of
curvature.coef. Values below roughly0.01indicate the linear mean-variance model is a poor fit for that detector's full range.curvature.tableData frame of per-tranche means, variances, and counts, one block per detector, for QC plotting – the same shape as
fit.tablebut at tranche rather than bin resolution.noise.floor.signalsqrt(read.var), in signal units, for passing to the existingnoise.floorargument of the C++ pipeline. Note the unit difference:read.varis a variance, the C++noise.flooris a signal level.read.var.sourceNamed character vector,
"external"or"regression"per detector, indicating whetherread.varcame fromread.var.flooror the fitted intercept.kappa.sourceNamed character vector,
"regression"or"pooled.median"per detector, flagging detectors where the fitted slope was non-positive andcounts.per.unitwas filled from the pooled median instead of measured directly. Treat these detectors'counts.per.unit, and any ratio computed from it, with caution.