From 1ffaf8c1a3afb907b51f734d2df2bb6973c5f459 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Thu, 8 Oct 2026 10:40:09 +0100 Subject: [PATCH] Clarify likelihood implementation labels and menu priority --- REFERENCE.md | 8 ++++++++ dashboard.html | 24 +++++++++++++++++++----- pulse/setup_browser.js | 24 +++++++++++++++++++----- tests/browser_fixture.py | 29 +++++++++++++++++++++++++++++ tests/browser_setup.cjs | 8 ++++++++ 5 files changed, 83 insertions(+), 10 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index c40d623..7878bcc 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -319,3 +319,11 @@ seven-setup subset captured from autolens_profiling commit are unchanged; the catalogue is scoped to those setups for hermetic browser tests. It includes MGE/rectangular HST runs without reference candidates and without memory measurements, so empty-memory and useful-runtime behavior are both tested. + +Likelihood navigation labels known implementations explicitly as (JAX) or (Numba). +Unspecified implementation variants are omitted from the menu without relabelling +their evidence; existing direct links remain supported. Menu priority is Delaunay, +Rectangular, MGE, KNN, MGE Mass, Sersic, then other families alphabetically. + +Sersic retains one plain menu entry when only unclassified latent tools exist; +this does not assign a backend. Known Sersic variants replace that fallback. diff --git a/dashboard.html b/dashboard.html index b374bbb..6f6daf0 100644 --- a/dashboard.html +++ b/dashboard.html @@ -1158,9 +1158,11 @@ label(model) + (implementation === "numba" ? " (Numba)" - : implementation === "unknown" - ? " (implementation unspecified)" - : ""); + : implementation === "jax" + ? " (JAX)" + : model === "sersic" + ? "" + : " (implementation unspecified)"); const axes = { runtime: "Runtime", breakdown: "Breakdown", @@ -1481,8 +1483,20 @@ .map((s) => `${s.model}|${implementationFor(s)}`), ]), ] - .filter((choice) => !choice.startsWith("pixelized|")) - .sort(); + .filter((choice, _, all) => + !choice.startsWith("pixelized|") && + (!choice.endsWith("|unknown") || + (choice === "sersic|unknown" && !all.some((other) => + other.startsWith("sersic|") && other !== choice))), + ) + .sort((a, b) => { + const priority = ["delaunay", "rectangular", "mge", "knn", "mge_mass", "sersic"]; + const rank = (choice) => { + const index = priority.indexOf(choice.split("|")[0]); + return index < 0 ? priority.length : index; + }; + return rank(a) - rank(b) || a.localeCompare(b); + }); for (const choice of choices) { const [model, implementation] = choice.split("|"); const button = append( diff --git a/pulse/setup_browser.js b/pulse/setup_browser.js index c24a50c..15583ff 100644 --- a/pulse/setup_browser.js +++ b/pulse/setup_browser.js @@ -34,9 +34,11 @@ label(model) + (implementation === "numba" ? " (Numba)" - : implementation === "unknown" - ? " (implementation unspecified)" - : ""); + : implementation === "jax" + ? " (JAX)" + : model === "sersic" + ? "" + : " (implementation unspecified)"); const axes = { runtime: "Runtime", breakdown: "Breakdown", @@ -357,8 +359,20 @@ .map((s) => `${s.model}|${implementationFor(s)}`), ]), ] - .filter((choice) => !choice.startsWith("pixelized|")) - .sort(); + .filter((choice, _, all) => + !choice.startsWith("pixelized|") && + (!choice.endsWith("|unknown") || + (choice === "sersic|unknown" && !all.some((other) => + other.startsWith("sersic|") && other !== choice))), + ) + .sort((a, b) => { + const priority = ["delaunay", "rectangular", "mge", "knn", "mge_mass", "sersic"]; + const rank = (choice) => { + const index = priority.indexOf(choice.split("|")[0]); + return index < 0 ? priority.length : index; + }; + return rank(a) - rank(b) || a.localeCompare(b); + }); for (const choice of choices) { const [model, implementation] = choice.split("|"); const button = append( diff --git a/tests/browser_fixture.py b/tests/browser_fixture.py index 30b34dd..b17835b 100644 --- a/tests/browser_fixture.py +++ b/tests/browser_fixture.py @@ -186,6 +186,35 @@ def write(destination): readable.doc["records"].append(numba_row) (destination / "readable.html").write_text(board.render_html([readable])) + menu = copy.deepcopy(readable) + for model in ("mge_mass", "knn", "mge", "rectangular"): + for suffix in ("", "_numba"): + menu.doc["navigation"].append( + { + "dataset": "imaging", + "model": model, + "category": "scientific_entrypoint", + "path": f"scripts/imaging/{model}/likelihood_runtime{suffix}.py", + } + ) + menu.doc["navigation"].append( + { + "dataset": "imaging", + "model": "delaunay", + "category": "scientific_entrypoint", + "path": "scripts/imaging/delaunay/unknown.py", + } + ) + menu.doc["navigation"].append( + { + "dataset": "imaging", + "model": "sersic", + "category": "scientific_entrypoint", + "path": "scripts/imaging/sersic/latent_magnification.py", + } + ) + (destination / "menu-order.html").write_text(board.render_html([menu])) + isolated = copy.deepcopy(readable) isolated.doc["records"] = [ r for r in isolated.doc["records"] if r["metric"] != "component_total" diff --git a/tests/browser_setup.cjs b/tests/browser_setup.cjs index ceafba8..efdbe41 100644 --- a/tests/browser_setup.cjs +++ b/tests/browser_setup.cjs @@ -547,6 +547,14 @@ const { execFileSync } = require("node:child_process"); "implementation", ) === "numba", ); + await page.goto(base + "/menu-order.html"); + assert.deepEqual( + await page.locator('[data-family="imaging"] .model-choice').allTextContents(), + ["Delaunay (JAX)", "Delaunay (Numba)", "Rectangular (JAX)", "Rectangular (Numba)", + "MGE (JAX)", "MGE (Numba)", "KNN (JAX)", "KNN (Numba)", + "MGE Mass (JAX)", "MGE Mass (Numba)", "Sersic"], + ); + assert.equal(await page.locator('.model-choice[data-implementation="unknown"]').count(), 1); await page.goto(base + "/readable.html"); assert.equal( await page.locator('a.model-choice[data-implementation="numba"]').count(),