@@ -58,7 +58,9 @@ def _open_store(
58
58
synchronizer = None ,
59
59
):
60
60
if not os .path .isdir (store_path ) and mode in ("r" , "r+" ):
61
- raise FileNotFoundError (f"Dataset directory not found at { store_path } ." )
61
+ raise FileNotFoundError (
62
+ f"Dataset directory not found at { store_path } ."
63
+ )
62
64
if version != "0.4" :
63
65
_logger .warning (
64
66
"IOHub is only tested against OME-NGFF v0.4. "
@@ -68,10 +70,14 @@ def _open_store(
68
70
else :
69
71
dimension_separator = "/"
70
72
try :
71
- store = zarr .DirectoryStore (store_path , dimension_separator = dimension_separator )
73
+ store = zarr .DirectoryStore (
74
+ store_path , dimension_separator = dimension_separator
75
+ )
72
76
root = zarr .open_group (store , mode = mode , synchronizer = synchronizer )
73
77
except Exception as e :
74
- raise RuntimeError (f"Cannot open Zarr root group at { store_path } " ) from e
78
+ raise RuntimeError (
79
+ f"Cannot open Zarr root group at { store_path } "
80
+ ) from e
75
81
return root
76
82
77
83
@@ -102,7 +108,9 @@ def __init__(
102
108
if channel_names :
103
109
self ._channel_names = channel_names
104
110
elif not parse_meta :
105
- raise ValueError ("Channel names need to be provided or in metadata." )
111
+ raise ValueError (
112
+ "Channel names need to be provided or in metadata."
113
+ )
106
114
if axes :
107
115
self .axes = axes
108
116
self ._group = group
@@ -533,8 +541,12 @@ def _parse_meta(self):
533
541
omero = self .zattrs .get ("omero" )
534
542
if multiscales and omero :
535
543
try :
536
- self .metadata = ImagesMeta (multiscales = multiscales , omero = omero )
537
- self ._channel_names = [c .label for c in self .metadata .omero .channels ]
544
+ self .metadata = ImagesMeta (
545
+ multiscales = multiscales , omero = omero
546
+ )
547
+ self ._channel_names = [
548
+ c .label for c in self .metadata .omero .channels
549
+ ]
538
550
self .axes = self .metadata .multiscales [0 ].axes
539
551
except ValidationError :
540
552
self ._warn_invalid_meta ()
@@ -548,7 +560,9 @@ def dump_meta(self):
548
560
@property
549
561
def _storage_options (self ):
550
562
return {
551
- "compressor" : Blosc (cname = "zstd" , clevel = 1 , shuffle = Blosc .BITSHUFFLE ),
563
+ "compressor" : Blosc (
564
+ cname = "zstd" , clevel = 1 , shuffle = Blosc .BITSHUFFLE
565
+ ),
552
566
"overwrite" : self ._overwrite ,
553
567
}
554
568
@@ -585,7 +599,8 @@ def data(self):
585
599
return self ["0" ]
586
600
except KeyError :
587
601
raise KeyError (
588
- "There is no array named '0' " f"in the group of: { self .array_keys ()} "
602
+ "There is no array named '0' "
603
+ f"in the group of: { self .array_keys ()} "
589
604
)
590
605
591
606
def __getitem__ (self , key : int | str ) -> ImageArray :
@@ -609,7 +624,9 @@ def __setitem__(self, key, value: NDArray):
609
624
"""Write an up-to-5D image with default settings."""
610
625
key = normalize_storage_path (key )
611
626
if not isinstance (value , np .ndarray ):
612
- raise TypeError (f"Value must be a NumPy array. Got type { type (value )} ." )
627
+ raise TypeError (
628
+ f"Value must be a NumPy array. Got type { type (value )} ."
629
+ )
613
630
self .create_image (key , value )
614
631
615
632
def images (self ) -> Generator [tuple [str , ImageArray ]]:
@@ -659,7 +676,9 @@ def create_image(
659
676
if check_shape :
660
677
self ._check_shape (data .shape )
661
678
img_arr = ImageArray (
662
- self ._group .array (name , data , chunks = chunks , ** self ._storage_options )
679
+ self ._group .array (
680
+ name , data , chunks = chunks , ** self ._storage_options
681
+ )
663
682
)
664
683
self ._create_image_meta (img_arr .basename , transform = transform )
665
684
return img_arr
@@ -742,7 +761,8 @@ def _check_shape(self, data_shape: tuple[int]):
742
761
_logger .warning (msg )
743
762
else :
744
763
_logger .info (
745
- "Dataset channel axis is not set. " "Skipping channel shape check."
764
+ "Dataset channel axis is not set. "
765
+ "Skipping channel shape check."
746
766
)
747
767
748
768
def _create_image_meta (
@@ -753,7 +773,9 @@ def _create_image_meta(
753
773
):
754
774
if not transform :
755
775
transform = [TransformationMeta (type = "identity" )]
756
- dataset_meta = DatasetMeta (path = name , coordinate_transformations = transform )
776
+ dataset_meta = DatasetMeta (
777
+ path = name , coordinate_transformations = transform
778
+ )
757
779
if not hasattr (self , "metadata" ):
758
780
self .metadata = ImagesMeta (
759
781
multiscales = [
@@ -762,13 +784,18 @@ def _create_image_meta(
762
784
axes = self .axes ,
763
785
datasets = [dataset_meta ],
764
786
name = name ,
765
- coordinateTransformations = [TransformationMeta (type = "identity" )],
787
+ coordinateTransformations = [
788
+ TransformationMeta (type = "identity" )
789
+ ],
766
790
metadata = extra_meta ,
767
791
)
768
792
],
769
793
omero = self ._omero_meta (id = 0 , name = self ._group .basename ),
770
794
)
771
- elif dataset_meta .path not in self .metadata .multiscales [0 ].get_dataset_paths ():
795
+ elif (
796
+ dataset_meta .path
797
+ not in self .metadata .multiscales [0 ].get_dataset_paths ()
798
+ ):
772
799
self .metadata .multiscales [0 ].datasets .append (dataset_meta )
773
800
self .dump_meta ()
774
801
@@ -781,11 +808,15 @@ def _omero_meta(
781
808
if not clims :
782
809
clims = [None ] * len (self .channel_names )
783
810
channels = []
784
- for i , (channel_name , clim ) in enumerate (zip (self .channel_names , clims )):
811
+ for i , (channel_name , clim ) in enumerate (
812
+ zip (self .channel_names , clims )
813
+ ):
785
814
if i == 0 :
786
815
first_chan = True
787
816
channels .append (
788
- channel_display_settings (channel_name , clim = clim , first_chan = first_chan )
817
+ channel_display_settings (
818
+ channel_name , clim = clim , first_chan = first_chan
819
+ )
789
820
)
790
821
omero_meta = OMEROMeta (
791
822
version = self .version ,
@@ -805,7 +836,8 @@ def _find_axis(self, axis_type):
805
836
def _get_channel_axis (self ):
806
837
if (ch_ax := self ._find_axis ("channel" )) is None :
807
838
raise KeyError (
808
- "Axis 'channel' does not exist. " "Please update `self.axes` first."
839
+ "Axis 'channel' does not exist. "
840
+ "Please update `self.axes` first."
809
841
)
810
842
else :
811
843
return ch_ax
@@ -834,10 +866,14 @@ def append_channel(self, chan_name: str, resize_arrays: bool = True):
834
866
elif ch_ax == len (shape ):
835
867
shape = _pad_shape (tuple (shape ), target = len (shape ) + 1 )
836
868
else :
837
- raise IndexError (f"Cannot infer channel axis for shape { shape } ." )
869
+ raise IndexError (
870
+ f"Cannot infer channel axis for shape { shape } ."
871
+ )
838
872
img .resize (shape )
839
873
if "omero" in self .metadata .model_dump ().keys ():
840
- self .metadata .omero .channels .append (channel_display_settings (chan_name ))
874
+ self .metadata .omero .channels .append (
875
+ channel_display_settings (chan_name )
876
+ )
841
877
self .dump_meta ()
842
878
843
879
def rename_channel (self , old : str , new : str ):
@@ -901,12 +937,18 @@ def initialize_pyramid(self, levels: int) -> None:
901
937
for level in range (1 , levels ):
902
938
factor = 2 ** level
903
939
904
- shape = array .shape [:- 3 ] + _scale_integers (array .shape [- 3 :], factor )
940
+ shape = array .shape [:- 3 ] + _scale_integers (
941
+ array .shape [- 3 :], factor
942
+ )
905
943
906
- chunks = _pad_shape (_scale_integers (array .chunks , factor ), len (shape ))
944
+ chunks = _pad_shape (
945
+ _scale_integers (array .chunks , factor ), len (shape )
946
+ )
907
947
908
948
transforms = deepcopy (
909
- self .metadata .multiscales [0 ].datasets [0 ].coordinate_transformations
949
+ self .metadata .multiscales [0 ]
950
+ .datasets [0 ]
951
+ .coordinate_transformations
910
952
)
911
953
for tr in transforms :
912
954
if tr .type == "scale" :
@@ -928,7 +970,9 @@ def scale(self) -> list[float]:
928
970
highest resolution scale.
929
971
"""
930
972
scale = [1 ] * self .data .ndim
931
- transforms = self .metadata .multiscales [0 ].datasets [0 ].coordinate_transformations
973
+ transforms = (
974
+ self .metadata .multiscales [0 ].datasets [0 ].coordinate_transformations
975
+ )
932
976
for trans in transforms :
933
977
if trans .type == "scale" :
934
978
if len (trans .scale ) != len (scale ):
@@ -946,7 +990,9 @@ def axis_names(self) -> list[str]:
946
990
947
991
Returns lowercase axis names.
948
992
"""
949
- return [axis .name .lower () for axis in self .metadata .multiscales [0 ].axes ]
993
+ return [
994
+ axis .name .lower () for axis in self .metadata .multiscales [0 ].axes
995
+ ]
950
996
951
997
def get_axis_index (self , axis_name : str ) -> int :
952
998
"""
@@ -1021,7 +1067,9 @@ def set_transform(
1021
1067
if image == "*" :
1022
1068
self .metadata .multiscales [0 ].coordinate_transformations = transform
1023
1069
elif image in self :
1024
- for i , dataset_meta in enumerate (self .metadata .multiscales [0 ].datasets ):
1070
+ for i , dataset_meta in enumerate (
1071
+ self .metadata .multiscales [0 ].datasets
1072
+ ):
1025
1073
if dataset_meta .path == image :
1026
1074
self .metadata .multiscales [0 ].datasets [i ] = DatasetMeta (
1027
1075
path = image , coordinate_transformations = transform
@@ -1050,7 +1098,9 @@ def set_scale(
1050
1098
Value of the new scale.
1051
1099
"""
1052
1100
if len (self .metadata .multiscales ) > 1 :
1053
- raise NotImplementedError ("Cannot set scale for multi-resolution images." )
1101
+ raise NotImplementedError (
1102
+ "Cannot set scale for multi-resolution images."
1103
+ )
1054
1104
1055
1105
if new_scale <= 0 :
1056
1106
raise ValueError ("New scale must be positive." )
@@ -1065,7 +1115,9 @@ def set_scale(
1065
1115
self .zattrs ["iohub" ] = iohub_dict
1066
1116
1067
1117
# Update scale while preserving existing transforms
1068
- transforms = self .metadata .multiscales [0 ].datasets [0 ].coordinate_transformations
1118
+ transforms = (
1119
+ self .metadata .multiscales [0 ].datasets [0 ].coordinate_transformations
1120
+ )
1069
1121
# Replace default identity transform with scale
1070
1122
if len (transforms ) == 1 and transforms [0 ].type == "identity" :
1071
1123
transforms = [TransformationMeta (type = "scale" , scale = [1 ] * 5 )]
@@ -1191,7 +1243,9 @@ def _parse_meta(self):
1191
1243
1192
1244
def dump_meta (self ):
1193
1245
"""Dumps metadata JSON to the `.zattrs` file."""
1194
- self .zattrs .update ({"well" : self .metadata .model_dump (** TO_DICT_SETTINGS )})
1246
+ self .zattrs .update (
1247
+ {"well" : self .metadata .model_dump (** TO_DICT_SETTINGS )}
1248
+ )
1195
1249
1196
1250
def __getitem__ (self , key : str ):
1197
1251
"""Get a position member of the well.
@@ -1372,7 +1426,8 @@ def from_positions(
1372
1426
for name , src_pos in positions .items ():
1373
1427
if not isinstance (src_pos , Position ):
1374
1428
raise TypeError (
1375
- f"Expected item type { type (Position )} , " f"got { type (src_pos )} "
1429
+ f"Expected item type { type (Position )} , "
1430
+ f"got { type (src_pos )} "
1376
1431
)
1377
1432
name = normalize_storage_path (name )
1378
1433
if name in plate .zgroup :
@@ -1455,7 +1510,9 @@ def dump_meta(self, field_count: bool = False):
1455
1510
"""
1456
1511
if field_count :
1457
1512
self .metadata .field_count = len (list (self .positions ()))
1458
- self .zattrs .update ({"plate" : self .metadata .model_dump (** TO_DICT_SETTINGS )})
1513
+ self .zattrs .update (
1514
+ {"plate" : self .metadata .model_dump (** TO_DICT_SETTINGS )}
1515
+ )
1459
1516
1460
1517
def _auto_idx (
1461
1518
self ,
@@ -1543,7 +1600,9 @@ def create_well(
1543
1600
self .metadata .wells .append (well_index_meta )
1544
1601
# create new row if needed
1545
1602
if row_name not in self :
1546
- row_grp = self .zgroup .create_group (row_meta .name , overwrite = self ._overwrite )
1603
+ row_grp = self .zgroup .create_group (
1604
+ row_meta .name , overwrite = self ._overwrite
1605
+ )
1547
1606
if row_meta not in self .metadata .rows :
1548
1607
self .metadata .rows .append (row_meta )
1549
1608
else :
@@ -1666,9 +1725,9 @@ def rename_well(
1666
1725
self .zgroup .move (old , new )
1667
1726
1668
1727
# update well metadata
1669
- old_well_index = [well_name . path for well_name in self . metadata . wells ]. index (
1670
- old
1671
- )
1728
+ old_well_index = [
1729
+ well_name . path for well_name in self . metadata . wells
1730
+ ]. index ( old )
1672
1731
self .metadata .wells [old_well_index ].path = new
1673
1732
new_well_names = [well .path for well in self .metadata .wells ]
1674
1733
0 commit comments