2import shelve, logging, sys, appdirs, os, platform
5from collections
import namedtuple
6from dataclasses
import dataclass
7from dataclasses_json
import dataclass_json
8from enum
import Enum, unique, auto
9from .lasp_cpp
import DaqChannel
12Common definitions used throughout the code.
16 'P_REF',
'FreqWeighting',
'TimeWeighting',
'getTime',
'getFreq',
'Qty',
18 'lasp_shelve',
'this_lasp_shelve',
'W_REF',
'U_REF',
'I_REF',
'dBFS_REF',
45 """Specificying the type of data, for adding and removing callbacks from
49 audio_input = (0,
'input')
52 audio_output = (1,
'output')
55 audio_duplex = (2,
'duplex')
72 level_ref_name: object
73 level_ref_value: object
74 cpp_enum: DaqChannel.Qty
77 return f
'{self.name} [{self.unit_symb}]'
81 Comparison breaks for the other objects, level unit, level ref name,
82 etc as these are tuples / a single string.
91 Convert quantity to its specific enum integer value
99 N =
Qty(name=
'Number',
100 unit_name=
'No unit / full scale',
102 level_unit=(
'dBFS',),
103 level_ref_name=(
'Relative to full scale sine wave',),
104 level_ref_value=(dBFS_REF,),
105 cpp_enum = DaqChannel.Qty.Number
107 AP =
Qty(name=
'Acoustic Pressure',
110 level_unit=(
'dB SPL',
'dBPa'),
111 level_ref_name=(
'2 micropascal',
'1 pascal',),
112 level_ref_value=(P_REF, 1),
113 cpp_enum = DaqChannel.Qty.AcousticPressure
120 level_ref_name=(
'1V',),
121 level_ref_value=(1.0,),
122 cpp_enum = DaqChannel.Qty.Voltage
127 return SIQtys.N.value
132 Convert enumeration index from - say - a measurement file back into
133 physical quantity information.
136 if qty.value.cpp_enum == enum:
138 raise RuntimeError(f
'Qty corresponding to enum {enum} not found')
143 Convert integer index from - say - a measurement file back into
144 physical quantity information.
147 if qty.value.cpp_enum.value == val:
149 raise RuntimeError(f
'Qty corresponding to integer {val} not found')
156 cal_value_linear: float
160 one =
CalSetting(
'94 dB SPL', 94.0 , 10**(94/20)*2e-5, SIQtys.AP.value)
162 three =
CalSetting(
'114 dB SPL', 114.0 , 10**(114/20)*2e-5, SIQtys.AP.value)
163 four =
CalSetting(
'10 Pa rms', 113.98, 10.0, SIQtys.AP.value)
164 five =
CalSetting(
'93.7 dB SPL', 93.7 , 1.0, SIQtys.AP.value)
166 types = (one, two, three, four, five)
173 Fill Calibration Settings to a combobox
176 cb: QComboBox to fill
179 for ty
in CalibrationSettings.types:
180 cb.addItem(f
'{ty.cal_value_dB}')
181 cb.setCurrentIndex(CalibrationSettings.default_index)
185 if cb.currentIndex() < len(CalibrationSettings.types):
186 return CalibrationSettings.types[cb.currentIndex()]
190lasp_appdir = appdirs.user_data_dir(
'Lasp',
'ASCEE')
192if not os.path.exists(lasp_appdir):
194 os.makedirs(lasp_appdir, exist_ok=
True)
196 print(
'Fatal error: could not create application directory')
202 def load(self, key, default_value):
204 Load data from a given key, if key is not found, returns the
205 default value if key is not found
207 if key
in self.
shelve.keys():
217 self._shelve[key] = val
221 del self._shelve[key]
226 print(list(self.
shelve.keys()))
231 self.
shelve = shelve.open(self.shelve_fn())
250 return lasp_shelve._refcount
254 lasp_shelve._refcount = val
258 return lasp_shelve._shelve
262 lasp_shelve._shelve = shelve
265 return os.path.join(lasp_appdir,
'config.shelve')
274 return this_lasp_shelve._refcount
278 this_lasp_shelve._refcount = val
282 return this_lasp_shelve._shelve
286 this_lasp_shelve._shelve = shelve
289 node = platform.node()
290 return os.path.join(lasp_appdir, f
'{node}_config.shelve')
294 none = (0,
'Raw (no time weighting)')
296 uufast = (1e-4,
'0.1 ms')
297 ufast = (35e-3,
'Impulse (35 ms)')
298 fast = (0.125,
'Fast (0.125 s)')
299 slow = (1.0,
'Slow (1.0 s)')
305 averaging = (-1,
'All-averaging')
307 types_all = (none, uufast, ufast, fast, slow, tens, averaging)
310 types_realtimeaps = (ufast, fast, slow, tens, averaging)
312 types_realtimeslm = (ufast, fast, slow, tens)
315 types_slmt = (none, uufast, ufast, fast, slow, tens)
318 types_slmstats = (uufast, ufast, fast, slow, tens)
325 Fill TimeWeightings to a combobox
328 cb: QComboBox to fill
329 types: The types to fill it with
333 logging.debug(f
'{types}')
335 cb.addItem(tw[1], tw)
336 if TimeWeighting.default == tw:
337 cb.setCurrentIndex(cb.count()-1)
341 for type
in TimeWeighting.types_all:
342 if cb.currentText() == type[1]:
348 Frequency weighting types
350 Z = (
'Z',
'Z-weighting')
351 A = (
'A',
'A-weighting')
352 C = (
'C',
'C-weighting')
360 Fill FreqWeightings to a combobox
363 cb: QComboBox to fill
366 for fw
in FreqWeighting.types:
367 cb.addItem(fw[1], fw)
368 cb.setCurrentIndex(FreqWeighting.default_index)
372 return FreqWeighting.types[cb.currentIndex()]
375def getTime(fs, N, start=0):
377 Return a time array for given number of points and sampling frequency.
380 fs: Sampling frequency [Hz]
381 N: Number of time samples
382 start: Optional start ofset in number of samples
384 assert N > 0
and fs > 0
385 return np.linspace(start, start + N/fs, N, endpoint=
False)
388def getFreq(fs, nfft):
390 return an array of frequencies for single-sided spectra
393 fs: Sampling frequency [Hz]
394 nfft: Fft length (int)
398 return np.linspace(0, (K-1)*df, K)
Specificying the type of data, for adding and removing callbacks from the stream.
fillComboBox(cb)
Fill Calibration Settings to a combobox.
Frequency weighting types.
fillComboBox(cb)
Fill FreqWeightings to a combobox.
toInt(self)
Convert quantity to its specific enum integer value.
__eq__(self, other)
Comparison breaks for the other objects, level unit, level ref name, etc as these are tuples / a sing...
fromCppEnum(enum)
Convert enumeration index from - say - a measurement file back into physical quantity information.
fromInt(val)
Convert integer index from - say - a measurement file back into physical quantity information.
__exit__(self, type, value, traceback)
load(self, key, default_value)
Load data from a given key, if key is not found, returns the default value if key is not found.
deleteIfPresent(self, key)
fillComboBox(cb, types)
Fill TimeWeightings to a combobox.