@@ -104,11 +104,10 @@ def globals_diff(run1, run2, group=None):
104104class Run (object ):
105105 def __init__ (self ,h5_path ,no_write = False ):
106106 self .no_write = no_write
107+ self ._no_group = None
107108 self .h5_path = h5_path
108109 if not self .no_write :
109- with h5py .File (h5_path ) as h5_file :
110- if not 'results' in h5_file :
111- h5_file .create_group ('results' )
110+ self ._create_group_if_not_exists (h5_path , '/' , 'results' )
112111
113112 try :
114113 if not self .no_write :
@@ -118,48 +117,65 @@ def __init__(self,h5_path,no_write=False):
118117 frame = inspect .currentframe ()
119118 __file__ = frame .f_back .f_globals ['__file__' ]
120119 self .group = os .path .basename (__file__ ).split ('.py' )[0 ]
121- with h5py .File (h5_path ) as h5_file :
122- if not self .group in h5_file ['results' ]:
123- h5_file ['results' ].create_group (self .group )
120+ self ._create_group_if_not_exists (h5_path , 'results' , self .group )
124121 except KeyError :
125122 # sys.stderr.write('Warning: to write results, call '
126123 # 'Run.set_group(groupname), specifying the name of the group '
127124 # 'you would like to save results to. This normally comes from '
128125 # 'the filename of your script, but since you\'re in interactive '
129126 # 'mode, there is no scipt name. Opening in read only mode for '
130127 # 'the moment.\n')
128+
129+ # Backup the value of self.no_write for restoration once the group
130+ # is set
131+ self ._no_group = (True , self .no_write )
131132 self .no_write = True
132133
134+ def _create_group_if_not_exists (self , h5_path , location , groupname ):
135+ """Creates a group in the HDF5 file at `location` if it does not exist.
136+
137+ Only opens the h5 file in write mode if a group must be created.
138+ This ensures the last modified time of the file is only updated if
139+ the file is actually written to."""
140+ create_group = False
141+ with h5py .File (h5_path , 'r' ) as h5_file :
142+ if not groupname in h5_file [location ]:
143+ create_group = True
144+ if create_group :
145+ with h5py .File (h5_path , 'r+' ) as h5_file :
146+ h5_file [location ].create_group (groupname )
147+
133148 def set_group (self , groupname ):
134149 self .group = groupname
135- with h5py .File (self .h5_path ) as h5_file :
136- if not self .group in h5_file ['results' ]:
137- h5_file ['results' ].create_group (self .group )
138- self .no_write = False
150+ self ._create_group_if_not_exists (self .h5_path , '/' , 'results' )
151+ # restore no_write attribute now we have set the group
152+ if self ._no_group is not None and self ._no_group [0 ]:
153+ self .no_write = self ._no_group [1 ]
154+ self ._no_group = None
139155
140156 def trace_names (self ):
141- with h5py .File (self .h5_path ) as h5_file :
157+ with h5py .File (self .h5_path , 'r' ) as h5_file :
142158 try :
143159 return list (h5_file ['data' ]['traces' ].keys ())
144160 except KeyError :
145161 return []
146162
147163 def get_attrs (self , group ):
148164 """Returns all attributes of the specified group as a dictionary."""
149- with h5py .File (self .h5_path ) as h5_file :
165+ with h5py .File (self .h5_path , 'r' ) as h5_file :
150166 if not group in h5_file :
151167 raise Exception ('The group \' %s\' does not exist' % group )
152168 return get_attributes (h5_file [group ])
153169
154170 def get_trace (self ,name ):
155- with h5py .File (self .h5_path ) as h5_file :
171+ with h5py .File (self .h5_path , 'r' ) as h5_file :
156172 if not name in h5_file ['data' ]['traces' ]:
157173 raise Exception ('The trace \' %s\' doesn not exist' % name )
158174 trace = h5_file ['data' ]['traces' ][name ]
159175 return array (trace ['t' ],dtype = float ),array (trace ['values' ],dtype = float )
160176
161177 def get_result_array (self ,group ,name ):
162- with h5py .File (self .h5_path ) as h5_file :
178+ with h5py .File (self .h5_path , 'r' ) as h5_file :
163179 if not group in h5_file ['results' ]:
164180 raise Exception ('The result group \' %s\' doesn not exist' % group )
165181 if not name in h5_file ['results' ][group ]:
@@ -169,7 +185,7 @@ def get_result_array(self,group,name):
169185 def get_result (self , group , name ):
170186 """Return 'result' in 'results/group' that was saved by
171187 the save_result() method."""
172- with h5py .File (self .h5_path ) as h5_file :
188+ with h5py .File (self .h5_path , 'r' ) as h5_file :
173189 if not group in h5_file ['results' ]:
174190 raise Exception ('The result group \' %s\' does not exist' % group )
175191 if not name in h5_file ['results' ][group ].attrs .keys ():
@@ -288,7 +304,7 @@ def save_result_arrays(self, *args, **kwargs):
288304 self .save_result_array (name , value , ** kwargs )
289305
290306 def get_image (self ,orientation ,label ,image ):
291- with h5py .File (self .h5_path ) as h5_file :
307+ with h5py .File (self .h5_path , 'r' ) as h5_file :
292308 if not 'images' in h5_file :
293309 raise Exception ('File does not contain any images' )
294310 if not orientation in h5_file ['images' ]:
@@ -307,13 +323,13 @@ def get_images(self,orientation,label, *images):
307323
308324 def get_all_image_labels (self ):
309325 images_list = {}
310- with h5py .File (self .h5_path ) as h5_file :
326+ with h5py .File (self .h5_path , 'r' ) as h5_file :
311327 for orientation in h5_file ['/images' ].keys ():
312328 images_list [orientation ] = list (h5_file ['/images' ][orientation ].keys ())
313329 return images_list
314330
315331 def get_image_attributes (self , orientation ):
316- with h5py .File (self .h5_path ) as h5_file :
332+ with h5py .File (self .h5_path , 'r' ) as h5_file :
317333 if not 'images' in h5_file :
318334 raise Exception ('File does not contain any images' )
319335 if not orientation in h5_file ['images' ]:
@@ -322,18 +338,18 @@ def get_image_attributes(self, orientation):
322338
323339 def get_globals (self ,group = None ):
324340 if not group :
325- with h5py .File (self .h5_path ) as h5_file :
341+ with h5py .File (self .h5_path , 'r' ) as h5_file :
326342 return dict (h5_file ['globals' ].attrs )
327343 else :
328344 try :
329- with h5py .File (self .h5_path ) as h5_file :
345+ with h5py .File (self .h5_path , 'r' ) as h5_file :
330346 return dict (h5_file ['globals' ][group ].attrs )
331347 except KeyError :
332348 return {}
333349
334350 def get_globals_raw (self , group = None ):
335351 globals_dict = {}
336- with h5py .File (self .h5_path ) as h5_file :
352+ with h5py .File (self .h5_path , 'r' ) as h5_file :
337353 if group == None :
338354 for obj in h5_file ['globals' ].values ():
339355 temp_dict = dict (obj .attrs )
@@ -374,7 +390,7 @@ def append_expansion(name, obj):
374390 for key , val in temp_dict .items ():
375391 if val :
376392 expansion_dict [key ] = val
377- with h5py .File (self .h5_path ) as h5_file :
393+ with h5py .File (self .h5_path , 'r' ) as h5_file :
378394 h5_file ['globals' ].visititems (append_expansion )
379395 return expansion_dict
380396
@@ -385,12 +401,12 @@ def append_units(name, obj):
385401 temp_dict = dict (obj .attrs )
386402 for key , val in temp_dict .items ():
387403 units_dict [key ] = val
388- with h5py .File (self .h5_path ) as h5_file :
404+ with h5py .File (self .h5_path , 'r' ) as h5_file :
389405 h5_file ['globals' ].visititems (append_units )
390406 return units_dict
391407
392408 def globals_groups (self ):
393- with h5py .File (self .h5_path ) as h5_file :
409+ with h5py .File (self .h5_path , 'r' ) as h5_file :
394410 try :
395411 return list (h5_file ['globals' ].keys ())
396412 except KeyError :
@@ -401,14 +417,13 @@ def globals_diff(self, other_run, group=None):
401417
402418
403419class Sequence (Run ):
404- def __init__ (self ,h5_path ,run_paths ):
420+ def __init__ (self , h5_path , run_paths , no_write = False ):
405421 if isinstance (run_paths , pandas .DataFrame ):
406422 run_paths = run_paths ['filepath' ]
407423 self .h5_path = h5_path
408- self .no_write = False
409- with h5py .File (h5_path ) as h5_file :
410- if not 'results' in h5_file :
411- h5_file .create_group ('results' )
424+ self .no_write = no_write
425+ if not self .no_write :
426+ self ._create_group_if_not_exists (h5_path , '/' , 'results' )
412427
413428 self .runs = {path : Run (path ,no_write = True ) for path in run_paths }
414429
@@ -419,9 +434,8 @@ def __init__(self,h5_path,run_paths):
419434 try :
420435 __file__ = frame .f_back .f_locals ['__file__' ]
421436 self .group = os .path .basename (__file__ ).split ('.py' )[0 ]
422- with h5py .File (h5_path ) as h5_file :
423- if not self .group in h5_file ['results' ]:
424- h5_file ['results' ].create_group (self .group )
437+ if not self .no_write :
438+ self ._create_group_if_not_exists (h5_path , 'results' , self .group )
425439 except KeyError :
426440 sys .stderr .write ('Warning: to write results, call '
427441 'Sequence.set_group(groupname), specifying the name of the group '
0 commit comments