@@ -43,49 +43,54 @@ def __init__(self):
4343 if zarr is None :
4444 self .UseReader = False
4545 msg = 'MIDAS_Zarr Reader skipped because zarr module is not installed.'
46- G2fil .ImportErrorMsg (msg ,{'MIDAS Zarr importer' :['zarr=2.18.* ' ]})
46+ G2fil .ImportErrorMsg (msg ,{'MIDAS Zarr importer' :['zarr' ]})
4747 super (self .__class__ ,self ).__init__ ( # fancy way to self-reference
4848 extensionlist = ('.zarr.zip' ,),strictExtension = True ,
4949 formatName = 'MIDAS zarr' ,longFormatName = 'MIDAS zarr intergrated scans' )
5050 self .scriptable = True
5151 #self.Iparm = {} #only filled for EDS data
5252
53+ def zarrOpen (self ,filename ):
54+ import asyncio
55+ async def zarrAsyncOpen (filename ):
56+ fp = store = None
57+ try :
58+ fp = zarr .open (filename , mode = 'r' )
59+ return fp ,store
60+ except :
61+ # workaround for zarr 3.0.x where "auto discover" is
62+ # not yet implemented
63+ # (https://github.com/zarr-developers/zarr-python/issues/2922)
64+ try :
65+ store = await zarr .storage .ZipStore .open (filename , mode = "r" )
66+ fp = zarr .open_group (store , mode = 'r' )
67+ return fp ,store
68+ except FileNotFoundError as msg :
69+ print (f'cannot read as zarr file: { filename } ' )
70+ except Exception as msg :
71+ self .errors = f'Exception from zarr module (version={ zarr .__version__ } ):'
72+ self .errors += '\n \t ' + str (msg )
73+ return None ,None
74+ fp ,store = asyncio .run (zarrAsyncOpen (filename ))
75+ return fp ,store
76+
5377 def ContentsValidator (self , filename ):
5478 '''Test if valid by seeing if the zarr module recognizes the file. Then
5579 get file type (currently Midas only)
5680 '''
57- fp = None
58- try :
59- fp = zarr .open (filename , mode = 'r' )
60- if all ([(i in fp ) for i in self .midassections ]): # are expected MIDAS sections present?
61- self .mode = 'midas'
62- return True # must be present for Midas output
63- except FileNotFoundError as msg :
81+ fp , store = self .zarrOpen (filename )
82+ if not fp :
6483 self .errors = f'Exception from zarr module (version={ zarr .__version__ } ):'
6584 self .errors += '\n \t ' + str (msg )
66- if os .path .exists (filename ) and zarr .__version__ .startswith ('3.0' ):
67- self .errors += '\n \n *** This is likely due to incompatibility between MIDAS and zarr v3.x'
68- if GSASIIpath .condaTest ():
69- self .errors += '\n *** please use "conda install zarr=2.18" to fix this'
70- print ('preparing to remove incompatible zarr package...' )
71- try :
72- import conda .cli .python_api
73- (out , err , rc ) = conda .cli .python_api .run_command (
74- conda .cli .python_api .Commands .REMOVE ,'zarr' )
75- self .errors += '\n *** zarr has been removed. Restarting GSAS-II and reinstalling'
76- self .errors += '\n *** zarr (using the Imports/Show Importer Errors) should fix this.'
77- except Exception as msg :
78- print ('remove failed\n ' ,msg )
79- print ('...done' )
80- else :
81- self .errors += '\n *** please use command pip install "zarr=2.18.*" to fix this'
82- except Exception as msg :
83- self .errors = f'Exception from zarr module (version={ zarr .__version__ } ):'
84- self .errors += '\n \t ' + str (msg )
85- return False
86- finally :
87- del fp
88- return False
85+ self .errors += '\n Please report this'
86+ elif all ([(i in fp ) for i in self .midassections ]): # are expected MIDAS sections present?
87+ self .mode = 'midas'
88+ del fp , store
89+ return True # Passes test for Midas output
90+ #else: # test here for any other formats that might use zarr
91+ # pass
92+ del fp , store
93+ return
8994
9095 def Reader (self , filename , ParentFrame = None , ** kwarg ):
9196 '''Scan file for sections needed by defined file types (currently
@@ -106,24 +111,21 @@ def Reader(self, filename, ParentFrame=None, **kwarg):
106111 self .blknum = 0 # image counter for multi-image files
107112 # check if this is a valid MIDAS file
108113 if self .mode is None :
109- try :
110- fp = zarr .open (filename , 'r' )
111- # are expected MIDAS sections present?
112- if all ([(i in fp ) for i in self .midassections ]):
113- self .mode = 'midas'
114- else :
115- print (f'{ filename } is not a MIDAS file' )
116- return False
117- except :
118- print (f'cannot read as zarr file: { filename } ' )
119- return False
120- finally :
121- del fp
122-
114+ fp , store = self .zarrOpen (filename )
115+ # are expected MIDAS sections present?
116+ if all ([(i in fp ) for i in self .midassections ]):
117+ self .mode = 'midas'
118+ else :
119+ print (f'{ filename } is not a MIDAS file' )
120+ del fp , store
121+ #else: # test here for any other formats that might use zarr
122+ # pass
123+
123124 if self .mode == 'midas' :
124- return self .readMidas (filename , fpbuffer )
125-
126- return False
125+ res = self .readMidas (filename , fpbuffer )
126+ else :
127+ res = False
128+ return res
127129
128130 def readMidas (self , filename , fpbuffer = {}):
129131 '''Read zarr file produced by Midas
@@ -143,7 +145,7 @@ def readMidas(self, filename, fpbuffer={}):
143145 if doread : # read into buffer
144146 print ('Caching MIDAS zarr contents...' )
145147 try :
146- fp = zarr . open (filename , 'r' )
148+ fp , store = self . zarrOpen (filename )
147149 fpbuffer ['REtaMap' ] = np .array (fp ['REtaMap' ]) # 4 x Nbins x Nazimuth
148150 # [0]: radius; [1] 2theta; [2] eta; [3] bin area
149151 # tabulate integrated intensities image & eta
@@ -176,7 +178,7 @@ def readMidas(self, filename, fpbuffer={}):
176178 # 2thetas: fpbuffer['REtaMap'][1][:,iAzm][unmasked[iAzm]]
177179 fpbuffer ['2Read' ] = [(i % Nazim ,i // Nazim ) for i in sel if i % Nazim in mAzm ]
178180 # xfrom Zarr dict into a native dict
179- self .MIDASinstprm = {i :j [ 0 ] for i , j in fp ['InstrumentParameters' ]. items () }
181+ self .MIDASinstprm = {i :fp [ 'InstrumentParameters' ][ i ][ 0 ] for i in fp ['InstrumentParameters' ]}
180182 # change a few keys
181183 for key ,newkey in [('Polariz' ,'Polariz.' ),('SH_L' ,'SH/L' )]:
182184 if key in self .MIDASinstprm :
@@ -186,7 +188,7 @@ def readMidas(self, filename, fpbuffer={}):
186188 print ('cannot open file ' + filename )
187189 return False
188190 finally :
189- del fp
191+ del fp , store
190192 # get overriding sample & instrument parameters
191193 self .MIDASsampleprm = {}
192194 samplefile = os .path .splitext (filename )[0 ] + '.samprm'
0 commit comments