P3: normalization fit (1.2.0 and 1.1.2), apply, polar, simurg normalize
- signal/normalization/numerics.py: vendor percentile, trimmean, MAD sigma (old/new), bisquare robust fits, float32/float64 typing and sequential sums reproduced exactly (ported from gtc2vcf, MIT) - signal/normalization/fit.py: outlier removal, offset, rotation, shear, scale, nn12/rr12, single-channel model for small Infinium I bins, exact and binned nearest-neighbour sweeps; vendor quirks marked QUIRK - signal/normalization/apply.py: affine transform and theta/R - pipeline/normalize.py + CLI `simurg normalize` - oracle GTCs rebuilt with -ffp-contract=off (aarch64 gcc fuses a*b+c by default, shifting the last bits); the old FMA oracle differed by <=4 ULP Result: transforms bit-identical to the oracle for all 36 GSA samples x 48 bins, for both normalization versions (3456/3456 bins, 0 ULP).
This commit is contained in:
1 parent
f1e22ab339
commit
95e4e41560
12 files changed
+1097
-14
No files matched your search
+23
-1
@@ -1,6 +1,7 @@
|
||||
"""``simurg`` command-line interface (spec §2, plan §14).
|
||||
|
||||
Available: ``version``, ``inspect`` (P1), ``ingest`` (P2). Later phases add the other commands of CLI-001.
|
||||
Available: ``version``, ``inspect`` (P1), ``ingest`` (P2), ``normalize`` (P3).
|
||||
Later phases add the other commands of CLI-001.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -252,5 +253,26 @@ def ingest_cmd(
|
||||
run_guarded(rep, lambda: run_ingest(opts, rep))
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------
|
||||
@app.command("normalize")
|
||||
def normalize_cmd(
|
||||
indir: Annotated[Path, typer.Option("--in", help="Output folder of `simurg ingest`.")],
|
||||
norm_version: Annotated[str, typer.Option("--norm-version", help="1.2.0 (current) or 1.1.2 (older)")] = "1.2.0",
|
||||
threads: Annotated[int, typer.Option("--threads", min=0, max=1024, help="Worker processes (0 = auto).")] = 0,
|
||||
force: Annotated[bool, typer.Option("--force", help="Replace existing outputs.")] = False,
|
||||
log_json: Annotated[bool, typer.Option("--log-json", "--json-log", help="JSON Lines log on stderr.")] = False,
|
||||
debug: Annotated[bool, typer.Option("--debug", help="Debug logging with tracebacks.")] = False,
|
||||
quiet: Annotated[bool, typer.Option("--quiet", "--no-progress", help="Suppress info messages.")] = False,
|
||||
) -> None:
|
||||
"""Fit per-bin normalization transforms and write normalized X/Y, theta and R (phase P3)."""
|
||||
from simurg.pipeline.normalize import NormalizeOptions, run_normalize
|
||||
|
||||
rep = Reporter(
|
||||
command="normalize", level="debug" if debug else "info", json_stderr=log_json, debug=debug, quiet=quiet
|
||||
)
|
||||
opts = NormalizeOptions(indir=indir, version=norm_version, threads=threads, force=force, argv=sys.argv[1:])
|
||||
run_guarded(rep, lambda: run_normalize(opts, rep))
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
app()
|
||||
Reference in new issue
Block a user