pytesprocess 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytesprocess/__init__.py +9 -0
- pytesprocess/_version.py +2 -0
- pytesprocess/cli/__init__.py +1 -0
- pytesprocess/cli/commands/__init__.py +5 -0
- pytesprocess/cli/commands/event.py +66 -0
- pytesprocess/cli/commands/filter.py +17 -0
- pytesprocess/cli/commands/ivsweep.py +29 -0
- pytesprocess/cli/common.py +86 -0
- pytesprocess/cli/main.py +81 -0
- pytesprocess/config/__init__.py +4 -0
- pytesprocess/config/loader.py +94 -0
- pytesprocess/config/manager.py +297 -0
- pytesprocess/config/resolvers/__init__.py +5 -0
- pytesprocess/config/resolvers/common.py +56 -0
- pytesprocess/config/resolvers/feature.py +293 -0
- pytesprocess/config/resolvers/salting.py +86 -0
- pytesprocess/config/resolvers/trigger.py +84 -0
- pytesprocess/config/selectors.py +108 -0
- pytesprocess/config/validation.py +314 -0
- pytesprocess/config/warnings.py +2 -0
- pytesprocess/core/__init__.py +10 -0
- pytesprocess/core/algorithms.py +1455 -0
- pytesprocess/core/didv.py +1648 -0
- pytesprocess/core/eventbuilder.py +495 -0
- pytesprocess/core/filterbuilder.py +81 -0
- pytesprocess/core/filterdata.py +1849 -0
- pytesprocess/core/ivsweep.py +2072 -0
- pytesprocess/core/noise.py +923 -0
- pytesprocess/core/noisemodel.py +1408 -0
- pytesprocess/core/oftrigger.py +1035 -0
- pytesprocess/core/template.py +450 -0
- pytesprocess/process/__init__.py +6 -0
- pytesprocess/process/data_source.py +185 -0
- pytesprocess/process/event_context.py +35 -0
- pytesprocess/process/feature_plan.py +186 -0
- pytesprocess/process/feature_resources.py +267 -0
- pytesprocess/process/features.py +1024 -0
- pytesprocess/process/filterprocess.py +1176 -0
- pytesprocess/process/ivprocess.py +1380 -0
- pytesprocess/process/processing_data.py +967 -0
- pytesprocess/process/randoms.py +921 -0
- pytesprocess/process/triggers.py +1011 -0
- pytesprocess/salting/__init__.py +7 -0
- pytesprocess/salting/generator.py +364 -0
- pytesprocess/salting/injector.py +329 -0
- pytesprocess/salting/sampling.py +84 -0
- pytesprocess/utils/__init__.py +5 -0
- pytesprocess/utils/arg_utils.py +122 -0
- pytesprocess/utils/dataframe_output.py +120 -0
- pytesprocess/utils/filter_hdf5.py +594 -0
- pytesprocess/utils/utils.py +701 -0
- pytesprocess/workflows/__init__.py +3 -0
- pytesprocess/workflows/processing.py +317 -0
- pytesprocess/workflows/salting.py +133 -0
- pytesprocess-0.1.1.dist-info/METADATA +211 -0
- pytesprocess-0.1.1.dist-info/RECORD +60 -0
- pytesprocess-0.1.1.dist-info/WHEEL +5 -0
- pytesprocess-0.1.1.dist-info/entry_points.txt +2 -0
- pytesprocess-0.1.1.dist-info/licenses/LICENSE +21 -0
- pytesprocess-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import numpy as np
|
|
4
|
+
os.environ["HDF5_USE_FILE_LOCKING"] = 'FALSE'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
__all__ = ['FilterH5IO']
|
|
8
|
+
|
|
9
|
+
class FilterH5IO:
|
|
10
|
+
"""
|
|
11
|
+
Class to manage HDF5 filter file, which contains
|
|
12
|
+
noise PSD, template, and pre-calculated optimal filter
|
|
13
|
+
quantities.
|
|
14
|
+
|
|
15
|
+
The data are stored in the file as pandas Series or DataFrame.
|
|
16
|
+
Attibutes (metadata) can be included.
|
|
17
|
+
|
|
18
|
+
Overall format of the filter file:
|
|
19
|
+
/channel_name/parameter_name: pandas.Series or pandas.DataFrame
|
|
20
|
+
|
|
21
|
+
Note that parameter name with + (sum) and | (NxM)
|
|
22
|
+
are converted to natural naming with __plus__ and __and__ respectively
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def __init__(self, filter_file, verbose=True):
|
|
28
|
+
"""
|
|
29
|
+
Initialize class
|
|
30
|
+
|
|
31
|
+
Parameters:
|
|
32
|
+
----------
|
|
33
|
+
|
|
34
|
+
filter_file : str (required)
|
|
35
|
+
filter file name (full path)
|
|
36
|
+
verbose : Bool (optional)
|
|
37
|
+
display informations (default = False)
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
self._filter_file = filter_file
|
|
42
|
+
self._verbose = verbose
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def verbose(self):
|
|
47
|
+
return self._verbose
|
|
48
|
+
|
|
49
|
+
@verbose.setter
|
|
50
|
+
def verbose(self,value):
|
|
51
|
+
self._verbose=value
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def set_filter_file(self, file_name):
|
|
55
|
+
"""
|
|
56
|
+
Set filter file name
|
|
57
|
+
|
|
58
|
+
Parameters:
|
|
59
|
+
----------
|
|
60
|
+
|
|
61
|
+
filter_file : str (required)
|
|
62
|
+
filter file name (full path)
|
|
63
|
+
|
|
64
|
+
Return:
|
|
65
|
+
------
|
|
66
|
+
None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
self._filter_file = file_name
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def describe(self):
|
|
74
|
+
"""
|
|
75
|
+
Display informations about the file content
|
|
76
|
+
|
|
77
|
+
Parameters:
|
|
78
|
+
----------
|
|
79
|
+
None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
Return:
|
|
83
|
+
------
|
|
84
|
+
None
|
|
85
|
+
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
filter_file = pd.HDFStore(self._filter_file)
|
|
89
|
+
|
|
90
|
+
msg_title = 'Filter file: ' + self._filter_file + ':'
|
|
91
|
+
print(msg_title)
|
|
92
|
+
sep = '='
|
|
93
|
+
for i in range(len(msg_title)):
|
|
94
|
+
sep += '='
|
|
95
|
+
print(sep + '\n')
|
|
96
|
+
|
|
97
|
+
# loop keys
|
|
98
|
+
for key in filter_file.keys():
|
|
99
|
+
|
|
100
|
+
# modify key to have "natural naming"
|
|
101
|
+
key_name = self._convert_from_natural_naming(key)
|
|
102
|
+
|
|
103
|
+
msg = key_name + ': '
|
|
104
|
+
|
|
105
|
+
val = filter_file[key]
|
|
106
|
+
if isinstance(val, pd.Series):
|
|
107
|
+
msg += 'pandas.Series '
|
|
108
|
+
elif isinstance(val, pd.DataFrame):
|
|
109
|
+
msg += 'pandas.DataFrame '
|
|
110
|
+
else:
|
|
111
|
+
msg += str(type(val))
|
|
112
|
+
|
|
113
|
+
msg += str(val.shape)
|
|
114
|
+
|
|
115
|
+
if 'metadata' in filter_file.get_storer(key).attrs:
|
|
116
|
+
msg += ('\n metadata: '
|
|
117
|
+
+ str(filter_file.get_storer(key).attrs.metadata)
|
|
118
|
+
+ '\n')
|
|
119
|
+
|
|
120
|
+
print(msg)
|
|
121
|
+
|
|
122
|
+
filter_file.close()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def get_param(self, channel, param_name,
|
|
127
|
+
add_metadata=False):
|
|
128
|
+
"""
|
|
129
|
+
Get parameter and associated metadata (optional) for the specified
|
|
130
|
+
channel. Return pandas Series or Dataframe or 2D/3D numpy array
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
Parameters:
|
|
134
|
+
----------
|
|
135
|
+
|
|
136
|
+
channel : str (required)
|
|
137
|
+
channel name
|
|
138
|
+
|
|
139
|
+
param_name : str (required)
|
|
140
|
+
parameter name
|
|
141
|
+
|
|
142
|
+
add_medatata: bool (optional, default=False)
|
|
143
|
+
if True, return metadata
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
Return:
|
|
147
|
+
------
|
|
148
|
+
|
|
149
|
+
value : pandas Series or DataFrame or 2D/3D numpy array
|
|
150
|
+
parameter values
|
|
151
|
+
|
|
152
|
+
metadata : dict (if add_metadata=True)
|
|
153
|
+
Metadata associated with parameter
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
# key name
|
|
157
|
+
key = '/' + channel + '/' + param_name
|
|
158
|
+
|
|
159
|
+
# check if available
|
|
160
|
+
val = None
|
|
161
|
+
metadata = None
|
|
162
|
+
if self._is_key(key):
|
|
163
|
+
val, medatata = self._get(key)
|
|
164
|
+
if (isinstance(val, pd.DataFrame)
|
|
165
|
+
and metadata and 'type' in metadata):
|
|
166
|
+
if metadata['type'] == '2darray':
|
|
167
|
+
val = val.values
|
|
168
|
+
|
|
169
|
+
elif self._is_key(f'{key}_slice_0'):
|
|
170
|
+
_, medatata = self._get(f'{key}_slice_0')
|
|
171
|
+
dfs = []
|
|
172
|
+
for i in range(medatata['nb_slices']):
|
|
173
|
+
df, _ = self._get(f'{key}_slice_{i}')
|
|
174
|
+
dfs.append(df.values)
|
|
175
|
+
val = np.stack(dfs, axis=0)
|
|
176
|
+
|
|
177
|
+
else:
|
|
178
|
+
raise ValueError(f'ERROR: parameter {param_name} for '
|
|
179
|
+
f'channel {channel} not found in hdf5 '
|
|
180
|
+
f'file {self._filter_file}')
|
|
181
|
+
|
|
182
|
+
if add_metadata:
|
|
183
|
+
return val, medatata
|
|
184
|
+
else:
|
|
185
|
+
return val
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def save_param(self, channel, param_name, param_value,
|
|
190
|
+
param_index=None, attributes=None,
|
|
191
|
+
overwrite=False):
|
|
192
|
+
"""
|
|
193
|
+
Save parameter values, index,
|
|
194
|
+
and associated metadata for the specified channel
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
Parameters:
|
|
198
|
+
----------
|
|
199
|
+
|
|
200
|
+
channel : str (required)
|
|
201
|
+
channel name
|
|
202
|
+
|
|
203
|
+
param_name : str (required)
|
|
204
|
+
parameter name
|
|
205
|
+
|
|
206
|
+
param_value : numpy array or pandas Series/DataFrame (required)
|
|
207
|
+
values of the parameter (numpy arrays are converted to pandas)
|
|
208
|
+
|
|
209
|
+
param_index : 1D numpy array (optional, default=None)
|
|
210
|
+
index of the parameter (if param_value is a 1D numpy array)
|
|
211
|
+
|
|
212
|
+
attributes : dict (optional, default=None)
|
|
213
|
+
metadata associated with parameter
|
|
214
|
+
|
|
215
|
+
overwrite : bool (optional, default=False)
|
|
216
|
+
overwrite existing parameter in filter file (other parameters are unmodified)
|
|
217
|
+
|
|
218
|
+
Return:
|
|
219
|
+
------
|
|
220
|
+
|
|
221
|
+
None
|
|
222
|
+
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
# attributes
|
|
226
|
+
if attributes is None:
|
|
227
|
+
attributes = dict()
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
# convert to pandas Series or DataFrame object(s)
|
|
231
|
+
param_value_sliced = dict()
|
|
232
|
+
if isinstance(param_value, np.ndarray):
|
|
233
|
+
|
|
234
|
+
if param_value.ndim == 1:
|
|
235
|
+
param_value = pd.Series(param_value, param_index)
|
|
236
|
+
attributes['type'] = 'series'
|
|
237
|
+
elif param_value.ndim == 2:
|
|
238
|
+
param_value = pd.DataFrame(param_value)
|
|
239
|
+
attributes['type'] = '2darray'
|
|
240
|
+
elif param_value.ndim == 3:
|
|
241
|
+
attributes['type'] = '3darray'
|
|
242
|
+
attributes['nb_slices'] = param_value.shape[0]
|
|
243
|
+
for i in range(param_value.shape[0]):
|
|
244
|
+
df = pd.DataFrame(param_value[i, :, :])
|
|
245
|
+
slice_name = f'{param_name}_slice_{i}'
|
|
246
|
+
param_value_sliced[slice_name] = df
|
|
247
|
+
|
|
248
|
+
elif isinstance(param_value, pd.Series):
|
|
249
|
+
attributes['type'] = 'series'
|
|
250
|
+
elif isinstance(param_value, pd.DataFrame):
|
|
251
|
+
attributes['type'] = 'dataframe'
|
|
252
|
+
else:
|
|
253
|
+
raise ValueError(f'ERROR: Parameter "{param_name}" '
|
|
254
|
+
f'should be eiter a numpy array'
|
|
255
|
+
f'or pandas Series/dataFrame')
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
if param_value_sliced:
|
|
259
|
+
for key_name, df in param_value_sliced.items():
|
|
260
|
+
key = '/' + channel + '/' + key_name
|
|
261
|
+
self._put(key,
|
|
262
|
+
df,
|
|
263
|
+
attributes=attributes,
|
|
264
|
+
overwrite=overwrite)
|
|
265
|
+
else:
|
|
266
|
+
# key name
|
|
267
|
+
key = '/' + channel + '/' + param_name
|
|
268
|
+
self._put(key,
|
|
269
|
+
param_value,
|
|
270
|
+
attributes=attributes,
|
|
271
|
+
overwrite=overwrite)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def save_fromdict(self, filter_dict, overwrite=False):
|
|
275
|
+
"""
|
|
276
|
+
Save parameter from dictionary
|
|
277
|
+
|
|
278
|
+
Parameters:
|
|
279
|
+
----------
|
|
280
|
+
|
|
281
|
+
filter_dict : dict (required)
|
|
282
|
+
dictionary with following format:
|
|
283
|
+
['channel_name']
|
|
284
|
+
['parameter_name']: array or pandas Series/DataFrame
|
|
285
|
+
['parameter_name_metadata']: metadata dictionary
|
|
286
|
+
...
|
|
287
|
+
['channel_name_2']
|
|
288
|
+
...
|
|
289
|
+
|
|
290
|
+
overwrite : bool (optional, default=False)
|
|
291
|
+
overwrite existing parameter(s) in filter file
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
Return:
|
|
295
|
+
------
|
|
296
|
+
|
|
297
|
+
None
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
# loop filter data and save data
|
|
303
|
+
for chan_name, chan_dict in filter_dict.items():
|
|
304
|
+
|
|
305
|
+
# first get list of parameters
|
|
306
|
+
param_name_list = list()
|
|
307
|
+
for param_name in chan_dict.keys():
|
|
308
|
+
if '_metadata' in param_name:
|
|
309
|
+
continue
|
|
310
|
+
else:
|
|
311
|
+
param_name_list.append(param_name)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
# loop parameters and get value and metadata
|
|
315
|
+
for param_name in param_name_list:
|
|
316
|
+
|
|
317
|
+
# parameter value
|
|
318
|
+
val = chan_dict[param_name]
|
|
319
|
+
|
|
320
|
+
# parameter metadata
|
|
321
|
+
metadata = None
|
|
322
|
+
param_name_metadata = param_name + '_metadata'
|
|
323
|
+
if param_name_metadata in chan_dict.keys():
|
|
324
|
+
metadata = chan_dict[param_name_metadata]
|
|
325
|
+
|
|
326
|
+
# save
|
|
327
|
+
self.save_param(chan_name, param_name, val,
|
|
328
|
+
attributes=metadata,
|
|
329
|
+
overwrite=overwrite)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def load(self):
|
|
335
|
+
"""
|
|
336
|
+
Load filter file into dictionary
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
Parameters:
|
|
340
|
+
----------
|
|
341
|
+
|
|
342
|
+
None
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
Return:
|
|
346
|
+
-------
|
|
347
|
+
|
|
348
|
+
filter_dict : dict
|
|
349
|
+
dictionary with following format:
|
|
350
|
+
['channel_name']
|
|
351
|
+
['parameter_name']: array or pandas Series/DataFrame
|
|
352
|
+
['parameter_name_metadata']: metadata dictionary
|
|
353
|
+
...
|
|
354
|
+
['channel_name_2']
|
|
355
|
+
...
|
|
356
|
+
|
|
357
|
+
['channel_name']
|
|
358
|
+
['parameter_name']: array or pandas Series/DataFrame
|
|
359
|
+
['parameter_name_metadata']: metadata dictionary
|
|
360
|
+
...
|
|
361
|
+
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
output_dict = dict()
|
|
365
|
+
|
|
366
|
+
# open file and key list of keys
|
|
367
|
+
filter_file = pd.HDFStore(self._filter_file)
|
|
368
|
+
file_keys = filter_file.keys()
|
|
369
|
+
filter_file.close()
|
|
370
|
+
|
|
371
|
+
# loop keys to deal with sliced data
|
|
372
|
+
list_of_keys = []
|
|
373
|
+
for key in file_keys:
|
|
374
|
+
|
|
375
|
+
pos = key.find('slice_')
|
|
376
|
+
if pos != -1:
|
|
377
|
+
key = key[0:pos-1]
|
|
378
|
+
|
|
379
|
+
if key not in list_of_keys:
|
|
380
|
+
list_of_keys.append(key)
|
|
381
|
+
|
|
382
|
+
# loop and get dat
|
|
383
|
+
for key in list_of_keys:
|
|
384
|
+
|
|
385
|
+
key = self._convert_from_natural_naming(key)
|
|
386
|
+
|
|
387
|
+
# split channel / parameter name
|
|
388
|
+
key_split = key.split('/')
|
|
389
|
+
if len(key_split) != 3:
|
|
390
|
+
continue
|
|
391
|
+
|
|
392
|
+
# channel/par name
|
|
393
|
+
channel = key_split[1]
|
|
394
|
+
param_name = key_split[2]
|
|
395
|
+
|
|
396
|
+
# get value
|
|
397
|
+
val, metadata = self.get_param(channel,
|
|
398
|
+
param_name,
|
|
399
|
+
add_metadata=True)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
# create channel dict if needed
|
|
403
|
+
if channel not in output_dict:
|
|
404
|
+
output_dict[channel] = dict()
|
|
405
|
+
|
|
406
|
+
# fill value
|
|
407
|
+
output_dict[channel][param_name] = val
|
|
408
|
+
output_dict[channel][param_name + '_metadata'] = metadata
|
|
409
|
+
|
|
410
|
+
return output_dict
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def _put(self, key, value, attributes=None, overwrite=False):
|
|
414
|
+
"""
|
|
415
|
+
Save parameter in hdf5 file
|
|
416
|
+
|
|
417
|
+
Parameters:
|
|
418
|
+
----------
|
|
419
|
+
|
|
420
|
+
key : str (required)
|
|
421
|
+
key name in the form of '/channel_name/parameter_name'
|
|
422
|
+
|
|
423
|
+
value : pandas Series or DataFrame (required)
|
|
424
|
+
parameter values
|
|
425
|
+
|
|
426
|
+
attributes : dict (optional, default=None)
|
|
427
|
+
metadata associated with parameter
|
|
428
|
+
|
|
429
|
+
overwrite : bool (optional, default=False)
|
|
430
|
+
overwrite existing parameter in filter file (other parameters are unmodified)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
Return:
|
|
434
|
+
------
|
|
435
|
+
|
|
436
|
+
None
|
|
437
|
+
|
|
438
|
+
"""
|
|
439
|
+
|
|
440
|
+
# open file
|
|
441
|
+
filter_file = pd.HDFStore(self._filter_file)
|
|
442
|
+
|
|
443
|
+
# verbose
|
|
444
|
+
if self._verbose:
|
|
445
|
+
print(f'INFO: Storing {key} in {self._filter_file}')
|
|
446
|
+
|
|
447
|
+
# modify key to have "natural naming"
|
|
448
|
+
key_natural = self._convert_to_natural_naming(key)
|
|
449
|
+
|
|
450
|
+
# check if key exist already
|
|
451
|
+
file_keys = filter_file.keys()
|
|
452
|
+
if (key_natural in file_keys and not overwrite):
|
|
453
|
+
raise ValueError(f'Key {key} already stored in '
|
|
454
|
+
f'{self._filter_file}. Use "overwrite=True" '
|
|
455
|
+
f'to overwrite parameter or '
|
|
456
|
+
f'change file name')
|
|
457
|
+
|
|
458
|
+
# save
|
|
459
|
+
filter_file.put(key_natural, value, format='fixed')
|
|
460
|
+
|
|
461
|
+
# add attributes
|
|
462
|
+
if attributes is not None:
|
|
463
|
+
filter_file.get_storer(key_natural).attrs.metadata = attributes
|
|
464
|
+
|
|
465
|
+
# close
|
|
466
|
+
filter_file.close()
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def _get(self, key):
|
|
471
|
+
"""
|
|
472
|
+
|
|
473
|
+
Get parameter fromhdf5 file
|
|
474
|
+
|
|
475
|
+
Parameters:
|
|
476
|
+
----------
|
|
477
|
+
|
|
478
|
+
key : str (required)
|
|
479
|
+
key name in the form of '/channel_name/parameter_name'
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
Return:
|
|
483
|
+
------
|
|
484
|
+
|
|
485
|
+
value : pandas Series or DataFrame
|
|
486
|
+
channel/parameter values
|
|
487
|
+
|
|
488
|
+
metadata : dict
|
|
489
|
+
metadata associated with parameter
|
|
490
|
+
(return None if no metadata available)
|
|
491
|
+
|
|
492
|
+
"""
|
|
493
|
+
|
|
494
|
+
# open file
|
|
495
|
+
filter_file = pd.HDFStore(self._filter_file)
|
|
496
|
+
|
|
497
|
+
# modify key to have "natural naming"
|
|
498
|
+
key_natural = self._convert_to_natural_naming(key)
|
|
499
|
+
|
|
500
|
+
# check key
|
|
501
|
+
file_keys = filter_file.keys()
|
|
502
|
+
|
|
503
|
+
if key_natural not in file_keys:
|
|
504
|
+
raise ValueError(f'Key {key} is not in '
|
|
505
|
+
f'{self._filter_file}. '
|
|
506
|
+
f'Check file with "describe()"')
|
|
507
|
+
|
|
508
|
+
# get
|
|
509
|
+
value = filter_file.get(key_natural)
|
|
510
|
+
|
|
511
|
+
# get attributes
|
|
512
|
+
metadata = None
|
|
513
|
+
attributes = filter_file.get_storer(key_natural).attrs
|
|
514
|
+
if 'metadata' in attributes:
|
|
515
|
+
metadata = filter_file.get_storer(key_natural).attrs.metadata
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
# close
|
|
519
|
+
filter_file.close()
|
|
520
|
+
|
|
521
|
+
return value, metadata
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def _is_key(self, key):
|
|
525
|
+
"""
|
|
526
|
+
|
|
527
|
+
Check if key in hdf5 file
|
|
528
|
+
|
|
529
|
+
Parameters:
|
|
530
|
+
----------
|
|
531
|
+
|
|
532
|
+
key : str (required)
|
|
533
|
+
key name in the form of '/channel_name/parameter_name'
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
Return:
|
|
537
|
+
------
|
|
538
|
+
|
|
539
|
+
is_key : boolean
|
|
540
|
+
True is key exist, False if key doesn't exist
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
# open file
|
|
546
|
+
filter_file = pd.HDFStore(self._filter_file)
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
# modify key to have "natural naming"
|
|
550
|
+
key_natural = self._convert_to_natural_naming(key)
|
|
551
|
+
|
|
552
|
+
# check key
|
|
553
|
+
file_keys = filter_file.keys()
|
|
554
|
+
|
|
555
|
+
is_key = False
|
|
556
|
+
if key_natural in file_keys:
|
|
557
|
+
is_key = True
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
# close
|
|
561
|
+
filter_file.close()
|
|
562
|
+
|
|
563
|
+
return is_key
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
def _convert_to_natural_naming(self, key):
|
|
567
|
+
"""
|
|
568
|
+
convert to natural naming
|
|
569
|
+
= string containing only
|
|
570
|
+
^[a-zA-Z_][a-zA-Z0-9_]*$
|
|
571
|
+
"""
|
|
572
|
+
|
|
573
|
+
if '+' in key:
|
|
574
|
+
key = key.replace('+', '__plus__')
|
|
575
|
+
|
|
576
|
+
if '|' in key:
|
|
577
|
+
key = key.replace('|', '__and__')
|
|
578
|
+
|
|
579
|
+
return key
|
|
580
|
+
|
|
581
|
+
def _convert_from_natural_naming(self, key):
|
|
582
|
+
"""
|
|
583
|
+
convert from natural naming
|
|
584
|
+
= string containing only
|
|
585
|
+
^[a-zA-Z_][a-zA-Z0-9_]*$
|
|
586
|
+
"""
|
|
587
|
+
|
|
588
|
+
if '__plus__' in key:
|
|
589
|
+
key = key.replace('__plus__', '+')
|
|
590
|
+
|
|
591
|
+
if '__and__' in key:
|
|
592
|
+
key = key.replace('__and__', '|')
|
|
593
|
+
|
|
594
|
+
return key
|