methylation: combine_neg option; oracle compares both background variants and logs sesame's negative controls

This commit is contained in:
kemal committed 2026-09-29 00:36:44 +01:00
1 parent e5bf0dcee2
commit cdb95e72c1
3 files changed
+32 -22

No files matched your search

+9 -7
View File
@@ -88,9 +88,9 @@ def _finite(a: F64) -> F64:
return a[np.isfinite(a)]
def background(s: MethylSignals) -> tuple[F64, F64]:
"""Out-of-band background per channel (green, red): Infinium I OOB signal + negative controls."""
neg = np.array([t.casefold() == "negative" for t in s.ctrl_type], dtype=np.bool_)
def background(s: MethylSignals, combine_neg: bool = True) -> tuple[F64, F64]:
"""Out-of-band background per channel (green, red): Infinium I OOB signal (+ negative controls)."""
neg = np.array([combine_neg and t.casefold() == "negative" for t in s.ctrl_type], dtype=np.bool_)
red_i, grn_i = s.col == "R", s.col == "G"
oob_g = np.concatenate([s.oob_m[red_i], s.oob_u[red_i], s.ctrl_green[neg]])
oob_r = np.concatenate([s.oob_m[grn_i], s.oob_u[grn_i], s.ctrl_red[neg]])
@@ -118,9 +118,9 @@ def _ecdf(ref: F64): # type: ignore[no-untyped-def]
return f
def detection_p(s: MethylSignals) -> F64:
def detection_p(s: MethylSignals, combine_neg: bool = True) -> F64:
"""pOOBAH detection p-value per probe; 1 where masked."""
bg_g, bg_r = background(s)
bg_g, bg_r = background(s, combine_neg)
fg, fr = _ecdf(bg_g), _ecdf(bg_r)
red_i, t2 = s.col == "R", s.col == ""
m, u = np.nan_to_num(s.m, nan=0.0), np.nan_to_num(s.u, nan=0.0)
@@ -194,9 +194,11 @@ def noob_fit(ib: F64, oob: F64) -> NoobFit:
return NoobFit(mu, s, max(huber(ib)[0] - mu, 10.0))
def noob(s: MethylSignals, offset: float = NOOB_OFFSET) -> tuple[MethylSignals, NoobFit, NoobFit]:
def noob(
s: MethylSignals, offset: float = NOOB_OFFSET, combine_neg: bool = True
) -> tuple[MethylSignals, NoobFit, NoobFit]:
"""Background-corrected copy of ``s`` (probe and control signals); returns the green and red fits."""
bg_g, bg_r = background(s)
bg_g, bg_r = background(s, combine_neg)
ib_g, ib_r = in_band(s)
fit_g, fit_r = noob_fit(ib_g, bg_g), noob_fit(ib_r, bg_r)