chunkmirage 0.1.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. chunkmirage-0.1.0a1/.github/workflows/ci.yml +30 -0
  2. chunkmirage-0.1.0a1/.github/workflows/docs.yml +47 -0
  3. chunkmirage-0.1.0a1/.github/workflows/publish.yml +44 -0
  4. chunkmirage-0.1.0a1/.gitignore +21 -0
  5. chunkmirage-0.1.0a1/CHANGELOG.md +67 -0
  6. chunkmirage-0.1.0a1/CLAUDE.md +40 -0
  7. chunkmirage-0.1.0a1/LICENSE +28 -0
  8. chunkmirage-0.1.0a1/PKG-INFO +220 -0
  9. chunkmirage-0.1.0a1/README.md +127 -0
  10. chunkmirage-0.1.0a1/docs/concepts/caching.md +191 -0
  11. chunkmirage-0.1.0a1/docs/concepts/formats.md +633 -0
  12. chunkmirage-0.1.0a1/docs/concepts/interactivity.md +160 -0
  13. chunkmirage-0.1.0a1/docs/concepts/pipelines.md +136 -0
  14. chunkmirage-0.1.0a1/docs/contributing.md +122 -0
  15. chunkmirage-0.1.0a1/docs/demos.md +80 -0
  16. chunkmirage-0.1.0a1/docs/design.md +414 -0
  17. chunkmirage-0.1.0a1/docs/faq.md +118 -0
  18. chunkmirage-0.1.0a1/docs/getting-started.md +105 -0
  19. chunkmirage-0.1.0a1/docs/index.md +71 -0
  20. chunkmirage-0.1.0a1/docs/reference/api.md +133 -0
  21. chunkmirage-0.1.0a1/docs/reference/cli.md +64 -0
  22. chunkmirage-0.1.0a1/docs/reference/ops.md +98 -0
  23. chunkmirage-0.1.0a1/docs/reference/python.md +88 -0
  24. chunkmirage-0.1.0a1/docs/roadmap.md +125 -0
  25. chunkmirage-0.1.0a1/examples/contact_sites.py +238 -0
  26. chunkmirage-0.1.0a1/examples/demo.log +0 -0
  27. chunkmirage-0.1.0a1/examples/demo.py +138 -0
  28. chunkmirage-0.1.0a1/examples/fish_spots.py +245 -0
  29. chunkmirage-0.1.0a1/examples/fly_brain_registration.py +257 -0
  30. chunkmirage-0.1.0a1/examples/hurricane_wakes.py +179 -0
  31. chunkmirage-0.1.0a1/examples/model_at_one_resolution.py +95 -0
  32. chunkmirage-0.1.0a1/examples/quickstart.py +46 -0
  33. chunkmirage-0.1.0a1/examples/register_demo.py +281 -0
  34. chunkmirage-0.1.0a1/examples/solar_flares.py +175 -0
  35. chunkmirage-0.1.0a1/examples/swirl_demo.py +222 -0
  36. chunkmirage-0.1.0a1/examples/track_nucleus.py +80 -0
  37. chunkmirage-0.1.0a1/mkdocs.yml +62 -0
  38. chunkmirage-0.1.0a1/pyproject.toml +120 -0
  39. chunkmirage-0.1.0a1/src/chunkmirage/__init__.py +10 -0
  40. chunkmirage-0.1.0a1/src/chunkmirage/cache.py +90 -0
  41. chunkmirage-0.1.0a1/src/chunkmirage/cli.py +379 -0
  42. chunkmirage-0.1.0a1/src/chunkmirage/core.py +160 -0
  43. chunkmirage-0.1.0a1/src/chunkmirage/demand.py +265 -0
  44. chunkmirage-0.1.0a1/src/chunkmirage/frontends/__init__.py +25 -0
  45. chunkmirage-0.1.0a1/src/chunkmirage/frontends/_ome.py +52 -0
  46. chunkmirage-0.1.0a1/src/chunkmirage/frontends/base.py +113 -0
  47. chunkmirage-0.1.0a1/src/chunkmirage/frontends/codecs.py +80 -0
  48. chunkmirage-0.1.0a1/src/chunkmirage/frontends/mesh.py +117 -0
  49. chunkmirage-0.1.0a1/src/chunkmirage/frontends/n5.py +101 -0
  50. chunkmirage-0.1.0a1/src/chunkmirage/frontends/precomputed.py +111 -0
  51. chunkmirage-0.1.0a1/src/chunkmirage/frontends/zarr2.py +84 -0
  52. chunkmirage-0.1.0a1/src/chunkmirage/frontends/zarr3.py +90 -0
  53. chunkmirage-0.1.0a1/src/chunkmirage/fused.py +149 -0
  54. chunkmirage-0.1.0a1/src/chunkmirage/meshes.py +295 -0
  55. chunkmirage-0.1.0a1/src/chunkmirage/netutil.py +262 -0
  56. chunkmirage-0.1.0a1/src/chunkmirage/neuroglancer.py +177 -0
  57. chunkmirage-0.1.0a1/src/chunkmirage/ngff.py +451 -0
  58. chunkmirage-0.1.0a1/src/chunkmirage/ops/__init__.py +32 -0
  59. chunkmirage-0.1.0a1/src/chunkmirage/ops/base.py +171 -0
  60. chunkmirage-0.1.0a1/src/chunkmirage/ops/combine.py +161 -0
  61. chunkmirage-0.1.0a1/src/chunkmirage/ops/filters.py +231 -0
  62. chunkmirage-0.1.0a1/src/chunkmirage/ops/pointwise.py +80 -0
  63. chunkmirage-0.1.0a1/src/chunkmirage/ops/segment.py +238 -0
  64. chunkmirage-0.1.0a1/src/chunkmirage/ops/terrain.py +83 -0
  65. chunkmirage-0.1.0a1/src/chunkmirage/pipeline.py +432 -0
  66. chunkmirage-0.1.0a1/src/chunkmirage/py.typed +0 -0
  67. chunkmirage-0.1.0a1/src/chunkmirage/registration.py +537 -0
  68. chunkmirage-0.1.0a1/src/chunkmirage/schema.py +66 -0
  69. chunkmirage-0.1.0a1/src/chunkmirage/server.py +660 -0
  70. chunkmirage-0.1.0a1/src/chunkmirage/serving.py +137 -0
  71. chunkmirage-0.1.0a1/src/chunkmirage/sources/__init__.py +16 -0
  72. chunkmirage-0.1.0a1/src/chunkmirage/sources/base.py +200 -0
  73. chunkmirage-0.1.0a1/src/chunkmirage/sources/flip.py +79 -0
  74. chunkmirage-0.1.0a1/src/chunkmirage/sources/geotiff.py +186 -0
  75. chunkmirage-0.1.0a1/src/chunkmirage/sources/hdf5_source.py +70 -0
  76. chunkmirage-0.1.0a1/src/chunkmirage/sources/register.py +775 -0
  77. chunkmirage-0.1.0a1/src/chunkmirage/sources/registry.py +128 -0
  78. chunkmirage-0.1.0a1/src/chunkmirage/sources/scene.py +361 -0
  79. chunkmirage-0.1.0a1/src/chunkmirage/sources/stack.py +105 -0
  80. chunkmirage-0.1.0a1/src/chunkmirage/sources/stitch.py +125 -0
  81. chunkmirage-0.1.0a1/src/chunkmirage/sources/synthetic.py +317 -0
  82. chunkmirage-0.1.0a1/src/chunkmirage/sources/tensorstore_source.py +649 -0
  83. chunkmirage-0.1.0a1/src/chunkmirage/sources/warp.py +266 -0
  84. chunkmirage-0.1.0a1/src/chunkmirage/static/ui.html +270 -0
  85. chunkmirage-0.1.0a1/src/chunkmirage/stitching.py +548 -0
  86. chunkmirage-0.1.0a1/src/chunkmirage/tracking.py +181 -0
  87. chunkmirage-0.1.0a1/src/chunkmirage/transforms.py +417 -0
  88. chunkmirage-0.1.0a1/src/chunkmirage/viewer.py +199 -0
  89. chunkmirage-0.1.0a1/tests/conftest.py +114 -0
  90. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/LICENSE +21 -0
  91. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/README.md +7 -0
  92. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine.ome.zarr/conformance.toml +54 -0
  93. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine.ome.zarr/zarr.json +79 -0
  94. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_downProjection.ome.zarr/conformance.toml +23 -0
  95. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_downProjection.ome.zarr/zarr.json +69 -0
  96. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_identity.ome.zarr/conformance.toml +22 -0
  97. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_identity.ome.zarr/zarr.json +63 -0
  98. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_identity_inverse.ome.zarr/conformance.toml +22 -0
  99. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_identity_inverse.ome.zarr/zarr.json +63 -0
  100. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse.ome.zarr/conformance.toml +54 -0
  101. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse.ome.zarr/zarr.json +79 -0
  102. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float32.ome.zarr/conformance.toml +54 -0
  103. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float32.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +0 -0
  104. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float32.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  105. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float32.ome.zarr/coordinateTransformations/zarr.json +5 -0
  106. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float32.ome.zarr/zarr.json +60 -0
  107. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float64.ome.zarr/conformance.toml +54 -0
  108. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float64.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +0 -0
  109. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float64.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  110. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float64.ome.zarr/coordinateTransformations/zarr.json +5 -0
  111. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_inverse_path_float64.ome.zarr/zarr.json +60 -0
  112. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float32.ome.zarr/conformance.toml +54 -0
  113. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float32.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +0 -0
  114. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float32.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  115. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float32.ome.zarr/coordinateTransformations/zarr.json +5 -0
  116. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float32.ome.zarr/zarr.json +60 -0
  117. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float64.ome.zarr/conformance.toml +54 -0
  118. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float64.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +0 -0
  119. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float64.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  120. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float64.ome.zarr/coordinateTransformations/zarr.json +5 -0
  121. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_path_float64.ome.zarr/zarr.json +60 -0
  122. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_upProjection.ome.zarr/conformance.toml +23 -0
  123. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/affine_upProjection.ome.zarr/zarr.json +72 -0
  124. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/bijection_forward.ome.zarr/conformance.toml +22 -0
  125. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/bijection_forward.ome.zarr/zarr.json +65 -0
  126. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/bijection_inverse.ome.zarr/conformance.toml +22 -0
  127. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/bijection_inverse.ome.zarr/zarr.json +65 -0
  128. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension.ome.zarr/conformance.toml +22 -0
  129. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension.ome.zarr/zarr.json +78 -0
  130. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension_inverse.ome.zarr/conformance.toml +22 -0
  131. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension_inverse.ome.zarr/zarr.json +78 -0
  132. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension_nonContiguous.ome.zarr/conformance.toml +24 -0
  133. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension_nonContiguous.ome.zarr/zarr.json +100 -0
  134. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension_nonContiguous_inverse.ome.zarr/conformance.toml +24 -0
  135. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/byDimension_nonContiguous_inverse.ome.zarr/zarr.json +100 -0
  136. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_1d.ome.zarr/conformance.toml +68 -0
  137. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_1d.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +0 -0
  138. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_1d.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +61 -0
  139. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_1d.ome.zarr/coordinateTransformations/zarr.json +5 -0
  140. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_1d.ome.zarr/zarr.json +45 -0
  141. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_2d-3d.ome.zarr/conformance.toml +86 -0
  142. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_2d-3d.ome.zarr/coordinateTransformations/inputToOutput/c/0/0/0 +0 -0
  143. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_2d-3d.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +67 -0
  144. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_2d-3d.ome.zarr/coordinateTransformations/zarr.json +5 -0
  145. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/coordinates_2d-3d.ome.zarr/zarr.json +57 -0
  146. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/displacements_constant.ome.zarr/conformance.toml +46 -0
  147. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/displacements_constant.ome.zarr/coordinateTransformations/inputToOutput/c/0/0/0 +0 -0
  148. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/displacements_constant.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +67 -0
  149. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/displacements_constant.ome.zarr/coordinateTransformations/zarr.json +5 -0
  150. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/displacements_constant.ome.zarr/zarr.json +53 -0
  151. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/identity.ome.zarr/conformance.toml +22 -0
  152. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/identity.ome.zarr/zarr.json +51 -0
  153. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/identity_inverse.ome.zarr/conformance.toml +22 -0
  154. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/identity_inverse.ome.zarr/zarr.json +51 -0
  155. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/mapAxis.ome.zarr/conformance.toml +22 -0
  156. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/mapAxis.ome.zarr/zarr.json +55 -0
  157. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/mapAxis_inverse.ome.zarr/conformance.toml +22 -0
  158. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/mapAxis_inverse.ome.zarr/zarr.json +55 -0
  159. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation.ome.zarr/conformance.toml +46 -0
  160. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation.ome.zarr/zarr.json +61 -0
  161. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_identity.ome.zarr/conformance.toml +22 -0
  162. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_identity.ome.zarr/zarr.json +61 -0
  163. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_identity_inverse.ome.zarr/conformance.toml +22 -0
  164. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_identity_inverse.ome.zarr/zarr.json +61 -0
  165. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse.ome.zarr/conformance.toml +46 -0
  166. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse.ome.zarr/zarr.json +61 -0
  167. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float32.ome.zarr/conformance.toml +46 -0
  168. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float32.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +1 -0
  169. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float32.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  170. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float32.ome.zarr/coordinateTransformations/zarr.json +5 -0
  171. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float32.ome.zarr/zarr.json +52 -0
  172. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float64.ome.zarr/conformance.toml +46 -0
  173. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float64.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +1 -0
  174. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float64.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  175. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float64.ome.zarr/coordinateTransformations/zarr.json +5 -0
  176. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_inverse_path_float64.ome.zarr/zarr.json +52 -0
  177. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float32.ome.zarr/conformance.toml +46 -0
  178. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float32.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +1 -0
  179. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float32.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  180. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float32.ome.zarr/coordinateTransformations/zarr.json +5 -0
  181. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float32.ome.zarr/zarr.json +52 -0
  182. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float64.ome.zarr/conformance.toml +46 -0
  183. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float64.ome.zarr/coordinateTransformations/inputToOutput/c/0/0 +1 -0
  184. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float64.ome.zarr/coordinateTransformations/inputToOutput/zarr.json +35 -0
  185. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float64.ome.zarr/coordinateTransformations/zarr.json +5 -0
  186. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/rotation_path_float64.ome.zarr/zarr.json +52 -0
  187. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/scale.ome.zarr/conformance.toml +22 -0
  188. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/scale.ome.zarr/zarr.json +55 -0
  189. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/scale_inverse.ome.zarr/conformance.toml +22 -0
  190. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/scale_inverse.ome.zarr/zarr.json +55 -0
  191. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/sequence.ome.zarr/conformance.toml +22 -0
  192. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/sequence.ome.zarr/zarr.json +67 -0
  193. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/sequence_inverse.ome.zarr/conformance.toml +22 -0
  194. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/sequence_inverse.ome.zarr/zarr.json +67 -0
  195. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/simple_path.ome.zarr/conformance.toml +22 -0
  196. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/simple_path.ome.zarr/zarr.json +74 -0
  197. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/simple_path_inverse.ome.zarr/conformance.toml +22 -0
  198. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/simple_path_inverse.ome.zarr/zarr.json +74 -0
  199. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/translation.ome.zarr/conformance.toml +22 -0
  200. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/translation.ome.zarr/zarr.json +55 -0
  201. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/translation_inverse.ome.zarr/conformance.toml +22 -0
  202. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/translation_inverse.ome.zarr/zarr.json +55 -0
  203. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/unknown_source.ome.zarr/conformance.toml +16 -0
  204. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/unknown_source.ome.zarr/zarr.json +51 -0
  205. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/unknown_target.ome.zarr/conformance.toml +16 -0
  206. chunkmirage-0.1.0a1/tests/data/rfc5_conformance/cases/unknown_target.ome.zarr/zarr.json +51 -0
  207. chunkmirage-0.1.0a1/tests/test_cache_token.py +55 -0
  208. chunkmirage-0.1.0a1/tests/test_channel_ops.py +58 -0
  209. chunkmirage-0.1.0a1/tests/test_cli.py +95 -0
  210. chunkmirage-0.1.0a1/tests/test_clients.py +129 -0
  211. chunkmirage-0.1.0a1/tests/test_demand.py +136 -0
  212. chunkmirage-0.1.0a1/tests/test_docs.py +62 -0
  213. chunkmirage-0.1.0a1/tests/test_frontends.py +198 -0
  214. chunkmirage-0.1.0a1/tests/test_fused.py +74 -0
  215. chunkmirage-0.1.0a1/tests/test_geotiff.py +64 -0
  216. chunkmirage-0.1.0a1/tests/test_inflight.py +47 -0
  217. chunkmirage-0.1.0a1/tests/test_input_voxel_size.py +215 -0
  218. chunkmirage-0.1.0a1/tests/test_interactive.py +177 -0
  219. chunkmirage-0.1.0a1/tests/test_kind.py +115 -0
  220. chunkmirage-0.1.0a1/tests/test_meshes.py +150 -0
  221. chunkmirage-0.1.0a1/tests/test_mount.py +61 -0
  222. chunkmirage-0.1.0a1/tests/test_netutil.py +107 -0
  223. chunkmirage-0.1.0a1/tests/test_normalized_difference.py +37 -0
  224. chunkmirage-0.1.0a1/tests/test_pipeline.py +146 -0
  225. chunkmirage-0.1.0a1/tests/test_plugins.py +21 -0
  226. chunkmirage-0.1.0a1/tests/test_register.py +344 -0
  227. chunkmirage-0.1.0a1/tests/test_resolver.py +60 -0
  228. chunkmirage-0.1.0a1/tests/test_scene.py +599 -0
  229. chunkmirage-0.1.0a1/tests/test_schema.py +60 -0
  230. chunkmirage-0.1.0a1/tests/test_serving.py +30 -0
  231. chunkmirage-0.1.0a1/tests/test_shape_changing_ops.py +129 -0
  232. chunkmirage-0.1.0a1/tests/test_slots.py +38 -0
  233. chunkmirage-0.1.0a1/tests/test_source_metadata.py +315 -0
  234. chunkmirage-0.1.0a1/tests/test_source_schemes.py +68 -0
  235. chunkmirage-0.1.0a1/tests/test_spots.py +94 -0
  236. chunkmirage-0.1.0a1/tests/test_stack.py +171 -0
  237. chunkmirage-0.1.0a1/tests/test_stitching.py +175 -0
  238. chunkmirage-0.1.0a1/tests/test_storage.py +72 -0
  239. chunkmirage-0.1.0a1/tests/test_synthetic_and_segment.py +117 -0
  240. chunkmirage-0.1.0a1/tests/test_token.py +44 -0
  241. chunkmirage-0.1.0a1/tests/test_tracking.py +73 -0
  242. chunkmirage-0.1.0a1/tests/test_warp.py +208 -0
  243. chunkmirage-0.1.0a1/uv.lock +3546 -0
  244. chunkmirage-0.1.0a1/web/.gitignore +3 -0
  245. chunkmirage-0.1.0a1/web/index.html +47 -0
  246. chunkmirage-0.1.0a1/web/map.html +78 -0
  247. chunkmirage-0.1.0a1/web/package-lock.json +1541 -0
  248. chunkmirage-0.1.0a1/web/package.json +26 -0
  249. chunkmirage-0.1.0a1/web/pipeline.html +88 -0
  250. chunkmirage-0.1.0a1/web/public/cards/contacts.jpg +0 -0
  251. chunkmirage-0.1.0a1/web/public/cards/fires.jpg +0 -0
  252. chunkmirage-0.1.0a1/web/public/cards/fronts.jpg +0 -0
  253. chunkmirage-0.1.0a1/web/public/cards/hurricanes.jpg +0 -0
  254. chunkmirage-0.1.0a1/web/public/cards/mandelbulb.jpg +0 -0
  255. chunkmirage-0.1.0a1/web/public/cards/mesh-bulb.jpg +0 -0
  256. chunkmirage-0.1.0a1/web/public/cards/mesh-moon.jpg +0 -0
  257. chunkmirage-0.1.0a1/web/public/cards/moon.jpg +0 -0
  258. chunkmirage-0.1.0a1/web/public/cards/register-efish.jpg +0 -0
  259. chunkmirage-0.1.0a1/web/public/cards/register-fly.jpg +0 -0
  260. chunkmirage-0.1.0a1/web/public/cards/solar.jpg +0 -0
  261. chunkmirage-0.1.0a1/web/public/cards/spots.jpg +0 -0
  262. chunkmirage-0.1.0a1/web/public/cards/stitch.jpg +0 -0
  263. chunkmirage-0.1.0a1/web/public/cards/track.jpg +0 -0
  264. chunkmirage-0.1.0a1/web/register.html +173 -0
  265. chunkmirage-0.1.0a1/web/scripts/fetch_example.py +170 -0
  266. chunkmirage-0.1.0a1/web/serve.py +151 -0
  267. chunkmirage-0.1.0a1/web/src/affine.ts +248 -0
  268. chunkmirage-0.1.0a1/web/src/blocks.ts +166 -0
  269. chunkmirage-0.1.0a1/web/src/cards.ts +411 -0
  270. chunkmirage-0.1.0a1/web/src/chunks.ts +174 -0
  271. chunkmirage-0.1.0a1/web/src/consumers.ts +118 -0
  272. chunkmirage-0.1.0a1/web/src/demand.ts +91 -0
  273. chunkmirage-0.1.0a1/web/src/engine.ts +498 -0
  274. chunkmirage-0.1.0a1/web/src/gallery.ts +32 -0
  275. chunkmirage-0.1.0a1/web/src/generated/chunkmirage.schema.json +1120 -0
  276. chunkmirage-0.1.0a1/web/src/generated/chunkmirage.ts +532 -0
  277. chunkmirage-0.1.0a1/web/src/main.ts +705 -0
  278. chunkmirage-0.1.0a1/web/src/map.ts +128 -0
  279. chunkmirage-0.1.0a1/web/src/ome.ts +187 -0
  280. chunkmirage-0.1.0a1/web/src/pipeline.ts +212 -0
  281. chunkmirage-0.1.0a1/web/src/pyworker.ts +325 -0
  282. chunkmirage-0.1.0a1/web/src/raw.d.ts +5 -0
  283. chunkmirage-0.1.0a1/web/src/reader.ts +52 -0
  284. chunkmirage-0.1.0a1/web/src/solver.ts +448 -0
  285. chunkmirage-0.1.0a1/web/src/sources.ts +338 -0
  286. chunkmirage-0.1.0a1/web/src/stitch.ts +318 -0
  287. chunkmirage-0.1.0a1/web/src/sw.ts +137 -0
  288. chunkmirage-0.1.0a1/web/src/track.ts +421 -0
  289. chunkmirage-0.1.0a1/web/src/types.ts +108 -0
  290. chunkmirage-0.1.0a1/web/stitch.html +106 -0
  291. chunkmirage-0.1.0a1/web/test/demand.test.ts +66 -0
  292. chunkmirage-0.1.0a1/web/track.html +107 -0
  293. chunkmirage-0.1.0a1/web/tsconfig.base.json +15 -0
  294. chunkmirage-0.1.0a1/web/tsconfig.json +9 -0
  295. chunkmirage-0.1.0a1/web/tsconfig.worker.json +8 -0
  296. chunkmirage-0.1.0a1/web/vite.config.ts +26 -0
@@ -0,0 +1,30 @@
1
+ name: ci
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - uses: astral-sh/setup-uv@v5
12
+ - run: uv sync --extra all --extra cpu --group dev --group docs # cpu: no GPU here, so PyTorch's small build
13
+ - run: uv run ruff check src tests examples web
14
+ - run: uv run pytest -q
15
+ - run: uv run mkdocs build --strict
16
+ web: # the browser engine: its types follow chunkmirage's schema (tests/test_schema.py keeps that current)
17
+ runs-on: ubuntu-latest
18
+ defaults:
19
+ run:
20
+ working-directory: web
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - uses: actions/setup-node@v4
24
+ with:
25
+ node-version: 22
26
+ cache: npm
27
+ cache-dependency-path: web/package-lock.json
28
+ - run: npm ci
29
+ - run: npm run gen && git diff --exit-code src/generated
30
+ - run: npm run check
@@ -0,0 +1,47 @@
1
+ name: docs
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ workflow_dispatch:
6
+ permissions:
7
+ contents: write
8
+ env:
9
+ # The Neuroglancer the browser engine embeds, built from Google's source here rather than
10
+ # kept in this repo. The page answers the viewer's requests through a service worker,
11
+ # which only sees requests from pages on its own site, so the viewer has to be served
12
+ # from here too (an iframe of neuroglancer-demo.appspot.com would miss them).
13
+ NEUROGLANCER: v2.41.2
14
+ jobs:
15
+ deploy:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: astral-sh/setup-uv@v5
20
+ - uses: actions/setup-node@v4
21
+ with:
22
+ node-version: 22
23
+ cache: npm
24
+ cache-dependency-path: web/package-lock.json
25
+ - run: uv sync --group docs
26
+ - run: uv run mkdocs build --strict
27
+ # the browser engine (web/): its gallery at <site>/browser/, the demo pages beside it
28
+ - run: npm ci && npm run build
29
+ working-directory: web
30
+ - uses: actions/cache@v4
31
+ id: neuroglancer
32
+ with:
33
+ path: neuroglancer
34
+ key: neuroglancer-${{ env.NEUROGLANCER }}
35
+ - if: steps.neuroglancer.outputs.cache-hit != 'true'
36
+ run: |
37
+ git clone --depth 1 --branch "$NEUROGLANCER" https://github.com/google/neuroglancer "$RUNNER_TEMP/src"
38
+ cd "$RUNNER_TEMP/src"
39
+ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci --no-audit --no-fund
40
+ npm run build -- --output="$GITHUB_WORKSPACE/neuroglancer"
41
+ find "$GITHUB_WORKSPACE/neuroglancer" -name '*.map' -delete
42
+ # its viewer at browser/ng/ and its example (two fly brain templates, about 10 MB) at browser/data/
43
+ - run: |
44
+ cp -r web/dist site/browser
45
+ cp -r neuroglancer site/browser/ng
46
+ uv run python web/scripts/fetch_example.py site/browser/data
47
+ - run: uv run ghp-import --no-jekyll --push --force -m "Deployed ${GITHUB_SHA} with the browser engine" site
@@ -0,0 +1,44 @@
1
+ name: publish
2
+ on:
3
+ release:
4
+ types: [published] # a release goes to PyPI
5
+ workflow_dispatch: # a manual run goes to TestPyPI
6
+ jobs:
7
+ build:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - uses: astral-sh/setup-uv@v5
12
+ - run: uv build
13
+ - uses: actions/upload-artifact@v4
14
+ with:
15
+ name: dist
16
+ path: dist/
17
+ testpypi: # trusted publishing: set the publisher for this repo and workflow on test.pypi.org first
18
+ if: github.event_name == 'workflow_dispatch'
19
+ needs: build
20
+ runs-on: ubuntu-latest
21
+ environment: testpypi
22
+ permissions:
23
+ id-token: write
24
+ steps:
25
+ - uses: actions/download-artifact@v4
26
+ with:
27
+ name: dist
28
+ path: dist/
29
+ - uses: pypa/gh-action-pypi-publish@release/v1
30
+ with:
31
+ repository-url: https://test.pypi.org/legacy/
32
+ pypi: # trusted publishing: set the publisher for this repo and workflow on pypi.org first
33
+ if: github.event_name == 'release'
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment: pypi
37
+ permissions:
38
+ id-token: write
39
+ steps:
40
+ - uses: actions/download-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,21 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .pixi/
10
+ *.zarr/
11
+ *.n5/
12
+ .chunkmirage-cache/
13
+ .DS_Store
14
+ .idea/
15
+ .vscode/
16
+ .uv-cache/
17
+ .claude/settings.local.json
18
+ site/
19
+
20
+ # vendored test fixtures are OME-Zarr hierarchies
21
+ !tests/data/**/*.zarr/
@@ -0,0 +1,67 @@
1
+ # Changelog
2
+
3
+ Notable changes per release. Versions follow the rules in
4
+ [contributing](docs/contributing.md#plugin-api-and-versioning): the plugin API is stable,
5
+ and a release that breaks it says so here.
6
+
7
+ ## 0.1.0a1 (unreleased)
8
+
9
+ The first release, an alpha: the plugin API can still change before 0.1.0.
10
+
11
+ ### Serving
12
+
13
+ - Pipelines served as N5, Zarr v2 (OME-NGFF 0.4), Zarr v3 (OME-NGFF 0.5) and Neuroglancer
14
+ precomputed at once, and meshes made when fetched.
15
+ - A per-stage chunk cache keyed by the pipeline's hash, and cache-busting digests in links.
16
+ - Live edits through the REST API, Server-Sent Events, a control page and a
17
+ python-neuroglancer viewer that follows them.
18
+ - Work bounded, shared between requests and ordered finest level first, then by when
19
+ each request arrived; work no client waits for any more is dropped.
20
+ - `--token` for the control API, `--https` with a self-signed certificate.
21
+ - zarr v2 and v3 chunks compressed with blosc (zstd, byte shuffle) by default, 10 to 30
22
+ times quicker to encode than gzip; `--compressor` chooses another. `--cache-gb` takes effect (an empty cache
23
+ given to the registry used to be replaced by the default 2 GiB one), and `0` turns the
24
+ cache off.
25
+ - `serve --port 0` and `--ready-file` for launchers; the port is bound before it is
26
+ announced.
27
+ - Datasets resolved by name on first request (`resolver`), routes from other packages
28
+ (`extra_routes`, the `chunkmirage.routes` entry point), and the app mounted under a prefix
29
+ in another app.
30
+ - `chunkmirage.serve` and `Server`: an app served from Python on a port bound first, with a
31
+ callback once it accepts connections, in a background thread or this one.
32
+
33
+ ### Sources
34
+
35
+ - zarr v2/v3, N5, precomputed and HDF5 on file, S3, GCS and HTTP; xarray arrays with their
36
+ coordinates and CF packing; cloud-optimized GeoTIFFs.
37
+ - Computed sources: `synthetic://`, `scene://` (OME-Zarr 0.6 transformations), `warp://`,
38
+ `register://` (deformable registration on a GPU), `stitch://` (BigStitcher tiles),
39
+ `stack://` and `flip://`.
40
+ - S3 read anonymously before credentials, GCS through its public URL when credentials
41
+ fail, metadata reads that give up after seconds, zarr compressors with members
42
+ tensorstore rejects.
43
+ - Voxels placed as Neuroglancer places them: precomputed `voxel_offset` and funlib `offset`
44
+ are corners.
45
+ - Stored integers of 32 bits or more read as labels, booleans as masks, unless the spec's
46
+ `kind` says otherwise.
47
+
48
+ ### Ops and pipelines
49
+
50
+ - Pointwise ops, filters, morphology, connected components, spots, contacts, differences,
51
+ gradients, downsampling, normalized differences, slope and hillshade, with halos handled
52
+ by the pipeline.
53
+ - Ops that return their block shaved by the halo or add leading axes; ops at one
54
+ resolution with the coarser levels downsampled from their output, or the nearest level
55
+ read as it is (`input_level`, `level_rtol`).
56
+ - `cache_token()` for ops whose output depends on state outside their parameters, and
57
+ `DatasetRegistry.refresh` to read it again.
58
+ - `slots` to bound how many calls of an op run at once.
59
+ - Zero padding past the volume's edge (`padding`).
60
+ - Channel axes read whole, so an op may change their length: select or combine channels.
61
+ - A level shrunk by a whole factor for an op at one voxel size is the mean of each block,
62
+ not linear samples.
63
+
64
+ ### Browser engine
65
+
66
+ - Registration on WebGPU and pipelines of the package's own ops in Pyodide, in a gallery of
67
+ demos.
@@ -0,0 +1,40 @@
1
+ # chunkmirage: notes for AI-assisted sessions
2
+
3
+ Library + CLI that spoofs zarr v2/v3, N5 and Neuroglancer precomputed over HTTP with a
4
+ pipeline of block ops, per-stage caching, and a REST API. General-purpose: not built for
5
+ any one downstream project. example-virtual-n5 and cellmap-flow are prior art / example
6
+ consumers, not the purpose. Architecture and rationale: `docs/design.md`.
7
+
8
+ ## Workflow
9
+
10
+ - Env: `uv sync --extra all --extra gpu --group dev --group docs` (`--extra cpu` on a machine
11
+ without an NVIDIA GPU; the two conflict, so not `--all-extras`). In the Claude Code sandbox the
12
+ default uv cache is read-only; use `UV_CACHE_DIR=$PWD/.uv-cache` (gitignored).
13
+ - Check: `uv run pytest -q && uv run ruff check src tests examples web && uv run mkdocs build --strict`.
14
+ - Browser engine (`web/`, TypeScript + Vite): `cd web && npm ci && npm run check`. After
15
+ changing a Pydantic model it mirrors, regenerate its types:
16
+ `uv run chunkmirage schema --out web/src/generated/chunkmirage.schema.json && (cd web && npm run gen)`.
17
+ - Do not push or create the GitHub repo unless asked.
18
+
19
+ ## Documentation policy (non-negotiable)
20
+
21
+ Docs are part of every change. When you add, remove or rename anything user-visible,
22
+ update the matching page in the same commit:
23
+
24
+ - op → `docs/reference/ops.md`; frontend/URL → `docs/concepts/formats.md`;
25
+ REST route → `docs/reference/api.md`; CLI flag → `docs/reference/cli.md`;
26
+ caching behaviour → `docs/concepts/caching.md`; control page / viewer / events →
27
+ `docs/concepts/interactivity.md`; design decision → `docs/design.md`;
28
+ shipped roadmap item → remove from `docs/roadmap.md` and document where it landed.
29
+ - `tests/test_docs.py` enforces ops/frontends/routes coverage; `mkdocs build --strict`
30
+ catches broken links. Keep both green.
31
+ - Prefer updating an existing page over adding a new one. Keep `README.md` short and
32
+ pointing at the docs.
33
+
34
+ ## Conventions
35
+
36
+ - Arrays are numpy C order `(z, y, x)`; N5 and precomputed reverse axis lists at the edge.
37
+ - Every pipeline stage is a `ChunkedSource`; caching and halos live there, not in ops.
38
+ - Ops are pydantic models with class-level `name`, `halo`, `cache` (and `packages` they import
39
+ beyond numpy, for the browser engine); register via
40
+ `@register` and the `chunkmirage.ops` entry point.
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Howard Hughes Medical Institute
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.5
2
+ Name: chunkmirage
3
+ Version: 0.1.0a1
4
+ Summary: Spoof chunked array formats (zarr, n5, neuroglancer precomputed) over HTTP with on-the-fly processing, caching, and pluggable ops.
5
+ Project-URL: Homepage, https://janeliascicomp.github.io/chunkmirage/
6
+ Project-URL: Documentation, https://janeliascicomp.github.io/chunkmirage/
7
+ Project-URL: Source, https://github.com/JaneliaSciComp/chunkmirage
8
+ Project-URL: Issues, https://github.com/JaneliaSciComp/chunkmirage/issues
9
+ Project-URL: Changelog, https://github.com/JaneliaSciComp/chunkmirage/blob/main/CHANGELOG.md
10
+ Author: David Ackerman (@davidackerman), Yurii Zubov (@yuriyzubov)
11
+ License: BSD 3-Clause License
12
+
13
+ Copyright (c) 2026, Howard Hughes Medical Institute
14
+
15
+ Redistribution and use in source and binary forms, with or without
16
+ modification, are permitted provided that the following conditions are met:
17
+
18
+ 1. Redistributions of source code must retain the above copyright notice, this
19
+ list of conditions and the following disclaimer.
20
+
21
+ 2. Redistributions in binary form must reproduce the above copyright notice,
22
+ this list of conditions and the following disclaimer in the documentation
23
+ and/or other materials provided with the distribution.
24
+
25
+ 3. Neither the name of the copyright holder nor the names of its
26
+ contributors may be used to endorse or promote products derived from
27
+ this software without specific prior written permission.
28
+
29
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
33
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
37
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
+ License-File: LICENSE
40
+ Keywords: chunked,imaging,n5,neuroglancer,tensorstore,virtual,zarr
41
+ Classifier: Development Status :: 3 - Alpha
42
+ Classifier: Intended Audience :: Science/Research
43
+ Classifier: License :: OSI Approved :: BSD License
44
+ Classifier: Programming Language :: Python :: 3
45
+ Classifier: Programming Language :: Python :: 3.11
46
+ Classifier: Programming Language :: Python :: 3.12
47
+ Classifier: Programming Language :: Python :: 3.13
48
+ Classifier: Topic :: Scientific/Engineering
49
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
50
+ Classifier: Typing :: Typed
51
+ Requires-Python: >=3.11
52
+ Requires-Dist: hypercorn[h2]>=0.17
53
+ Requires-Dist: numcodecs>=0.12
54
+ Requires-Dist: numpy>=1.26
55
+ Requires-Dist: pydantic>=2.6
56
+ Requires-Dist: starlette>=0.37
57
+ Requires-Dist: tensorstore>=0.1.60
58
+ Requires-Dist: typer>=0.12
59
+ Requires-Dist: uvicorn[standard]>=0.29
60
+ Provides-Extra: all
61
+ Requires-Dist: cryptography>=42; extra == 'all'
62
+ Requires-Dist: dracopy>=1.4; extra == 'all'
63
+ Requires-Dist: h5py>=3.10; extra == 'all'
64
+ Requires-Dist: imagecodecs>=2024.1; extra == 'all'
65
+ Requires-Dist: mcp>=1.0; extra == 'all'
66
+ Requires-Dist: neuroglancer>=2.40; extra == 'all'
67
+ Requires-Dist: scikit-image>=0.22; extra == 'all'
68
+ Requires-Dist: scipy>=1.12; extra == 'all'
69
+ Requires-Dist: tifffile>=2024.1; extra == 'all'
70
+ Provides-Extra: cpu
71
+ Requires-Dist: scipy>=1.12; extra == 'cpu'
72
+ Requires-Dist: torch>=2.6; extra == 'cpu'
73
+ Provides-Extra: gpu
74
+ Requires-Dist: scipy>=1.12; extra == 'gpu'
75
+ Requires-Dist: torch>=2.6; extra == 'gpu'
76
+ Provides-Extra: hdf5
77
+ Requires-Dist: h5py>=3.10; extra == 'hdf5'
78
+ Provides-Extra: https
79
+ Requires-Dist: cryptography>=42; extra == 'https'
80
+ Provides-Extra: mcp
81
+ Requires-Dist: mcp>=1.0; extra == 'mcp'
82
+ Provides-Extra: mesh
83
+ Requires-Dist: dracopy>=1.4; extra == 'mesh'
84
+ Requires-Dist: scikit-image>=0.22; extra == 'mesh'
85
+ Provides-Extra: ops
86
+ Requires-Dist: scipy>=1.12; extra == 'ops'
87
+ Provides-Extra: tiff
88
+ Requires-Dist: imagecodecs>=2024.1; extra == 'tiff'
89
+ Requires-Dist: tifffile>=2024.1; extra == 'tiff'
90
+ Provides-Extra: viewer
91
+ Requires-Dist: neuroglancer>=2.40; extra == 'viewer'
92
+ Description-Content-Type: text/markdown
93
+
94
+ # chunkmirage
95
+
96
+ **Spoof chunked array formats over HTTP with on-the-fly processing.**
97
+
98
+ chunkmirage serves *virtual* datasets that look, to any HTTP-capable viewer or library
99
+ (Neuroglancer, BigDataViewer/Fiji, vizarr, napari, webKnossos, zarr-python, dask,
100
+ tensorstore, ...), like ordinary Zarr v2, Zarr v3, N5 or Neuroglancer precomputed volumes.
101
+ Nothing exists on disk. Each chunk is computed when it is requested: read from a real
102
+ source (zarr, N5, precomputed, HDF5, GeoTIFF; local, S3, GCS or HTTP) or generated, pushed
103
+ through a pipeline of ops, encoded in the format the client asked for, and cached per
104
+ stage, so changing a parameter downstream never recomputes what comes before it.
105
+
106
+ **▶ [Try the demos in your browser](https://janeliascicomp.github.io/chunkmirage/browser/)**,
107
+ nothing to install. Every chunk on screen is computed in the page by chunkmirage's own
108
+ Python, from public data, as the viewer asks for it.
109
+
110
+ <p>
111
+ <a href="https://janeliascicomp.github.io/chunkmirage/browser/pipeline.html?card=fires"><img src="https://raw.githubusercontent.com/JaneliaSciComp/chunkmirage/main/web/public/cards/fires.jpg" alt="Los Angeles fires: burn severity, read by Neuroglancer, a web map or GDAL" title="Los Angeles fires: burn severity, read by Neuroglancer, a web map or GDAL" width="32%"></a>
112
+ <a href="https://janeliascicomp.github.io/chunkmirage/browser/pipeline.html?card=mandelbulb"><img src="https://raw.githubusercontent.com/JaneliaSciComp/chunkmirage/main/web/public/cards/mandelbulb.jpg" alt="A 3-D fractal 2^28 voxels across" title="A 3-D fractal 2^28 voxels across" width="32%"></a>
113
+ <a href="https://janeliascicomp.github.io/chunkmirage/browser/pipeline.html?card=fronts"><img src="https://raw.githubusercontent.com/JaneliaSciComp/chunkmirage/main/web/public/cards/fronts.jpg" alt="The Gulf Stream's fronts" title="The Gulf Stream's fronts" width="32%"></a>
114
+ </p>
115
+
116
+ They include burn severity of the Los Angeles fires, the Gulf Stream's fronts and
117
+ hurricanes' cold wakes, landing slopes at the Moon's south pole, a 3-D fractal, microscope
118
+ tiles stitched by RANSAC, two fly brains registered on your GPU, organelle contact sites,
119
+ mRNA spots and nuclei tracked through a colony. Each shows the `chunkmirage serve` command
120
+ that serves the same from Python. The [demos page](https://janeliascicomp.github.io/chunkmirage/demos/) lists them all, with the
121
+ Python examples.
122
+
123
+ ## How it works
124
+
125
+ ```
126
+ viewer --HTTP--> chunkmirage --tensorstore/h5py--> real data (zarr/n5/precomputed/hdf5, file/s3/gcs/http)
127
+ |
128
+ +-- pipeline: source -> [op, op, ...] -> encoded chunk
129
+ +-- per-stage chunk cache keyed by pipeline hash
130
+ +-- frontends: n5 | zarr (v2) | zarr3 | precomputed, all served at once
131
+ +-- REST API for live pipeline edits, and plugins for ops, sources and routes
132
+ ```
133
+
134
+ It was inspired by [example-virtual-n5](https://github.com/stuarteberg/example-virtual-n5)
135
+ and [cellmap-flow](https://github.com/janelia-cellmap/cellmap-flow), which grew out of it,
136
+ and makes their trick general: any format, any source, any per-chunk computation, any
137
+ client.
138
+
139
+ ## Quick start
140
+
141
+ ```bash
142
+ uv sync --extra all --group dev # or: pip install -e ".[all]"
143
+ chunkmirage serve /path/to/data.zarr/em/fibsem-uint8 --op threshold:low=120
144
+ ```
145
+
146
+ With no data at all, a generated 4096³ volume, segmented live:
147
+
148
+ ```bash
149
+ uv run chunkmirage serve "synthetic://blobs+noise?shape=4096,4096,4096" \
150
+ --op gaussian:sigma=1.5 --op threshold:low=110 \
151
+ --op morphology:operation=open,radius=2 --op label:min_size=200 --python-viewer
152
+ ```
153
+
154
+ Open the printed control page (`http://<your-ip>:8000/ui`) and drag the `threshold` slider:
155
+ only the changed stage recomputes. Or point any viewer at one of these:
156
+
157
+ | viewer source URL | format |
158
+ | -------------------------------------------------------- | ------------------------ |
159
+ | `n5://http://localhost:8000/<name>/n5` | N5 |
160
+ | `zarr://http://localhost:8000/<name>/zarr` | Zarr v2 (+ OME-NGFF 0.4) |
161
+ | `zarr3://http://localhost:8000/<name>/zarr3` | Zarr v3 (+ OME-NGFF 0.5) |
162
+ | `precomputed://http://localhost:8000/<name>/precomputed` | Neuroglancer precomputed |
163
+
164
+ Edit the pipeline without restarting:
165
+
166
+ ```bash
167
+ curl -X PUT localhost:8000/api/datasets/<name> -H 'content-type: application/json' \
168
+ -d '{"source": "/path/to/data.zarr/em/fibsem-uint8", "ops": [{"op": "threshold", "low": 150}]}'
169
+ ```
170
+
171
+ More in [getting started](https://janeliascicomp.github.io/chunkmirage/getting-started/), including viewing from another machine.
172
+
173
+ ## As a library
174
+
175
+ ```python
176
+ from chunkmirage import Pipeline, open_source, create_app
177
+ from chunkmirage.ops import Op, Threshold
178
+
179
+ class MyModel(Op):
180
+ name = "my_model"
181
+ halo = 16 # voxels of context read on every side
182
+ cache = True # keep this stage's output chunks
183
+
184
+ def apply(self, block):
185
+ return run_my_network(block)
186
+
187
+ pipe = Pipeline(open_source("s3://bucket/data.zarr/em/s0"), ops=[MyModel(), Threshold(low=120)])
188
+ app = create_app({"em": pipe}) # a Starlette ASGI app
189
+ ```
190
+
191
+ Ops, source schemes and HTTP routes from other packages register through entry points
192
+ (`chunkmirage.ops`, `chunkmirage.sources`, `chunkmirage.routes`), and the app can be mounted
193
+ inside another one. See [pipelines](https://janeliascicomp.github.io/chunkmirage/concepts/pipelines/) and the
194
+ [REST API](https://janeliascicomp.github.io/chunkmirage/reference/api/).
195
+
196
+ ## What it does today
197
+
198
+ * **Sources:** zarr v2/v3, N5, precomputed and HDF5 on file, S3, GCS or HTTP; xarray arrays
199
+ and GeoTIFFs; computed `synthetic://` volumes, `scene://` resampling through OME-Zarr 0.6
200
+ transformations, `register://` deformable registration solved on a GPU, `stitch://`
201
+ BigStitcher tiles stitched and fused as read, and `warp://`, `stack://` and `flip://`.
202
+ * **Frontends:** N5, Zarr v2, Zarr v3 and precomputed, all at once, and meshes made when
203
+ fetched.
204
+ * **Ops:** pointwise, filters, morphology, connected components, spots, contacts,
205
+ downsampling, slope and hillshade, with halos handled for you.
206
+ * **Serving:** per-stage cache, live REST edits, a control page, work ordered by what clients
207
+ ask for and dropped when they stop waiting.
208
+ * **In the browser:** the same ops run in Pyodide, and registration on WebGPU.
209
+
210
+ Not yet: GPU ops other than registration, an MCP server. See the [roadmap](https://janeliascicomp.github.io/chunkmirage/roadmap/).
211
+
212
+ ## Documentation
213
+
214
+ **https://janeliascicomp.github.io/chunkmirage/** (built from `docs/`; `uv run mkdocs serve`
215
+ locally). [the design page](https://janeliascicomp.github.io/chunkmirage/design/) explains the architecture and the choices behind
216
+ it.
217
+
218
+ ## License
219
+
220
+ BSD 3-Clause, Howard Hughes Medical Institute. Authors: TBD (collaborative project).
@@ -0,0 +1,127 @@
1
+ # chunkmirage
2
+
3
+ **Spoof chunked array formats over HTTP with on-the-fly processing.**
4
+
5
+ chunkmirage serves *virtual* datasets that look, to any HTTP-capable viewer or library
6
+ (Neuroglancer, BigDataViewer/Fiji, vizarr, napari, webKnossos, zarr-python, dask,
7
+ tensorstore, ...), like ordinary Zarr v2, Zarr v3, N5 or Neuroglancer precomputed volumes.
8
+ Nothing exists on disk. Each chunk is computed when it is requested: read from a real
9
+ source (zarr, N5, precomputed, HDF5, GeoTIFF; local, S3, GCS or HTTP) or generated, pushed
10
+ through a pipeline of ops, encoded in the format the client asked for, and cached per
11
+ stage, so changing a parameter downstream never recomputes what comes before it.
12
+
13
+ **▶ [Try the demos in your browser](https://janeliascicomp.github.io/chunkmirage/browser/)**,
14
+ nothing to install. Every chunk on screen is computed in the page by chunkmirage's own
15
+ Python, from public data, as the viewer asks for it.
16
+
17
+ <p>
18
+ <a href="https://janeliascicomp.github.io/chunkmirage/browser/pipeline.html?card=fires"><img src="https://raw.githubusercontent.com/JaneliaSciComp/chunkmirage/main/web/public/cards/fires.jpg" alt="Los Angeles fires: burn severity, read by Neuroglancer, a web map or GDAL" title="Los Angeles fires: burn severity, read by Neuroglancer, a web map or GDAL" width="32%"></a>
19
+ <a href="https://janeliascicomp.github.io/chunkmirage/browser/pipeline.html?card=mandelbulb"><img src="https://raw.githubusercontent.com/JaneliaSciComp/chunkmirage/main/web/public/cards/mandelbulb.jpg" alt="A 3-D fractal 2^28 voxels across" title="A 3-D fractal 2^28 voxels across" width="32%"></a>
20
+ <a href="https://janeliascicomp.github.io/chunkmirage/browser/pipeline.html?card=fronts"><img src="https://raw.githubusercontent.com/JaneliaSciComp/chunkmirage/main/web/public/cards/fronts.jpg" alt="The Gulf Stream's fronts" title="The Gulf Stream's fronts" width="32%"></a>
21
+ </p>
22
+
23
+ They include burn severity of the Los Angeles fires, the Gulf Stream's fronts and
24
+ hurricanes' cold wakes, landing slopes at the Moon's south pole, a 3-D fractal, microscope
25
+ tiles stitched by RANSAC, two fly brains registered on your GPU, organelle contact sites,
26
+ mRNA spots and nuclei tracked through a colony. Each shows the `chunkmirage serve` command
27
+ that serves the same from Python. The [demos page](https://janeliascicomp.github.io/chunkmirage/demos/) lists them all, with the
28
+ Python examples.
29
+
30
+ ## How it works
31
+
32
+ ```
33
+ viewer --HTTP--> chunkmirage --tensorstore/h5py--> real data (zarr/n5/precomputed/hdf5, file/s3/gcs/http)
34
+ |
35
+ +-- pipeline: source -> [op, op, ...] -> encoded chunk
36
+ +-- per-stage chunk cache keyed by pipeline hash
37
+ +-- frontends: n5 | zarr (v2) | zarr3 | precomputed, all served at once
38
+ +-- REST API for live pipeline edits, and plugins for ops, sources and routes
39
+ ```
40
+
41
+ It was inspired by [example-virtual-n5](https://github.com/stuarteberg/example-virtual-n5)
42
+ and [cellmap-flow](https://github.com/janelia-cellmap/cellmap-flow), which grew out of it,
43
+ and makes their trick general: any format, any source, any per-chunk computation, any
44
+ client.
45
+
46
+ ## Quick start
47
+
48
+ ```bash
49
+ uv sync --extra all --group dev # or: pip install -e ".[all]"
50
+ chunkmirage serve /path/to/data.zarr/em/fibsem-uint8 --op threshold:low=120
51
+ ```
52
+
53
+ With no data at all, a generated 4096³ volume, segmented live:
54
+
55
+ ```bash
56
+ uv run chunkmirage serve "synthetic://blobs+noise?shape=4096,4096,4096" \
57
+ --op gaussian:sigma=1.5 --op threshold:low=110 \
58
+ --op morphology:operation=open,radius=2 --op label:min_size=200 --python-viewer
59
+ ```
60
+
61
+ Open the printed control page (`http://<your-ip>:8000/ui`) and drag the `threshold` slider:
62
+ only the changed stage recomputes. Or point any viewer at one of these:
63
+
64
+ | viewer source URL | format |
65
+ | -------------------------------------------------------- | ------------------------ |
66
+ | `n5://http://localhost:8000/<name>/n5` | N5 |
67
+ | `zarr://http://localhost:8000/<name>/zarr` | Zarr v2 (+ OME-NGFF 0.4) |
68
+ | `zarr3://http://localhost:8000/<name>/zarr3` | Zarr v3 (+ OME-NGFF 0.5) |
69
+ | `precomputed://http://localhost:8000/<name>/precomputed` | Neuroglancer precomputed |
70
+
71
+ Edit the pipeline without restarting:
72
+
73
+ ```bash
74
+ curl -X PUT localhost:8000/api/datasets/<name> -H 'content-type: application/json' \
75
+ -d '{"source": "/path/to/data.zarr/em/fibsem-uint8", "ops": [{"op": "threshold", "low": 150}]}'
76
+ ```
77
+
78
+ More in [getting started](https://janeliascicomp.github.io/chunkmirage/getting-started/), including viewing from another machine.
79
+
80
+ ## As a library
81
+
82
+ ```python
83
+ from chunkmirage import Pipeline, open_source, create_app
84
+ from chunkmirage.ops import Op, Threshold
85
+
86
+ class MyModel(Op):
87
+ name = "my_model"
88
+ halo = 16 # voxels of context read on every side
89
+ cache = True # keep this stage's output chunks
90
+
91
+ def apply(self, block):
92
+ return run_my_network(block)
93
+
94
+ pipe = Pipeline(open_source("s3://bucket/data.zarr/em/s0"), ops=[MyModel(), Threshold(low=120)])
95
+ app = create_app({"em": pipe}) # a Starlette ASGI app
96
+ ```
97
+
98
+ Ops, source schemes and HTTP routes from other packages register through entry points
99
+ (`chunkmirage.ops`, `chunkmirage.sources`, `chunkmirage.routes`), and the app can be mounted
100
+ inside another one. See [pipelines](https://janeliascicomp.github.io/chunkmirage/concepts/pipelines/) and the
101
+ [REST API](https://janeliascicomp.github.io/chunkmirage/reference/api/).
102
+
103
+ ## What it does today
104
+
105
+ * **Sources:** zarr v2/v3, N5, precomputed and HDF5 on file, S3, GCS or HTTP; xarray arrays
106
+ and GeoTIFFs; computed `synthetic://` volumes, `scene://` resampling through OME-Zarr 0.6
107
+ transformations, `register://` deformable registration solved on a GPU, `stitch://`
108
+ BigStitcher tiles stitched and fused as read, and `warp://`, `stack://` and `flip://`.
109
+ * **Frontends:** N5, Zarr v2, Zarr v3 and precomputed, all at once, and meshes made when
110
+ fetched.
111
+ * **Ops:** pointwise, filters, morphology, connected components, spots, contacts,
112
+ downsampling, slope and hillshade, with halos handled for you.
113
+ * **Serving:** per-stage cache, live REST edits, a control page, work ordered by what clients
114
+ ask for and dropped when they stop waiting.
115
+ * **In the browser:** the same ops run in Pyodide, and registration on WebGPU.
116
+
117
+ Not yet: GPU ops other than registration, an MCP server. See the [roadmap](https://janeliascicomp.github.io/chunkmirage/roadmap/).
118
+
119
+ ## Documentation
120
+
121
+ **https://janeliascicomp.github.io/chunkmirage/** (built from `docs/`; `uv run mkdocs serve`
122
+ locally). [the design page](https://janeliascicomp.github.io/chunkmirage/design/) explains the architecture and the choices behind
123
+ it.
124
+
125
+ ## License
126
+
127
+ BSD 3-Clause, Howard Hughes Medical Institute. Authors: TBD (collaborative project).