monai-weekly 1.5.dev2522__py3-none-any.whl → 1.6.dev2524__py3-none-any.whl

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.
monai/__init__.py CHANGED
@@ -136,4 +136,4 @@ except BaseException:
136
136
 
137
137
  if MONAIEnvVars.debug():
138
138
  raise
139
- __commit_id__ = "c3a317d2bcb486199f40bda0d722a41e3869712a"
139
+ __commit_id__ = "d388d1c6fec8cb3a0eebee5b5a0b9776ca59ca83"
monai/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-06-01T02:46:06+0000",
11
+ "date": "2025-06-15T02:40:48+0000",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "3e75ca0d8f4cf7ce1e4b3e01ef6058c56af87fdd",
15
- "version": "1.5.dev2522"
14
+ "full-revisionid": "1be81d981f92f8fa2fb1c27dfe5dad8c2e371624",
15
+ "version": "1.6.dev2524"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
monai/inferers/merger.py CHANGED
@@ -21,7 +21,14 @@ from typing import TYPE_CHECKING, Any
21
21
  import numpy as np
22
22
  import torch
23
23
 
24
- from monai.utils import ensure_tuple_size, get_package_version, optional_import, require_pkg, version_geq
24
+ from monai.utils import (
25
+ deprecated_arg,
26
+ ensure_tuple_size,
27
+ get_package_version,
28
+ optional_import,
29
+ require_pkg,
30
+ version_geq,
31
+ )
25
32
 
26
33
  if TYPE_CHECKING:
27
34
  import zarr
@@ -218,15 +225,41 @@ class ZarrAvgMerger(Merger):
218
225
  store: the zarr store to save the final results. Default is "merged.zarr".
219
226
  value_store: the zarr store to save the value aggregating tensor. Default is a temporary store.
220
227
  count_store: the zarr store to save the sample counting tensor. Default is a temporary store.
221
- compressor: the compressor for final merged zarr array. Default is "default".
228
+ compressor: the compressor for final merged zarr array. Default is None.
229
+ Deprecated since 1.5.0 and will be removed in 1.7.0. Use codecs instead.
222
230
  value_compressor: the compressor for value aggregating zarr array. Default is None.
231
+ Deprecated since 1.5.0 and will be removed in 1.7.0. Use value_codecs instead.
223
232
  count_compressor: the compressor for sample counting zarr array. Default is None.
233
+ Deprecated since 1.5.0 and will be removed in 1.7.0. Use count_codecs instead.
234
+ codecs: the codecs for final merged zarr array. Default is None.
235
+ For zarr v3, this is a list of codec configurations. See zarr documentation for details.
236
+ value_codecs: the codecs for value aggregating zarr array. Default is None.
237
+ For zarr v3, this is a list of codec configurations. See zarr documentation for details.
238
+ count_codecs: the codecs for sample counting zarr array. Default is None.
239
+ For zarr v3, this is a list of codec configurations. See zarr documentation for details.
224
240
  chunks : int or tuple of ints that defines the chunk shape, or boolean. Default is True.
225
241
  If True, chunk shape will be guessed from `shape` and `dtype`.
226
242
  If False, it will be set to `shape`, i.e., single chunk for the whole array.
227
243
  If an int, the chunk size in each dimension will be given by the value of `chunks`.
228
244
  """
229
245
 
246
+ @deprecated_arg(
247
+ name="compressor", since="1.5.0", removed="1.7.0", new_name="codecs", msg_suffix="Please use 'codecs' instead."
248
+ )
249
+ @deprecated_arg(
250
+ name="value_compressor",
251
+ since="1.5.0",
252
+ removed="1.7.0",
253
+ new_name="value_codecs",
254
+ msg_suffix="Please use 'value_codecs' instead.",
255
+ )
256
+ @deprecated_arg(
257
+ name="count_compressor",
258
+ since="1.5.0",
259
+ removed="1.7.0",
260
+ new_name="count_codecs",
261
+ msg_suffix="Please use 'count_codecs' instead.",
262
+ )
230
263
  def __init__(
231
264
  self,
232
265
  merged_shape: Sequence[int],
@@ -240,6 +273,9 @@ class ZarrAvgMerger(Merger):
240
273
  compressor: str | None = None,
241
274
  value_compressor: str | None = None,
242
275
  count_compressor: str | None = None,
276
+ codecs: list | None = None,
277
+ value_codecs: list | None = None,
278
+ count_codecs: list | None = None,
243
279
  chunks: Sequence[int] | bool = True,
244
280
  thread_locking: bool = True,
245
281
  ) -> None:
@@ -251,7 +287,11 @@ class ZarrAvgMerger(Merger):
251
287
  self.count_dtype = count_dtype
252
288
  self.store = store
253
289
  self.tmpdir: TemporaryDirectory | None
254
- if version_geq(get_package_version("zarr"), "3.0.0"):
290
+
291
+ # Handle zarr v3 vs older versions
292
+ is_zarr_v3 = version_geq(get_package_version("zarr"), "3.0.0")
293
+
294
+ if is_zarr_v3:
255
295
  if value_store is None:
256
296
  self.tmpdir = TemporaryDirectory()
257
297
  self.value_store = zarr.storage.LocalStore(self.tmpdir.name) # type: ignore
@@ -266,34 +306,119 @@ class ZarrAvgMerger(Merger):
266
306
  self.tmpdir = None
267
307
  self.value_store = zarr.storage.TempStore() if value_store is None else value_store # type: ignore
268
308
  self.count_store = zarr.storage.TempStore() if count_store is None else count_store # type: ignore
309
+
269
310
  self.chunks = chunks
270
- self.compressor = compressor
271
- self.value_compressor = value_compressor
272
- self.count_compressor = count_compressor
273
- self.output = zarr.empty(
274
- shape=self.merged_shape,
275
- chunks=self.chunks,
276
- dtype=self.output_dtype,
277
- compressor=self.compressor,
278
- store=self.store,
279
- overwrite=True,
280
- )
281
- self.values = zarr.zeros(
282
- shape=self.merged_shape,
283
- chunks=self.chunks,
284
- dtype=self.value_dtype,
285
- compressor=self.value_compressor,
286
- store=self.value_store,
287
- overwrite=True,
288
- )
289
- self.counts = zarr.zeros(
290
- shape=self.merged_shape,
291
- chunks=self.chunks,
292
- dtype=self.count_dtype,
293
- compressor=self.count_compressor,
294
- store=self.count_store,
295
- overwrite=True,
296
- )
311
+
312
+ # Handle compressor/codecs based on zarr version
313
+ is_zarr_v3 = version_geq(get_package_version("zarr"), "3.0.0")
314
+
315
+ # Initialize codecs/compressor attributes with proper types
316
+ self.codecs: list | None = None
317
+ self.value_codecs: list | None = None
318
+ self.count_codecs: list | None = None
319
+
320
+ if is_zarr_v3:
321
+ # For zarr v3, use codecs or convert compressor to codecs
322
+ if codecs is not None:
323
+ self.codecs = codecs
324
+ elif compressor is not None:
325
+ # Convert compressor to codec format
326
+ if isinstance(compressor, (list, tuple)):
327
+ self.codecs = compressor
328
+ else:
329
+ self.codecs = [compressor]
330
+ else:
331
+ self.codecs = None
332
+
333
+ if value_codecs is not None:
334
+ self.value_codecs = value_codecs
335
+ elif value_compressor is not None:
336
+ if isinstance(value_compressor, (list, tuple)):
337
+ self.value_codecs = value_compressor
338
+ else:
339
+ self.value_codecs = [value_compressor]
340
+ else:
341
+ self.value_codecs = None
342
+
343
+ if count_codecs is not None:
344
+ self.count_codecs = count_codecs
345
+ elif count_compressor is not None:
346
+ if isinstance(count_compressor, (list, tuple)):
347
+ self.count_codecs = count_compressor
348
+ else:
349
+ self.count_codecs = [count_compressor]
350
+ else:
351
+ self.count_codecs = None
352
+ else:
353
+ # For zarr v2, use compressors
354
+ if codecs is not None:
355
+ # If codecs are specified in v2, use the first codec as compressor
356
+ self.codecs = codecs[0] if isinstance(codecs, (list, tuple)) else codecs
357
+ else:
358
+ self.codecs = compressor # type: ignore[assignment]
359
+
360
+ if value_codecs is not None:
361
+ self.value_codecs = value_codecs[0] if isinstance(value_codecs, (list, tuple)) else value_codecs
362
+ else:
363
+ self.value_codecs = value_compressor # type: ignore[assignment]
364
+
365
+ if count_codecs is not None:
366
+ self.count_codecs = count_codecs[0] if isinstance(count_codecs, (list, tuple)) else count_codecs
367
+ else:
368
+ self.count_codecs = count_compressor # type: ignore[assignment]
369
+
370
+ # Create zarr arrays with appropriate parameters based on version
371
+ if is_zarr_v3:
372
+ self.output = zarr.empty(
373
+ shape=self.merged_shape,
374
+ chunks=self.chunks,
375
+ dtype=self.output_dtype,
376
+ codecs=self.codecs,
377
+ store=self.store,
378
+ overwrite=True,
379
+ )
380
+ self.values = zarr.zeros(
381
+ shape=self.merged_shape,
382
+ chunks=self.chunks,
383
+ dtype=self.value_dtype,
384
+ codecs=self.value_codecs,
385
+ store=self.value_store,
386
+ overwrite=True,
387
+ )
388
+ self.counts = zarr.zeros(
389
+ shape=self.merged_shape,
390
+ chunks=self.chunks,
391
+ dtype=self.count_dtype,
392
+ codecs=self.count_codecs,
393
+ store=self.count_store,
394
+ overwrite=True,
395
+ )
396
+ else:
397
+ self.output = zarr.empty(
398
+ shape=self.merged_shape,
399
+ chunks=self.chunks,
400
+ dtype=self.output_dtype,
401
+ compressor=self.codecs,
402
+ store=self.store,
403
+ overwrite=True,
404
+ )
405
+ self.values = zarr.zeros(
406
+ shape=self.merged_shape,
407
+ chunks=self.chunks,
408
+ dtype=self.value_dtype,
409
+ compressor=self.value_codecs,
410
+ store=self.value_store,
411
+ overwrite=True,
412
+ )
413
+ self.counts = zarr.zeros(
414
+ shape=self.merged_shape,
415
+ chunks=self.chunks,
416
+ dtype=self.count_dtype,
417
+ compressor=self.count_codecs,
418
+ store=self.count_store,
419
+ overwrite=True,
420
+ )
421
+
297
422
  self.lock: threading.Lock | nullcontext
298
423
  if thread_locking:
299
424
  # use lock to protect the in-place addition during aggregation
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: monai-weekly
3
- Version: 1.5.dev2522
3
+ Version: 1.6.dev2524
4
4
  Summary: AI Toolkit for Healthcare Imaging
5
5
  Home-page: https://monai.io/
6
6
  Author: MONAI Consortium
@@ -215,7 +215,7 @@ Please refer to [the installation guide](https://docs.monai.io/en/latest/install
215
215
 
216
216
  ## Getting Started
217
217
 
218
- [MedNIST demo](https://colab.research.google.com/drive/1wy8XUSnNWlhDNazFdvGBHLfdkGvOHBKe) and [MONAI for PyTorch Users](https://colab.research.google.com/drive/1boqy7ENpKrqaJoxFlbHIBnIODAs1Ih1T) are available on Colab.
218
+ [MedNIST demo](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/main/2d_classification/mednist_tutorial.ipynb) and [MONAI for PyTorch Users](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/main/modules/developer_guide.ipynb) are available on Colab.
219
219
 
220
220
  Examples and notebook tutorials are located at [Project-MONAI/tutorials](https://github.com/Project-MONAI/tutorials).
221
221
 
@@ -236,7 +236,7 @@ For guidance on making a contribution to MONAI, see the [contributing guidelines
236
236
 
237
237
  ## Community
238
238
 
239
- Join the conversation on Twitter/X [@ProjectMONAI](https://twitter.com/ProjectMONAI) or join our [Slack channel](https://forms.gle/QTxJq3hFictp31UM9).
239
+ Join the conversation on Twitter/X [@ProjectMONAI](https://twitter.com/ProjectMONAI), [LinkedIn](https://www.linkedin.com/company/projectmonai), or join our [Slack channel](https://forms.gle/QTxJq3hFictp31UM9).
240
240
 
241
241
  Ask and answer questions over on [MONAI's GitHub Discussions tab](https://github.com/Project-MONAI/MONAI/discussions).
242
242
 
@@ -1,5 +1,5 @@
1
- monai/__init__.py,sha256=eZQIXyDYcb7TrjIfc4e844rVm7n1JSyFVCrSaNR63h8,4095
2
- monai/_version.py,sha256=7wXHOrAWUBKXGlWLCp1a8MS05DKSCeFNQSp2QC6OdFY,503
1
+ monai/__init__.py,sha256=Tuhv3OtRt0Z1-fcKWtwVyLxG1O1LkQDCpUwdIa2LHYU,4095
2
+ monai/_version.py,sha256=E7VRkhmkHHNCXgdYbiP8HabZyg5eJjmgwqx2qSkoFDY,503
3
3
  monai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  monai/_extensions/__init__.py,sha256=NEBPreRhQ8H9gVvgrLr_y52_TmqB96u_u4VQmeNT93I,642
5
5
  monai/_extensions/loader.py,sha256=7SiKw36q-nOzH8CRbBurFrz7GM40GCu7rc93Tm8XpnI,3643
@@ -197,7 +197,7 @@ monai/handlers/utils.py,sha256=Ib1u-PLrtIkiLqTfREnrCWpN4af1btdNzkyMZuuuYyU,10239
197
197
  monai/handlers/validation_handler.py,sha256=NZO21c6zzXbmAgJZHkkdoZQSQIHwuxh94QD3PLUldGU,3674
198
198
  monai/inferers/__init__.py,sha256=K74t_RCeUPdEZvHzIPzVAwZ9DtmouLqhb3qDEmFBWs4,1107
199
199
  monai/inferers/inferer.py,sha256=kfrxbSRAug_2oO943gQNHPfhfllu-DrseimT3vEb7uE,97280
200
- monai/inferers/merger.py,sha256=JxSLdlXTKW1xug11UWQNi6dNtpqVRbGCLc-ifj06g8U,16613
200
+ monai/inferers/merger.py,sha256=fjoaFq5HuKrZ1A0UwlMtd38fk2coa8axJlOjPfP8DQg,21575
201
201
  monai/inferers/splitter.py,sha256=_hTnFdvDNRckkA7ZGQehVsNZw83oXoGFWyk5VXNqgJg,21149
202
202
  monai/inferers/utils.py,sha256=dvZBCAjaPa8xXcJuXRzNQ-fBzteauzkKbxE5YZdGBGY,20374
203
203
  monai/losses/__init__.py,sha256=igy7BjoQzM3McmJPD2tmeiW2ljSXfB2HBdc4YiDzYEg,1778
@@ -426,7 +426,7 @@ monai/visualize/img2tensorboard.py,sha256=n4ztSa5BQAUxSTGvi2tp45v-F7-RNgSlbsdy-9
426
426
  monai/visualize/occlusion_sensitivity.py,sha256=0SwhLO7ePDfIXJj67_UmXDZLxXItMeM-uNrPaCE0xXg,18159
427
427
  monai/visualize/utils.py,sha256=B-MhTVs7sQbIqYS3yPnpBwPw2K82rE2PBtGIfpwZtWM,9894
428
428
  monai/visualize/visualizer.py,sha256=qckyaMZCbezYUwE20k5yc-Pb7UozVavMDbrmyQwfYHY,1377
429
- monai_weekly-1.5.dev2522.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
429
+ monai_weekly-1.6.dev2524.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
430
430
  tests/apps/__init__.py,sha256=s9djSd6kvViPnFvMR11Dgd30Lv4oY6FaPJr4ZZJZLq0,573
431
431
  tests/apps/test_auto3dseg_bundlegen.py,sha256=FpTJo9Lfe8vdhGuWeZ9y1BQmqYwTt-s8mDVtoLGAz_I,5594
432
432
  tests/apps/test_check_hash.py,sha256=MuZslW2DDCxHKEo6-PiL7hnbxGuZRRYf6HOh3ZQv1qQ,1761
@@ -584,7 +584,7 @@ tests/inferers/test_slice_inferer.py,sha256=kzaJjjTnf2rAiR75l8A_J-Kie4NaLj2bogi-
584
584
  tests/inferers/test_sliding_window_inference.py,sha256=6DiCbVhsGVbicepb6rJ-9ThFY3YToRb4E5qh8mJew5I,15529
585
585
  tests/inferers/test_sliding_window_splitter.py,sha256=LXCqtyMx8D2Ps29EeoiEZTBsBsTYN6H4pBTMwT8Ru0I,9620
586
586
  tests/inferers/test_wsi_sliding_window_splitter.py,sha256=Y0d1Er4kOljfZ79pdd2U2I59M6l3xYuvfvEL0T_wIw8,8434
587
- tests/inferers/test_zarr_avg_merger.py,sha256=CRC_lzwzafOfV3RP0DvuNorQiEnIV0fjMqvHjgFhIbQ,10594
587
+ tests/inferers/test_zarr_avg_merger.py,sha256=o4civt2BgOzI2P2KFD5LVLlw3AVsygXVbgild-fd4pM,15421
588
588
  tests/integration/__init__.py,sha256=s9djSd6kvViPnFvMR11Dgd30Lv4oY6FaPJr4ZZJZLq0,573
589
589
  tests/integration/test_auto3dseg_ensemble.py,sha256=CIdgRSNX1VBfSmSvx_8HgsIfFsJpoLAC5sg8_HrRP_c,7570
590
590
  tests/integration/test_auto3dseg_hpo.py,sha256=J5Us-7iVE5UFbbsZdzNVcvPPQENTlPFarVsSt7KR3Yo,7286
@@ -592,7 +592,7 @@ tests/integration/test_deepedit_interaction.py,sha256=tmryp1cP_QlI_tgguZybRZc7-F
592
592
  tests/integration/test_hovernet_nuclear_type_post_processingd.py,sha256=yTRmYdQBXEMMmXJjPDBPMxPSkLWj2U3bdRhaAfDXrpE,2661
593
593
  tests/integration/test_integration_autorunner.py,sha256=tDK1XkMZp4hehfuzMr2LQIgavP36L_vkFcOcI1Z68Lk,7571
594
594
  tests/integration/test_integration_bundle_run.py,sha256=uO87WnnG3EYnAxhudpfHy7fyxHNNzifFTw2rrMm_6XU,10734
595
- tests/integration/test_integration_classification_2d.py,sha256=psUvLWNtndkPkgc14YCKqvVQJ9oS1EBdxpg3dOqoF7E,11373
595
+ tests/integration/test_integration_classification_2d.py,sha256=4NT_dkty3cpSvzPGcz9l4_e7uhAsWOwNEsXqz0XEc5c,11373
596
596
  tests/integration/test_integration_determinism.py,sha256=AiSBXHcPwDtKRbt_lejI-IDDkYtDWccMkNVoHuyrtU0,3172
597
597
  tests/integration/test_integration_fast_train.py,sha256=WxEIJV52F0Cf2wmGlIQDiVs1m2QZrvxmta_UAsa0OCI,9736
598
598
  tests/integration/test_integration_gpu_customization.py,sha256=z-w6iBaY72LEi8TBVxZuzvsEBgBecZAP2YPwl6KFUhA,5547
@@ -605,7 +605,7 @@ tests/integration/test_integration_stn.py,sha256=1bwzCn8X-1xjV-SGalOtlpRPLFnYpDG
605
605
  tests/integration/test_integration_unet_2d.py,sha256=rMOCG7eYt3jrCjG5HXCfTdF-XnCvyO1X631H7l-F1w4,2376
606
606
  tests/integration/test_integration_workers.py,sha256=bSHRXskT-FSRXg5GGj30mIYRPgG_wtVWfcc11XwpsEE,2195
607
607
  tests/integration/test_integration_workflows.py,sha256=B3INF2PzXwggxxEHGCaXGH754htlsvJbU7Dw1J73Sg0,13971
608
- tests/integration/test_integration_workflows_adversarial.py,sha256=q0QvEOGf97z0MKyoqHY3iwTP3jsk9NHiSwGtiAaNhPo,6375
608
+ tests/integration/test_integration_workflows_adversarial.py,sha256=6PAjwQHePPmL5eW7RpSRVtYFvWD5n-vOLhi3a9S7sJc,6375
609
609
  tests/integration/test_integration_workflows_gan.py,sha256=42cSwfIgXHmXqBF5a5tnWJV5NT4nfJzn2WSw6GguCRY,5496
610
610
  tests/integration/test_loader_semaphore.py,sha256=-Fk4qRA6Up1Lf2uK79Y8WRmDIlOPJEU01kb-3cRX0aM,1195
611
611
  tests/integration/test_mapping_filed.py,sha256=19C_tQ5YvYI0b8v-QsHF1sWDymq5D0chKoe86JICREo,4813
@@ -1189,7 +1189,7 @@ tests/visualize/test_vis_gradcam.py,sha256=WpA-pvTB75eZs7JoIc5qyvOV9PwgkzWI8-Vow
1189
1189
  tests/visualize/utils/__init__.py,sha256=s9djSd6kvViPnFvMR11Dgd30Lv4oY6FaPJr4ZZJZLq0,573
1190
1190
  tests/visualize/utils/test_blend_images.py,sha256=RVs2p_8RWQDfhLHDNNtZaMig27v8o0km7XxNa-zWjKE,2274
1191
1191
  tests/visualize/utils/test_matshow3d.py,sha256=wXYj77L5Jvnp0f6DvL1rsi_-YlCxS0HJ9hiPmrbpuP8,5021
1192
- monai_weekly-1.5.dev2522.dist-info/METADATA,sha256=SECyXqQSdsULPcpimKHFcaPJko0nMWSVYjg31Za4OHU,13152
1193
- monai_weekly-1.5.dev2522.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1194
- monai_weekly-1.5.dev2522.dist-info/top_level.txt,sha256=hn2Y6P9xBf2R8faMeVMHhPMvrdDKxMsIOwMDYI0yTjs,12
1195
- monai_weekly-1.5.dev2522.dist-info/RECORD,,
1192
+ monai_weekly-1.6.dev2524.dist-info/METADATA,sha256=B9GjloAyVPFRuOtOEfOkjrECaE6O6Ij2c-a4sja7jmA,13285
1193
+ monai_weekly-1.6.dev2524.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1194
+ monai_weekly-1.6.dev2524.dist-info/top_level.txt,sha256=hn2Y6P9xBf2R8faMeVMHhPMvrdDKxMsIOwMDYI0yTjs,12
1195
+ monai_weekly-1.6.dev2524.dist-info/RECORD,,
@@ -24,6 +24,7 @@ from tests.test_utils import assert_allclose
24
24
 
25
25
  np.seterr(divide="ignore", invalid="ignore")
26
26
  zarr, has_zarr = optional_import("zarr")
27
+ print(version_geq(get_package_version("zarr"), "3.0.0"))
27
28
  if has_zarr:
28
29
  if version_geq(get_package_version("zarr"), "3.0.0"):
29
30
  directory_store = zarr.storage.LocalStore("test.zarr")
@@ -200,9 +201,20 @@ TEST_CASE_12_CHUNKS = [
200
201
  TENSOR_4x4,
201
202
  ]
202
203
 
203
- # test for LZ4 compressor
204
+ # Define zarr v3 codec configurations with proper bytes codec
205
+ ZARR_V3_LZ4_CODECS = [{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "lz4"}}]
206
+
207
+ ZARR_V3_PICKLE_CODECS = [{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zstd"}}]
208
+
209
+ ZARR_V3_LZMA_CODECS = [{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zlib"}}]
210
+
211
+ # test for LZ4 compressor (zarr v2) or codecs (zarr v3)
204
212
  TEST_CASE_13_COMPRESSOR_LZ4 = [
205
- dict(merged_shape=TENSOR_4x4.shape, compressor="LZ4"),
213
+ (
214
+ dict(merged_shape=TENSOR_4x4.shape, compressor="LZ4")
215
+ if not version_geq(get_package_version("zarr"), "3.0.0")
216
+ else dict(merged_shape=TENSOR_4x4.shape, codecs=ZARR_V3_LZ4_CODECS)
217
+ ),
206
218
  [
207
219
  (TENSOR_4x4[..., :2, :2], (0, 0)),
208
220
  (TENSOR_4x4[..., :2, 2:], (0, 2)),
@@ -212,9 +224,13 @@ TEST_CASE_13_COMPRESSOR_LZ4 = [
212
224
  TENSOR_4x4,
213
225
  ]
214
226
 
215
- # test for pickle compressor
227
+ # test for pickle compressor (zarr v2) or codecs (zarr v3)
216
228
  TEST_CASE_14_COMPRESSOR_PICKLE = [
217
- dict(merged_shape=TENSOR_4x4.shape, compressor="Pickle"),
229
+ (
230
+ dict(merged_shape=TENSOR_4x4.shape, compressor="Pickle")
231
+ if not version_geq(get_package_version("zarr"), "3.0.0")
232
+ else dict(merged_shape=TENSOR_4x4.shape, codecs=ZARR_V3_PICKLE_CODECS)
233
+ ),
218
234
  [
219
235
  (TENSOR_4x4[..., :2, :2], (0, 0)),
220
236
  (TENSOR_4x4[..., :2, 2:], (0, 2)),
@@ -224,9 +240,13 @@ TEST_CASE_14_COMPRESSOR_PICKLE = [
224
240
  TENSOR_4x4,
225
241
  ]
226
242
 
227
- # test for LZMA compressor
243
+ # test for LZMA compressor (zarr v2) or codecs (zarr v3)
228
244
  TEST_CASE_15_COMPRESSOR_LZMA = [
229
- dict(merged_shape=TENSOR_4x4.shape, compressor="LZMA"),
245
+ (
246
+ dict(merged_shape=TENSOR_4x4.shape, compressor="LZMA")
247
+ if not version_geq(get_package_version("zarr"), "3.0.0")
248
+ else dict(merged_shape=TENSOR_4x4.shape, codecs=ZARR_V3_LZMA_CODECS)
249
+ ),
230
250
  [
231
251
  (TENSOR_4x4[..., :2, :2], (0, 0)),
232
252
  (TENSOR_4x4[..., :2, 2:], (0, 2)),
@@ -260,6 +280,48 @@ TEST_CASE_17_WITHOUT_LOCK = [
260
280
  TENSOR_4x4,
261
281
  ]
262
282
 
283
+ # test with codecs for zarr v3
284
+ TEST_CASE_18_CODECS = [
285
+ dict(merged_shape=TENSOR_4x4.shape, codecs=ZARR_V3_LZ4_CODECS),
286
+ [
287
+ (TENSOR_4x4[..., :2, :2], (0, 0)),
288
+ (TENSOR_4x4[..., :2, 2:], (0, 2)),
289
+ (TENSOR_4x4[..., 2:, :2], (2, 0)),
290
+ (TENSOR_4x4[..., 2:, 2:], (2, 2)),
291
+ ],
292
+ TENSOR_4x4,
293
+ ]
294
+
295
+ # test with value_codecs for zarr v3
296
+ TEST_CASE_19_VALUE_CODECS = [
297
+ dict(
298
+ merged_shape=TENSOR_4x4.shape,
299
+ value_codecs=[{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zstd"}}],
300
+ ),
301
+ [
302
+ (TENSOR_4x4[..., :2, :2], (0, 0)),
303
+ (TENSOR_4x4[..., :2, 2:], (0, 2)),
304
+ (TENSOR_4x4[..., 2:, :2], (2, 0)),
305
+ (TENSOR_4x4[..., 2:, 2:], (2, 2)),
306
+ ],
307
+ TENSOR_4x4,
308
+ ]
309
+
310
+ # test with count_codecs for zarr v3
311
+ TEST_CASE_20_COUNT_CODECS = [
312
+ dict(
313
+ merged_shape=TENSOR_4x4.shape,
314
+ count_codecs=[{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zlib"}}],
315
+ ),
316
+ [
317
+ (TENSOR_4x4[..., :2, :2], (0, 0)),
318
+ (TENSOR_4x4[..., :2, 2:], (0, 2)),
319
+ (TENSOR_4x4[..., 2:, :2], (2, 0)),
320
+ (TENSOR_4x4[..., 2:, 2:], (2, 2)),
321
+ ],
322
+ TENSOR_4x4,
323
+ ]
324
+
263
325
  ALL_TESTS = [
264
326
  TEST_CASE_0_DEFAULT_DTYPE,
265
327
  TEST_CASE_1_DEFAULT_DTYPE,
@@ -276,11 +338,15 @@ ALL_TESTS = [
276
338
  TEST_CASE_12_CHUNKS,
277
339
  TEST_CASE_16_WITH_LOCK,
278
340
  TEST_CASE_17_WITHOUT_LOCK,
341
+ # Add compression/codec tests regardless of zarr version - they're now version-aware
342
+ TEST_CASE_13_COMPRESSOR_LZ4,
343
+ TEST_CASE_14_COMPRESSOR_PICKLE,
344
+ TEST_CASE_15_COMPRESSOR_LZMA,
279
345
  ]
280
346
 
281
- # add compression tests only when using Zarr version before 3.0
282
- if not version_geq(get_package_version("zarr"), "3.0.0"):
283
- ALL_TESTS += [TEST_CASE_13_COMPRESSOR_LZ4, TEST_CASE_14_COMPRESSOR_PICKLE, TEST_CASE_15_COMPRESSOR_LZMA]
347
+ # Add zarr v3 specific codec tests only when using Zarr version 3.0 or later
348
+ if version_geq(get_package_version("zarr"), "3.0.0"):
349
+ ALL_TESTS += [TEST_CASE_18_CODECS, TEST_CASE_19_VALUE_CODECS, TEST_CASE_20_COUNT_CODECS]
284
350
 
285
351
 
286
352
  @unittest.skipUnless(has_zarr and has_numcodecs, "Requires zarr (and numcodecs) packages.)")
@@ -288,16 +354,57 @@ class ZarrAvgMergerTests(unittest.TestCase):
288
354
 
289
355
  @parameterized.expand(ALL_TESTS)
290
356
  def test_zarr_avg_merger_patches(self, arguments, patch_locations, expected):
357
+ is_zarr_v3 = version_geq(get_package_version("zarr"), "3.0.0")
291
358
  codec_reg = numcodecs.registry.codec_registry
292
- if "compressor" in arguments:
293
- if arguments["compressor"] != "default":
359
+
360
+ # Handle compressor/codecs based on zarr version
361
+ if "compressor" in arguments and is_zarr_v3:
362
+ # For zarr v3, convert compressor to codecs
363
+ if arguments["compressor"] != "default" and arguments["compressor"] is not None:
364
+ compressor_name = arguments["compressor"].lower()
365
+ if compressor_name == "lz4":
366
+ arguments["codecs"] = ZARR_V3_LZ4_CODECS
367
+ elif compressor_name == "pickle":
368
+ arguments["codecs"] = ZARR_V3_PICKLE_CODECS
369
+ elif compressor_name == "lzma":
370
+ arguments["codecs"] = ZARR_V3_LZMA_CODECS
371
+ # Remove compressor as it's not supported in zarr v3
372
+ del arguments["compressor"]
373
+ elif "compressor" in arguments and not is_zarr_v3:
374
+ # For zarr v2, use the compressor registry
375
+ if arguments["compressor"] != "default" and arguments["compressor"] is not None:
294
376
  arguments["compressor"] = codec_reg[arguments["compressor"].lower()]()
295
- if "value_compressor" in arguments:
296
- if arguments["value_compressor"] != "default":
377
+
378
+ # Same for value_compressor
379
+ if "value_compressor" in arguments and is_zarr_v3:
380
+ if arguments["value_compressor"] != "default" and arguments["value_compressor"] is not None:
381
+ compressor_name = arguments["value_compressor"].lower()
382
+ if compressor_name == "lz4":
383
+ arguments["value_codecs"] = ZARR_V3_LZ4_CODECS
384
+ elif compressor_name == "pickle":
385
+ arguments["value_codecs"] = ZARR_V3_PICKLE_CODECS
386
+ elif compressor_name == "lzma":
387
+ arguments["value_codecs"] = ZARR_V3_LZMA_CODECS
388
+ del arguments["value_compressor"]
389
+ elif "value_compressor" in arguments and not is_zarr_v3:
390
+ if arguments["value_compressor"] != "default" and arguments["value_compressor"] is not None:
297
391
  arguments["value_compressor"] = codec_reg[arguments["value_compressor"].lower()]()
298
- if "count_compressor" in arguments:
299
- if arguments["count_compressor"] != "default":
392
+
393
+ # Same for count_compressor
394
+ if "count_compressor" in arguments and is_zarr_v3:
395
+ if arguments["count_compressor"] != "default" and arguments["count_compressor"] is not None:
396
+ compressor_name = arguments["count_compressor"].lower()
397
+ if compressor_name == "lz4":
398
+ arguments["count_codecs"] = ZARR_V3_LZ4_CODECS
399
+ elif compressor_name == "pickle":
400
+ arguments["count_codecs"] = ZARR_V3_PICKLE_CODECS
401
+ elif compressor_name == "lzma":
402
+ arguments["count_codecs"] = ZARR_V3_LZMA_CODECS
403
+ del arguments["count_compressor"]
404
+ elif "count_compressor" in arguments and not is_zarr_v3:
405
+ if arguments["count_compressor"] != "default" and arguments["count_compressor"] is not None:
300
406
  arguments["count_compressor"] = codec_reg[arguments["count_compressor"].lower()]()
407
+
301
408
  merger = ZarrAvgMerger(**arguments)
302
409
  for pl in patch_locations:
303
410
  merger.aggregate(pl[0], pl[1])
@@ -320,7 +427,3 @@ class ZarrAvgMergerTests(unittest.TestCase):
320
427
  def test_zarr_avg_merge_none_merged_shape_error(self):
321
428
  with self.assertRaises(ValueError):
322
429
  ZarrAvgMerger(merged_shape=None)
323
-
324
-
325
- if __name__ == "__main__":
326
- unittest.main()
@@ -256,7 +256,7 @@ class IntegrationClassification2D(DistTestCase):
256
256
  # check training properties
257
257
  self.assertTrue(test_integration_value(TASK, key="losses", data=losses, rtol=1e-2))
258
258
  self.assertTrue(test_integration_value(TASK, key="best_metric", data=best_metric, rtol=1e-4))
259
- np.testing.assert_allclose(best_metric_epoch, 4)
259
+ np.testing.assert_allclose(best_metric_epoch, 1)
260
260
  model_file = os.path.join(self.data_dir, "best_metric_model.pth")
261
261
  self.assertTrue(os.path.exists(model_file))
262
262
  # check inference properties
@@ -268,7 +268,7 @@ class IntegrationClassification2D(DistTestCase):
268
268
 
269
269
  def test_training(self):
270
270
  repeated = []
271
- for i in range(1):
271
+ for i in range(2):
272
272
  results = self.train_and_infer(i)
273
273
  repeated.append(results)
274
274
  np.testing.assert_allclose(repeated[0], repeated[1])
@@ -158,7 +158,7 @@ class IntegrationWorkflowsAdversarialTrainer(DistTestCase):
158
158
  set_determinism(seed=None)
159
159
  shutil.rmtree(self.data_dir)
160
160
 
161
- @TimedCall(seconds=200, daemon=False)
161
+ @TimedCall(seconds=300, daemon=False)
162
162
  def test_training(self):
163
163
  torch.manual_seed(0)
164
164