mt-metadata 0.3.3__py2.py3-none-any.whl → 0.3.5__py2.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.
Potentially problematic release.
This version of mt-metadata might be problematic. Click here for more details.
- mt_metadata/__init__.py +12 -10
- mt_metadata/base/metadata.py +24 -13
- mt_metadata/data/transfer_functions/tf_zmm.zmm +1 -1
- mt_metadata/timeseries/channel.py +8 -3
- mt_metadata/timeseries/filters/__init__.py +2 -2
- mt_metadata/timeseries/filters/{channel_response_filter.py → channel_response.py} +62 -29
- mt_metadata/timeseries/filters/coefficient_filter.py +1 -3
- mt_metadata/timeseries/filters/filter_base.py +70 -37
- mt_metadata/timeseries/filters/filtered.py +32 -22
- mt_metadata/timeseries/filters/fir_filter.py +10 -11
- mt_metadata/timeseries/filters/frequency_response_table_filter.py +9 -8
- mt_metadata/timeseries/filters/helper_functions.py +112 -3
- mt_metadata/timeseries/filters/pole_zero_filter.py +9 -8
- mt_metadata/timeseries/filters/standards/filter_base.json +2 -2
- mt_metadata/timeseries/filters/time_delay_filter.py +9 -8
- mt_metadata/timeseries/stationxml/fdsn_tools.py +8 -7
- mt_metadata/timeseries/stationxml/xml_channel_mt_channel.py +1 -1
- mt_metadata/timeseries/stationxml/xml_inventory_mt_experiment.py +4 -1
- mt_metadata/timeseries/tools/from_many_mt_files.py +15 -3
- mt_metadata/transfer_functions/__init__.py +1 -1
- mt_metadata/transfer_functions/core.py +89 -49
- mt_metadata/transfer_functions/io/edi/edi.py +9 -5
- mt_metadata/transfer_functions/io/edi/metadata/define_measurement.py +7 -3
- mt_metadata/transfer_functions/io/emtfxml/emtfxml.py +1 -4
- mt_metadata/transfer_functions/io/jfiles/jfile.py +2 -1
- mt_metadata/transfer_functions/io/zfiles/zmm.py +108 -62
- mt_metadata/transfer_functions/io/zonge/zonge.py +2 -2
- mt_metadata/transfer_functions/processing/aurora/band.py +16 -0
- mt_metadata/transfer_functions/processing/aurora/channel_nomenclature.py +34 -31
- mt_metadata/transfer_functions/processing/aurora/processing.py +12 -5
- mt_metadata/transfer_functions/processing/aurora/stations.py +11 -2
- mt_metadata/transfer_functions/processing/fourier_coefficients/decimation.py +1 -1
- mt_metadata/transfer_functions/processing/fourier_coefficients/standards/decimation.json +1 -1
- mt_metadata/transfer_functions/processing/fourier_coefficients/standards/fc_channel.json +23 -1
- mt_metadata/transfer_functions/tf/transfer_function.py +93 -1
- {mt_metadata-0.3.3.dist-info → mt_metadata-0.3.5.dist-info}/METADATA +379 -379
- {mt_metadata-0.3.3.dist-info → mt_metadata-0.3.5.dist-info}/RECORD +41 -41
- {mt_metadata-0.3.3.dist-info → mt_metadata-0.3.5.dist-info}/WHEEL +1 -1
- {mt_metadata-0.3.3.dist-info → mt_metadata-0.3.5.dist-info}/AUTHORS.rst +0 -0
- {mt_metadata-0.3.3.dist-info → mt_metadata-0.3.5.dist-info}/LICENSE +0 -0
- {mt_metadata-0.3.3.dist-info → mt_metadata-0.3.5.dist-info}/top_level.txt +0 -0
|
@@ -25,6 +25,7 @@ from mt_metadata.transfer_functions.tf import (
|
|
|
25
25
|
from mt_metadata.transfer_functions.io.tools import get_nm_elev
|
|
26
26
|
from .metadata import Channel
|
|
27
27
|
from mt_metadata.utils.list_dict import ListDict
|
|
28
|
+
from mt_metadata import DEFAULT_CHANNEL_NOMENCLATURE
|
|
28
29
|
|
|
29
30
|
# ==============================================================================
|
|
30
31
|
PERIOD_FORMAT = ".10g"
|
|
@@ -40,7 +41,6 @@ class ZMMHeader(object):
|
|
|
40
41
|
"""
|
|
41
42
|
|
|
42
43
|
def __init__(self, fn=None, **kwargs):
|
|
43
|
-
|
|
44
44
|
self.logger = logger
|
|
45
45
|
self.processing_type = None
|
|
46
46
|
self.num_channels = None
|
|
@@ -73,9 +73,7 @@ class ZMMHeader(object):
|
|
|
73
73
|
if value.suffix.lower() in [".zmm", ".zrr", ".zss"]:
|
|
74
74
|
self._zfn = value
|
|
75
75
|
else:
|
|
76
|
-
msg =
|
|
77
|
-
f"Input file must be a *.zmm or *.zrr file not {value.suffix}"
|
|
78
|
-
)
|
|
76
|
+
msg = f"Input file must be a *.zmm or *.zrr file not {value.suffix}"
|
|
79
77
|
self.logger.error(msg)
|
|
80
78
|
raise ValueError(msg)
|
|
81
79
|
|
|
@@ -255,6 +253,15 @@ class ZMMHeader(object):
|
|
|
255
253
|
continue
|
|
256
254
|
return lines
|
|
257
255
|
|
|
256
|
+
@property
|
|
257
|
+
def channel_dict(self):
|
|
258
|
+
channels = {}
|
|
259
|
+
for cc in ["ex", "ey", "hx", "hy", "hz"]:
|
|
260
|
+
ch = getattr(self, cc)
|
|
261
|
+
if ch is not None:
|
|
262
|
+
channels[cc] = ch.channel
|
|
263
|
+
return channels
|
|
264
|
+
|
|
258
265
|
@property
|
|
259
266
|
def channels_recorded(self):
|
|
260
267
|
channels = {}
|
|
@@ -293,7 +300,6 @@ class ZMM(ZMMHeader):
|
|
|
293
300
|
"""
|
|
294
301
|
|
|
295
302
|
def __init__(self, fn=None, **kwargs):
|
|
296
|
-
|
|
297
303
|
super().__init__()
|
|
298
304
|
|
|
299
305
|
self.fn = fn
|
|
@@ -304,23 +310,7 @@ class ZMM(ZMMHeader):
|
|
|
304
310
|
self.periods = None
|
|
305
311
|
self.dataset = None
|
|
306
312
|
self.decimation_dict = {}
|
|
307
|
-
self.channel_nomenclature =
|
|
308
|
-
|
|
309
|
-
self._ch_input_dict = {
|
|
310
|
-
"impedance": ["hx", "hy"],
|
|
311
|
-
"tipper": ["hx", "hy"],
|
|
312
|
-
"isp": ["hx", "hy"],
|
|
313
|
-
"res": ["ex", "ey", "hz"],
|
|
314
|
-
"tf": ["hx", "hy"],
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
self._ch_output_dict = {
|
|
318
|
-
"impedance": ["ex", "ey"],
|
|
319
|
-
"tipper": ["hz"],
|
|
320
|
-
"isp": ["hx", "hy"],
|
|
321
|
-
"res": ["ex", "ey", "hz"],
|
|
322
|
-
"tf": ["ex", "ey", "hz"],
|
|
323
|
-
}
|
|
313
|
+
self.channel_nomenclature = DEFAULT_CHANNEL_NOMENCLATURE
|
|
324
314
|
|
|
325
315
|
self._transfer_function = self._initialize_transfer_function()
|
|
326
316
|
|
|
@@ -369,6 +359,78 @@ class ZMM(ZMMHeader):
|
|
|
369
359
|
|
|
370
360
|
return f"MT( {(', ').join(lines)} )"
|
|
371
361
|
|
|
362
|
+
def __eq__(self, other):
|
|
363
|
+
"""
|
|
364
|
+
compare equals
|
|
365
|
+
|
|
366
|
+
:param other: DESCRIPTION
|
|
367
|
+
:type other: TYPE
|
|
368
|
+
:return: DESCRIPTION
|
|
369
|
+
:rtype: TYPE
|
|
370
|
+
|
|
371
|
+
"""
|
|
372
|
+
|
|
373
|
+
if not isinstance(other, ZMM):
|
|
374
|
+
raise TypeError(f"Cannot compare type {type(other)} with ZMM.")
|
|
375
|
+
|
|
376
|
+
is_equal = True
|
|
377
|
+
if self.station_metadata != other.station_metadata:
|
|
378
|
+
is_equal = False
|
|
379
|
+
if not self.dataset.equals(other.dataset):
|
|
380
|
+
is_equal = False
|
|
381
|
+
self.logger.info("Datasets are not equal")
|
|
382
|
+
print(self.dataset.fillna(0) != other.dataset.fillna(0).all())
|
|
383
|
+
return is_equal
|
|
384
|
+
|
|
385
|
+
@property
|
|
386
|
+
def channel_nomenclature(self):
|
|
387
|
+
return self._channel_nomenclature
|
|
388
|
+
|
|
389
|
+
@channel_nomenclature.setter
|
|
390
|
+
def channel_nomenclature(self, ch_dict):
|
|
391
|
+
"""
|
|
392
|
+
channel dictionary
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
if not isinstance(ch_dict, dict):
|
|
396
|
+
raise TypeError(
|
|
397
|
+
"Channel_nomenclature must be a dictionary with keys "
|
|
398
|
+
"['ex', 'ey', 'hx', 'hy', 'hz']."
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
self._channel_nomenclature = ch_dict
|
|
402
|
+
# unpack channel nomenclature dict
|
|
403
|
+
for comp in DEFAULT_CHANNEL_NOMENCLATURE.keys():
|
|
404
|
+
try:
|
|
405
|
+
setattr(self, f"_{comp}", ch_dict[comp])
|
|
406
|
+
except KeyError:
|
|
407
|
+
setattr(self, f"_{comp}", comp)
|
|
408
|
+
ch_dict[comp] = comp
|
|
409
|
+
|
|
410
|
+
self._ex_ey = [self._ex, self._ey]
|
|
411
|
+
self._hx_hy = [self._hx, self._hy]
|
|
412
|
+
self._ex_ey_hz = [self._ex, self._ey, self._hz]
|
|
413
|
+
|
|
414
|
+
@property
|
|
415
|
+
def _ch_input_dict(self):
|
|
416
|
+
return {
|
|
417
|
+
"isp": self._hx_hy,
|
|
418
|
+
"res": self._ex_ey_hz,
|
|
419
|
+
"tf": self._hx_hy,
|
|
420
|
+
"tf_error": self._hx_hy,
|
|
421
|
+
"all": [self._ex, self._ey, self._hz, self._hx, self._hy],
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
@property
|
|
425
|
+
def _ch_output_dict(self):
|
|
426
|
+
return {
|
|
427
|
+
"isp": self._hx_hy,
|
|
428
|
+
"res": self._ex_ey_hz,
|
|
429
|
+
"tf": self._ex_ey_hz,
|
|
430
|
+
"tf_error": self._ex_ey_hz,
|
|
431
|
+
"all": [self._ex, self._ey, self._hz, self._hx, self._hy],
|
|
432
|
+
}
|
|
433
|
+
|
|
372
434
|
def _initialize_transfer_function(self, periods=[1]):
|
|
373
435
|
"""
|
|
374
436
|
create an empty x array for the data. For now this accommodates
|
|
@@ -381,45 +443,45 @@ class ZMM(ZMMHeader):
|
|
|
381
443
|
"""
|
|
382
444
|
# create an empty array for the transfer function
|
|
383
445
|
tf = xr.DataArray(
|
|
384
|
-
data=0 + 0j,
|
|
446
|
+
data=0.0 + 0j,
|
|
385
447
|
dims=["period", "output", "input"],
|
|
386
448
|
coords={
|
|
387
449
|
"period": periods,
|
|
388
|
-
"output": self._ch_output_dict["
|
|
389
|
-
"input": self._ch_input_dict["
|
|
450
|
+
"output": self._ch_output_dict["all"],
|
|
451
|
+
"input": self._ch_input_dict["all"],
|
|
390
452
|
},
|
|
391
453
|
name="transfer_function",
|
|
392
454
|
)
|
|
393
455
|
|
|
394
456
|
tf_err = xr.DataArray(
|
|
395
|
-
data=0,
|
|
457
|
+
data=0.0,
|
|
396
458
|
dims=["period", "output", "input"],
|
|
397
459
|
coords={
|
|
398
460
|
"period": periods,
|
|
399
|
-
"output": self._ch_output_dict["
|
|
400
|
-
"input": self._ch_input_dict["
|
|
461
|
+
"output": self._ch_output_dict["all"],
|
|
462
|
+
"input": self._ch_input_dict["all"],
|
|
401
463
|
},
|
|
402
464
|
name="error",
|
|
403
465
|
)
|
|
404
466
|
|
|
405
467
|
inv_signal_power = xr.DataArray(
|
|
406
|
-
data=0 + 0j,
|
|
468
|
+
data=0.0 + 0j,
|
|
407
469
|
dims=["period", "output", "input"],
|
|
408
470
|
coords={
|
|
409
471
|
"period": periods,
|
|
410
|
-
"output": self._ch_output_dict["
|
|
411
|
-
"input": self._ch_input_dict["
|
|
472
|
+
"output": self._ch_output_dict["all"],
|
|
473
|
+
"input": self._ch_input_dict["all"],
|
|
412
474
|
},
|
|
413
475
|
name="inverse_signal_power",
|
|
414
476
|
)
|
|
415
477
|
|
|
416
478
|
residual_covariance = xr.DataArray(
|
|
417
|
-
data=0 + 0j,
|
|
479
|
+
data=0.0 + 0j,
|
|
418
480
|
dims=["period", "output", "input"],
|
|
419
481
|
coords={
|
|
420
482
|
"period": periods,
|
|
421
|
-
"output": self._ch_output_dict["
|
|
422
|
-
"input": self._ch_input_dict["
|
|
483
|
+
"output": self._ch_output_dict["all"],
|
|
484
|
+
"input": self._ch_input_dict["all"],
|
|
423
485
|
},
|
|
424
486
|
name="residual_covariance",
|
|
425
487
|
)
|
|
@@ -431,7 +493,12 @@ class ZMM(ZMMHeader):
|
|
|
431
493
|
tf_err.name: tf_err,
|
|
432
494
|
inv_signal_power.name: inv_signal_power,
|
|
433
495
|
residual_covariance.name: residual_covariance,
|
|
434
|
-
}
|
|
496
|
+
},
|
|
497
|
+
coords={
|
|
498
|
+
"period": periods,
|
|
499
|
+
"output": self._ch_output_dict["all"],
|
|
500
|
+
"input": self._ch_input_dict["all"],
|
|
501
|
+
},
|
|
435
502
|
)
|
|
436
503
|
|
|
437
504
|
@property
|
|
@@ -464,7 +531,7 @@ class ZMM(ZMMHeader):
|
|
|
464
531
|
# this dimension is hard-coded
|
|
465
532
|
self.sigma_s = np.zeros((self.num_freq, 2, 2), dtype=np.complex64)
|
|
466
533
|
|
|
467
|
-
def read(self, fn=None, get_elevation=
|
|
534
|
+
def read(self, fn=None, get_elevation=False):
|
|
468
535
|
"""
|
|
469
536
|
Read in Egbert zrr/zmm file
|
|
470
537
|
|
|
@@ -474,24 +541,9 @@ class ZMM(ZMMHeader):
|
|
|
474
541
|
if fn is not None:
|
|
475
542
|
self.fn = fn
|
|
476
543
|
self.read_header()
|
|
544
|
+
self.channel_nomenclature = self.channel_dict
|
|
477
545
|
self.initialize_arrays()
|
|
478
546
|
|
|
479
|
-
self._ch_input_dict = {
|
|
480
|
-
"impedance": self.input_channels,
|
|
481
|
-
"tipper": self.input_channels,
|
|
482
|
-
"isp": self.input_channels,
|
|
483
|
-
"res": self.output_channels,
|
|
484
|
-
"tf": self.input_channels,
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
self._ch_output_dict = {
|
|
488
|
-
"impedance": ["ex", "ey"],
|
|
489
|
-
"tipper": ["hz"],
|
|
490
|
-
"isp": self.input_channels,
|
|
491
|
-
"res": self.output_channels,
|
|
492
|
-
"tf": self.output_channels,
|
|
493
|
-
}
|
|
494
|
-
|
|
495
547
|
self._transfer_function = self._initialize_transfer_function()
|
|
496
548
|
self.dataset = self._initialize_transfer_function()
|
|
497
549
|
|
|
@@ -649,9 +701,7 @@ class ZMM(ZMMHeader):
|
|
|
649
701
|
-0.2231E-05 -0.2863E-06 0.8866E-05 0.0000E+00
|
|
650
702
|
"""
|
|
651
703
|
|
|
652
|
-
period = float(
|
|
653
|
-
period_block[0].strip().split(":")[1].split()[0].strip()
|
|
654
|
-
)
|
|
704
|
+
period = float(period_block[0].strip().split(":")[1].split()[0].strip())
|
|
655
705
|
level = int(
|
|
656
706
|
period_block[0].strip().split("level")[1].split()[0].strip()
|
|
657
707
|
)
|
|
@@ -660,12 +710,8 @@ class ZMM(ZMMHeader):
|
|
|
660
710
|
int(period_block[0].strip().split("to")[1].split()[0].strip()),
|
|
661
711
|
)
|
|
662
712
|
|
|
663
|
-
npts = int(
|
|
664
|
-
|
|
665
|
-
)
|
|
666
|
-
sr = float(
|
|
667
|
-
period_block[1].strip().split("freq.")[1].split()[0].strip()
|
|
668
|
-
)
|
|
713
|
+
npts = int(period_block[1].strip().split("point")[1].split()[0].strip())
|
|
714
|
+
sr = float(period_block[1].strip().split("freq.")[1].split()[0].strip())
|
|
669
715
|
self.decimation_dict[f"{period:{PERIOD_FORMAT}}"] = {
|
|
670
716
|
"level": level,
|
|
671
717
|
"bands": bands,
|
|
@@ -722,7 +768,7 @@ class ZMM(ZMMHeader):
|
|
|
722
768
|
sig_block = self._flatten_list(sig_block)
|
|
723
769
|
self.sigma_s[index, 0, 0] = sig_block[0]
|
|
724
770
|
self.sigma_s[index, 1, 0] = sig_block[1]
|
|
725
|
-
self.sigma_s[index, 0, 1] = sig_block[1]
|
|
771
|
+
self.sigma_s[index, 0, 1] = sig_block[1].conjugate()
|
|
726
772
|
self.sigma_s[index, 1, 1] = sig_block[2]
|
|
727
773
|
|
|
728
774
|
def _fill_res_array_from_block(self, res_block, index):
|
|
@@ -28,6 +28,7 @@ from mt_metadata.transfer_functions.tf import (
|
|
|
28
28
|
)
|
|
29
29
|
from mt_metadata.transfer_functions.io.tools import get_nm_elev
|
|
30
30
|
|
|
31
|
+
|
|
31
32
|
# ==============================================================================
|
|
32
33
|
# deal with avg files output from mtedit
|
|
33
34
|
# ==============================================================================
|
|
@@ -37,7 +38,6 @@ class ZongeMTAvg:
|
|
|
37
38
|
"""
|
|
38
39
|
|
|
39
40
|
def __init__(self, fn=None, **kwargs):
|
|
40
|
-
|
|
41
41
|
self.logger = logger
|
|
42
42
|
self.header = Header()
|
|
43
43
|
|
|
@@ -122,7 +122,7 @@ class ZongeMTAvg:
|
|
|
122
122
|
else:
|
|
123
123
|
self._fn = None
|
|
124
124
|
|
|
125
|
-
def read(self, fn=None, get_elevation=
|
|
125
|
+
def read(self, fn=None, get_elevation=False):
|
|
126
126
|
"""
|
|
127
127
|
Read into a pandas data frame
|
|
128
128
|
|
|
@@ -24,6 +24,7 @@ class Band(Base):
|
|
|
24
24
|
def __init__(self, **kwargs):
|
|
25
25
|
|
|
26
26
|
super().__init__(attr_dict=attr_dict, **kwargs)
|
|
27
|
+
self._name = None
|
|
27
28
|
|
|
28
29
|
@property
|
|
29
30
|
def lower_bound(self):
|
|
@@ -41,6 +42,21 @@ class Band(Base):
|
|
|
41
42
|
def upper_closed(self):
|
|
42
43
|
return self.to_interval().closed_right
|
|
43
44
|
|
|
45
|
+
@property
|
|
46
|
+
def name(self):
|
|
47
|
+
"""
|
|
48
|
+
:return: The name of the frequency band (currently defaults to fstring with 6 decimal places.
|
|
49
|
+
:rtype: str
|
|
50
|
+
"""
|
|
51
|
+
if self._name is None:
|
|
52
|
+
self._name = f"{self.center_frequency:.6f}"
|
|
53
|
+
return self._name
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@name.setter
|
|
57
|
+
def name(self, value):
|
|
58
|
+
self._name = value
|
|
59
|
+
|
|
44
60
|
def _indices_from_frequencies(self, frequencies):
|
|
45
61
|
"""
|
|
46
62
|
|
|
@@ -25,6 +25,13 @@ STANDARD_OUTPUT_NAMES = [
|
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
def load_channel_maps():
|
|
28
|
+
"""
|
|
29
|
+
:return: Keys are the channel_nomenclature schema keywords.
|
|
30
|
+
Values are dictionaries which map the STANDARD_INPUT_NAMES, \
|
|
31
|
+
STANDARD_OUTPUT_NAMES to the channel names associated with a given
|
|
32
|
+
channel nomenclature
|
|
33
|
+
:rtype: dict
|
|
34
|
+
"""
|
|
28
35
|
import json
|
|
29
36
|
import pathlib
|
|
30
37
|
fn = pathlib.Path(__file__).parent.joinpath("standards", "channel_nomenclatures.json")
|
|
@@ -35,6 +42,12 @@ def load_channel_maps():
|
|
|
35
42
|
CHANNEL_MAPS = load_channel_maps()
|
|
36
43
|
|
|
37
44
|
def get_allowed_channel_names(standard_names):
|
|
45
|
+
"""
|
|
46
|
+
:param standard_names: one of STANDARD_INPUT_NAMES, or STANDARD_OUTPUT_NAMES
|
|
47
|
+
:type standard_names: list
|
|
48
|
+
:return: allowed_names: list of channel names that are supported
|
|
49
|
+
:rtype: list
|
|
50
|
+
"""
|
|
38
51
|
allowed_names = []
|
|
39
52
|
for ch in standard_names:
|
|
40
53
|
for _, channel_map in CHANNEL_MAPS.items():
|
|
@@ -49,25 +62,12 @@ ALLOWED_OUTPUT_CHANNELS = get_allowed_channel_names(STANDARD_OUTPUT_NAMES)
|
|
|
49
62
|
class ChannelNomenclature(Base):
|
|
50
63
|
__doc__ = write_lines(attr_dict)
|
|
51
64
|
|
|
52
|
-
def __init__(self,
|
|
53
|
-
|
|
54
|
-
super().__init__(attr_dict=attr_dict, **kwargs)
|
|
55
|
-
self._keyword = None
|
|
56
|
-
|
|
57
|
-
def update_by_keyword(self, keyword):
|
|
58
|
-
"""
|
|
59
|
-
Assign the HEXY values "ex", "ey" etc based on a pre-defined dict that
|
|
60
|
-
corresponds to a common use case
|
|
61
|
-
Parameters
|
|
62
|
-
----------
|
|
63
|
-
keyword
|
|
64
|
-
|
|
65
|
-
Returns
|
|
66
|
-
-------
|
|
67
|
-
|
|
68
|
-
"""
|
|
69
|
-
self._update_by_keyword(keyword)
|
|
65
|
+
def __init__(self, keyword=None):
|
|
70
66
|
|
|
67
|
+
super().__init__(attr_dict=attr_dict)
|
|
68
|
+
self._keyword = keyword
|
|
69
|
+
if self._keyword is not None:
|
|
70
|
+
self.update()
|
|
71
71
|
|
|
72
72
|
@property
|
|
73
73
|
def ex_ey(self):
|
|
@@ -100,28 +100,31 @@ class ChannelNomenclature(Base):
|
|
|
100
100
|
@keyword.setter
|
|
101
101
|
def keyword(self, keyword):
|
|
102
102
|
self._keyword = keyword
|
|
103
|
-
self.
|
|
103
|
+
self.update()
|
|
104
104
|
|
|
105
|
-
def get_channel_map(self
|
|
106
|
-
if keyword == "default":
|
|
105
|
+
def get_channel_map(self):
|
|
106
|
+
if self.keyword == "default":
|
|
107
107
|
channel_map = CHANNEL_MAPS["default"]
|
|
108
|
-
elif keyword.upper() == "LEMI12":
|
|
108
|
+
elif self.keyword.upper() == "LEMI12":
|
|
109
109
|
channel_map = CHANNEL_MAPS["lemi12"]
|
|
110
|
-
elif keyword.upper() == "LEMI34":
|
|
110
|
+
elif self.keyword.upper() == "LEMI34":
|
|
111
111
|
channel_map = CHANNEL_MAPS["lemi34"]
|
|
112
|
-
elif keyword.upper() == "NIMS":
|
|
112
|
+
elif self.keyword.upper() == "NIMS":
|
|
113
113
|
channel_map = CHANNEL_MAPS["default"]
|
|
114
|
-
elif keyword.upper() == "PHOENIX123":
|
|
114
|
+
elif self.keyword.upper() == "PHOENIX123":
|
|
115
115
|
channel_map = CHANNEL_MAPS["phoenix123"]
|
|
116
|
-
elif keyword.upper() == "MUSGRAVES":
|
|
116
|
+
elif self.keyword.upper() == "MUSGRAVES":
|
|
117
117
|
channel_map = CHANNEL_MAPS["musgraves"]
|
|
118
118
|
else:
|
|
119
|
-
|
|
120
|
-
raise NotImplementedError
|
|
119
|
+
msg = f"channel mt_system {self.keyword} unknown"
|
|
120
|
+
raise NotImplementedError(msg)
|
|
121
121
|
return channel_map
|
|
122
122
|
|
|
123
|
-
def
|
|
124
|
-
|
|
123
|
+
def update(self):
|
|
124
|
+
"""
|
|
125
|
+
Assign values to standard channel names "ex", "ey" etc based on channel_map dict
|
|
126
|
+
"""
|
|
127
|
+
channel_map = self.get_channel_map()
|
|
125
128
|
self.ex = channel_map["ex"]
|
|
126
129
|
self.ey = channel_map["ey"]
|
|
127
130
|
self.hx = channel_map["hx"]
|
|
@@ -133,5 +136,5 @@ class ChannelNomenclature(Base):
|
|
|
133
136
|
|
|
134
137
|
@property
|
|
135
138
|
def channels(self):
|
|
136
|
-
channels = list(self.get_channel_map(
|
|
139
|
+
channels = list(self.get_channel_map().values())
|
|
137
140
|
return channels
|
|
@@ -28,7 +28,6 @@ class Processing(Base):
|
|
|
28
28
|
__doc__ = write_lines(attr_dict)
|
|
29
29
|
|
|
30
30
|
def __init__(self, **kwargs):
|
|
31
|
-
|
|
32
31
|
self.stations = Stations()
|
|
33
32
|
self._decimations = []
|
|
34
33
|
self.channel_nomenclature = ChannelNomenclature()
|
|
@@ -86,6 +85,12 @@ class Processing(Base):
|
|
|
86
85
|
f"List entry must be a DecimationLevel or dict object not {type(obj)}"
|
|
87
86
|
)
|
|
88
87
|
|
|
88
|
+
elif isinstance(value, str):
|
|
89
|
+
if len(value) > 4:
|
|
90
|
+
raise TypeError(f"Not sure what to do with {type(value)}")
|
|
91
|
+
else:
|
|
92
|
+
self._decimations = []
|
|
93
|
+
|
|
89
94
|
else:
|
|
90
95
|
raise TypeError(f"Not sure what to do with {type(value)}")
|
|
91
96
|
|
|
@@ -224,7 +229,6 @@ class Processing(Base):
|
|
|
224
229
|
decimation_obj.add_band(band)
|
|
225
230
|
self.add_decimation_level(decimation_obj)
|
|
226
231
|
|
|
227
|
-
|
|
228
232
|
def json_fn(self):
|
|
229
233
|
json_fn = self.id + "_processing_config.json"
|
|
230
234
|
return json_fn
|
|
@@ -280,11 +284,14 @@ class Processing(Base):
|
|
|
280
284
|
if not self.stations.remote:
|
|
281
285
|
for decimation in self.decimations:
|
|
282
286
|
if decimation.estimator.engine == "RME_RR":
|
|
283
|
-
|
|
287
|
+
self.logger.info(
|
|
288
|
+
"No RR station specified, switching RME_RR to RME"
|
|
289
|
+
)
|
|
284
290
|
decimation.estimator.engine = "RME"
|
|
285
291
|
|
|
286
292
|
# Make sure that a local station is defined
|
|
287
293
|
if not self.stations.local.id:
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
self.logger.warning(
|
|
295
|
+
"Local station not specified, should be set from Kernel Dataset"
|
|
296
|
+
)
|
|
290
297
|
self.stations.from_dataset_dataframe(kernel_dataset.df)
|
|
@@ -5,6 +5,7 @@ Created on Thu Feb 24 13:58:07 2022
|
|
|
5
5
|
@author: jpeacock
|
|
6
6
|
"""
|
|
7
7
|
import pandas as pd
|
|
8
|
+
|
|
8
9
|
# =============================================================================
|
|
9
10
|
# Imports
|
|
10
11
|
# =============================================================================
|
|
@@ -16,6 +17,7 @@ from .station import Station
|
|
|
16
17
|
attr_dict = get_schema("stations", SCHEMA_FN_PATHS)
|
|
17
18
|
attr_dict.add_dict(get_schema("station", SCHEMA_FN_PATHS), "local")
|
|
18
19
|
|
|
20
|
+
|
|
19
21
|
# =============================================================================
|
|
20
22
|
class Stations(Base):
|
|
21
23
|
"""
|
|
@@ -66,6 +68,11 @@ class Stations(Base):
|
|
|
66
68
|
elif isinstance(rr_station, Station):
|
|
67
69
|
rr_station.remote = True
|
|
68
70
|
self._remote.append(rr_station)
|
|
71
|
+
|
|
72
|
+
elif isinstance(rr_station, str):
|
|
73
|
+
if len(rr_station) > 4:
|
|
74
|
+
raise ValueError(f"not sure to do with {type(rr_station)}")
|
|
75
|
+
|
|
69
76
|
else:
|
|
70
77
|
raise ValueError(f"not sure to do with {type(rr_station)}")
|
|
71
78
|
|
|
@@ -75,7 +82,9 @@ class Stations(Base):
|
|
|
75
82
|
"""
|
|
76
83
|
|
|
77
84
|
if not isinstance(rr, (Station, dict)):
|
|
78
|
-
raise TypeError(
|
|
85
|
+
raise TypeError(
|
|
86
|
+
f"List entry must be a Station object not {type(rr)}"
|
|
87
|
+
)
|
|
79
88
|
if isinstance(rr, dict):
|
|
80
89
|
obj = Station()
|
|
81
90
|
obj.from_dict(rr)
|
|
@@ -130,7 +139,7 @@ class Stations(Base):
|
|
|
130
139
|
df = self.local.to_dataset_dataframe()
|
|
131
140
|
for rr in self.remote:
|
|
132
141
|
remote_df = rr.to_dataset_dataframe()
|
|
133
|
-
df = pd.concat([df, remote_df])
|
|
142
|
+
df = pd.concat([df, remote_df]) # , axis=1, ignore_index=True)
|
|
134
143
|
|
|
135
144
|
df.reset_index(inplace=True, drop=True)
|
|
136
145
|
|
|
@@ -320,7 +320,7 @@ class Decimation(Base):
|
|
|
320
320
|
else:
|
|
321
321
|
required_channels = decimation_level.local_channels
|
|
322
322
|
try:
|
|
323
|
-
assert set(self.channels_estimated)
|
|
323
|
+
assert set(required_channels).issubset(self.channels_estimated)
|
|
324
324
|
except AssertionError:
|
|
325
325
|
msg = (
|
|
326
326
|
f"required_channels for processing {required_channels} not available"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"required": true,
|
|
5
5
|
"style": "number",
|
|
6
6
|
"units": null,
|
|
7
|
-
"description": "Decimation level, must be a
|
|
7
|
+
"description": "Decimation level, must be a non-negative integer starting at 0",
|
|
8
8
|
"options": [],
|
|
9
9
|
"alias": [],
|
|
10
10
|
"example": "1",
|
|
@@ -9,13 +9,35 @@
|
|
|
9
9
|
"alias": [],
|
|
10
10
|
"example": "ex",
|
|
11
11
|
"default": null
|
|
12
|
+
},
|
|
13
|
+
"frequency_max": {
|
|
14
|
+
"type": "float",
|
|
15
|
+
"required": true,
|
|
16
|
+
"style": "number",
|
|
17
|
+
"units": "samples per second",
|
|
18
|
+
"description": "Highest frequency present in the sprectrogam data.",
|
|
19
|
+
"options": [],
|
|
20
|
+
"alias": [],
|
|
21
|
+
"example": 77.0,
|
|
22
|
+
"default": 0.0
|
|
23
|
+
},
|
|
24
|
+
"frequency_min": {
|
|
25
|
+
"type": "float",
|
|
26
|
+
"required": true,
|
|
27
|
+
"style": "number",
|
|
28
|
+
"units": "samples per second",
|
|
29
|
+
"description": "Lowest frequency present in the sprectrogam data.",
|
|
30
|
+
"options": [],
|
|
31
|
+
"alias": [],
|
|
32
|
+
"example": 99.0,
|
|
33
|
+
"default": 0.0
|
|
12
34
|
},
|
|
13
35
|
"sample_rate_decimation_level": {
|
|
14
36
|
"type": "float",
|
|
15
37
|
"required": true,
|
|
16
38
|
"style": "number",
|
|
17
39
|
"units": "samples per second",
|
|
18
|
-
"description": "Sample rate of the decimation level.",
|
|
40
|
+
"description": "Sample rate of the time series that was Fourier transformed to generate the FC decimation level.",
|
|
19
41
|
"options": [],
|
|
20
42
|
"alias": [],
|
|
21
43
|
"example": 60,
|