From 2b91d3c02b961abbd5dd808ccb2cdebbaf4054c2 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 23 Oct 2026 14:49:37 +0000 Subject: [PATCH] Report unplaced reads against noise, not the placement-validity tolerance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #236 relaxed `PLACEMENT_WEIGHT_SUM_TOL` from 1e-5 to 0.05 so that a candidate list truncated by the placement tool still counts as `:valid`. The `unplaced_reads` field of the clade-cumulus diversity payload reused that same constant as its reporting floor, so a placement at LWR 0.99 — whose remaining 1% genuinely never reached the tree — was silently reported as 0 unplaced reads. `Julia tests` on the merged #234 tree caught it: 5679 pass, 2 fail, both in `test/unit/test_clade_cumulus.jl` ("6. POST combined mode against a study `.jplace` artifact"), expecting 0.05 and 0.10 and getting 0. The push-run CI for #236 itself was cancelled by the workflow concurrency group, so the regression reached `main` unverified. Reporting now uses `PLACEMENT_WEIGHT_OVER_TOL` (1e-9) as its floor, which is what the metric actually means, and the comment records why the two tolerances are not interchangeable. The existing assertions cover it; no test change. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com> --- src/server/routes/clade_cumulus.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/server/routes/clade_cumulus.jl b/src/server/routes/clade_cumulus.jl index d140cda6..d864b16f 100644 --- a/src/server/routes/clade_cumulus.jl +++ b/src/server/routes/clade_cumulus.jl @@ -310,8 +310,15 @@ function _clade_cumulus_post_impl(req::HTTP.Request, study::String, run::String) for (ri, w) in taxa_rows row_weight[ri] = get(row_weight, ri, 0.0) + w end + # `unplaced_reads` reports how much of each row's abundance never + # reached the tree, so its floor is floating-point noise, not the + # *validity* tolerance. `PLACEMENT_WEIGHT_SUM_TOL` (0.05) exists so + # that a candidate list truncated by the placement tool stays + # `:valid`; reusing it here reported 0 unplaced reads for a + # placement at LWR 0.99 whose remaining 1% really is off the tree. + noise_floor = MetaManifold.CladeCumulus.PLACEMENT_WEIGHT_OVER_TOL short_rows = [(ri, 1.0 - wsum) for (ri, wsum) in row_weight - if wsum < 1.0 - MetaManifold.CladeCumulus.PLACEMENT_WEIGHT_SUM_TOL] + if 1.0 - wsum > noise_floor] unplaced_reads = OrderedDict{String,Float64}() for sc in scols col_vals = df[!, sc]