fr$notes, design_notes.txt and the Methods paragraph of summary.md: the moderation (continuous or binary moderator), quadratic, threshold and moderated-curvature arms held their null bands on the contest-3b substrate; the exponential arm did not (10 of 20 permuted scans with a selection; unit-p ratio 2.24) and remains opt-in, its reading printed beside any exponential result; a moderator with excess kurtosis above 1 is reported with the NR2 caution for heavy-tailed moderators and the pointer to the registered v1.9 candidate (rank inverse-normal transform of the moderator; not applied). The former "registered candidates" note is replaced. No statistic, parameter or selection changes; tests/test_engine.R and the linear-arm identity test in tests/test_frame.R assert it.tests/test_frame.R block 10 now writes its first report with genes = "none", so the "No gene annotation" assertion holds whether or not cpgdirection is installed (on a machine with cpgdirection, 1.6.0's check failed at that line). No change to any R function; the engine is bit-identical to 1.6.0, 1.5.0 and 1.4.0 (asserted by tests/test_engine.R).tewas_frame() declares a design and runs the registered v1.6 engine on it - a linear arm (the registered scan, asserted identical), a moderation arm (y x mod, optionally three-way), the non-linear departure arms (quadratic, threshold; type = "non-linear") and the exponential arm (type = "exponential"), a moderated-curvature arm, and frame_role = "outcome" (methylation as the outcome; identical statistics by partial-correlation symmetry, expression-tone reporting). Every arm is one focal regressor after a nuisance design (tewas_focal_stats()), so the engine and its residual-permutation stream run unchanged.tewas_report(): unit / DMR / probe tables (csv, html, md), the genome-wide unit scan, locus panels, the calibration figure, simple-slope and Johnson-Neyman panels for moderation, fitted-curve panels with the Sasabuchi test and the Fieller interval for the shape scan, and summary.md with the calibration of the scan first, the DMR tables, a how-to-read, and a Methods and a Results paragraph for the actual run.fig_link_<arm>.png and fig_shape.png draw each DMR's covariate-adjusted unit score against the phenotype with the trajectory of every arm that ran (linear, + quadratic, + threshold, + exponential; each the hierarchical model its unit p came from, solid across the central 90 % of the phenotype and dashed beyond, the quadratic extremum marked when inside the data); fig_moderation.png draws simple slopes at observed moderator quantiles (10th / 50th / 90th, ladder for ties; binary levels) over the partial residuals and the Johnson-Neyman band; fig_mod_curvature.png the simple curves and the curvature band of the moderated-curvature arm, and fig_surface.png its fitted surface (perspective and contour with the sample). Three-way moderation is drawn at the 10th and 90th percentile of the second moderator.tewas_genes(): for every probe, unit and DMR, the related genes through cpgdirection::cpg_gene_pairs() (one row per CpG x target gene; mapping provenance - EPICv2 manifest, tissue catalog, measured eQTM, SMR - separate from the pair's methylation-expression direction). tewas_report(genes = "auto") runs it when cpgdirection is installed; the DMR tables, the loci panels, summary.md (a Genes section and a genes column in every DMR table) and genes_by_probe.csv / gene_pairs.csv carry the result. cpgdirection is Suggested, not Imported.tewas_engine2() additionally returns members, unit_type (with singletons) and the unit q-values; the selection is unchanged (tests).inst/scripts/63_nr2_frames.R) is on record.tewas_engine2() is bit-identical to 1.4.0 (asserted in tests/).tewas_v16() and the kit functions tewas_scan_stats, tewas_run_units, tewas_anchor_table, tewas_ruler_stats, tewas_removability, tewas_inverse_normal, tewas_panel.inst/extdata; the registered kits in inst/scripts.inst/legacy (not loaded).| package | engine | what changed | registered by |
|---|---|---|---|
| 1.5.0 | v1.6 (unchanged) | packaging for the methods paper: the v0 prototype moved to inst/legacy (not loaded); tewas_v16() and the kit functions (tewas_scan_stats, tewas_run_units, tewas_anchor_table, tewas_ruler_stats, tewas_removability, tewas_inverse_normal, tewas_panel); the R11 anchor panel v3 and the alive ruler v4 in inst/extdata; the registered kits in inst/scripts; engine invariants in tests/. tewas_engine2() is bit-identical to 1.4.0 (asserted). | — |
| 1.4.0 | v1.6 | positives testable; absolute inflation guard (guard, guard_stats); bit-identical to 1.3.1 with guard = NULL | V16 (2026-09-12) |
| 1.3.1 | v1.5.1 | darkness amendment (R12 Amendment 1) | R12 |
| 1.3.0 | v1.5 | knowledge prior, anchors, the lens, chromosome-fold tempering | R12 |
| 1.2.1 | v1.4.1 candidate | combine = "minp" (not adopted; acat default = v1.4) | R10b |
| 1.2.0 | v1.2 / v1.4 | matched-filter arm, cross-fitted structural weights, coherence-gated flip | contest 3 / 3b |
| 1.1.1 | v1.1.1 | frozen reference engine (tewas_engine) | contest 2 |
guard, guard_stats); bit-identical to 1.3.1 with guard = NULL.tewas_frame() and tewas_v16() accept a SummarizedExperiment (a minfi GenomicRatioSet included) in place of the beta matrix: the beta values are taken from the "Beta" assay (or "M", converted; or the assay named by the new assay argument), chr and pos from rowRanges() when not given, and y, X, mod, mod2 may name columns of colData(). The object is unpacked into the matrix-path inputs and the run is the matrix-path run; tests/test_frame.R block 14 asserts identical selections and statistics on both paths (the object built in the test needs SummarizedExperiment, now imported).tewas_engine2(), tewas_engine(), tewas_removability() and tewas_simulate() restore the caller's .Random.seed on exit. Each seeds its own stream from its documented seed argument, as before (the permutation stream is unchanged; tests/test_engine.R asserts the engine identity), and the session's RNG state is no longer moved by a run.tewas_granges() returns the selected regions ("dmrs"), every tested unit ("units") or every probe ("probes") of a frame arm (including "shape") or of a tewas_v16() result as a GRanges, with the table's columns as metadata. GenomicRanges, IRanges, SummarizedExperiment and methods are imported.tewas_panel() decompresses the shipped panels with a base R gzfile() connection and parses the text with data.table::fread(text = ), instead of handing the .csv.gz path to fread(), which requires the R.utils package on the build machine (the Bioconductor build report for 0.99.0 failed in the vignette at that point). The tables read are identical; no other change.tewas_simulate(): a small synthetic array with three planted loci, so that every example, the vignette and the tests run in seconds on data whose truth is known.tewas_v16() runs on an array that carries no anchor-panel probe (a synthetic array, a targeted panel) without the knowledge layer, with a message and versions$knowledge = FALSE, instead of stopping; on a real 450k / EPIC array nothing changes.tewas_engine) and the calibration-set and lens helpers (tewas_calibration, tewas_apply_calib, tewas_calibration_spec, tewas_gain, tewas_temper, tewas_roles) are internal: they are called by the engine and by the registered kits, which run against the deposited tarballs, and were never part of a user analysis.tewas (the linear scan, the frame layer, the report, the genes, the standing of each arm); inst/scripts and inst/legacy removed from the package (in the deposit).Depends: R (>= 4.5.0); biocViews.