Get calibcant working with the new load_from_config-based pyafm.
[calibcant.git] / calibcant / util.py
1 # Copyright
2
3 """Useful utilites not related to calibration.
4
5 Currently just a framework for consistently saving/loading calibration
6 data.
7 """
8
9 import h5py as _h5py
10
11 from h5config.storage.hdf5 import HDF5_Storage as _HDF5_Storage
12 from h5config.storage.hdf5 import h5_create_group as _h5_create_group
13
14
15 from . import LOG as _LOG
16
17
18 class SaveSpec (object):
19     def __init__(self, item=None, relpath='/', key=None, config=False,
20                  array=False, units=None, deviation=None):
21         self.item = item
22         self.relpath = relpath
23         self.key = key
24         self.config = config
25         self.array = array
26         self.units = units
27         self.deviation = deviation
28
29 def save(filename=None, group='/', specs=tuple()):
30     f = None
31     storage = _HDF5_Storage()
32     try:
33         if isinstance(group, str):
34             f = _h5py.File(filename, 'a')
35             group = _h5_create_group(f, group)
36         for spec in specs:
37             if spec.item is None:
38                 continue
39             cwg = _h5_create_group(group, spec.relpath)
40             if spec.config:
41                 storage.save(config=spec.item, group=cwg)
42                 continue
43             assert spec.units, spec.item
44             try:
45                 del cwg['data']
46             except KeyError:
47                 pass
48             try:
49                 del cwg['units']
50             except KeyError:
51                 pass
52             cwg['data'] = spec.item
53             cwg['units'] = spec.units
54             if spec.deviation is not None:
55                 cwg['standard-deviation'] = spec.deviation
56     finally:
57         if f:
58             f.close()
59
60 def load(filename=None, group='/', specs=tuple()):
61     data = {}
62     f = None
63     storage = _HDF5_Storage()
64     try:
65         if isinstance(group, str):
66             f = _h5py.File(filename, 'a')
67             group = _h5_create_group(f, group)
68         for spec in specs:
69             try:
70                 cwg = group[spec.relpath]
71             except KeyError:
72                 continue
73             d = data
74             for n in spec.key[:-1]:
75                 if n not in d:
76                     d[n] = {}
77                 d = d[n]
78             if spec.config:
79                 d[spec.key[-1]] = spec.config(storage=_HDF5_Storage(group=cwg))
80                 d[spec.key[-1]].load()
81                 continue
82             assert spec.units, spec.key
83             try:
84                 if spec.array:
85                     d[spec.key[-1]] = cwg['data'][...]
86                 else:
87                     d[spec.key[-1]] = float(cwg['data'][...])
88             except KeyError:
89                 continue
90             except TypeError, e:
91                 _LOG.warn('while loading {} from {}: {}'.format(
92                         spec.key, cwg['data'], e))
93                 raise
94             if spec.key[-1] in d:
95                 units_ = cwg['units'][...]
96                 assert units_ == spec.units, (units_, spec.units)
97                 if spec.deviation is not None:
98                     try:
99                         d[spec.deviation] = float(
100                             cwg['standard-deviation'][...])
101                     except KeyError:
102                         pass
103     finally:
104         if f:
105             f.close()
106     return data