Repository navigation
Measurement markers in the waveform viewer; mT/m by default (v0.4.1) - #29
Merged
Merged
Conversation
The preview workflow served one branch, feature/simulation, at a fixed path. Each run replaced the whole site, so a second branch could not be previewed without wiping the first. It now builds main at the root and every branch in PREVIEW_BRANCHES under /preview/<branch without "feature/">/, each stamped with its commit in preview.txt. The branch that triggered the run is validated with `npm run check`. main and the other listed branches are only rebuilt, since their own pushes validate them. A run from a branch that is not listed fails before building anything. This branch, feature/measurement-markers, is the first entry. It is also in the github-pages environment's deployment branch policy. A deploy from main still removes the previews; re-run this workflow to restore them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Measurement markers snap to RF centres and read waveform values at any time, so the viewer needs two facts the transport dropped: - `rf.c`, the pulse's effective centre (absolute), already computed by the decoder. TE and TR are measured from it. - `r: 1` on a gradient or RF waveform whose samples the overview reduced. Values interpolated across dropped samples are only approximate, and a reduced waveform's interior bends are not reliable snap targets. The flag is written only when set, to keep the JSON envelope small; exact detail windows never carry it. Both hosts use this packer (the web app calls it in the page), so neither needs another change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Right-click the waveform viewer and choose Add marker to drop a vertical
marker; add as many as needed (M1, M2, …).
- Snapping. Near a gradient corner the menu offers that point:
- a trapezoid's ramp and flat-top corners;
- an extended trapezoid's breakpoints, or an arbitrary gradient's bends
(found by simplifying the waveform and keeping flat↔ramp changes,
reversals, steps and large slope changes);
- RF start, centre and end; ADC start, centre and end; trigger starts;
- block boundaries.
Coincident targets share one label, with the pointer's own row first. Once
markers are in use, a ring marks the snap point as the pointer approaches.
"Add marker at pointer (no snap)", or Shift while dragging, places one
exactly; a remembered checkbox turns snapping off.
- Readouts. Each marker crosses the RF and gradient rows with a dot and its
value, and Δt is drawn between neighbours. A table strip under the plot
lists time, block and time within it, Δt, Gx/Gy/Gz in the current unit,
RF amplitude and phase, the ADC sample and the trigger. Copy gives
tab-separated text. Values read from a reduced overview are marked ≈.
- Editing. Drag to move (without panning the view), right-click next to a
marker to remove it, or use the table. Esc closes the menu or cancels a
drag. Markers are cleared when another sequence loads.
The viewer has two renderers: the bundle (VS Code) and web/index.html's own
copy (web app, preview, MATLAB). So the feature is one module, markers.js,
that each renderer installs with accessors to its own state. The last install
wins, and the module owns its listeners on #cc. A capture-phase mousedown
there claims a marker drag before either renderer's pan handler sees it, so
neither copy's mouse code changed. Each renderer adds one line to its
overlay pass and one reset per load path.
Tests:
- unit tests for corner detection, snapping and ranking, readouts with and
without detail, the marker list and the table;
- browser tests in the web app for add, snap, Δt, no-snap, Esc and
outside-click, overlay pixels, zoom, a new file, remove and clear, drag
with and without Shift, and the remembered setting;
- one test through the VS Code renderer.
Also corrects a comment from the simulation work: the Python viewer has its
own renderer and does not load this bundle.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Touch: - A long-press (half a second, without moving) opens the marker menu. The finger's later moves and lift are swallowed, so the view does not pan and the tap tooltip does not appear. - A finger on a marker drags it, again without panning; snapping reaches twice as far as with a mouse. - A plain tap still shows the readout, as before. Like the mouse handling, this runs in the capture phase on #cc, so neither renderer's touch code changed. The table gains an "M1 / PNS" column while those rows are shown. It takes each renderer's own hover-readout lines, so the values match the tooltip and the plot (including coarse bands), and the column is in the copied TSV. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…r, default to mT/m - The marker table's × moves from the last column to the first, so it stays in reach when the table is wider than the window. Cells now carry data-col, and alignment uses classes rather than column positions, which shift when the M1/PNS column appears. - The table's scrollbars use the theme's colours (thumb --ax, hovered --lb, on the strip's --trbg), via ::-webkit-scrollbar in Chromium, VS Code and Safari, and scrollbar-color elsewhere. They replace the platform's light grey bar, which stood out in dark themes. - Gradients read in mT/m by default in the web app, VS Code and MATLAB. A unit someone has already chosen is still restored. The Python viewer's grad_disp default is part of its API and is unchanged. The persistence test now picks G/cm, since choosing the default proved nothing, and the opt-out test expects the new default. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The web app, VS Code and MATLAB viewers now open in mT/m, so the Python package follows: `grad_disp` defaults to "mT/m" in `SeqEyesViewer`, `render_html` and the patched `Sequence.plot`. An unsupported unit falls back to it, and the bundled viewer template selects it. Passing grad_disp="Hz/m" still works as before. The demo notebook's parameter table says so (it also listed Hz/m twice). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bump every surface carrying a version: package.json, both root package-lock entries, python/pyproject.toml, the Python __version__, matlab/toolboxInfo.xml, and the generated pulseq bundles. The lock entries are edited by line, so a dependency sharing the version is not rewritten. This release adds measurement markers to the waveform viewer and makes mT/m the default gradient unit in every host. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds measurement markers to the waveform viewer. Right-click a waveform (long-press on touch) and choose Add marker to drop a vertical marker. Each marker shows every channel's value where it crosses, Δt to its neighbours, and its row in a table under the plot. Placement snaps to gradient corners and block boundaries as the pointer approaches.
It also makes mT/m the default gradient unit in every host, Python included, and lets the GitHub Pages preview host several feature branches at once. Released as v0.4.1.
Live preview of this branch: https://bughht.github.io/seqeyes_plugin/preview/measurement-markers/
What it does
Markers (any number, labelled M1, M2, …)
Shiftto place it off the snap points.Esccloses the menu or cancels a drag.Snapping
Gx ramp-down end · block #12/#13).Readouts
mT/m by default in the web app, VS Code, MATLAB and the Python package:
grad_dispdefaults to"mT/m"inSeqEyesViewer,render_htmland the patchedSequence.plot, and unsupported units fall back to it. Passinggrad_disp="Hz/m"still works.How it fits the two renderers
The viewer is drawn by two copies of the renderer: the bundle (VS Code) and
web/index.html's own copy (web app, MATLAB). Rather than writing the feature twice:markers.js(SeqEyesMarkers) is installed by each renderer with accessors to its own state. The last install wins, and the DOM is wired once.#cc. Grabbing a marker therefore pre-empts both renderers' pan handlers, and neither copy's mouse or touch code changed.Transport
packSequenceBlocksnow also sends:rf.c: the RF centre, which TE and TR are measured from.r: 1on waveforms whose samples the overview reduced. It is written only when set, and exact detail windows never carry it.Preview workflow
preview-pages.ymlnow builds main at the root plus every branch inPREVIEW_BRANCHESunder/preview/<branch>/, so one preview no longer wipes another. Notes:feature/measurement-markerswas added to the github-pages environment's deployment branch policy. That entry can be removed after merging.Testing
test/editor/markers.test.ts(corner detection, snapping and ranking, readouts with and without detail, the marker list and table), plus a transport test forrf.candr.test/browser/markers.spec.ts:vscode-webview.spec.ts.npm run check(687 unit tests), all 111 browser tests andnpm run test:vscodepass. CI is green for every commit.Files changed
src/editor/webview/assets/markers.js(new)src/editor/webview/assets/drawing.js,state.js,interaction.js,prefs.js,prefs-ui.js,styles.css,template.htmlweb/index.htmlsrc/editor/blockTransport.tsscripts/build-webview.mjs.github/workflows/preview-pages.ymlREADME.md(Features, Usage, and a new "Measurement markers" section)test/editor/markers.test.ts(new),test/browser/markers.spec.ts(new),test/pulseq/block-transport.test.ts,test/browser/vscode-webview.spec.ts,test/browser/persisted-settings.spec.tspython/src/seqeyes/_plot.py,_renderer.py,resources/viewer.html,python/tests/test_plot.py,python/examples/demo.ipynbpackage.json,package-lock.json,python/pyproject.toml,python/src/seqeyes/__init__.py,matlab/toolboxInfo.xmlweb/*-bundle.js,web/styles.css,python/src/seqeyes/resources/*-bundle.js🤖 Generated with Claude Code