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.
Files changed (60) hide show
  1. pytesprocess/__init__.py +9 -0
  2. pytesprocess/_version.py +2 -0
  3. pytesprocess/cli/__init__.py +1 -0
  4. pytesprocess/cli/commands/__init__.py +5 -0
  5. pytesprocess/cli/commands/event.py +66 -0
  6. pytesprocess/cli/commands/filter.py +17 -0
  7. pytesprocess/cli/commands/ivsweep.py +29 -0
  8. pytesprocess/cli/common.py +86 -0
  9. pytesprocess/cli/main.py +81 -0
  10. pytesprocess/config/__init__.py +4 -0
  11. pytesprocess/config/loader.py +94 -0
  12. pytesprocess/config/manager.py +297 -0
  13. pytesprocess/config/resolvers/__init__.py +5 -0
  14. pytesprocess/config/resolvers/common.py +56 -0
  15. pytesprocess/config/resolvers/feature.py +293 -0
  16. pytesprocess/config/resolvers/salting.py +86 -0
  17. pytesprocess/config/resolvers/trigger.py +84 -0
  18. pytesprocess/config/selectors.py +108 -0
  19. pytesprocess/config/validation.py +314 -0
  20. pytesprocess/config/warnings.py +2 -0
  21. pytesprocess/core/__init__.py +10 -0
  22. pytesprocess/core/algorithms.py +1455 -0
  23. pytesprocess/core/didv.py +1648 -0
  24. pytesprocess/core/eventbuilder.py +495 -0
  25. pytesprocess/core/filterbuilder.py +81 -0
  26. pytesprocess/core/filterdata.py +1849 -0
  27. pytesprocess/core/ivsweep.py +2072 -0
  28. pytesprocess/core/noise.py +923 -0
  29. pytesprocess/core/noisemodel.py +1408 -0
  30. pytesprocess/core/oftrigger.py +1035 -0
  31. pytesprocess/core/template.py +450 -0
  32. pytesprocess/process/__init__.py +6 -0
  33. pytesprocess/process/data_source.py +185 -0
  34. pytesprocess/process/event_context.py +35 -0
  35. pytesprocess/process/feature_plan.py +186 -0
  36. pytesprocess/process/feature_resources.py +267 -0
  37. pytesprocess/process/features.py +1024 -0
  38. pytesprocess/process/filterprocess.py +1176 -0
  39. pytesprocess/process/ivprocess.py +1380 -0
  40. pytesprocess/process/processing_data.py +967 -0
  41. pytesprocess/process/randoms.py +921 -0
  42. pytesprocess/process/triggers.py +1011 -0
  43. pytesprocess/salting/__init__.py +7 -0
  44. pytesprocess/salting/generator.py +364 -0
  45. pytesprocess/salting/injector.py +329 -0
  46. pytesprocess/salting/sampling.py +84 -0
  47. pytesprocess/utils/__init__.py +5 -0
  48. pytesprocess/utils/arg_utils.py +122 -0
  49. pytesprocess/utils/dataframe_output.py +120 -0
  50. pytesprocess/utils/filter_hdf5.py +594 -0
  51. pytesprocess/utils/utils.py +701 -0
  52. pytesprocess/workflows/__init__.py +3 -0
  53. pytesprocess/workflows/processing.py +317 -0
  54. pytesprocess/workflows/salting.py +133 -0
  55. pytesprocess-0.1.1.dist-info/METADATA +211 -0
  56. pytesprocess-0.1.1.dist-info/RECORD +60 -0
  57. pytesprocess-0.1.1.dist-info/WHEEL +5 -0
  58. pytesprocess-0.1.1.dist-info/entry_points.txt +2 -0
  59. pytesprocess-0.1.1.dist-info/licenses/LICENSE +21 -0
  60. 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