{"name":"napari-czitools","display_name":"CziReadTools","visibility":"public","icon":null,"categories":["IO"],"schema_version":"0.3.0","on_activate":null,"on_deactivate":null,"contributions":{"commands":[{"id":"napari-czitools.get_reader_adv","title":"Open *.czi image files with CziTools","python_name":"napari_czitools._reader:napari_get_reader","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-czitools.celldivision_data","title":"Load 5D Data","python_name":"napari_czitools._sample_data:celldivision_data","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-czitools.wellplate_data","title":"Load WellPlate Data","python_name":"napari_czitools._sample_data:wellplate_data","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-czitools.zstack_data","title":"Load ZStack Data","python_name":"napari_czitools._sample_data:zstack_data","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-czitools.airyscan_zstack_data","title":"Load Airyscan ZStack Data","python_name":"napari_czitools._sample_data:airyscan_zstack_data","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-czitools.he_stain_data","title":"Load HE Stain Data","python_name":"napari_czitools._sample_data:he_stain_data","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-czitools.make_czireader_widget","title":"Create CZI Reader Widget","python_name":"napari_czitools._widget:CziReaderWidget","short_title":null,"category":null,"icon":null,"enablement":null}],"readers":[{"command":"napari-czitools.get_reader_adv","filename_patterns":["*.czi"],"accepts_directories":false}],"writers":null,"widgets":[{"command":"napari-czitools.make_czireader_widget","display_name":"Advanced CZI Reader","autogenerate":false}],"sample_data":[{"command":"napari-czitools.celldivision_data","key":"unique_id.0","display_name":"Celldivision 5D dataset"},{"command":"napari-czitools.wellplate_data","key":"unique_id.1","display_name":"WellPlate 6D dataset"},{"command":"napari-czitools.zstack_data","key":"unique_id.2","display_name":"Z-Stack dataset"},{"command":"napari-czitools.airyscan_zstack_data","key":"unique_id.3","display_name":"Airyscan Z-Stack dataset"},{"command":"napari-czitools.he_stain_data","key":"unique_id.4","display_name":"HE Stain dataset"}],"themes":null,"menus":{},"submenus":null,"keybindings":null,"configurations":{}},"package_metadata":{"metadata_version":"2.4","name":"napari-czitools","version":"0.12.4","dynamic":["license-file"],"platform":null,"supported_platform":null,"summary":"Plugin to read CZI image files and their metadata","description":"# napari-czitools\n\n- [napari-czitools](#napari-czitools)\n  - [Installation](#installation)\n  - [Supported Operating Systems](#supported-operating-systems)\n  - [Usage - Core Functionalities](#usage---core-functionalities)\n    - [Open Complete CZI Files](#open-complete-czi-files)\n    - [Open CZI Sample Data](#open-czi-sample-data)\n      - [CellDivision 5D Stack](#celldivision-5d-stack)\n      - [Neurons 3D Stack](#neurons-3d-stack)\n      - [AiryScan 3D Stack](#airyscan-3d-stack)\n      - [Wellplate Data](#wellplate-data)\n    - [Advanced CZI Reader (CziReadTools) plugin](#advanced-czi-reader-czireadtools-plugin)\n      - [General Usage](#general-usage)\n      - [After Metadata Loads](#after-metadata-loads)\n      - [Reading a subset](#reading-a-subset)\n      - [3D Preview Size](#3d-preview-size)\n      - [Lazy Loading](#lazy-loading)\n      - [Scene Tolerance](#scene-tolerance)\n      - [Gigapixel CZIs (whole-slide, large 2D scans)](#gigapixel-czis-whole-slide-large-2d-scans)\n      - [Advanced Python usage](#advanced-python-usage)\n  - [Current Limitations](#current-limitations)\n    - [Future plans](#future-plans)\n  - [Contributing](#contributing)\n    - [Running Tests](#running-tests)\n    - [Recent Compatibility Notes](#recent-compatibility-notes)\n  - [License](#license)\n  - [Issues](#issues)\n  - [Disclaimer](#disclaimer)\n\n[![License MIT](https://img.shields.io/pypi/l/napari-czitools.svg?color=green)](https://github.com/sebi06/napari-czitools/raw/main/LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/napari-czitools.svg?color=green)](https://pypi.org/project/napari-czitools)\n[![Python Version](https://img.shields.io/pypi/pyversions/napari-czitools.svg?color=green)](https://python.org)\n[![tests](https://github.com/sebi06/napari-czitools/actions/workflows/test_and_deploy_pypi.yml/badge.svg)](https://github.com/sebi06/napari-czitools/actions/workflows/test_and_deploy_pypi.yml)\n[![codecov](https://codecov.io/gh/sebi06/napari-czitools/branch/main/graph/badge.svg)](https://codecov.io/gh/sebi06/napari-czitools)\n[![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-czitools)](https://napari-hub.org/plugins/napari-czitools)\n[![npe2](https://img.shields.io/badge/plugin-npe2-blue?link=https://napari.org/stable/plugins/index.html)](https://napari.org/stable/plugins/index.html)\n[![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-purple.json)](https://github.com/copier-org/copier)\n\nnapari plugin for reading CZI image data and metadata.\n\n----------------------------------\n\nThis [napari] plugin was generated with [copier] using the [napari-plugin-template].\n\n![napari-czitools - Read CZI Metadata and load image Data](https://github.com/sebi06/napari-czitools/raw/main/readme_images/title_pic.png)\n\n<!--\nDon't miss the full getting started guide to set up your new package:\nhttps://github.com/napari/napari-plugin-template#getting-started\n\nand review the napari docs for plugin developers:\nhttps://napari.org/stable/plugins/index.html\n-->\n\n## Installation\n\nYou can install `napari-czitools` via [pip]:\n\n    pip install napari-czitools\n\nThe current release requires Python 3.12 or 3.13 and `czitools>=0.22.1`.\n\nTo install latest development version :\n\n    pip install git+https://github.com/sebi06/napari-czitools.git\n\n## Supported Operating Systems\n\nThe test suite runs on Python 3.12 and 3.13 for:\n\n- Linux\n- Windows\n- macOS\n\n## Usage - Core Functionalities\n\nThe plugin reads CZI image data into [napari] and displays the associated\nmetadata in a table or tree.\n\n### Open Complete CZI Files\n\n- Open complete CZI files and display their metadata in napari using [czitools].\n\n![Open complete CZI file](https://github.com/sebi06/napari-czitools/raw/main/readme_images/file_open_mdtable_lls7.png)\n\n- Open different CZI sample datasets.\n- If sample data are unavailable locally, they are downloaded from the remote\n  repository, which may take some time.\n\n![Open sample data](https://github.com/sebi06/napari-czitools/raw/main/readme_images/open_sample1.png)\n\n### Open CZI Sample Data\n\n#### CellDivision 5D Stack\n\n![Sample Data - 5D Stack](https://github.com/sebi06/napari-czitools/raw/main/readme_images/open_sample_5D.png)\n\n#### Neurons 3D Stack\n\n![Sample Data - 3D Stack](https://github.com/sebi06/napari-czitools/raw/main/readme_images/open_sample_3D.png)\n\n#### AiryScan 3D Stack\n\n![Sample Data - AiryScan 3D Stack](https://github.com/sebi06/napari-czitools/raw/main/readme_images/open_sample_airyscan.png)\n\n#### Wellplate Data\n\n![Sample Data - Wellplate](https://github.com/sebi06/napari-czitools/raw/main/readme_images/open_sample_wellplate.png)\n\n### Advanced CZI Reader (CziReadTools) plugin\n\n#### General Usage\n\nOpen **Plugins > Advanced CZI Reader (CziReadTools)**. The initial panel has\nfour main areas:\n\n1. Select a local CZI file. Drag and drop onto the file field is also supported.\n2. Inspect metadata as a table or tree. Tree view can optionally show value\n  types.\n3. Configure scene handling and the 3D preview, then load the selected pixels.\n4. Select scene, time, channel, and Z ranges. Dimensions with only one position\n  are hidden after metadata loads.\n\n<!-- markdownlint-disable-next-line MD033 -->\n<img src=\"https://github.com/sebi06/napari-czitools/raw/main/readme_images/reader_adv1.png\" alt=\"Advanced CZI Reader before selecting a file\" style=\"width:40%; height:auto;\">\n\n#### After Metadata Loads\n\nSelecting a valid CZI file reads metadata but does not load its pixel data. The\nmetadata view, **Load Pixel Data**, **3D preview size**, and applicable dimension\nsliders then become available. **Stack scenes** remains disabled unless the CZI\ncontains multiple scenes with different pixel dimensions.\n\nUse **Slider Type** to switch between a dual-handle range slider and separate\nminimum/maximum sliders. Setting both endpoints to the same value selects one\nposition, for example `T=3-3`.\n\n<!-- markdownlint-disable-next-line MD033 -->\n<img src=\"https://github.com/sebi06/napari-czitools/raw/main/readme_images/reader_adv2.png\" alt=\"Table and tree metadata views with both slider layouts\" style=\"width:85%; height:auto;\">\n\n#### Reading a subset\n\n- Use the dimension sliders to select the scene, time, channel, and Z positions\n  to load.\n- The displayed metadata continue to describe the complete CZI, not only the\n  selected subset.\n\n![Selecting a CZI subset](https://github.com/sebi06/napari-czitools/raw/main/readme_images/load_pixel1.png)\n\nFor example, selecting timepoints 4-7, channel 0-0, and Z-planes 7-10\nloads four timepoints, one channel, and four Z-planes.\n\n![Loaded CZI subset in napari](https://github.com/sebi06/napari-czitools/raw/main/readme_images/load_pixel2.png)\n\n#### 3D Preview Size\n\n**3D preview size** sets the target maximum width or height, in pixels, of the\ncoarsest pyramid level sent to napari. The default is **2048 px**, a conservative\nsize that fits the minimum broadly supported OpenGL 3D texture limit.\n\nThis setting does **not** crop the image, change the selected S/T/C/Z ranges, or\nreduce the resolution of the finest source level. If the coarsest pyramid level\nstored in the CZI is already at or below the selected size, nothing additional\nis generated. If it is larger, `czitools` lazily adds half-resolution levels\nuntil the longest Y/X edge fits the target.\n\n- Use a lower value to reduce GPU memory use and improve compatibility with\n  older GPUs. The first overview will contain less spatial detail.\n- Keep **2048 px** for portable 3D rendering in most cases.\n- Use a higher value only when more preview detail is useful and the GPU\n  supports larger textures. Higher values can use more GPU memory.\n\nThe value is saved between napari sessions and becomes editable after valid CZI\nmetadata loads. For small images, changing it often has no visible effect\nbecause the existing coarsest level already fits.\n\n![3D rendering with the 3D preview size control](https://github.com/sebi06/napari-czitools/raw/main/readme_images/3D_preview_size.png)\n\n#### Lazy Loading\n\nThe advanced reader always uses lazy multiscale loading after **Load Pixel\nData** is pressed. It requests Dask-backed xarray stacks for the selected\nscene, time, channel, and Z ranges, so pixel tiles are read only when napari\nneeds them. This avoids loading the complete selection into RAM, supports\ndifferently sized scenes, and enables efficient 3D previews.\n\nPython callers can still pass `use_lazy=False` to `CZIDataLoader` or\n`reader_function_adv` when they explicitly need the eager `read_6darray` path.\nThat path constructs one regular array in `STCZYX(A)` order, loads every\nselected plane into RAM, and requires compatible scene shapes.\n\n#### Scene Tolerance\n\nWhen a file is selected the plugin reads the bounding rectangle of every scene\nand computes the maximum pixel difference in width and height across all scenes.\nIf any difference is detected, a label appears next to the load controls:\n\n    Scene size diff — W: 72px  H: 9px\n\nand the **Stack scenes** checkbox becomes enabled. Checking it re-evaluates the\nmetadata with a tolerance equal to the computed maximum difference, which:\n\n![Scene Tolerance](https://github.com/sebi06/napari-czitools/raw/main/readme_images/scene_mismatch.png)\n\n1. **Unlocks the scene slider** so you can select any range of scenes.\n2. **Crops all scenes** to the smallest common W×H shape when pixel data is\n   loaded — no zero-padding is introduced.\n\nWhen the checkbox is unchecked (default), scenes must be pixel-identical to be\nstacked; files where scene sizes differ are limited to one scene at a time.\n\nThis is particularly useful for **HCS plate CZIs** where each scene is a\nmulti-tile mosaic covering one well: the per-well tile grids are assembled from\nstage coordinates independently, so the total pixel extent of each well can\ndiffer by tens of pixels even when the acquisition settings are identical.\n\n#### Gigapixel CZIs (whole-slide, large 2D scans)\n\nFor files whose individual 2D planes are larger than about 256 MB uncompressed\n(for example a `93,555 × 138,996` `uint16` plane ≈ 24 GB), `czitools`\nautomatically switches to spatial Y/X tiling: each Dask chunk becomes one\nROI-based read via `pylibCZIrw`, so napari only fetches the tiles that\nintersect the current viewport instead of full planes. Small planes keep the\nfaster whole-plane path.\n\nOn top of tiling, lazy mode also enables **multiscale rendering**. The plugin\ncalls `czitools.read_tools.read_stacks_multiscale` to detect the CZI's stored\npyramid levels (via `pylibCZIrw` subblock enumeration) and hands napari one\nlazy Dask array per level as `viewer.add_image(..., multiscale=True)`. This\nlets napari render the coarsest level immediately from a single GPU texture\nand stream finer tiles on zoom. If the coarsest stored level is still larger\nthan `DEFAULT_MAX_COARSE_EDGE` (2048 px), extra synthetic coarser levels are\nadded on the fly using libCZI's C++ resampler. The conservative default fits\nthe minimum broadly supported OpenGL 3D texture size; 2D texture limits are\noften much larger. Files without an on-disk pyramid are passed to napari as\nsingle-scale images when no additional level is needed.\n\nTo keep opening these files usable, the plugin also passes an explicit\n`contrast_limits` argument to `viewer.add_image` (derived from the CZI's\nembedded display settings). Without this, napari would auto-scan every chunk\nof the Dask array to determine the display range and materialize the entire\nplane in RAM before the first pixel is shown.\n\n#### Advanced Python usage\n\nThe Python reader API forwards the same lazy behaviour:\n\n  from napari_czitools._io import DEFAULT_MAX_COARSE_EDGE\n  from napari_czitools._reader import reader_function_adv\n\n  reader_function_adv(\n    \"image.czi\",\n    use_lazy=True,        # read pixel data only when requested\n    use_dask=True,        # required for on-demand reads\n    use_multiscale=True,  # napari renders coarse-level tiles first\n    max_coarse_edge=DEFAULT_MAX_COARSE_EDGE,\n  )\n\n`max_coarse_edge` is the Python equivalent of **3D preview size**. Keep the\ndefault for portable 3D rendering, lower it to reduce GPU memory use, or raise\nit when the GPU supports larger textures.\n\nWith `use_lazy=True`, `czitools` reads the CZI metadata and builds Dask task\ngraphs first — individual pixel planes are not loaded at that point. When\n`use_multiscale=True` (the default) the plugin also constructs a per-level\npyramid so napari can render gigapixel planes without materialising layer 0.\nDisabling `use_lazy`, even with `use_dask=True`, still reads all pixels\neagerly before wrapping the result in a Dask array.\n\n## Current Limitations\n\nThe sample-data commands add image layers directly and do not open the\nAdvanced CZI Reader metadata panel.\n\n### Future plans\n\n- Evaluate interoperability with [bioio-czi].\n- Add metadata-table export.\n\nFeedback is always welcome!\n\n## Contributing\n\nContributions are welcome. Tests can be run with [tox]; please ensure coverage\ndoes not decrease when submitting a pull request.\n\n### Running Tests\n\nInstall test dependencies first (recommended for full local coverage):\n\n    pip install -e \".[testing]\"\n\nThis installs `pytest-qt`, which provides the `qtbot` fixture used by\nnapari/Qt tests.\n\n**Windows/macOS:**\n\n    pytest\n\n**Linux (recommended - use tox):**\n\n    tox -e py312-linux\n\n(Replace `py312` with your Python version: `py312` or `py313`)\n\n**Linux (direct pytest):**\n\n    pytest -v --forked --color=yes\n\nNote: The `--forked` flag is required on Linux to prevent CZI + Qt crashes by running each test in its own process. This flag is not available on Windows.\n\n### Recent Compatibility Notes\n\n- `czitools>=0.22.1` is required.\n- `read_tools.read_stacks` returns\n  `(arrays_or_list, dims, num_stacks, metadata)`. The plugin handles both a\n  single stacked xarray object and a list containing one xarray stack per\n  scene.\n- Channel extraction uses positional indexing to support channel coordinates\n  represented by names (for example `\"DAPI\"`, `\"EGFP\"`) instead of numeric\n  labels.\n- URL metadata tests can be affected by transient remote read failures (for\n  example GitHub/network hiccups). The test suite retries and skips these\n  network-dependent checks if remote headers cannot be read reliably.\n- The custom dual-handle `DoubleRangeSlider` has been replaced with wrappers\n  around [superqt]'s `QLabeledRangeSlider` and `QRangeSlider`, reducing\n  custom painting/mouse handling code and using a well-tested community\n  component. The public slider API (`low()`, `high()`, `setLow()`,\n  `setHigh()`, single-value mode) is unchanged.\n- A small internal patch (`_allow_handle_overlap`) is applied to every\n  superqt range slider so that both handles can sit on the same value,\n  enabling single-frame extraction (e.g. T=4-4 to read one timepoint).\n\n## License\n\nDistributed under the terms of the [MIT] license, `napari-czitools` is free and\nopen-source software.\n\n## Issues\n\nIf you encounter any problems, please [file an issue] along with a detailed description.\n\n## Disclaimer\n\nThe software and scripts are free to use. The author provides no warranty for\ntheir use. Use them at your own risk.\n\nBy using this plugin you agree to this disclaimer.\n\n[napari]: https://github.com/napari/napari\n[copier]: https://copier.readthedocs.io/en/stable/\n[MIT]: http://opensource.org/licenses/MIT\n[napari-plugin-template]: https://github.com/napari/napari-plugin-template\n[file an issue]: https://github.com/sebi06/napari-czitools/issues\n[tox]: https://tox.readthedocs.io/en/latest/\n[pip]: https://pypi.org/project/pip/\n[czitools]: https://pypi.org/project/czitools/\n[bioio-czi]: https://pypi.org/project/bioio-czi/\n[superqt]: https://pyapp-kit.github.io/superqt/\n","description_content_type":"text/markdown","keywords":null,"home_page":null,"download_url":null,"author":"Sebastian Rhode","author_email":"sebrhode@gmail.com","maintainer":null,"maintainer_email":null,"license":"The MIT License (MIT)\n\nCopyright (c) 2025 Sebastian Rhode\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","classifier":["Development Status :: 4 - Beta","Framework :: napari","Intended Audience :: Developers","License :: OSI Approved :: MIT License","Operating System :: Unix","Operating System :: MacOS","Operating System :: Microsoft :: Windows","Programming Language :: Python","Programming Language :: Python :: 3","Programming Language :: Python :: 3 :: Only","Programming Language :: Python :: 3.12","Programming Language :: Python :: 3.13","Topic :: Scientific/Engineering :: Image Processing"],"requires_dist":["numpy","magicgui","qtpy","superqt","scikit-image","pyqtgraph","czitools>=0.22.1","tox; extra == \"testing\"","pytest; extra == \"testing\"","pytest-cov; extra == \"testing\"","pytest-mock; extra == \"testing\"","pytest-qt; extra == \"testing\"","pytest-timeout; extra == \"testing\"","pytest-forked; extra == \"testing\"","napari; extra == \"testing\"","pyqt6!=6.11.0,!=6.11.1,>=6.7; extra == \"testing\""],"requires_python":"<3.14,>=3.12","requires_external":null,"project_url":["Bug Tracker, https://github.com/sebi06/napari-czitools/issues","Documentation, https://github.com/sebi06/napari-czitools#README.md","Source Code, https://github.com/sebi06/napari-czitools","User Support, https://github.com/sebi06/napari-czitools/issues"],"provides_extra":["testing"],"provides_dist":null,"obsoletes_dist":null},"npe1_shim":false}