Newer
Older
import numpy as np
from obspy import UTCDateTime
from typing import Any, List, Optional, Tuple
from .. import ChannelConverter
from .. import pydantic_utcdatetime
class AdjustedMatrix(BaseModel):
"""Attributes pertaining to adjusted(affine) matrices, applied by the AdjustedAlgorithm
Attributes
----------
matrix: affine matrix generated by Affine's calculate method
pier_correction: pier correction generated by Affine's calculate method
starttime: beginning of interval that matrix is valid for
endtime: end of interval that matrix is valid for
NOTE: valid intervals are only generated when bad data is encountered.
Matrix is non-constrained otherwise
"""
matrix: Any
pier_correction: float
starttime: Optional[UTCDateTime] = None
endtime: Optional[UTCDateTime] = None
def process(self, values: List[List[float]], outchannels=["X", "Y", "Z", "F"]):
""" Apply matrix to raw data. Apply pier correction to F when necessary """
data = np.vstack([values[0:3]] + [np.ones_like(values[0])])
adjusted = self.matrix @ data
if "F" in outchannels:
f = values[-1] + self.pier_correction
adjusted = np.vstack([adjusted[0 : len(outchannels) - 1]] + [f])
else:
adjusted = adjusted[0 : len(outchannels)]
return adjusted
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def set_metrics(
self,
ordinates: Tuple[List[float], List[float], List[float]],
absolutes: Tuple[List[float], List[float], List[float]],
):
"""Computes mean absolute error and standard deviation for X, Y, Z, and dF between expected and predicted values.
Attributes
----------
absolutes: X, Y and Z absolutes
ordinates: H, E and Z ordinates
matrix: composed matrix
Outputs
-------
metrics: list of Metric objects
"""
ordinates = np.vstack((ordinates, np.ones_like(ordinates[0])))
predicted = self.matrix @ ordinates
metrics = []
elements = ["X", "Y", "Z", "dF"]
expected = absolutes + tuple(
ChannelConverter.get_computed_f_using_squares(*absolutes)
)
predicted = predicted[0:3] + tuple(
ChannelConverter.get_computed_f_using_squares(*predicted[0:3])
)
for i in range(len(elements) - 1):
diff = expected[i] - predicted[i]
metrics.append(
Metric(
element=elements[i],
absmean=abs(np.nanmean(diff)),
stddev=np.std(diff),
)
)
self.metrics = metrics