Added Advanced Options to Quasistatic GUI#57
Conversation
Retire the dead core/quasistationary.py (a partial, unwired port whose
reconstruct_grid used exp(+i(nφ+mθ)) — wrong for any phased mode) plus its
falsely-certifying test, and promote the *active* SLCONTOUR pipeline into core
under unified qs_ naming, deleting the omfit_compat OMFIT shim.
- Move _slcontour/{fit,prep,io_data,run,plots}.py -> core/qs_*.py.
- Delete omfit_compat.py, folding each symbol to its owner: printv/w/e -> logging;
OMFITexception -> ValueError; delta_degrees -> qs_fit; cornernote/uband ->
qs_plots; device readers -> new core/qs_device.py, which delegates to the data
layer (data.devices / data.diiid_geometry) and keeps only the QS-specific extras
(derived theta/end-coord sensor_geometry, resolve_channel_filter semantics).
- qs_device.load_wall now delegates to devices.feature_at, fixing the segmented-
schema bug (the shim read a nonexistent top-level `wall` key -> (None, None)).
- Lock the -i reconstruction convention: invariant comments at the three sites
+ a discriminating δ≠0 regression test the old zero-phase test missed.
- qs_plots docstring clarified as standalone matplotlib (not GUI/service wired).
- Rewire service/nodes.py + tests; pyproject drops the ruff exclude and retargets
a deferred ty exclude onto the qs_* files. Relocate the reference notebook/README
to docs/qs_slcontour/.
ruff format/check + ty (with service extra) clean; 209 passed, 1 skipped.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Finish the core/qs_* promotion by cleaning up its reference material, which was
still written for the old OMFIT `magnetics-code` layout.
- Move example_magnetics.ipynb into examples/ and rewire it onto the new
infrastructure: imports become magnetics.core.qs_{io_data,device,run} plus
`qs_plots as plots` (so the plot cells are unchanged); drop the sys.path hack
and the OMFIT-script mapping / "ported OMFIT scripts" framing.
- Replace docs/qs_slcontour/README.md with docs/quasistationary-mode-analysis.md:
no OMFIT-magnetics plumbing (module↔OMFIT-script table, omfit_compat, cd
analysis), instead a walkthrough of the qs_* pipeline (io_data → prep → fit →
run, plus qs_bridge→service and standalone qs_plots), data inputs, quick start,
and the -i reconstruction sign convention. Physics provenance (SLCONTOUR,
VISION §4.1) kept.
- Remove the now-empty docs/qs_slcontour/.
Docs-only; no src/ behavior change. ruff format --check clean.
(docs/magnetics-code-architecture.md is also OMFIT-era — left for a later sweep.)
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…ond), wall-outline fix - QS tab's Array dropdown now uses the same device sensor_sets list as the left sidebar instead of a hardcoded 9-item subset. - New Advanced Options controls in the QS tab: uncertainty (sigma), fraction of energy included, basis function, fit condition - wired through to the SLCONTOUR fit via new sigma_override/fit_basis/fit_cond query params. - Fix load_wall() reading the device JSON's legacy flat wall schema; it's been shot-segmented since 28c75c6, so the wall outline silently stopped rendering in the QS Sensor Map cross-section plot. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Prioritizes the incoming SLCONTOUR restructuring (_slcontour/* -> core/qs_*, qs_device.py replacing omfit_compat.py) over this branch's prior fixes where they overlapped: - Dropped this branch's _segment_fields-based load_wall fix on the legacy `wall` key in favor of the incoming qs_device.load_wall, which resolves the newer, canonical `first_wall` key via devices.feature_at. - Kept this branch's additive work with no incoming equivalent: the QS tab's Advanced Options UI, and the sigma_override/fit_basis/fit_cond query-param wiring in _qs_run/_prep_qs_ds (now pointed at core.qs_run/core.qs_device instead of the deleted _slcontour module). - Merged both branches' new tests in test_qs_bridge.py and test_slcontour_geometry.py rather than dropping either side's coverage.
Pulls in the cluster-network-config work that landed on develop while this branch was in progress (device-file network blocks, explicit cluster address + per-channel mdsthin default, auto hop-count resolution) plus new QS-correctness test coverage (PR #47). No conflicts with this branch's QS GUI/backend work.
Mirrors qs_plots.plot_svds's two diagnostic panels as GUI-servable LineNodes: data-matrix SVD cumulative energy fraction and design-matrix per-singular-value condition number, each carrying the relevant threshold (energy_limit / fit_condition) as a reference line. Co-Authored-By: Claude Sonnet 5 <[email protected]>
…lots - Add hover title= tooltips (sourced from OMFIT's magnetics_gui.py help text) to Array, n/m modes, Detrend, band, t trim, and basis function - the last gaps among the QS settings-bar and Advanced Options controls. - Surface svd_energy/svd_condition fetch errors instead of silently leaving the panels stuck on a generic "loading..." placeholder forever. - Move the SVD energy/condition plots into their own default-open section instead of nesting them inside the closed-by-default "fit quality" panel, so they're visible without extra clicks. - Fix SVD condition-number axis rendering: use a linear y-axis to match the qs_plots.plot_svds reference (was hardcoded log, which let an off-screen threshold line stretch the autorange and squash the data), add dtick=1 to both SVD x-axes (small-integer singular-value index), and give both legends more top margin so they don't crowd the header. Co-Authored-By: Claude Sonnet 5 <[email protected]>
- SVD conditioning: default the section closed like the other collapsible panels, and double both plots' height (150 -> 300). - Reorder the settings bar: move "t trim (ms)" next to "Array". - Shorten the Array tooltip to plain dropdown guidance. - Rename "band (ms)" to "detrend band (ms)" for clarity. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Main-series points 4 -> 8, "removed" x-markers 7 -> 12. Co-Authored-By: Claude Sonnet 5 <[email protected]>
|
Ready to merge I think |
# Conflicts: # gui/web/src/components/tabs/QuasiStationaryTab.tsx
|
@mfairborn23 can you post a screenshot of the new GUI layout? One thing I noticed yesterday was there was something called "band" that you guys said was actually the baselining window... I found that confusing and am interested to see how it's been clarified if you've added band-pass filtering as another entry as claimed in #81. None of the description above says anything about band pass filtering? |
…l when you click the button to adjust text size
|
Okay- I'll look into this and see if I missed something! |
|
Yeah, smoothing (i.e. filtering) is a top level thing - ESPECIALLY if it defaults to some value other than (0, inf). We should tell users if we are doing something to the data. Minor: Some of these are capitalized and others are not → standardize. Do you think the number of entries is too intimidating to just have all there? Lets group them more logically: I suppose you could collapse some, but I think if organized like this it would be pretty clean to just always have showing |
|
Alright- sounds good! I will reorganize the options! |
Replace the primary-bar + Advanced-toggle split with three always-visible rows grouped by function: Basics (array, time trim, mode numbers), Data (detrend, bandpass, SVD filtering, uncertainty), and Fitting (basis function, condition number). Removes the advancedOpen toggle so nothing is hidden by default. Co-Authored-By: Claude Sonnet 5 <[email protected]>



Summary
Improves the quasi-stationary (QS) GUI tab and merges in
refactor-quasistationary's SLCONTOURrestructuring, reconciling the overlap between the two.
drifted from the left sidebar's device-driven sensor-set list (28 entries). It now reads from
the same
device.sensor_setssource as the sidebar, falling back to the old curated listoffline/in mock mode.
settings bar (not the collapsible plot sections below it):
2e-5), now a real, overridable fit parameter instead of a hardcoded constant.this adds the missing UI control).
sinusoidal-integral/sinusoidal-point/gaussian-integral/gaussian-point, all of which already existed in the fit but were never exposed through theAPI.
wired).
Map cross-section plot.
load_wall()was still reading the device JSON'swallkey with theold flat schema after it was migrated to a shot-segmented one — it always returned
(None, None)with no error. Superseded byrefactor-quasistationary's independent fix, which resolvesthe newer
first_wallkey via the same shot-aware resolver the Sensors tab already uses.refactor-quasistationary: promotes the SLCONTOUR reference pipeline out of the_slcontour/OMFIT-shim layout into shim-freecore/qs_*modules (qs_fit,qs_prep,qs_io_data,qs_plots,qs_run,qs_device), deleting the oldomfit_compat.pyshim and theunused pure-numpy
core/quasistationary.pyport. Where the two branches touched the same code,the incoming restructuring was prioritized; this branch's additive work (the sigma/fit_basis/
fit_cond wiring, the Advanced Options UI) was re-pointed at the new module layout rather than
dropped.
Changes
gui/web/src/components/tabs/QuasiStationaryTab.tsx— array-dropdown parity + Advanced Optionspanel.
src/magnetics/service/nodes.py—_qs_run/_prep_qs_dsparse and forwardsigma,fit_basis,fit_cond;_sensor_map_rznow resolves the wall outline shot-aware.src/magnetics/core/qs_fit.py(renamed from_slcontour/fit.py) — newsigma_overrideparameter; uniform-σ override path.
src/magnetics/core/qs_device.py(new, replaces_slcontour/omfit_compat.py) — device/geometryadapter, including the
first_wall-basedload_wallfix.src/magnetics/core/{qs_prep,qs_io_data,qs_plots,qs_run}.py(renamed from_slcontour/*),qs_bridge.py— carried over fromrefactor-quasistationarywith no functional changes beyondthe rename/import-path updates.
src/magnetics/core/quasistationary.py,src/magnetics/_slcontour/*— deleted (superseded bycore/qs_*).tests/test_qs_bridge.py,tests/test_slcontour_geometry.py— new coverage from both brancheskept:
sigma/fit_basis/fit_condwiring tests,load_wallregression tests, and themode-reconstruction sign-convention test.
docs/specs/quasistationary-mode-analysis.md,examples/example_magnetics.ipynb— carried overfrom
refactor-quasistationary(relocated/modernized QS reference notebook + a new spec doc).Test plan
uv run pytest— 216 passed, 1 skippednpm test(gui/web) — 24 passednpx tsc --noEmit/npm run build/npm run lint— cleanuv run ty check— no new diagnostics (pre-existing, unrelated issues only, intests/test_spectral.py)sigma/fit_basis/fit_condquery params confirmed to reach and change the fit output(not just recorded as labels)
🤖 Generated with Claude Code