Repository navigation
Resolve node axis names from display_hints - #10
Merged
Merged
Conversation
Previously, VarlengthProperty held a flattened data array and an offset
table covering all nodes at once. This forced callers to pass a node
index to getData (getNodeData(i)) and isMissing(i), and every node in a
list ended up sharing the same VarlengthProperty object — a confusing
mismatch with the single-node abstraction of GeffNode and GeffEdge.
Each VarlengthProperty now stores the data slice for exactly one
node/edge. The per-node constructors are:
new VarlengthProperty(name, dtype, data)
new VarlengthProperty(name, dtype, data, missing)
getData() and isMissing() take no index. The old bulk constructor and
getNodeData(int) / getOffsets() are removed.
GeffUtils.readVarlengthProperty now returns VarlengthProperty[] (one
entry per node). GeffNode and GeffEdge split the returned array when
building node/edge objects on read, and assemble per-node data into the
bulk format required by writeVarlengthProperty on write.
Add proper uint8 read/write support to varlength properties so that
variable-length byte sequences — such as per-node labels encoded as
UTF-8 — can be stored and retrieved correctly.
On write, Integer elements are now converted to a byte[] before being
stored when the declared dtype is "uint8", avoiding the int-to-byte
sign mismatch that would otherwise occur via SubArrayCopy.
On read, the UINT8 zarr array is returned by N5 as a Java byte[].
convertVarlengthData now handles byte[] by applying "& 0xFF" to each
element, yielding unsigned Integer values (0–255) in the Object[] that
callers receive from VarlengthProperty.getData().
Multibyte characters (e.g. Japanese) work correctly because the
encoding/decoding is entirely UTF-8 byte-level; the varlength layer
treats the data as opaque uint8 values.
Update README to show the label/uint8 pattern in place of the polygon
example, which already has dedicated polygonX/polygonY fields and is
therefore a misleading illustration of arbitrary varlength properties.
Add testUint8LabelRoundTrip to VarlengthPropertyWriteTest covering both
ASCII ("cell_A") and multibyte ("細胞_B") labels.
Careful: double check deserialization.
Still hacky, but temporary. We miss the support of querying labels paths anyway.
Resolve node axis names from display_hints, falling back to axes order Add GeffDisplayHint to model the optional geff/display_hints attribute (display_horizontal/vertical/depth/time), and have GeffMetadata resolve each t/x/y/z axis name by combining display_hints with the declared axes in the following order: 1. the matching display hint, which names the axis explicitly; 2. a spatial axis named `x`, `y` or `z` (case-insensitive), or one whose name ends in `_x`, `_y`, `_z` (e.g. `cell_x`); 3. the position in the `axes` list, which the spec defines as image dimension order, i.e. slowest to fastest (`z`, `y`, `x`) and therefore counted from the end; 4. the standard name (`x`, `y`, `z`) for datasets that declare no spatial axes at all. GeffNode now reads/writes coordinates using these resolved names, and correctly omits the Z property for datasets with no third spatial axis instead of guessing "z". Did this in part with Claude
Collaborator
|
Hello @ksugar Could you also check the work done in this branch: https://github.com/live-image-tracking-tools/geff-java/commits/metadata-extra/ |
tinevez
approved these changes
Sep 8, 2026
Collaborator
Author
|
@tinevez Thank you for the feedback. You have already worked on it. I will pick it up here. |
Collaborator
|
Actually your version is much much better. |
DisplayHints class was renamed to GeffDisplayHints, and was made gson-serializable. Add validation code for GeffDisplayHints. GeffDisplayHints, RelatedObjects, extra metadata were taken into account for the toString(), equals( Object obj ), and hashCode() methods.
Collaborator
Author
|
@tinevez I put back my implementation. The only difference from the initial commit was the following point:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolve node axis names from display_hints, falling back to axes order
Add GeffDisplayHint to model the optional geff/display_hints attribute (display_horizontal/vertical/depth/time), and have GeffMetadata resolve each t/x/y/z axis name by combining display_hints with the declared axes in the following order:
x,yorz(case-insensitive), or one whose name ends in_x,_y,_z(e.g.cell_x);axeslist, which the spec defines as image dimension order, i.e. slowest to fastest (z,y,x) and therefore counted from the end;x,y,z) for datasets that declare no spatial axes at all.GeffNode now reads/writes coordinates using these resolved names, and correctly omits the Z property for datasets with no third spatial axis instead of guessing "z".
Did this in part with Claude