generated from w3c-ccg/markdown-to-spec
-
Notifications
You must be signed in to change notification settings - Fork 42
/
index.bs
927 lines (825 loc) · 38.2 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
<pre class='metadata'>
Title: Next-generation file formats (NGFF)
Shortname: ome-ngff
Level: 1
Status: LS-COMMIT
Status: w3c/ED
Group: ome
URL: https://ngff.openmicroscopy.org/latest/
Repository: https://github.com/ome/ngff
Issue Tracking: Forums https://forum.image.sc/tag/ome-ngff
Logo: http://www.openmicroscopy.org/img/logos/ome-logomark.svg
Local Boilerplate: header yes
Local Boilerplate: copyright yes
Boilerplate: style-darkmode off
Markup Shorthands: markdown yes
Editor: Josh Moore, Open Microscopy Environment (OME) https://www.openmicroscopy.org
Editor: Sébastien Besson, Open Microscopy Environment (OME) https://www.openmicroscopy.org
Editor: Constantin Pape, European Molecular Biology Laboratory (EMBL) https://www.embl.org/sites/heidelberg/
Abstract: This document contains next-generation file format (NGFF)
Abstract: specifications for storing bioimaging data in the cloud.
Abstract: All specifications are submitted to the https://image.sc community for review.
Status Text: The current released version of this specification is
Status Text: <a href="../0.3/index.html">0.3</a>. Migration scripts
Status Text: will be provided between numbered versions. Data written with these latest changes
Status Text: (an "editor's draft") will not necessarily be supported.
</pre>
Introduction {#intro}
=====================
Bioimaging science is at a crossroads. Currently, the drive to acquire more,
larger, preciser spatial measurements is unfortunately at odds with our ability
to structure and share those measurements with others. During a global pandemic
more than ever, we believe fervently that global, collaborative discovery as
opposed to the post-publication, "data-on-request" mode of operation is the
path forward. Bioimaging data should be shareable via open and commercial cloud
resources without the need to download entire datasets.
At the moment, that is not the norm. The plethora of data formats produced by
imaging systems are ill-suited to remote sharing. Individual scientists
typically lack the infrastructure they need to host these data themselves. When
they acquire images from elsewhere, time-consuming translations and data
cleaning are needed to interpret findings. Those same costs are multiplied when
gathering data into online repositories where curator time can be the limiting
factor before publication is possible. Without a common effort, each lab or
resource is left building the tools they need and maintaining that
infrastructure often without dedicated funding.
This document defines a specification for bioimaging data to make it possible
to enable the conversion of proprietary formats into a common, cloud-ready one.
Such next-generation file formats layout data so that individual portions, or
"chunks", of large data are reference-able eliminating the need to download
entire datasets.
Why "<dfn export="true"><abbr title="Next-generation file-format">NGFF</abbr></dfn>"? {#why-ngff}
-------------------------------------------------------------------------------------------------
A short description of what is needed for an imaging format is "a hierarchy
of n-dimensional (dense) arrays with metadata". This combination of features
is certainly provided by <dfn export="true"><abbr title="Hierarchical Data Format 5">HDF5</abbr></dfn>
from the <a href="https://www.hdfgroup.org">HDF Group</a>, which a number of
bioimaging formats do use. HDF5 and other larger binary structures, however,
are ill-suited for storage in the cloud where accessing individual chunks
of data by name rather than seeking through a large file is at the heart of
parallelization.
As a result, a number of formats have been developed more recently which provide
the basic data structure of an HDF5 file, but do so in a more cloud-friendly way.
In the [PyData](https://pydata.org/) community, the Zarr [[zarr]] format was developed
for easily storing collections of [NumPy](https://numpy.org/) arrays. In the
[ImageJ](https://imagej.net/) community, N5 [[n5]] was developed to work around
the limitations of HDF5 ("N5" was originally short for "Not-HDF5").
Both of these formats permit storing individual chunks of data either locally in
separate files or in cloud-based object stores as separate keys.
A [current effort](https://zarr-specs.readthedocs.io/en/core-protocol-v3.0-dev/protocol/core/v3.0.html)
is underway to unify the two similar specifications to provide a single binary
specification. The editor's draft will soon be entering a [request for comments (RFC)](https://github.com/zarr-developers/zarr-specs/issues/101) phase with the goal of having a first version early in 2021. As that
process comes to an end, this document will be updated.
OME-NGFF {#ome-ngff}
--------------------
The conventions and specifications defined in this document are designed to
enable next-generation file formats to represent the same bioimaging data
that can be represented in \[OME-TIFF](http://www.openmicroscopy.org/ome-files/)
and beyond. However, the conventions will also be usable by HDF5 and other sufficiently advanced
binary containers. Eventually, we hope, the moniker "next-generation" will no longer be
applicable, and this will simply be the most efficient, common, and useful representation
of bioimaging data, whether during acquisition or sharing in the cloud.
Note: The following text makes use of OME-Zarr [[ome-zarr-py]], the current prototype implementation,
for all examples.
On-disk (or in-cloud) layout {#on-disk}
=======================================
An overview of the layout of an OME-Zarr fileset should make
understanding the following metadata sections easier. The hierarchy
is represented here as it would appear locally but could equally
be stored on a web server to be accessed via HTTP or in object storage
like S3 or GCS.
OME-Zarr is an implementation of the OME-NGFF specification using the Zarr
format. Arrays MUST be defined and stored in a hierarchical organization as
defined by the
[version 2 of the Zarr specification ](https://zarr.readthedocs.io/en/stable/spec/v2.html).
OME-NGFF metadata MUST be stored as attributes in the corresponding Zarr
groups.
Images {#image-layout}
----------------------
The following layout describes the expected Zarr hierarchy for images with
multiple levels of resolutions and optionally associated labels.
Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [[#multiscale-md]] for details.
For this example we assume an image with 5 dimensions and axes called `t,c,z,y,x`.
<pre>
. # Root folder, potentially in S3,
│ # with a flat list of images by image ID.
│
├── 123.zarr # One image (id=123) converted to Zarr.
│
└── 456.zarr # Another image (id=456) converted to Zarr.
│
├── .zgroup # Each image is a Zarr group, or a folder, of other groups and arrays.
├── .zattrs # Group level attributes are stored in the .zattrs file and include
│ # "multiscales" and "omero" (see below). In addition, the group level attributes
│ # must also contain "_ARRAY_DIMENSIONS" if this group directly contains multi-scale arrays.
│
├── 0 # Each multiscale level is stored as a separate Zarr array,
│ ... # which is a folder containing chunk files which compose the array.
├── n # The name of the array is arbitrary with the ordering defined by
│ │ # by the "multiscales" metadata, but is often a sequence starting at 0.
│ │
│ ├── .zarray # All image arrays must be up to 5-dimensional
│ │ # with the axis of type time before type channel, before spatial axes.
│ │
│ └─ t # Chunks are stored with the nested directory layout.
│ └─ c # All but the last chunk element are stored as directories.
│ └─ z # The terminal chunk is a file. Together the directory and file names
│ └─ y # provide the "chunk coordinate" (t, c, z, y, x), where the maximum coordinate
│ └─ x # will be `dimension_size / chunk_size`.
│
└── labels
│
├── .zgroup # The labels group is a container which holds a list of labels to make the objects easily discoverable
│
├── .zattrs # All labels will be listed in `.zattrs` e.g. `{ "labels": [ "original/0" ] }`
│ # Each dimension of the label `(t, c, z, y, x)` should be either the same as the
│ # corresponding dimension of the image, or `1` if that dimension of the label
│ # is irrelevant.
│
└── original # Intermediate folders are permitted but not necessary and currently contain no extra metadata.
│
└── 0 # Multiscale, labeled image. The name is unimportant but is registered in the "labels" group above.
├── .zgroup # Zarr Group which is both a multiscaled image as well as a labeled image.
├── .zattrs # Metadata of the related image and as well as display information under the "image-label" key.
│
├── 0 # Each multiscale level is stored as a separate Zarr array, as above, but only integer values
│ ... # are supported.
└── n
</pre>
High-content screening {#hcs-layout}
------------------------------------
The following specification defines the hierarchy for a high-content screening
dataset. Three groups MUST be defined above the images:
- the group above the images defines the well and MUST implement the
[well specification](#well-md). All images contained in a well are fields
of view of the same well
- the group above the well defines a row of wells
- the group above the well row defines an entire plate i.e. a two-dimensional
collection of wells organized in rows and columns. It MUST implement the
[plate specification](#plate-md)
A well row group SHOULD NOT be present if there are no images in the well row.
A well group SHOULD NOT be present if there are no images in the well.
<pre>
. # Root folder, potentially in S3,
│
└── 5966.zarr # One plate (id=5966) converted to Zarr
├── .zgroup
├── .zattrs # Implements "plate" specification
├── A # First row of the plate
│ ├── .zgroup
│ │
│ ├── 1 # First column of row A
│ │ ├── .zgroup
│ │ ├── .zattrs # Implements "well" specification
│ │ │
│ │ ├── 0 # First field of view of well A1
│ │ │ │
│ │ │ ├── .zgroup
│ │ │ ├── .zattrs # Implements "multiscales", "omero"
│ │ │ ├── 0
│ │ │ │ ... # Resolution levels
│ │ │ ├── n
│ │ │ └── labels # Labels (optional)
│ │ ├── ... # Fields of view
│ │ └── m
│ ├── ... # Columns
│ └── 12
├── ... # Rows
└── H
</pre>
Metadata {#metadata}
====================
The various `.zattrs` files throughout the above array hierarchy may contain metadata
keys as specified below for discovering certain types of data, especially images.
"axes" metadata {#axes-md}
--------------------------
"axes" describes the dimensions of a physical coordinate space. It is a list of dictionaries, where each dictionary describes a dimension (axis) and:
- MUST contain the field "name" that gives the name for this dimension. The values MUST be unique across all "name" fields.
- SHOULD contain the field "type". It SHOULD be one of "space", "time" or "channel", but MAY take other values for custom axis types that are not part of this specification yet.
- SHOULD contain the field "unit" to specify the physical unit of this dimension. The value SHOULD be one of the following strings, which are valid units according to UDUNITS-2.
- Units for "space" axes: 'angstrom', 'attometer', 'centimeter', 'decimeter', 'exameter', 'femtometer', 'foot', 'gigameter', 'hectometer', 'inch', 'kilometer', 'megameter', 'meter', 'micrometer', 'mile', 'millimeter', 'nanometer', 'parsec', 'petameter', 'picometer', 'terameter', 'yard', 'yoctometer', 'yottameter', 'zeptometer', 'zettameter'
- Units for "time" axes: 'attosecond', 'centisecond', 'day', 'decisecond', 'exasecond', 'femtosecond', 'gigasecond', 'hectosecond', 'hour', 'kilosecond', 'megasecond', 'microsecond', 'millisecond', 'minute', 'nanosecond', 'petasecond', 'picosecond', 'second', 'terasecond', 'yoctosecond', 'yottasecond', 'zeptosecond', 'zettasecond'
If part of [[#multiscale-md]], the length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data.
"coordinateTransformations" metadata {#trafo-md}
-------------------------------------
"coordinateTransformations" describe a series of transformations that map between two coordinate spaces (defined by "axes").
For example, to map a discrete data space of an array to the corresponding physical space.
It is a list of dictionaries. Each entry describes a single transformation and MUST contain the field "type".
The value of "type" MUST be one of the elements of the `type` column in the table below.
Additional fields for the entry depend on "type" and are defined by the column `fields`.
<table>
<tr><th>`identity` <td> <td>identity transformation, is the default transformation and is typically not explicitly defined
<tr><th>`translation` <td> one of: `"translation":List[float]`, `"path":str` <td>translation vector, stored either as a list of floats (`"translation"`) or as binary data at a location in this container (`path`). The length of vector defines number of dimensions. |
<tr><th>`scale` <td> one of: `"scale":List[float]`, `"path":str` <td>scale vector, stored either as a list of floats (`scale`) or as binary data at a location in this container (`path`). The length of vector defines number of dimensions. |
<thead>
<tr><th>type<th>fields<th>description
</table>
The transformations in the list are applied sequentially and in order.
"multiscales" metadata {#multiscale-md}
---------------------------------------
Metadata about an image can be found under the "multiscales" key in the group-level metadata. Here, image refers to 2 to 5 dimensional data representing image or volumetric data with optional time or channel axes. It is stored in a multiple resolution representation.
"multiscales" contains a list of dictionaries where each entry describes a multiscale image.
Each "multiscales" dictionary MUST contain the field "axes", see [[#axes-md]].
The length of "axes" must be between 2 and 5 and MUST be equal to the dimensionality of the zarr arrays storing the image data (see "datasets:path").
The "axes" MUST contain 2 or 3 entries of "type:space" and MAY contain one additional entry of "type:time" and MAY contain one additional entry of "type:channel" or a null / custom type.
The order of the entries MUST correspond to the order of dimensions of the zarr arrays. In addition, the entries MUST be ordered by "type" where the "time" axis must come first (if present), followed by the "channel" or custom axis (if present) and the axes of type "space".
If there are three spatial axes where two correspond to the image plane ("yx") and images are stacked along the other (anisotropic) axis ("z"), the spatial axes SHOULD be ordered as "zyx".
The values of the "name" fields must be given as a list in the field "_ARRAY_DIMENSIONS" in the attributes (.zattr) of the zarr arrays.
This ensures compatibility with the [xarray zarr encoding](http://xarray.pydata.org/en/stable/internals/zarr-encoding-spec.html#zarr-encoding).
E.g. for "axes: [{"name": "z"}, {"name": "y"}, {"name": x}]", the zarr arrays must contain "{"_ARRAY_DIMENSIONS": ["z", "y", "x"]}" in their attributes.
Each "multiscales" dictionary MUST contain the field "datasets", which is a list of dictionaries describing the arrays storing the individual resolution levels.
Each dictionary in "datasets" MUST contain the field "path", whose value contains the path to the array for this resolution relative
to the current zarr group. The "path"s MUST be ordered from largest (i.e. highest resolution) to smallest.
Each "datasets" dictionary MUST have the same number of dimensions and MUST NOT have more than 5 dimensions. The number of dimensions and order MUST correspond to number and order of "axes".
Each dictionary MUST contain the field "coordinateTransformations", which contains a list of transformations that map the data coordinates to the physical coordinates (as specified by "axes") for this resolution level.
The transformations are defined according to [[#trafo-md]]. The transformation MUST only be of type `translation` or `scale`.
They MUST contain exactly one `scale` transformation that specifies the pixel size in physical units or time duration. If scaling information is not available or applicable for one of the axes set it to 1.
It MAY contain exactly one `translation` that specifies the offset from the origin in physical units. If `translation` is given it MUST be listed after `scale` to ensure that it is given in physical coordinates.
The length of the `scale` and `translation` array MUST be the same as the length of "axes".
The requirements (only `scale` and `translation`, restrictions on order) are in place to provide a simple mapping from data coordinates to physical coordinates while being compatible with the general transformation spec.
Each "multiscales" dictionary MAY contain the field "coordinateTransformations", describing transformations that are applied to all resolution levels in the same manner.
The transformations MUST follow the same rules about allowed types, order, etc. as in "datasets:coordinateTransformations" and are applied after them.
They can for example be used to specify the `scale` for a dimension that is the same for all resolutions.
Each "multiscales" dictionary SHOULD contain the field "name". It SHOULD contain the field "version", which indicates the version of the multiscale metadata of this image (current version is 0.4).
Each "multiscales" dictionary SHOULD contain the field "type", which gives the type of downscaling method used to generate the multiscale image pyramid.
It SHOULD contain the field "metadata", which contains a dictionary with additional information about the downscaling method.
```
{
"multiscales": [
{
"version": "0.4",
"name": "example",
"axes": [
{"name": "t", "type": "time", "unit": "millisecond"},
{"name": "c", "type": "channel"},
{"name": "z", "type": "space", "unit": "micrometer"},
{"name": "y", "type": "space", "unit": "micrometer"},
{"name": "x", "type": "space", "unit": "micrometer"}
],
"datasets": [
{
"path": "0",
"coordinateTransformations": [{"type": "scale", "scale": [1.0, 1.0, 0.5, 0.5, 0.5]}] # the voxel size for the first scale level (0.5 micrometer)
}
{
"path": "1",
"coordinateTransformations": [{"type": "scale", "scale": [1.0, 1.0, 1.0, 1.0, 1.0]}] # the voxel size for the second scale level (downscaled by a factor of 2 -> 1 micrometer)
},
{
"path": "2",
"coordinateTransformations": [{"type": "scale", "scale": [1.0, 1.0, 2.0, 2.0, 2.0]}] # the voxel size for the second scale level (downscaled by a factor of 4 -> 2 micrometer)
}
],
"coordinateTransformations": [{"type": "scale", "scale": [0.1, 1.0, 1.0, 1.0, 1.0]], # the time unit (0.1 milliseconds), which is the same for each scale level
"type": "gaussian",
"metadata": { # the fields in metadata depend on the downscaling implementation
"method": "skimage.transform.pyramid_gaussian", # here, the paramters passed to the skimage function are given
"version": "0.16.1",
"args": "[true]",
"kwargs": {"multichannel": true}
}
}
]
}
```
If only one multiscale is provided, use it. Otherwise, the user can choose by
name, using the first multiscale as a fallback:
```python
datasets = []
for named in multiscales:
if named["name"] == "3D":
datasets = [x["path"] for x in named["datasets"]]
break
if not datasets:
# Use the first by default. Or perhaps choose based on chunk size.
datasets = [x["path"] for x in multiscales[0]["datasets"]]
```
"omero" metadata {#omero-md}
----------------------------
Information specific to the channels of an image and how to render it
can be found under the "omero" key in the group-level metadata:
```json
"id": 1, # ID in OMERO
"name": "example.tif", # Name as shown in the UI
"version": "0.3", # Current version
"channels": [ # Array matching the c dimension size
{
"active": true,
"coefficient": 1,
"color": "0000FF",
"family": "linear",
"inverted": false,
"label": "LaminB1",
"window": {
"end": 1500,
"max": 65535,
"min": 0,
"start": 0
}
}
],
"rdefs": {
"defaultT": 0, # First timepoint to show the user
"defaultZ": 118, # First Z section to show the user
"model": "color" # "color" or "greyscale"
}
```
See https://docs.openmicroscopy.org/omero/5.6.1/developers/Web/WebGateway.html#imgdata
for more information.
"labels" metadata {#labels-md}
------------------------------
The special group "labels" found under an image Zarr contains the key `labels` containing
the paths to label objects which can be found underneath the group:
```json
{
"labels": [
"orphaned/0"
]
}
```
Unlisted groups MAY be labels.
"image-label" metadata {#label-md}
----------------------------------
Groups containing the `image-label` dictionary represent an image segmentation
in which each unique pixel value represents a separate segmented object.
`image-label` groups MUST also contain `multiscales` metadata and the two
"datasets" series MUST have the same number of entries.
The `colors` key defines a list of JSON objects describing the unique label
values. Each entry in the list MUST contain the key "label-value" with the
pixel value for that label. Additionally, the "rgba" key MAY be present, the
value for which is an RGBA unsigned-int 4-tuple: `[uint8, uint8, uint8, uint8]`
All `label-value`s must be unique. Clients who choose to not throw an error
should ignore all except the _last_ entry.
Some implementations may represent overlapping labels by using a specially assigned
value, for example the highest integer available in the pixel range.
The `properties` key defines a list of JSON objects which also describes the unique
label values. Each entry in the list MUST contain the key "label-value" with the
pixel value for that label. Additionally, an arbitrary number of key-value pairs
MAY be present for each label value denoting associated metadata. Not all label
values must share the same key-value pairs within the properties list.
The `source` key is an optional dictionary which contains information on the
image the label is associated with. If included it MAY include a key `image`
whose value is the relative path to a Zarr image group. The default value is
"../../" since most labels are stored under a subgroup named "labels/" (see
above).
```json
"image-label":
{
"version": "0.3",
"colors": [
{
"label-value": 1,
"rgba": [255, 255, 255, 0]
},
{
"label-value": 4,
"rgba": [0, 255, 255, 128]
},
...
],
"properties": [
{
"label-value": 1,
"area (pixels)": 1200,
"class": "foo"
},
{
"label-value": 4,
"area (pixels)": 1650
},
...
]
},
"source": {
"image": "../../"
}
]
```
"plate" metadata {#plate-md}
----------------------------
For high-content screening datasets, the plate layout can be found under the
custom attributes of the plate group under the `plate` key.
<dl>
<dt><strong>acquisitions</strong></dt>
<dd>An optional list of JSON objects defining the acquisitions for a given
plate. Each acquisition object MUST contain an `id` key providing an
unique identifier within the context of the plate to which fields of
view can refer to. It SHOULD contain a `name` key identifying the name
of the acquisition. It SHOULD contain a `maximumfieldcount` key
indicating the maximum number of fields of view for the acquisition. It
MAY contain a `description` key providing a description for the
acquisition. It MAY contain a `startime` and/or `endtime` key specifying
the start and/or end timestamp of the acquisition using an epoch
string.</dd>
<dt><strong>columns</strong></dt>
<dd>A list of JSON objects defining the columns of the plate. Each column
object defines the properties of the column at the index of the object
in the list. Each column in the physical plate MUST be defined, even
if no wells in the column are defined. Each defined column MUST contain
a `name` key specifying the column name. The `name` MUST contain only
alphanumeric characters, MUST be case-sensitive, and MUST NOT be a
duplicate of any other `name` in the `columns` list. Care SHOULD be
taken to avoid collisions on case-insensitive filesystems
(e.g. avoid using both `Aa` and `aA`).</dd>
<dt><strong>field_count</strong></dt>
<dd>An integer defining the maximum number of fields per view across all
wells.</dd>
<dt><strong>name</strong></dt>
<dd>A string defining the name of the plate.</dd>
<dt><strong>rows</strong></dt>
<dd>A list of JSON objects defining the rows of the plate. Each row object
defines the properties of the row at the index of the object in the
list. Each row in the physical plate MUST be defined, even if no wells
in the row are defined. Each defined row MUST contain a `name` key
specifying the row name. The `name` MUST contain only alphanumeric
characters, MUST be case-sensitive, and MUST NOT be a duplicate
of any other `name` in the `rows` list. Care SHOULD be taken to avoid
collisions on case-insensitive filesystems (e.g. avoid using both `Aa`
and `aA`).</dd>
<dt><strong>version</strong></dt>
<dd>A string defining the version of the specification.</dd>
<dt><strong>wells</strong></dt>
<dd>A list of JSON objects defining the wells of the plate. Each well object
MUST contain a `path` key identifying the path to the well subgroup.
The `path` MUST consist of a `name` in the `rows` list, a file separator (`/`),
and a `name` from the `columns` list, in that order. The `path` MUST NOT contain
additional leading or trailing directories.
Each well object MUST contain both a `rowIndex` key identifying the index into
the `rows` list and a `columnIndex` key indentifying the index into
the `columns` list. `rowIndex` and `columnIndex` MUST be 0-based.
The `rowIndex`, `columnIndex`, and `path` MUST all refer to the same
row/column pair.</dd>
</dl>
For example the following JSON object defines a plate with two acquisitions and
6 wells (2 rows and 3 columns), containing up to 2 fields of view per acquisition.
```json
"plate": {
"acquisitions": [
{
"id": 1,
"maximumfieldcount": 2,
"name": "Meas_01(2012-07-31_10-41-12)",
"starttime": 1343731272000
},
{
"id": 2,
"maximumfieldcount": 2,
"name": "Meas_02(201207-31_11-56-41)",
"starttime": 1343735801000
}
],
"columns": [
{
"name": "1"
},
{
"name": "2"
},
{
"name": "3"
}
],
"field_count": 4,
"name": "test",
"rows": [
{
"name": "A"
},
{
"name": "B"
}
],
"version": "0.3",
"wells": [
{
"path": "A/1",
"rowIndex": 0,
"columnIndex": 0
},
{
"path": "A/2"
"rowIndex": 0,
"columnIndex": 1
},
{
"path": "A/3"
"rowIndex": 0,
"columnIndex": 2
},
{
"path": "B/1"
"rowIndex": 1,
"columnIndex": 0
},
{
"path": "B/2"
"rowIndex": 1,
"columnIndex": 1
},
{
"path": "B/3"
"rowIndex": 1,
"columnIndex": 2
}
]
}
```
The following JSON object defines a sparse plate with one acquisition and
2 wells in a 96 well plate, containing one field of view per acquisition.
```json
"plate": {
"acquisitions": [
{
"id": 1,
"maximumfieldcount": 1,
"name": "single acquisition",
"starttime": 1343731272000
},
],
"columns": [
{
"name": "1"
},
{
"name": "2"
},
{
"name": "3"
},
{
"name": "4"
},
{
"name": "5"
},
{
"name": "6"
},
{
"name": "7"
},
{
"name": "8"
},
{
"name": "9"
},
{
"name": "10"
},
{
"name": "11"
},
{
"name": "12"
}
],
"field_count": 1,
"name": "sparse test",
"rows": [
{
"name": "A"
},
{
"name": "B"
},
{
"name": "C"
},
{
"name": "D"
},
{
"name": "E"
},
{
"name": "F"
},
{
"name": "G"
},
{
"name": "H"
}
],
"version": "0.1",
"wells": [
{
"path": "C/5"
"rowIndex": 2,
"columnIndex": 4
},
{
"path": "D/7"
"rowIndex": 3,
"columnIndex": 6
}
]
}
```
"well" metadata {#well-md}
--------------------------
For high-content screening datasets, the metadata about all fields of views
under a given well can be found under the "well" key in the attributes of the
well group.
<dl>
<dt><strong>images</strong></dt>
<dd>A list of JSON objects defining the fields of views for a given well.
Each object MUST contain a `path` key identifying the path to the
field of view. If multiple acquisitions were performed in the plate, it
MUST contain an `acquisition` key identifying the id of the
acquisition which must match one of acquisition JSON objects defined in
the plate metadata.</dd>
<dt><strong>version</strong></dt>
<dd>A string defining the version of the specification.</dd>
</dl>
For example the following JSON object defines a well with four fields of
view. The first two fields of view were part of the first acquisition while
the last two fields of view were part of the second acquisition.
```json
"well": {
"images": [
{
"acquisition": 1,
"path": "0"
},
{
"acquisition": 1,
"path": "1"
},
{
"acquisition": 2,
"path": "2"
},
{
"acquisition": 2,
"path": "3"
}
],
"version": "0.3"
}
```
The following JSON object defines a well with two fields of view in a plate with
four acquisitions. The first field is part of the first acquisition, and the second
field is part of the last acquisition.
```json
"well": {
"images": [
{
"acquisition": 0,
"path": "0"
},
{
"acquisition": 3,
"path": "1"
}
],
"version": "0.1"
}
```
Specification naming style {#naming-style}
==========================================
Multi-word keys in this specification should use the `camelCase` style.
NB: some parts of the specification don't obey this convention as they
were added before this was adopted, but they should be updated in due course.
Implementations {#implementations}
==================================
Projects which support reading and/or writing OME-NGFF data include:
<dl>
<dt><strong>[bigdataviewer-ome-zarr](https://github.com/mobie/bigdataviewer-ome-zarr)</strong></dt>
<dd>Fiji-plugin for reading OME-Zarr.</dd>
<dt><strong>[bioformats2raw](https://github.com/glencoesoftware/bioformats2raw)</strong></dt>
<dd>A performant, Bio-Formats image file format converter.</dd>
<dt><strong>[omero-ms-zarr](https://github.com/ome/omero-ms-zarr)</strong></dt>
<dd>A microservice for OMERO.server that converts images stored in OMERO to OME-Zarr files on the fly, served via a web API.</dd>
<dt><strong>[idr-zarr-tools](https://github.com/IDR/idr-zarr-tools)</strong></dt>
<dd>A full workflow demonstrating the conversion of IDR images to OME-Zarr images on S3.</dd>
<dt><strong>[OMERO CLI Zarr plugin](https://github.com/ome/omero-cli-zarr)</strong></dt>
<dd>An OMERO CLI plugin that converts images stored in OMERO.server into a local Zarr file.</dd>
<dt><strong>[ome-zarr-py](https://github.com/ome/ome-zarr-py)</strong></dt>
<dd>A napari plugin for reading ome-zarr files.</dd>
<dt><strong>[vizarr](https://github.com/hms-dbmi/vizarr/)</strong></dt>
<dd>A minimal, purely client-side program for viewing Zarr-based images with Viv & ImJoy.</dd>
</dl>
<img src="https://downloads.openmicroscopy.org/presentations/2020/Dundee/Workshops/NGFF/zarr_diagram/images/zarr-ome-diagram.png"
alt="Diagram of related projects"/>
All implementations prevent an equivalent representation of a dataset which can be downloaded or uploaded freely. An interactive
version of this diagram is available from the [OME2020 Workshop](https://downloads.openmicroscopy.org/presentations/2020/Dundee/Workshops/NGFF/zarr_diagram/).
Mouseover the blackboxes representing the implementations above to get a quick tip on how to use them.
Note: If you would like to see your project listed, please open an issue or PR on the [ome/ngff](https://github.com/ome/ngff) repository.
Citing {#citing}
================
[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.3)
J. Moore, *et al*. Editors. Open Microscopy Environment Consortium, 24 August 2021.
This edition of the specification is [https://ngff.openmicroscopy.org/0.3/](https://ngff.openmicroscopy.org/0.3/]).
The latest edition is available at [https://ngff.openmicroscopy.org/latest/](https://ngff.openmicroscopy.org/latest/).
[(doi:10.5281/zenodo.4282107)](https://doi.org/10.5281/zenodo.4282107)
Version History {#history}
==========================
<table>
<thead>
<tr>
<td>Revision</td>
<td>Date</td>
<td>Description</td>
</tr>
</thead>
<tr>
<td>0.3.0</td>
<td>2021-08-24</td>
<td>Add axes field to multiscale metadata </td>
</tr>
<tr>
<td>0.2.0</td>
<td>2021-03-29</td>
<td>Change chunk dimension separator to "/" </td>
</tr>
<tr>
<td>0.1.4</td>
<td>2020-11-26</td>
<td>Add HCS specification </td>
</tr>
<tr>
<td>0.1.3</td>
<td>2020-09-14</td>
<td>Add labels specification </td>
</tr>
<tr>
<td>0.1.2 </td>
<td>2020-05-07</td>
<td>Add description of "omero" metadata </td>
</tr>
<tr>
<td>0.1.1 </td>
<td>2020-05-06</td>
<td>Add info on the ordering of resolutions </td>
</tr>
<tr>
<td>0.1.0 </td>
<td>2020-04-20</td>
<td>First version for internal demo </td>
</tr>
</table>
<pre class="biblio">
{
"blogNov2020": {
"href": "https://blog.openmicroscopy.org/file-formats/community/2020/11/04/zarr-data/",
"title": "Public OME-Zarr data (Nov. 2020)",
"authors": [
"OME Team"
],
"status": "Informational",
"publisher": "OME",
"id": "blogNov2020",
"date": "04 November 2020"
},
"imagesc26952": {
"href": "https://forum.image.sc/t/ome-s-position-regarding-file-formats/26952",
"title": "OME’s position regarding file formats",
"authors": [
"OME Team"
],
"status": "Informational",
"publisher": "OME",
"id": "imagesc26952",
"date": "19 June 2020"
},
"n5": {
"id": "n5",
"href": "https://github.com/saalfeldlab/n5/issues/62",
"title": "N5---a scalable Java API for hierarchies of chunked n-dimensional tensors and structured meta-data",
"status": "Informational",
"authors": [
"John A. Bogovic",
"Igor Pisarev",
"Philipp Hanslovsky",
"Neil Thistlethwaite",
"Stephan Saalfeld"
],
"date": "2020"
},
"ome-zarr-py": {
"id": "ome-zarr-py",
"href": "https://doi.org/10.5281/zenodo.4113931",
"title": "ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.",
"status": "Informational",
"publisher": "Zenodo",
"authors": [
"OME",
"et al"
],
"date": "06 October 2020"
},
"zarr": {
"id": "zarr",
"href": "https://doi.org/10.5281/zenodo.4069231",
"title": "Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.",
"status": "Informational",
"publisher": "Zenodo",
"authors": [
"Alistair Miles",
"et al"
],
"date": "06 October 2020"
}
}
</pre>