Skip to content

Update the animator contour match test for matched image tiles - #90

Merged
markccchiang merged 4 commits into
devfrom
mark/update_animator_contour_match
Aug 11, 2026
Merged

Update the animator contour match test for matched image tiles#90
markccchiang merged 4 commits into
devfrom
mark/update_animator_contour_match

Conversation

@markccchiang

@markccchiang markccchiang commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Description

Closes #24. Updates ANIMATOR_CONTOUR_MATCH for backend PR CARTAvis/carta-backend #1270, which started sending raster tiles of spectrally matched images during animation.

The test previously watched only the reference image: it awaited one tile group per frame and asserted contours for both files. It passed for the wrong reason: the matched image was never tiled, because nothing in the test ever gave it animation view settings.

Session::ExecuteAnimationFrameInner (Session.cc:2214-2278) now walks every file in matched_frames on each animation frame, advances its z, and sends contours, vector field, tile
data
and region data for each. The tile request comes from that file's stored GetAnimationViewSettings().

How a matched image acquires those settings is the non-obvious part. OnMessageTask.tcc:18 dispatches ADD_REQUIRED_TILES with skip_data = AnimationRunning(), and OnAddRequiredTiles stores the message as animation view settings only on that path:

when effect
outside an animation returns tile data immediately, stores nothing
during an animation stores the view settings, sends nothing now
during an animation, empty tiles stores empty settings, so later frames early-return

So a matched image opened before START_ANIMATION is not tiled at all until the frontend sends a tile request for it while the animation runs, and an empty tile list, which is what AppStore.ts:2056-2062 pushes when a matched image is no longer visible, stops its tiles again without stopping its channel updates.

What the test pins

One continuous playback through four states, three channels checked in each:

  1. Channels 1-3, before any tile request for the matched image: only the reference image is tiled, and no RASTER_TILE_SYNC arrives for the matched one.

  2. Channels 7-9, after ADD_REQUIRED_TILES for the matched image, sent mid-animation on channel 4: both images get one RASTER_TILE_DATA and a complete start/end sync pair per channel.

  3. Channels 13-15, after ADD_REQUIRED_TILES with an empty tile list on channel 10: only the reference image again.

  4. Channels 19-21, after the tile request is repeated on channel 16: both images again.

Across every checked channel of every phase, both images return their contours (at progress = 1, with reference_file_id = 1) and one histogram. That is the discriminating check: the matched image keeps stepping through its own channels while it is not tiled, so an empty tile list suppresses only raster data.

Two structural changes

The per-frame stream loop had to go. Stream(CARTA.RasterTileData, n) takes two messages off rasterSyncStream and n-2 off rasterTileStream, resolving on the end sync. It assumes a single sync group, and there are two per frame once the matched image is tiled. The old subscribe/await/ack loop was also problematic: the RxJS subjects do not buffer, and the backend runs a frame ahead, so messages of the frame in flight could be dropped. The test now subscribes once to all four streams for the whole playback and acknowledges flow control from the reference image's tile, which is what paces the animation.

Tiles are asserted per file_id, not by arrival order. _matched_frames is an unordered_map, so the order in which the two images are served within a frame is not part of the interface.

Phases are spaced 6 channels apart with a 3-channel window asserted. The backend runs at most one frame ahead of the last flow-control ack, and a client message queued mid-frame lands a frame or two later, so the unchecked channels around each message are a settling band worth ~600 ms.

The channel a message is sent on is not asserted. Within a frame, the backend serves the reference image, and then each matched image, and the test sends its message as soon as the reference image tile arrives. So the message races the remaining half of that frame and may or may not take effect on it.

milestone - 1 is the last channel whose matched image was already on the wire when the message went out, so the window ends there. This is race-free by construction rather than by timing margin, which matters because the two sides of that race resolve differently per platform: the first draft asserted the milestone channel itself and passed on every Linux runner while failing all three view-setting milestones on macOS.

Changes

File
src/test/ANIMATOR_CONTOUR_MATCH.test.ts rewritten - 34 tests
docs/source/animator.rst document the four phases as Checks 1-7

No stage-file change: ICD_test_stages/animator.tests already lists the test. Fixtures (M17_SWex.fits, M17_SWex.image) are unchanged and already in set_QA.

Also fixes a latent fixture bug: setImageChannel[1] had fileId: 1 but requiredTiles.fileId: 0, so the post-animation tile request was aimed at the wrong image.

Checklist

For the pull request:

  • Documentation has been updated (or no documentation changes are needed)

Within one animation frame the backend serves the reference image and then each
matched image, and the test sends ADD_REQUIRED_TILES as soon as the reference
image tile arrives, so the message can still take effect on the matched image of
that same frame. The milestone channel was therefore ambiguous, and the macOS CI
runner won the race the Linux runners lose.

Check the three channels before each milestone instead of ending on it, and move
the milestones to 4, 10, 16 and 22 to keep the checked channels at 1 to 3,
7 to 9, 13 to 15 and 19 to 21.

@loveluthien loveluthien left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😎

@markccchiang
markccchiang merged commit 3e1598b into dev Aug 11, 2026
148 checks passed
@markccchiang
markccchiang deleted the mark/update_animator_contour_match branch August 13, 2026 13:37
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.

Update the ANIMATOR_CONTOUR_MATCH.test.ts

2 participants