@@ -104,11 +104,10 @@ def globals_diff(run1, run2, group=None):
104
104
class Run (object ):
105
105
def __init__ (self ,h5_path ,no_write = False ):
106
106
self .no_write = no_write
107
+ self ._no_group = None
107
108
self .h5_path = h5_path
108
109
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' )
112
111
113
112
try :
114
113
if not self .no_write :
@@ -118,48 +117,65 @@ def __init__(self,h5_path,no_write=False):
118
117
frame = inspect .currentframe ()
119
118
__file__ = frame .f_back .f_globals ['__file__' ]
120
119
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 )
124
121
except KeyError :
125
122
# sys.stderr.write('Warning: to write results, call '
126
123
# 'Run.set_group(groupname), specifying the name of the group '
127
124
# 'you would like to save results to. This normally comes from '
128
125
# 'the filename of your script, but since you\'re in interactive '
129
126
# 'mode, there is no scipt name. Opening in read only mode for '
130
127
# '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 )
131
132
self .no_write = True
132
133
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
+
133
148
def set_group (self , groupname ):
134
149
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
139
155
140
156
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 :
142
158
try :
143
159
return list (h5_file ['data' ]['traces' ].keys ())
144
160
except KeyError :
145
161
return []
146
162
147
163
def get_attrs (self , group ):
148
164
"""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 :
150
166
if not group in h5_file :
151
167
raise Exception ('The group \' %s\' does not exist' % group )
152
168
return get_attributes (h5_file [group ])
153
169
154
170
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 :
156
172
if not name in h5_file ['data' ]['traces' ]:
157
173
raise Exception ('The trace \' %s\' doesn not exist' % name )
158
174
trace = h5_file ['data' ]['traces' ][name ]
159
175
return array (trace ['t' ],dtype = float ),array (trace ['values' ],dtype = float )
160
176
161
177
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 :
163
179
if not group in h5_file ['results' ]:
164
180
raise Exception ('The result group \' %s\' doesn not exist' % group )
165
181
if not name in h5_file ['results' ][group ]:
@@ -169,7 +185,7 @@ def get_result_array(self,group,name):
169
185
def get_result (self , group , name ):
170
186
"""Return 'result' in 'results/group' that was saved by
171
187
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 :
173
189
if not group in h5_file ['results' ]:
174
190
raise Exception ('The result group \' %s\' does not exist' % group )
175
191
if not name in h5_file ['results' ][group ].attrs .keys ():
@@ -288,7 +304,7 @@ def save_result_arrays(self, *args, **kwargs):
288
304
self .save_result_array (name , value , ** kwargs )
289
305
290
306
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 :
292
308
if not 'images' in h5_file :
293
309
raise Exception ('File does not contain any images' )
294
310
if not orientation in h5_file ['images' ]:
@@ -307,13 +323,13 @@ def get_images(self,orientation,label, *images):
307
323
308
324
def get_all_image_labels (self ):
309
325
images_list = {}
310
- with h5py .File (self .h5_path ) as h5_file :
326
+ with h5py .File (self .h5_path , 'r' ) as h5_file :
311
327
for orientation in h5_file ['/images' ].keys ():
312
328
images_list [orientation ] = list (h5_file ['/images' ][orientation ].keys ())
313
329
return images_list
314
330
315
331
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 :
317
333
if not 'images' in h5_file :
318
334
raise Exception ('File does not contain any images' )
319
335
if not orientation in h5_file ['images' ]:
@@ -322,18 +338,18 @@ def get_image_attributes(self, orientation):
322
338
323
339
def get_globals (self ,group = None ):
324
340
if not group :
325
- with h5py .File (self .h5_path ) as h5_file :
341
+ with h5py .File (self .h5_path , 'r' ) as h5_file :
326
342
return dict (h5_file ['globals' ].attrs )
327
343
else :
328
344
try :
329
- with h5py .File (self .h5_path ) as h5_file :
345
+ with h5py .File (self .h5_path , 'r' ) as h5_file :
330
346
return dict (h5_file ['globals' ][group ].attrs )
331
347
except KeyError :
332
348
return {}
333
349
334
350
def get_globals_raw (self , group = None ):
335
351
globals_dict = {}
336
- with h5py .File (self .h5_path ) as h5_file :
352
+ with h5py .File (self .h5_path , 'r' ) as h5_file :
337
353
if group == None :
338
354
for obj in h5_file ['globals' ].values ():
339
355
temp_dict = dict (obj .attrs )
@@ -374,7 +390,7 @@ def append_expansion(name, obj):
374
390
for key , val in temp_dict .items ():
375
391
if val :
376
392
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 :
378
394
h5_file ['globals' ].visititems (append_expansion )
379
395
return expansion_dict
380
396
@@ -385,12 +401,12 @@ def append_units(name, obj):
385
401
temp_dict = dict (obj .attrs )
386
402
for key , val in temp_dict .items ():
387
403
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 :
389
405
h5_file ['globals' ].visititems (append_units )
390
406
return units_dict
391
407
392
408
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 :
394
410
try :
395
411
return list (h5_file ['globals' ].keys ())
396
412
except KeyError :
@@ -401,14 +417,13 @@ def globals_diff(self, other_run, group=None):
401
417
402
418
403
419
class Sequence (Run ):
404
- def __init__ (self ,h5_path ,run_paths ):
420
+ def __init__ (self , h5_path , run_paths , no_write = False ):
405
421
if isinstance (run_paths , pandas .DataFrame ):
406
422
run_paths = run_paths ['filepath' ]
407
423
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' )
412
427
413
428
self .runs = {path : Run (path ,no_write = True ) for path in run_paths }
414
429
@@ -419,9 +434,8 @@ def __init__(self,h5_path,run_paths):
419
434
try :
420
435
__file__ = frame .f_back .f_locals ['__file__' ]
421
436
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 )
425
439
except KeyError :
426
440
sys .stderr .write ('Warning: to write results, call '
427
441
'Sequence.set_group(groupname), specifying the name of the group '
0 commit comments