Skip to content

Reorient stitched ViT mosaic canvas before Tiled upload (#50)#56

Draft
Garrett Bischof (gwbischof) wants to merge 1 commit into
mainfrom
mosaic/reorient-canvas
Draft

Reorient stitched ViT mosaic canvas before Tiled upload (#50)#56
Garrett Bischof (gwbischof) wants to merge 1 commit into
mainfrom
mosaic/reorient-canvas

Conversation

@gwbischof

@gwbischof Garrett Bischof (gwbischof) commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

⚠️ HOLD — do not merge yet (under discussion). This may be the wrong layer to fix the orientation, for two reasons:

  1. Reorient stitched canvas before uploading to Tiled #50 predates the Coordinate-correct detector frames; single global ROI #53 coordinate-correction rework. Coordinate-correct detector frames; single global ROI #53 changed detector_orientation/dp_orient, which changes what the model sees and therefore the patch content orientation — so the canvas orientation today is likely not what it was when "needs rot90_ccw + hflip" was measured. The hardcoded antitranspose default could now rotate an already-correct canvas the wrong way. The post-Coordinate-correct detector frames; single global ROI #53 411993 replay (without this PR) "looked decent" — we should first verify whether the current mosaic is already beamline-oriented. If it is, Reorient stitched canvas before uploading to Tiled #50 is effectively addressed by Coordinate-correct detector frames; single global ROI #53 and this PR would break it.
  2. This is a display band-aid. The mosaic's orientation is really set by the convention knobsswap_xy / x_direction / y_direction (grid layout) and patch_flip (patch content). The "right depth" fix is to set those so the canvas stitches beamline-oriented natively (then mosaic_orient=identity, positions and canvas stay consistent, no overlay problem). Reorienting only the final canvas leaves the underlying frame wrong and — as below — breaks any position overlay.

Positions/overlay caveat: this reorients the canvas image but leaves canvas_origin_um (the position→pixel map) describing the un-rotated frame. If synaps-dash overlays positions_um, the markers would be misaligned. positions_um are physical ground truth and must NOT be flipped; if we keep a canvas transform, the fix is to store the mosaic_orient D4 in the metadata so consumers apply it to the position→pixel mapping (not to reorient the positions).

Next step: check the current (post-#53) mosaic orientation vs the beamline; if still off, fix at the convention level (swap_xy/directions/patch_flip) rather than here. Keep mosaic_orient only as an escape hatch.


Closes #50.

Summary

The stitched ViT mosaic was uploaded to Tiled in the raw stitching frame, which doesn't match the beamline's display convention (top→bottom, left→right). This reorients the canvas just before the upload.

MosaicWriterOp now applies a D4 (ptychoml.apply_d4) to both the phase and amplitude canvases right before write_vit_mosaic / write_vit_amp_mosaic. The reorientation is a config field, mosaic_orient, default antitranspose — which is exactly the issue's "rotate 90° CCW, then horizontal flip" (asserted in a test). identity uploads the canvas in the raw stitching frame.

Notes

  • It's a presentation transform on the final array: pixel_size_m is a scalar (transpose-invariant), and canvas_origin_um is passed through unchanged (it refers to the stitching-frame reference). See the positions/overlay caveat above.
  • patch_vit_mosaic (the incremental bbox path) is dead — the staircase fix made every write a full-canvas write_vit_mosaic — so only the full writes needed handling.

Behavior change

The default flips the uploaded mosaic orientation. Set mosaic_orient=identity to keep the old stitching-frame upload.

Tests

tests/test_mosaic_orient.py (pure numpy): default antitranspose == rot90_ccw then fliplr (the issue's spec); shape swap; identity no-op; involution; --mosaic-orient flag default/override + JSON round-trip. Full suite: 127 passed (2 pre-existing test_smoke tiled-server failures).

The stitched mosaic was uploaded in the raw stitching frame, which doesn't
match the beamline display convention (top→bottom, left→right). Reorient the
canvas just before the Tiled write.

- MosaicWriterOp: apply a D4 (config mosaic_orient, default 'antitranspose' =
  rot90_ccw then horizontal flip, per the issue) to both the phase and
  amplitude canvases with ptychoml.apply_d4 right before write_vit_mosaic /
  write_vit_amp_mosaic. 'identity' short-circuits to a no-op. It's a
  presentation transform on the final array: pixel_size_m is scalar
  (transpose-invariant); canvas_origin_um is passed through unchanged.
  (patch_vit_mosaic is dead — the staircase fix made every write full-canvas —
  so only the full writes need handling.)
- ptycho_holo: wire mosaic_orient from config (validated against D4_NAMES).
- config_from_tiled: --mosaic-orient flag (default antitranspose), emitted.
- Tests: default antitranspose == rot90_ccw∘hflip (the issue's spec); shape
  swap; identity no-op; involution; config flag default/override/round-trip.
- Docs: AGENTS.md config-field row + orientation note.

Closes #50.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reorient stitched canvas before uploading to Tiled

1 participant