Output File Formats ====================== mesoSPIM-control writes acquired image data through a pluggable **image writer** system. Each acquisition entry in the Acquisition Manager selects its own writer via the file-naming wizard, so a single acquisition list can mix formats across rows if needed. .. tip:: Not sure which one to pick? * **Tiff_Writer** (ImageJ-TIFF) for the broadest compatibility with external viewers and stitchers — the safest default if you're not sure what your downstream tools support. * **MP_OME_Zarr_Writer** for new acquisitions on a fast (NVMe/SSD) system — natively saves multi-resolution pyramids with compression, and won't stall acquisition on disk I/O. * **H5_BDV_Writer** for the easiest BigStitcher stitching workflow. See the caveats below before relying on it for Imaris. At a glance ------------- .. list-table:: :widths: 20 12 14 14 14 26 :header-rows: 1 * - Writer - Extension - Files per acquisition - Pyramid - Compression - Notes * - ``MP_OME_Zarr_Writer`` - ``.ome.zarr`` - One store (per-tile subgroups) - Yes - zstd / lz4 - Writes in a background process; recommended default * - ``OME_Zarr_Writer`` - ``.ome.zarr`` / ``.zarr`` - One store (per-tile subgroups) - Yes - zstd / lz4 - Single-core; same format as above * - ``H5_BDV_Writer`` - ``.h5`` - One file (all tiles) - Not in practice :sup:`†` - gzip / lzf / none - Easiest BigStitcher stitching workflow; Imaris-compatible only for a single-tile, uncompressed, pyramid-free dataset * - ``Tiff_Writer`` - ``.tif`` / ``.tiff`` - One per tile/channel - No - No - ImageJ-compatible; broadest compatibility with external viewers/stitchers * - ``Big_Tiff_Writer`` - ``.btf`` / ``.tf2`` / ``.tf8`` - One per tile/channel - No - No - Same as TIFF, in the BigTIFF container format * - ``RAW_Writer`` - ``.raw`` - One per tile/channel - No - No - Uncompressed uint16 binary dump, no metadata :sup:`†` ``H5_BDV_Writer`` accepts a pyramid (``subsamp``) option, but generating it during acquisition is slow enough (see below) that it's not used in practice. Selecting a writer --------------------- Pick the writer for each acquisition entry in the **file-naming wizard**. The ``plugins['first_image_writer']`` setting in the config file only controls which writer is pre-selected/listed first there — it does not restrict which writers are available: .. code-block:: python plugins = { 'path_list': ["../src/plugins"], 'first_image_writer': 'OME_Zarr_Writer', } See :doc:`configuration` for the full ``plugins`` config reference. OME-Zarr (``OME_Zarr_Writer`` / ``MP_OME_Zarr_Writer``) ---------------------------------------------------------- Both write the same `OME-Zarr `_ format — one ``.ome.zarr`` store per acquisition, with each tile in its own subgroup — and accept identical configuration. The only difference is *how* the writing happens: * **``OME_Zarr_Writer``** writes on the main acquisition thread (single-core). * **``MP_OME_Zarr_Writer``** offloads writing to a separate background process via a shared-memory ring buffer, so a slow disk can't stall acquisition. This is the **recommended writer for new acquisitions** on systems with fast (NVMe/SSD) storage. Both save multi-resolution pyramids natively, with compression, and can optionally emit an XML file for drag-and-drop stitching in BigStitcher. .. code-block:: python OME_Zarr_Writer = { 'ome_version': '0.5', # '0.4' (zarr v2) or '0.5' (zarr v3, sharding supported) 'generate_multiscales': True, # False: only save the original resolution 'compression': 'zstd', # None, 'zstd', 'lz4' 'compression_level': 5, # 1-9 'shards': (64, 6000, 6000), # max shard size (z,y,x); ignored if ome_version == '0.4' 'base_chunks': (64, 256, 256), # starting chunk size (level 0), (z,y,x) 'target_chunks': (64, 64, 64), # chunk size at the highest pyramid level, (z,y,x) 'async_finalize': True, # let the next tile start before this one's pyramid finishes # BigStitcher-specific 'write_big_stitcher_xml': True, # only takes effect for ome_version == '0.4' 'flip_xyz': (True, True, False), # match BigStitcher coordinates to mesoSPIM axes 'transpose_xy': False, # swap X/Y if tile positions come out wrong } MP_OME_Zarr_Writer = { # ... same keys as above, plus: 'ring_buffer_size': 512, # frames buffered in shared memory; lower (e.g. 16) for demo/simulation mode 'write_cache': None, # optional fast local scratch path, moved to the final folder once a tile finishes } .. note:: The BigStitcher XML export only works with ``ome_version: '0.4'`` (zarr v2). Choosing ``'0.5'`` gets you sharding (fewer files on disk) but no BigStitcher XML. .. important:: Bigger chunks/shards generally mean fewer, more efficient files; very small chunks can noticeably slow down writing on some hardware. The defaults above are a reasonable starting point — benchmark on your own hardware before changing them for a real acquisition. H5_BDV_Writer ---------------- Writes all tiles of the acquisition into a **single** ``.h5`` file in `BigDataViewer `_ format, plus a companion BigDataViewer/BigStitcher XML — the **easiest stitching workflow in BigStitcher** of any of the writers here. .. code-block:: python H5_BDV_Writer = { 'subsamp': ((1, 1, 1),), # e.g. ((1,1,1), (1,4,4)) for a 2-level (z,y,x) pyramid 'compression': None, # None, 'gzip', 'lzf' 'flip_xyz': (True, True, False), # match BigStitcher coordinates to mesoSPIM axes 'transpose_xy': False, # swap X/Y if tile positions come out wrong } .. warning:: ``subsamp`` (multiscale pyramid) is technically available but **not used in practice** — generating pyramids and/or compressing on the fly during acquisition can slow writing down by **5-10×**, which most acquisitions can't afford. Leave both at their defaults (no subsampling, no compression) unless you've specifically benchmarked otherwise. .. important:: **Imaris can only open these files if the dataset has a single tile (one position, no mosaic), with no compression and no multiscale pyramid.** Tiff_Writer / Big_Tiff_Writer --------------------------------- One plain, uncompressed, ImageJ-compatible TIFF stack per tile, no pyramid. ``Tiff_Writer`` (regular TIFF) and ``Big_Tiff_Writer`` (the BigTIFF container format) are both **not limited to 4 GB per file** — pick either; ``Tiff_Writer``'s plain ImageJ-TIFF output has the broadest compatibility with external viewers and stitchers, and is a safe default if you're unsure what your downstream tools support. Filenames from both follow the BigStitcher auto-loader naming convention, so individual-TIFF acquisitions can still be imported into BigStitcher. RAW_Writer ------------- The simplest possible option: a single uncompressed ``uint16`` binary file per tile (no header, no metadata), written via a direct memory-mapped array. Useful for custom downstream pipelines that read raw binary directly, or as a baseline for debugging I/O performance issues in the other writers. Writer capabilities ----------------------- .. list-table:: :widths: 25 15 15 15 15 15 :header-rows: 1 * - Writer - Chunking - Compression - Multiscale - Overwrite existing - dtypes * - ``MP_OME_Zarr_Writer`` - Yes - Yes - Yes - No - uint16 * - ``OME_Zarr_Writer`` - Yes - Yes - Yes - No - uint16 * - ``H5_BDV_Writer`` - No - No :sup:`*` - No :sup:`*` - No - uint8, uint16, float32 * - ``Tiff_Writer`` - No - No - No - No - uint8, uint16, float32 * - ``Big_Tiff_Writer`` - No - No - No - No - uint8, uint16, float32 * - ``RAW_Writer`` - No - No - No - No - uint16 :sup:`*` ``H5_BDV_Writer`` declares ``supports_compression=False`` and ``supports_multiscale=False`` in its plugin capabilities, but its ``compression`` and ``subsamp`` config keys (above) do work at runtime — a known inconsistency between the declared capability flags and actual behavior, not a documentation error. For the plugin architecture itself (writing a new writer, the ``ImageWriter`` interface, discovery rules), see :doc:`plugins`.