You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -280,74 +280,33 @@ Here, we refer to any method that obtains values at real-valued coordinates usin
280
280
As such, label images may be interpolated using "nearest neighbor" to obtain labels at points along the continuum.
281
281
```
282
282
283
-
#### Array coordinate systems
284
-
285
-
The dimensions of an array do not have an interpretation
286
-
until they are associated with a coordinate system via a coordinate transformation.
287
-
Nevertheless, it can be useful to refer to the "raw" coordinates of the array.
288
-
Some applications might prefer to define points or regions-of-interest in "pixel coordinates" rather than "physical coordinates," for example.
289
-
Indicating that choice explicitly will be important for interoperability.
290
-
This is possible by using **array coordinate systems**.
291
-
292
-
Every array has a default coordinate system whose parameters need not be explicitly defined.
293
-
The dimensionality of each array coordinate system equals the dimensionality of its corresponding Zarr array.
294
-
Its name is the path to the array in the container,
295
-
its axes have `"type": "array"`, are unitless, and have default names.
296
-
The i-th axis has `"name": "dim_i"` (these are the same default names used by [xarray](https://docs.xarray.dev/en/stable/user-guide/terminology.html)).
297
-
As with all coordinate systems, the dimension names must be unique and non-null.
298
-
299
-
:::{dropdown} Example
300
-
```json
301
-
{
302
-
"arrayCoordinateSystem" : {
303
-
"name" : "myDataArray",
304
-
"axes" : [
305
-
{"name": "dim_0", "type": "array"},
306
-
{"name": "dim_1", "type": "array"},
307
-
{"name": "dim_2", "type": "array"}
308
-
]
309
-
}
310
-
}
311
-
312
-
```
313
-
314
-
For example, if 0/zarr.json contains:
315
-
```json
316
-
{
317
-
"zarr_format": 3,
318
-
"node_type": "array",
319
-
"shape": [4, 3, 5],
320
-
//...
321
-
}
322
-
```
323
-
324
-
Then `dim_0` has length 4, `dim_1` has length 3, and `dim_2` has length 5.
325
-
326
-
:::
327
-
328
-
The axes and their order align with the shape of the corresponding Zarr array,
329
-
and whose data depends on the byte order used to store chunks.
330
-
As described in the [Zarr array metadata](https://zarr.readthedocs.io/en/stable/spec/v3.html#arrays),
331
-
the last dimension of an array in "C" order are stored contiguously on disk or in-memory when directly loaded.
332
-
333
-
The name and axes names MAY be customized by including a `arrayCoordinateSystem` field
334
-
in the user-defined attributes of the array whose value is a coordinate system object.
335
-
The length of `axes` MUST be equal to the dimensionality.
336
-
The value of `type` for each object in the axes array MUST equal `"array"`.
337
-
338
283
#### Coordinate convention
339
284
340
285
**The pixel/voxel center is the origin of the continuous coordinate system.**
341
286
342
-
It is vital to consistently define relationship
343
-
between the discrete/array and continuous/interpolated coordinate systems.
344
-
A pixel/voxel is the continuous region (rectangle) that corresponds to a single sample in the discrete array, i.e.,
345
-
the area corresponding to nearest-neighbor (NN) interpolation of that sample.
346
-
The center of a 2d pixel corresponding to the origin `(0,0)` in the discrete array
347
-
is the origin of the continuous coordinate system `(0.0, 0.0)` (when the transformation is the identity).
348
-
The continuous rectangle of the pixel is given
349
-
by the half-open interval `[-0.5, 0.5) x [-0.5, 0.5)` (i.e., -0.5 is included, +0.5 is excluded).
350
-
See chapter 4 and figure 4.1 of the ITK Software Guide.
287
+
It is vital to consistently define relationship between the discrete/array and continuous/interpolated coordinate systems.
288
+
The following conventions apply in this specification:
289
+
290
+
- The discrete coordinate grid for a Zarr array of shape `[N₀, N₁, ..., Nₖ]`
291
+
is defined as zero-based, with indices ranging from 0 to Nᵢ - 1 for each dimension i.
292
+
For example, given an array with shape (2, 3),
293
+
the discrete coordinate system for that array defines the following array of points:
294
+
```
295
+
[
296
+
[(0, 0), (0, 1)],
297
+
[(1, 0), (1, 1)],
298
+
[(2, 0), (3, 1)],
299
+
]
300
+
```
301
+
- A "pixel"/"voxel" is the continuous region (rectangle/box) that corresponds to a single sample in the discrete array,
302
+
i.e., the area corresponding to nearest-neighbor (NN) interpolation of that sample.
303
+
- The center of a 2d pixel corresponding to the origin (0,0) in the discrete array
304
+
is the origin of the continuous coordinate system (0.0, 0.0) (when the transformation is the identity).
305
+
- The continuous rectangle of the pixel is given
306
+
by the half-open interval [-0.5, 0.5) x [-0.5, 0.5) (i.e., -0.5 is included, +0.5 is excluded).
307
+
308
+
For a more formal and in-depth definition,
309
+
see chapter 4 and figure 4.1 of the [ITK Software Guide](https://itk.org/ItkSoftwareGuide.pdf).
351
310
352
311
### bioformats2raw.layout
353
312
@@ -620,6 +579,113 @@ to do so by estimating the transformations' inverse if they choose to.
620
579
```
621
580
:::
622
581
582
+
**Transformations in array coordinate units**:
583
+
Some applications might prefer to define points, regions-of-interest or transformation parameters
584
+
in array coordinates (also referred to as pixel coordinates) rather than physical units.
585
+
Because transformations are agnostic to whether they operate on array or physical coordinates,
586
+
indicating that choice explicitly will be important for interoperability.
587
+
This can be expressed in the metadata in multiple ways, including:
588
+
- One can embed a transformation defined in array units into a `sequence` transformation
589
+
that includes the appropriate scale transformation and its inverse to convert to physical units (see example below).
590
+
- One can define a unitless coordinate system and connect it to the "intrinsic" coordinate system
591
+
with a scale transformation that has the appropriate scale factors to convert to physical units.
592
+
593
+
:::{dropdown} Example: Embedded expression
594
+
595
+
In the context of [`scene`](#scene-md), one may want to express a transformation between two images in dimensionless units,
596
+
even though the coordinate systems of the two images are in physical units.
597
+
This can be achieved by embedding the transformation into a `sequence` transformation like this:
This example assumes that the coordinate system named `"intrinsic"` in both referenced images is in physical units,
625
+
and is linked to the lowest resolution level (e.g., `s0`) of the multiscale image with a `scale` transformation that has the scale factors `[0.5, 0.5]`.
626
+
In this case, the the first `scale` transformation in this example converts the input coordinates from physical to dimensionless units.
627
+
The `translation` transformation is applied in dimensionless units,
628
+
and finally the second `scale` transformation converts the coordinates back to physical units.
629
+
:::
630
+
631
+
:::{dropdown} Example: Unitless coordinate system
632
+
633
+
Alternatively, users may choose to define a unitless coordinate system and connect it to the "intrinsic" coordinate system
634
+
with a scale transformation that has the appropriate scale factors to convert to physical units.
635
+
In the context of multiscales metadata, this could look like this:
In this case, the `scale` transformation under `coordinateTransformations`
683
+
defines the mapping from the "intrinsic" coordinate system to the unitless "array" coordinate system.
684
+
Another transformation (e.g. in a `scene`) could then use the "array" coordinate system as an input or output to define transformations in array units.
0 commit comments