ChooseLattice Storyboard#
Use with Storyboard.
Stories#
CL-01: Open A Real Lattice Image Quickly#
User story: As a microscopist about to measure a crystal’s lattice vectors, I want a useful preview of the atomic-resolution image in about a second so I can start placing points without waiting.
Primary widgets: ChooseLattice.
Data to use: real atomic-resolution HAADF/ABF image with a visible periodic lattice; a large real image (4k or larger) for the stress variant.
Acceptance checks:
Load from a NumPy/PyTorch array, from a quantem
Dataset2d, and from an in-memory real file load on the backend.Measure first visible paint and note image shape, dtype, and native bytes.
Verify the title (or
Dataset2d.namewhen not given explicitly) is readable and the image renders with no points placed (Origin,u,vall read “not placed”).Verify the widget remains usable (zoom/pan responsive) while the backend/kernel is idle after first paint.
Repeat with the large stress image and confirm pan/zoom stays responsive at native resolution.
CL-02: Pick The Origin And Lattice Vectors#
User story: As a user measuring a crystal lattice, I want to click an
ordered origin, a1, and a2 on the image and immediately see the derived
lattice vectors so I can carry them into downstream analysis.
Primary widgets: ChooseLattice.
Data to use: real lattice image with clearly resolved atomic columns.
Acceptance checks:
Click three points in order and verify each appears immediately with the correct label/color (
Originfirst, then theu/vmarkers) and a guide line from the origin to each.Verify the on-screen readout and
widget.origin,widget.a1,widget.a2,widget.u,widget.v, andwidget.points_arrayupdate together and thatu = a1 - origin,v = a2 - originhold exactly.Drag an existing point to a nearby atomic column and verify the point, guide lines, readout, and derived vectors update live with no lag.
Click a 4th time after 3 points are placed and verify it does nothing (at most 3 points).
Press Clear Points (and call
clear_points()from Python) and verify all points, guide lines, and readouts reset together, and the button disables itself when there are no points to clear.Call
set_points(...)from Python with fewer than 3 points and verify the widget reflects the partial state (missing points read “not placed”, derived vectors stayNoneuntil both endpoints exist).
CL-03: Zoom And Pan Without Losing Original Pixel Coordinates#
User story: As a user placing points precisely, I want to zoom into a specific atomic column and click without the reported coordinates shifting, so the lattice vectors stay correct regardless of how I framed the click.
Primary widgets: ChooseLattice.
Data to use: real lattice image where individual atomic columns are only distinguishable when zoomed in.
Acceptance checks:
Wheel-zoom in on a specific atomic column, verify the zoom is anchored under the cursor, then place a point and confirm the reported
(row, col)matches the column’s position in the ORIGINAL, un-zoomed image.Drag-pan the view, place a second point, and verify its reported coordinates are also in original-image pixel space.
Double-click to reset zoom/pan and verify already-placed points render at the correct screen position after the reset.
Verify the live cursor readout next to the hint text tracks the hovered original-image pixel while zoomed and panned.
CL-04: Save And Reopen Picked Points#
User story: As a notebook user, I want my picked lattice points to survive a saved-notebook reopen when I asked for that, and I want a lightweight static preview otherwise, so I don’t have to re-click every time I revisit the notebook.
Primary widgets: ChooseLattice.
Data to use: real lattice image in a Jupyter notebook.
Acceptance checks:
With
save_state=True, place 3 points, pressCmd+S, close and reopen the notebook, and verify the image and all 3 points restore without rerunning the cell.With
save_state=Falseand the defaultnotebook_preview_format=None, verify NO static-fallback sibling (img.quantem-static-fallback) is added — this widget intentionally opts out of the shared fallback by default because its live view does not reliably hide that sibling while interactive, unlike Show2D/Show3D. A cold reopen with no kernel is expected to show “Error displaying widget: model not found” in this default configuration.Pass
notebook_preview_format="jpeg"explicitly and verify the fallback sibling now appears in the saved notebook, and check whether it stays visibly hidden behind the live widget or shows as a redundant duplicate image — if the hide behavior is still broken for this widget, that is a known gap to fix before recommending opt-in fallback previews to users.Confirm the default (
save_state=False,notebook_preview_format=None) saved notebook stays small — no full interactive point/zoom state and no fallback image baked in.