Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up coordinate transforms #95

Merged
merged 1 commit into from
Dec 18, 2024
Merged

Clean up coordinate transforms #95

merged 1 commit into from
Dec 18, 2024

Conversation

dstansby
Copy link
Collaborator

@dstansby dstansby commented Dec 18, 2024

This improves validation messages and code structure by:

  • Having Scale/Translation objects that have both vector and path fields, but validate that only one of them is not None.
  • Improving the error message when validating the type of transform

Fixes #94 - the error message if the transform is (incorrectly) translation then scale is now

E       pydantic_core._pydantic_core.ValidationError: 3 validation errors for ImageAttrs
E       multiscales.0.datasets.0.coordinateTransformations
E         Value error, The first element of `coordinateTransformations` must be a scale transform. Got type='translation' translation=[0.5, 0.5, 0.5] instead. [type=value_error, input_value=[{'translation': [0.5, 0.... 5.0], 'type': 'scale'}], input_type=list]
E           For further information visit https://errors.pydantic.dev/2.10/v/value_error
E       multiscales.0.datasets.1.coordinateTransformations
E         Value error, The first element of `coordinateTransformations` must be a scale transform. Got type='translation' translation=[0.5, 0.5, 0.5] instead. [type=value_error, input_value=[{'translation': [0.5, 0....10.0], 'type': 'scale'}], input_type=list]
E           For further information visit https://errors.pydantic.dev/2.10/v/value_error
E       multiscales.0.datasets
E         Tuple should have at least 1 item after validation, not 0 [type=too_short, input_value=[{'coordinateTransformati...'scale'}], 'path': '1'}], input_type=list]
E           For further information visit https://errors.pydantic.dev/2.10/v/too_short

@dstansby dstansby requested a review from d-v-b December 18, 2024 16:31
@d-v-b
Copy link
Collaborator

d-v-b commented Dec 18, 2024

IMO this is not the most elegant solution to that error message. If we go by the structure of the data defined in the spec, there are 4 types of transforms, not 2. I think a better solution to that error message is to write our own error message, instead of deviating from the types defined in the spec (even though they are very clunky types)

@dstansby
Copy link
Collaborator Author

dstansby commented Dec 18, 2024

Hmm, I dunno - https://ngff.openmicroscopy.org/0.4/index.html#trafo-md doesn't seem to explicitly define 4 data structures, just says that on the data structures either path or "name of vector" can be defined.

@dstansby dstansby force-pushed the clean-up-transforms branch from 0068c1e to 289b294 Compare December 18, 2024 17:33
@dstansby
Copy link
Collaborator Author

Okay, I unded my over-zealous refactoring, and this is a minimal change needed to make the error message nicer now

@d-v-b
Copy link
Collaborator

d-v-b commented Dec 18, 2024

Hmm, I dunno - https://ngff.openmicroscopy.org/0.4/index.html#trafo-md doesn't seem to explicitly define 4 data structures, just says that on the data structures either path or "name of vector" can be defined.

In python we can't really model a type with an optional (i.e. potentially missing) attribute, only an attribute might be None. Put another way, Python types require "optionality" to be expressed as a kind of value, not in the structure of the type itself. The python type system also doesn't really let us express types defined by statements like "if such and such a field is None, then this other field must not be None". So with that in mind, if we want to closely model the transforms defined in the spec as types, we basically have write out 4 separate types. In a type system that allowed dict-like types with truly missing fields and fields that exist conditioned on the values of other fields, then maybe we could do it with just 2 types, but we don't have a language like that :)

@d-v-b
Copy link
Collaborator

d-v-b commented Dec 18, 2024

fwiw I tried using just 2 types in pydantic-ome-ngff, but I ended up writing a lot of input validation and special serialization logic, and the actual data structures were confusing because they had a combination of fields (path and translation) that could never appear together in actual metadata. So I just accepted that the spec does define 4 types, even if I would rather it only defined 2.

@dstansby dstansby merged commit 01e2a4b into main Dec 18, 2024
5 checks passed
@dstansby dstansby deleted the clean-up-transforms branch December 18, 2024 21:17
@dstansby
Copy link
Collaborator Author

That all makes sense - thanks for taking the time to explain!

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.

Improve swapped scale/translation error message
2 participants