"use strict"; /* ============================================================ PBC3 SWEEP ANALYZER Reads the live `pbc3` Optuna study via /api/sweeps/study, ranks by MSE (positive, lower = better), filters by megapixel range (server-side re-aggregation), plots 2D tradeoffs (incl. efficiency vs speed) and an opt-in 3D view, and overlays JPEG/AVIF/WEBP/preset baselines that are already stored in the DB. The metric filters (MSE/bpp/seconds) apply to the codec curves too. The Pareto front is recomputed client-side over all PBC trials (presets included) so it always matches what's plotted. Exposes window.SweepAnalyzer.onShow() for the Sweep Lab tab. ============================================================ */ (function () { const PLOT = window.Plotly; const $ = (id) => document.getElementById(id); const S = { study: null, trials: [], filtered: [], selected: null, codec: null, built: false, fsKind: null, sort: { key: "mse", dir: 1 }, // MSE ascending = best first show: { pbcAll: true, pbcPareto: true, presets: true, jpeg: false, jp2: false, avif: false, webp: false, jxl: false, downsample: false, png: false }, dyn: [], mpMin: null, mpMax: null, logx: true, logy: false, psnr: false, fnum: { mse: NaN, bpp: NaN, sp: NaN }, // numeric metric filters (apply to PBC + codec curves) }; const COLORS = { gray: "#5c3839", pareto: "#ff3b41", sel: "#ffce2e", base: "#ff280c", jpeg: "#7d8cff", jp2: "#4fa3ff", avif: "#34d39a", webp: "#54c0ff", jxl: "#c084fc", downsample: "#e6e6e6", png: "#ef19ef", }; const TOGGLES = [["pbcAll", "PBC All"], ["pbcPareto", "PBC Pareto"], ["presets", "PBC Presets"], ["jpeg", "JPEG"], ["jp2", "JPEG2000"], ["webp", "WebP"], ["jxl", "JXL"], ["avif", "AVIF"], ["downsample", "Downsample"], ["png", "PNG"]]; // 2D plot defs. efficiency = 1/(bpp·mse) (higher is better). const P2D = { qc: { x: "bpp", y: "mse", xt: "bpp", yt: "MSE", note: "↙ lower-left is best", title: "MSE vs Compression" }, qs: { x: "speed", y: "mse", xt: "seconds", yt: "MSE", note: "↙ lower-left is best", title: "MSE vs Speed" }, cs: { x: "speed", y: "bpp", xt: "seconds", yt: "bpp", note: "↙ lower-left is best", title: "Compression vs Speed" }, qcs: { x: "speed", y: "eff", xt: "seconds", yt: "efficiency 1/(bpp·MSE)", note: "↖ upper-left is best", title: "Efficiency vs Speed" }, }; const FS_STYLE = ` .sw-plot-box{position:relative;} .sw-fs-btn{position:absolute;top:10px;right:10px;z-index:5;background:rgba(18,18,20,.72); border:1px solid var(--border2);color:var(--text);border-radius:7px;width:28px;height:28px; cursor:pointer;font-size:15px;line-height:1;display:flex;align-items:center;justify-content:center;transition:.15s;} .sw-fs-btn:hover{border-color:var(--red-dim);color:#fff;background:rgba(18,18,20,.9);} #sw-fs{position:fixed;inset:0;z-index:1000;background:rgba(0,0,0,.82);backdrop-filter:blur(6px); display:flex;padding:24px;animation:swfs .14s ease;} #sw-fs[hidden]{display:none;} @keyframes swfs{from{opacity:0}to{opacity:1}} .sw-fs-inner{margin:auto;width:96vw;height:92vh;background:var(--surface);border:1px solid var(--border); border-radius:16px;display:flex;flex-direction:column;padding:14px 16px;box-shadow:0 24px 70px rgba(0,0,0,.55);} .sw-fs-bar{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;} .sw-fs-bar span{font-size:13px;font-weight:600;color:var(--text);} #sw-fs-plot{flex:1;min-height:0;}`; const fmt = (v, d = 4) => (v === null || v === undefined || isNaN(v)) ? "—" : (+v).toFixed(d); const efficiency = (t) => (t.bpp > 0 && t.mse > 0) ? 1 / (t.bpp * t.mse) : 0; const baseLabel = (t) => t.preset ? `${t.preset} preset` : (t.codec ? `${t.codec} q${t.q}` : ""); /* -------------------- shell -------------------- */ function build() { const st = document.createElement("style"); st.textContent = FS_STYLE; document.head.appendChild(st); $("view-sweep").innerHTML = `

Tuning databasepbc3 · live on the Space

`; $("sw-load").onclick = load; ["f-mpmin", "f-mpmax"].forEach((id) => $(id).addEventListener("change", () => { S.mpMin = $("f-mpmin").value === "" ? null : +$("f-mpmin").value; S.mpMax = $("f-mpmax").value === "" ? null : +$("f-mpmax").value; load(); })); $("sw-mpreset").onclick = () => { $("f-mpmin").value = ""; $("f-mpmax").value = ""; S.mpMin = null; S.mpMax = null; load(); }; ["f-msemax", "f-bppmax", "f-spmax"].forEach((id) => $(id).addEventListener("input", applyFilters)); $("sw-addfilter").onchange = (e) => { if (e.target.value) { addDynFilter(e.target.value); e.target.value = ""; } }; $("sw-logx").onchange = (e) => { S.logx = e.target.checked; render2d(); }; $("sw-logy").onchange = (e) => { S.logy = e.target.checked; render2d(); }; $("sw-psnr").onchange = (e) => { S.psnr = e.target.checked; render2d(); }; $("sw-deselect").onclick = () => select(null); $("sw-3d-show").onchange = (e) => { $("sw-3d-wrap").hidden = !e.target.checked; if (e.target.checked) render3d(); }; $("sw-3dcolor").onchange = render3d; $("view-sweep").querySelectorAll(".sw-fs-btn").forEach((b) => b.onclick = () => openFs(b.dataset.fs)); $("sw-fs-close").onclick = closeFs; document.addEventListener("keydown", (e) => { if (e.key === "Escape" && !$("sw-fs").hidden) closeFs(); }); buildToggles(); S.built = true; } function buildToggles() { $("sw-toggles").innerHTML = `Show:` + TOGGLES.map(([k, l]) => ``).join(""); $("sw-toggles").querySelectorAll("input").forEach((el) => el.onchange = () => { S.show[el.dataset.show] = el.checked; render2d(); codecReadout(); }); } /* -------------------- data loading -------------------- */ async function load() { msg("Loading…", true); const qs = []; if (S.mpMin != null) qs.push("mp_min=" + S.mpMin); if (S.mpMax != null) qs.push("mp_max=" + S.mpMax); try { const d = await (await fetch("/api/sweeps/study?" + qs.join("&"))).json(); if (!d.exists) { $("sw-summary-card").hidden = true; $("sw-main").hidden = true; return msg("No sweep database yet — run a sweep first."); } const all = (d.trials || []).map((t) => ({ ...t, eff: efficiency(t) })); S.study = d; S.trials = all.filter((t) => t.kind === "pbc3"); computePareto(S.trials); buildCodec(all); S.selected = null; S.dyn = []; msg(`${S.trials.length} PBC trials · ${S.trials.filter((t) => t.pareto).length} on the Pareto front`); $("sw-summary-card").hidden = false; $("sw-main").hidden = false; renderSummary(); buildAddFilterOptions(); renderDyn(); applyFilters(); } catch (e) { msg("Failed to load: " + e.message); } } // Client-side Pareto front over all PBC trials (presets included) on the three // minimized objectives. Overrides the server flag so the front always matches // the (MP-re-aggregated) values we actually plot. function computePareto(rows) { rows.forEach((a) => { a.pareto = !rows.some((b) => b !== a && b.speed <= a.speed && b.bpp <= a.bpp && b.mse <= a.mse && (b.speed < a.speed || b.bpp < a.bpp || b.mse < a.mse)); }); } function buildCodec(all) { const pick = (c) => all.filter((t) => t.codec === c) .map((t) => ({ q: t.q, bpp: t.bpp, mse: t.mse, speed: t.speed, eff: t.eff })).sort((a, b) => a.q - b.q); const jpeg = pick("JPEG"), jp2 = pick("JPEG2000"), avif = pick("AVIF"), webp = pick("WEBP"), jxl = pick("JXL"), downsample = pick("DOWNSAMPLE"), png = pick("PNG"); S.codec = (jpeg.length || jp2.length || avif.length || webp.length || jxl.length || downsample.length || png.length) ? { jpeg, jp2, avif, webp, jxl, downsample, png } : null; } function renderSummary() { const d = S.study; $("sw-warn").innerHTML = d.completed ? "" : `
No completed trials in this study yet.
`; const cells = [ ["Study", d.study_name], ["MP filter", `${S.mpMin ?? "any"} – ${S.mpMax ?? "any"}`], ["PBC trials", S.trials.length, "hl"], ["Pareto trials", S.trials.filter((t) => t.pareto).length, "hl"], ["Metrics", (d.metric_names || []).join(" · ")], ]; $("sw-summary").innerHTML = cells.map(([k, v, c]) => `
${k}${v}
`).join(""); } /* -------------------- dynamic param filters -------------------- */ function paramKeys() { const keys = new Set(); S.trials.forEach((t) => Object.keys(t.params || {}).forEach((k) => keys.add(k))); return [...keys].sort(); } function isNumericParam(k) { let seen = false; for (const t of S.trials) { const v = t.params[k]; if (v === undefined || v === null) continue; seen = true; if (isNaN(+v)) return false; } return seen; } function buildAddFilterOptions() { $("sw-addfilter").innerHTML = `` + paramKeys().map((k) => ``).join(""); } function addDynFilter(param) { if (S.dyn.some((d) => d.param === param)) return; if (isNumericParam(param)) S.dyn.push({ param, kind: "num", min: null, max: null }); else { const values = [...new Set(S.trials.map((t) => String(t.params[param])).filter((v) => v !== "undefined"))].sort(); S.dyn.push({ param, kind: "cat", values: new Set(values), all: values }); } renderDyn(); applyFilters(); } function renderDyn() { const wrap = $("sw-dyn"); if (!S.dyn.length) { wrap.innerHTML = ""; return; } wrap.innerHTML = S.dyn.map((d, i) => { if (d.kind === "num") { return `
${d.param}
`; } return `
${d.param} ${d.all.map((v) => ``).join("")}
`; }).join(""); wrap.querySelectorAll("[data-i]").forEach((row) => { const i = +row.dataset.i, d = S.dyn[i]; row.querySelectorAll("[data-dyn]").forEach((el) => { const kind = el.dataset.dyn; if (kind === "rm") el.onclick = () => { S.dyn.splice(i, 1); renderDyn(); applyFilters(); }; else if (kind === "min" || kind === "max") el.oninput = () => { d[kind] = el.value === "" ? null : +el.value; applyFilters(); }; else if (kind === "cat") el.onchange = () => { el.checked ? d.values.add(el.dataset.v) : d.values.delete(el.dataset.v); applyFilters(); }; }); }); } function applyFilters() { if (!S.study) return; const msemax = parseFloat($("f-msemax").value), bppmax = parseFloat($("f-bppmax").value), spmax = parseFloat($("f-spmax").value); S.fnum = { mse: msemax, bpp: bppmax, sp: spmax }; S.filtered = S.trials.filter((t) => { if (!isNaN(msemax) && t.mse > msemax) return false; if (!isNaN(bppmax) && t.bpp > bppmax) return false; if (!isNaN(spmax) && t.speed > spmax) return false; for (const d of S.dyn) { const v = t.params[d.param]; if (d.kind === "num") { const n = +v; if (d.min !== null && !(n >= d.min)) return false; if (d.max !== null && !(n <= d.max)) return false; } else if (d.values.size && !d.values.has(String(v))) return false; } return true; }); $("sw-tcount").textContent = ` ${S.filtered.length} / ${S.trials.length} shown`; renderAll(); } function renderAll() { render2d(); render3d(); renderTable(); } /* -------------------- codec baselines (from DB) -------------------- */ // Metric filters apply to codec points too — a JPEG q95 above the bpp cap is hidden. function codecPoints(key) { if (!S.codec || !S.codec[key]) return null; const f = S.fnum || {}; return S.codec[key].filter((p) => (isNaN(f.mse) || p.mse <= f.mse) && (isNaN(f.bpp) || p.bpp <= f.bpp) && (isNaN(f.sp) || p.speed <= f.sp)); } function interp(xs, ys, x) { for (let i = 1; i < xs.length; i++) { if (x >= xs[i - 1] && x <= xs[i]) { const f = (x - xs[i - 1]) / (xs[i] - xs[i - 1] || 1); return ys[i - 1] + f * (ys[i] - ys[i - 1]); } } return null; } function codecReadout() { const jp = codecPoints("jpeg"); const sorted = jp ? [...jp].sort((a, b) => a.mse - b.mse) : []; if (!S.show.jpeg || !sorted.length) { $("sw-readout").textContent = ""; return; } const par = S.filtered.filter((t) => t.pareto); const lo = sorted[0].mse, hi = sorted[sorted.length - 1].mse; let line = `JPEG baselines span MSE ${fmt(lo, 1)}–${fmt(hi, 1)}.`; const mids = par.filter((t) => t.mse >= lo && t.mse <= hi); if (mids.length) { const mid = (lo + hi) / 2; const t = mids.reduce((a, b) => (Math.abs(b.mse - mid) < Math.abs(a.mse - mid) ? b : a)); const jbpp = interp(sorted.map((p) => p.mse), sorted.map((p) => p.bpp), t.mse); if (jbpp) { const pct = (t.bpp - jbpp) / jbpp * 100; line += ` At MSE ${fmt(t.mse, 1)} (trial #${t.number}), PBC is ${Math.abs(pct).toFixed(0)}% ${pct < 0 ? "smaller" : "larger"} than JPEG.`; } } $("sw-readout").textContent = line; } /* -------------------- 2D plots -------------------- */ const hover = (t) => { const p = t.params || {}; return `#${t.number}${t.pareto ? " · Pareto" : ""}${t.baseline ? " · " + baseLabel(t) : ""}
` + `MSE ${fmt(t.mse, 1)}
bpp ${fmt(t.bpp)}
seconds ${fmt(t.speed, 3)}
eff ${fmt(t.eff, 3)}
` + `patches ${p.patch_count ?? "—"} · ${p.color_space ?? ""}`; }; const floorVal = (v, isLog, floor) => (isLog && (v == null || v <= 0)) ? floor : v; const mseToPsnr = (v) => (v != null && v > 0) ? 10 * Math.log10(65025 / v) : null; function ptTrace(rows, xKey, yKey, style, fx = 0, fy = 0, yfn = null, logy = S.logy) { return { x: rows.map((t) => floorVal(t[xKey], S.logx, fx)), y: rows.map((t) => yfn ? yfn(t[yKey]) : floorVal(t[yKey], logy, fy)), customdata: rows.map((t) => t.number), text: rows.map(hover), hovertemplate: "%{text}", mode: "markers", type: "scatter", ...style, }; } function codecTrace(pts, xKey, yKey, name, color, fx = 0, fy = 0, yfn = null, logy = S.logy) { return { x: pts.map((p) => floorVal(p[xKey], S.logx, fx)), y: pts.map((p) => yfn ? yfn(p[yKey]) : floorVal(p[yKey], logy, fy)), mode: "lines+markers", type: "scatter", name, line: { color }, marker: { size: 5, color }, text: pts.map((p) => { const tag = name === "DOWNSAMPLE" ? `f${p.q}` : name === "PNG" ? "lossless" : `q${p.q}`; return `${name} ${tag}
bpp ${fmt(p.bpp)}
MSE ${fmt(p.mse, 1)}
seconds ${fmt(p.speed, 3)}`; }), hovertemplate: "%{text}", }; } function scatter2d(xKey, yKey, usePsnr = false) { const all = S.filtered, traces = []; const CODECS = ["jpeg", "jp2", "webp", "jxl", "avif", "downsample", "png"]; const yfn = usePsnr ? mseToPsnr : null; const logy = S.logy && !usePsnr; const plotFloor = (key) => { let m = Infinity; const scan = (rows) => rows && rows.forEach((t) => { const v = t[key]; if (v != null && v > 0 && v < m) m = v; }); scan(all); CODECS.forEach((k) => { if (S.show[k]) scan(codecPoints(k)); }); return (m === Infinity ? 1 : m) / 2; // half a step below the smallest real value }; const fx = S.logx ? plotFloor(xKey) : 0; const fy = logy ? plotFloor(yKey) : 0; if (S.show.pbcAll) traces.push(ptTrace(all, xKey, yKey, { name: "PBC all", marker: { size: 5, color: COLORS.gray, opacity: .55 } }, fx, fy, yfn, logy)); if (S.show.pbcPareto) traces.push(ptTrace(all.filter((t) => t.pareto), xKey, yKey, { name: "PBC Pareto", marker: { size: 8, color: COLORS.pareto } }, fx, fy, yfn, logy)); [["jpeg", COLORS.jpeg], ["jp2", COLORS.jp2], ["webp", COLORS.webp], ["jxl", COLORS.jxl], ["avif", COLORS.avif], ["downsample", COLORS.downsample], ["png", COLORS.png]].forEach(([k, c]) => { if (!S.show[k]) return; const pts = codecPoints(k); if (pts && pts.length) traces.push(codecTrace([...pts].sort((a, b) => a[xKey] - b[xKey]), xKey, yKey, k.toUpperCase(), c, fx, fy, yfn, logy)); }); if (S.show.presets) { const pre = all.filter((t) => t.preset); if (pre.length) traces.push(ptTrace(pre, xKey, yKey, { name: "presets", marker: { size: 12, color: COLORS.base, symbol: "diamond", line: { color: "#fff", width: 1 } } }, fx, fy, yfn, logy)); } const sel = all.filter((t) => t.number === S.selected); if (sel.length) traces.push(ptTrace(sel, xKey, yKey, { name: "selected", marker: { size: 13, color: COLORS.sel, line: { color: "#fff", width: 1 } } }, fx, fy, yfn, logy)); return traces; } function layout2d(xt, yt, note, usePsnr = false) { const logy = S.logy && !usePsnr; return { margin: { l: 56, r: 10, t: note ? 26 : 12, b: 38 }, showlegend: false, paper_bgcolor: "rgba(0,0,0,0)", plot_bgcolor: "rgba(0,0,0,0)", font: { color: "#a6a6ad", size: 10 }, title: note ? { text: note, font: { size: 10, color: "#82828a" }, x: 0, xanchor: "left" } : undefined, // ~g formats log-axis minor ticks as their real value (0.2 instead of "2"). xaxis: { title: xt, gridcolor: "#262629", zeroline: false, type: S.logx ? "log" : "linear", tickformat: S.logx ? "~g" : undefined }, yaxis: { title: yt, gridcolor: "#262629", zeroline: false, type: logy ? "log" : "linear", tickformat: logy ? "~g" : undefined }, }; } function bindClick(id) { const el = $(id); if (el._swbound) return; el._swbound = true; el.on("plotly_click", (ev) => { const cd = ev.points[0] && ev.points[0].customdata; if (cd != null) select(cd); }); } function plot2d(elId, key) { const c = P2D[key]; const usePsnr = S.psnr && (key === "qc" || key === "qs"); const yt = usePsnr ? "PSNR (dB)" : c.yt; const note = usePsnr ? "↖ upper-left is best" : c.note; PLOT.react(elId, scatter2d(c.x, c.y, usePsnr), layout2d(c.xt, yt, note, usePsnr), { displayModeBar: false, responsive: true }); bindClick(elId); } function render2d() { if (typeof PLOT === "undefined" || !S.study) return; ["qc", "qs", "cs", "qcs"].forEach((k) => plot2d("sw-p-" + k, k)); codecReadout(); if (S.fsKind && S.fsKind !== "3d") { plot2d("sw-fs-plot", S.fsKind); resizeFs(); } } /* -------------------- 3D plot -------------------- */ function render3dInto(elId) { try { const by = $("sw-3dcolor").value, all = S.filtered; const colorVals = by === "pareto" ? all.map((t) => (t.pareto ? 1 : 0)) : ["mse", "bpp"].includes(by) ? all.map((t) => t[by]) : by === "seconds" ? all.map((t) => t.speed) : all.map((t) => +t.params[by]); const traces = [{ x: all.map((t) => t.bpp), y: all.map((t) => t.speed), z: all.map((t) => t.mse), customdata: all.map((t) => t.number), text: all.map(hover), hovertemplate: "%{text}", mode: "markers", type: "scatter3d", marker: { size: 3, color: colorVals, colorscale: "Viridis", opacity: .85, showscale: true, colorbar: { title: by, thickness: 10, len: .6 } }, }]; const par = all.filter((t) => t.pareto); traces.push({ x: par.map((t) => t.bpp), y: par.map((t) => t.speed), z: par.map((t) => t.mse), text: par.map(hover), hovertemplate: "%{text}", mode: "markers", type: "scatter3d", name: "Pareto", marker: { size: 5, color: COLORS.pareto }, }); const sel = all.find((t) => t.number === S.selected); if (sel) traces.push({ x: [sel.bpp], y: [sel.speed], z: [sel.mse], mode: "markers", type: "scatter3d", text: [hover(sel)], hovertemplate: "%{text}", marker: { size: 7, color: COLORS.sel, line: { color: "#fff", width: 1 } }, }); const layout = { margin: { l: 0, r: 0, t: 0, b: 0 }, showlegend: false, autosize: true, paper_bgcolor: "rgba(0,0,0,0)", font: { color: "#a6a6ad", size: 10 }, scene: { xaxis: { title: "bpp", gridcolor: "#262629", backgroundcolor: "rgba(0,0,0,0)" }, yaxis: { title: "seconds", gridcolor: "#262629", backgroundcolor: "rgba(0,0,0,0)" }, zaxis: { title: "MSE", gridcolor: "#262629", backgroundcolor: "rgba(0,0,0,0)" }, }, }; PLOT.react(elId, traces, layout, { displayModeBar: false, responsive: true }); PLOT.Plots.resize($(elId)); bindClick(elId); } catch (e) { $(elId).innerHTML = `
3D render failed: ${e.message}
`; } } function render3d() { if (typeof PLOT === "undefined" || !S.study) return; if ($("sw-3d-show") && $("sw-3d-show").checked) render3dInto("sw-3d"); if (S.fsKind === "3d") { render3dInto("sw-fs-plot"); resizeFs(); } } /* -------------------- fullscreen -------------------- */ function openFs(kind) { if (typeof PLOT === "undefined") return toastMsg("Plotly unavailable"); S.fsKind = kind; $("sw-fs-title").textContent = kind === "3d" ? "3D tradeoff" : P2D[kind].title; $("sw-fs").hidden = false; if (kind === "3d") render3dInto("sw-fs-plot"); else plot2d("sw-fs-plot", kind); resizeFs(); } function closeFs() { if (S.fsKind) { try { PLOT.purge("sw-fs-plot"); } catch (e) { /* noop */ } } S.fsKind = null; $("sw-fs-plot")._swbound = false; $("sw-fs").hidden = true; resizeAll(); } function resizeFs() { const el = $("sw-fs-plot"); if (el && el.data && !$("sw-fs").hidden) PLOT.Plots.resize(el); } /* -------------------- table -------------------- */ const COLS = [ ["number", "Trial"], ["pareto", "Par"], ["baseline", "Base"], ["mse", "MSE"], ["bpp", "BPP"], ["speed", "sec"], ["eff", "eff"], ["patch_count", "patches"], ["q_init", "q_init"], ["color_space", "color"], ["_actions", ""], ]; const METRIC_KEYS = ["mse", "bpp", "speed", "eff"]; const cellVal = (t, k) => k === "number" ? t.number : k === "pareto" ? (t.pareto ? 1 : 0) : k === "baseline" ? (t.baseline ? 1 : 0) : METRIC_KEYS.includes(k) ? t[k] : t.params[k]; function renderTable() { const table = $("sw-table"); const rows = [...S.filtered].sort((a, b) => { const va = cellVal(a, S.sort.key), vb = cellVal(b, S.sort.key); const na = +va, nb = +vb; if (!isNaN(na) && !isNaN(nb)) return (na - nb) * S.sort.dir; return String(va).localeCompare(String(vb)) * S.sort.dir; }); const head = COLS.map(([k, l]) => `${l}${S.sort.key === k ? (S.sort.dir > 0 ? " ▲" : " ▼") : ""}`).join(""); const body = rows.map((t) => { const cells = COLS.map(([k]) => { if (k === "number") return `#${t.number}`; if (k === "pareto") return `${t.pareto ? 'P' : ""}`; if (k === "baseline") return `${t.baseline ? 'B' : ""}`; if (k === "_actions") return ``; if (k === "mse") return `${fmt(t.mse, 1)}`; if (k === "speed") return `${fmt(t.speed, 3)}`; if (k === "eff") return `${fmt(t.eff, 3)}`; if (k === "bpp") return `${fmt(t.bpp)}`; return `${t.params[k] ?? "—"}`; }).join(""); return `${cells}`; }).join(""); table.innerHTML = `${head}${body}`; table.querySelectorAll("th").forEach((th) => th.onclick = () => { const k = th.dataset.k; if (k === "_actions") return; S.sort = { key: k, dir: S.sort.key === k ? -S.sort.dir : (METRIC_KEYS.includes(k) ? 1 : -1) }; renderTable(); }); table.querySelectorAll("tbody tr").forEach((tr) => tr.onclick = (e) => { const btn = e.target.closest("button"); if (btn) { copy(optunaText(byNum(+btn.dataset.n)), "Params copied"); return; } select(+tr.dataset.n); }); } /* -------------------- selection -------------------- */ const byNum = (n) => S.trials.find((t) => t.number === n); function select(n) { S.selected = n; renderTable(); render2d(); render3d(); renderSelected(); } function renderSelected() { const t = byNum(S.selected); $("sw-sel-sub").textContent = t ? `#${t.number}` : "none"; if (!t) { $("sw-sel-metrics").innerHTML = ""; $("sw-sel-params").textContent = ""; $("sw-copybar").innerHTML = ""; return; } $("sw-sel-metrics").innerHTML = [ ["MSE", fmt(t.mse, 1)], ["BPP", fmt(t.bpp)], ["Seconds", fmt(t.speed, 3)], ["Efficiency", fmt(t.eff, 3)], ["Pareto", t.pareto ? "yes" : "no"], ["Baseline", t.baseline ? baseLabel(t) : "no"], ].map(([k, v]) => `
${k}
${v}
`).join(""); $("sw-sel-params").textContent = optunaText(t); $("sw-copybar").innerHTML = ` `; $("cp-opt").onclick = () => copy(optunaText(t), "Params copied"); $("cp-cfg").onclick = () => copy(configPython(t), "PBC3Config copied"); $("cp-json").onclick = () => copy(JSON.stringify(t.params, null, 2), "JSON copied"); $("cp-load").onclick = () => loadIntoDemo(t); } /* -------------------- copy / load -------------------- */ function optunaText(t) { return Object.entries(t.params).map(([k, v]) => `${k} ${v === true ? "True" : v === false ? "False" : v}`).join("\n"); } function configPython(t) { const lines = Object.entries(t.params).map(([k, v]) => { if (typeof v === "boolean") return `${k}=${v ? "True" : "False"}`; if (typeof v === "number") return `${k}=${v}`; if (Array.isArray(v)) return `${k}=(${v.join(", ")})`; return `${k}="${v}"`; }); return `PBC3Config(\n ${lines.join(",\n ")},\n)`; } function loadIntoDemo(t) { const text = optunaText(t); if (typeof window.applyOptuna === "function") { window.applyOptuna(text); if (window.SweepLab && typeof window.SweepLab.toApp === "function") window.SweepLab.toApp(); else if (typeof window.gotoView === "function") window.gotoView("compress"); toastMsg("Loaded trial #" + t.number + " into the demo"); } else copy(text, "Copied — paste into the demo's params"); } function copy(text, ok) { navigator.clipboard.writeText(text).then(() => toastMsg(ok)).catch(() => toastMsg("Copy failed")); } /* -------------------- misc -------------------- */ function msg(text, busy) { $("sw-msg").innerHTML = (busy ? ` ` : "") + text; } function toastMsg(m) { typeof window.toast === "function" ? window.toast(m) : msg(m); } function resizeAll() { if (!S.built || typeof PLOT === "undefined") return; ["sw-p-qc", "sw-p-qs", "sw-p-cs", "sw-p-qcs"].forEach((id) => { const el = $(id); if (el && el.data) PLOT.Plots.resize(el); }); const td = $("sw-3d"); if (td && td.data && $("sw-3d-show").checked) PLOT.Plots.resize(td); } window.SweepAnalyzer = { onShow() { if (!S.built) build(); if (typeof PLOT === "undefined") msg("Plotly failed to load (offline / blocked). Charts disabled."); if (!S.study) load(); else resizeAll(); }, }; })();