Skip to content

Transformations0.6#80

Open
AlexSurtees wants to merge 14 commits into
transformations0.5from
transformations0.6
Open

Transformations0.6#80
AlexSurtees wants to merge 14 commits into
transformations0.5from
transformations0.6

Conversation

@AlexSurtees

Copy link
Copy Markdown
Collaborator

Description

Implements scene specification and 0.6 multiscales coordinateSystems.

Adds test images including scene. URL can be found at fixtures/scene.yaml e.g.

https://uk1s3.embassy.ebi.ac.uk/idr/zarr/test-data/v0.6.dev3/idr0050/4995115_scene.zarr

NOTE

Due to image metadata mis-specification, the image WILL NOT align correctly while conforming to the specification rules. However, if the additional 'rotated' transformations are included the image DOES align correctly (i.e. the rotation transformation logic is correctly implemented). This is because the scene-level transformations specified here

https://will-moore.github.io/ome-ngff-validator/?source=https://uk1s3.embassy.ebi.ac.uk/idr/zarr/test-data/v0.6.dev3/idr0050/4995115_scene.zarr

for each image have input coordinate system 'physical', meaning we should only apply the coordinate transformations with coordinate system 'physical' from these images.

@codecov

codecov Bot commented Jun 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.96386% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
viewer/src/coordinate-transformations.ts 86.79% 7 Missing ⚠️
viewer/src/io.ts 57.14% 5 Missing and 1 partial ⚠️
viewer/src/ome.ts 97.33% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@will-moore

Copy link
Copy Markdown
Collaborator

It would be good to test this with @jo-mueller's test samples listed at https://forum.image.sc/t/ngff-weekly-dev-update-thread/110810/98.
I tried running locally with e.g. http://localhost:5173/?source=https://s3.zih.tu-dresden.de/johamuel:rfc5-transform-sanity-checks/logan_shepp_rotation_30_degree_anticlockwise_around_center.ome.zarr/
but it seems this fails due to no validParsers being found for this data.

const parser = validParsers[validParsers.length - 1];

  return {
->    data: parser.schema.parse(data),

TypeError: Cannot read properties of undefined (reading 'schema')
    at parse (parse.ts:34:18)
    at createSourceData (io.ts:81:24)
    at async VizarrViewer.tsx:68:30

@AlexSurtees

Copy link
Copy Markdown
Collaborator Author

German-BioImaging/incubator#72

Sample images to test against

@jo-mueller

Copy link
Copy Markdown

German-BioImaging/incubator#72

Sample images to test against

I will mirror these in the image.sc dev thread

@davehorsfall davehorsfall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is good. Left some comments for discussion.

Comment thread viewer/src/io.ts
const parsedData = parse(node.attrs);
if (parsedData.version === "v06") {
if (parsedData.type === "SceneSchema") {
//Temporary assertion until parsing layer implemented

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If it doesn't already exist, can we create an Issue in the Backlog to follow up on this. Thanks.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added note/sub-issue to existing issue #64

Comment thread viewer/src/types.ts
coordinateSystems?: CoordinateSystem[];
}

//Once parsing and transforming is set up, it should be possible to significantly simplify these types

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please also point here from the Issue that is setup to track full implementation of the transformations from the ZOD schema parsing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added TODO and added sub-issue to #64

const parser = validParsers[validParsers.length - 1];

return {
data: parser.schema.parse(data),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What happens when the schema can't parse the data? How is this handled?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Schema parsing uses the safeParse method which prevents errors from being raised if the metadata does not match the given schema.

Comment thread viewer/src/ome.ts Outdated
);
console.log("Applying scene transformations to image: ", config.source);
const sceneModelMatrix = coordinateTransformationsToMatrix(transformations, [
{ type: "channel", name: "c" },

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This appears to be passing a hard-coded 4-element [c, z, y, x] axes array to coordinateTransformationsToMatrix regardless of the scene's actual coordinate systems. Is that intended, and long term?

coordinateTransformationsToMatrix also seems to throw and error if the shape of the axes and the transformations don't match.

@AlexSurtees AlexSurtees Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Changed to dynamically select the first coordinate system axes in the scene metadata.
Left a TODO for future work to allow the user to change between coordinate systems.
Linked TODO to sub-issue in existing issue #69

Comment thread viewer/src/ome.ts Outdated
const labels = await resolveOmeLabelsFromMultiscales(grp);
const modelMatrix = coordinateTransformationsToMatrix(
getOrderedTransformations(attrs.multiscales, selectedCoordinateSystem),
coordinateSystems[0].axes,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this perhaps be selectedCoordinateSystem.axes, or what is the selectedCoordinateSystem intended to be used for?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

TL;DR

It is the coordinateSystem name that is important for this function, not the axes. I have removed the nested function calls for clarity.

Explanation

The scene metadata defines which output coordinate systems should be used for each multiscale image in the scene (we can imagine that each multiscale image may have multiple coordinate systems and multiple transformations associated with each coordinate system). So, to create the multiscale image, the loadScene function takes the name of the selectedCoordinateSystem from the scene metadata. This is then used to filter which transformations are actually applied to the image.

This may be more clear from the example data:

Scene:

https://ome.github.io/ome-ngff-validator/?source=https%3A%2F%2Fuk1s3.embassy.ebi.ac.uk%2Fidr%2Fzarr%2Ftest-data%2Fv0.6.dev3%2Fidr0050%2F4995115_scene.zarr&roi=0&viewState=%7B%22target%22%3A%5B73.80140630789678%2C78.72150006175659%5D%2C%22zoom%22%3A2.508669115245146%7D

Scene.coordinateTransformations[0].input defines:

input: { "path": "4995115_full.zarr" , "name": "physical" } ,

i.e. the path to the image and the coordinate system of the image to use.

Multiscale image

https://ome.github.io/ome-ngff-validator/?source=https%3A%2F%2Fuk1s3.embassy.ebi.ac.uk%2Fidr%2Fzarr%2Ftest-data%2Fv0.6.dev3%2Fidr0050%2F4995115_scene.zarr&roi=0&viewState=%7B%22target%22%3A%5B73.80140630789678%2C78.72150006175659%5D%2C%22zoom%22%3A2.508669115245146%7D/4995115_full.zarr

Defines:

coordinateSystems: [
{
"name": "physical" ,
axes: [
{ ... } , // 2 items
{ ... } , // 3 items
{ ... } , // 3 items
{ ... } // 3 items
]
}
]

and transformation:

transformations: [
{ ... } , // 2 items
{ ... } // 2 items
] ,
"input": "s0" ,
"output": "physical"
}
]

mat = coordinateTransformationsToMatrix(transform.transformations, axes, mat);
}
if (transform.type === "affine") {
console.log("Affine transformation detected");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Perhaps also add an Issue to track support for this as it develops, and as test datasets start to be generated/shared.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Uncommented this as it actually works - it doesn't have any impact on the test image because the affine transformation defined is the identity. I think this was commented out while debugging at some point.

Comment thread viewer/src/ome.ts
//No type information for SceneSchema
scene: Ome.Scene,
): Promise<SourceData[]> {
console.log("Loading scene: ", config.source);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Currently there are lots of informational logs printed to the console (even in production?)

It would be good to start wrapping this into the app level logger (and error handler) we've been discussing, so it is easier to control what is printed, and where.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed to add these once logging PR has been merged #95

@AlexSurtees AlexSurtees requested a review from davehorsfall July 2, 2026 08:32
@AlexSurtees

Copy link
Copy Markdown
Collaborator Author

@davehorsfall addressed comments and workflows passing.

@will-moore

Copy link
Copy Markdown
Collaborator

https://ome.github.io/ome-ngff-validator/?source=https://livingobjects.ebi.ac.uk/idr/zarr/test-data/v0.6.dev4/idr0050/4995115_output_to_ms.zarr is a more up-to-date scene example, although slightly more complex than the v0.6.dev3 one above. The dev3 one is failing validation because it's using latest schemas which have been updated for dev4.

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.

4 participants