14
14
15
15
from mt_metadata .transfer_functions .core import TF
16
16
17
- from mtpy .core import Z , Tipper , COORDINATE_REFERENCE_FRAME_OPTIONS
17
+ from mtpy .core .transfer_function import IMPEDANCE_UNITS
18
+ from mtpy .core import (
19
+ Z ,
20
+ Tipper ,
21
+ COORDINATE_REFERENCE_FRAME_OPTIONS ,
22
+ )
18
23
from mtpy .core .mt_location import MTLocation
19
24
from mtpy .core .mt_dataframe import MTDataFrame
20
25
from mtpy .utils .estimate_tf_quality_factor import EMTFStats
@@ -74,7 +79,7 @@ class MT(TF, MTLocation):
74
79
75
80
"""
76
81
77
- def __init__ (self , fn = None , ** kwargs ):
82
+ def __init__ (self , fn = None , impedance_units = "mt" , ** kwargs ):
78
83
tf_kwargs = {}
79
84
for key in [
80
85
"period" ,
@@ -113,6 +118,9 @@ def __init__(self, fn=None, **kwargs):
113
118
self .station_metadata .transfer_function .sign_convention
114
119
)
115
120
121
+ self ._impedance_unit_factors = IMPEDANCE_UNITS
122
+ self .impedance_units = impedance_units
123
+
116
124
for key , value in kwargs .items ():
117
125
setattr (self , key , value )
118
126
@@ -132,6 +140,7 @@ def clone_empty(self):
132
140
new_mt_obj .model_elevation = self .model_elevation
133
141
new_mt_obj ._rotation_angle = self ._rotation_angle
134
142
new_mt_obj .profile_offset = self .profile_offset
143
+ new_mt_obj .impedance_units = self .impedance_units
135
144
136
145
return new_mt_obj
137
146
@@ -211,6 +220,23 @@ def coordinate_reference_frame(self, value):
211
220
212
221
self .station_metadata .transfer_function .sign_convention = value
213
222
223
+ @property
224
+ def impedance_units (self ):
225
+ """impedance units"""
226
+ return self ._impedance_units
227
+
228
+ @impedance_units .setter
229
+ def impedance_units (self , value ):
230
+ """impedance units setter options are [ mt | ohm ]"""
231
+ if not isinstance (value , str ):
232
+ raise TypeError ("Units input must be a string." )
233
+ if value .lower () not in self ._impedance_unit_factors .keys ():
234
+ raise ValueError (
235
+ f"{ value } is not an acceptable unit for impedance."
236
+ )
237
+
238
+ self ._impedance_units = value
239
+
214
240
@property
215
241
def rotation_angle (self ):
216
242
"""Rotation angle in degrees from north. In the coordinate reference frame"""
@@ -279,15 +305,17 @@ def rotate(self, theta_r, inplace=True):
279
305
280
306
@property
281
307
def Z (self ):
282
- r"""Mtpy.core.z.Z object to hold impedance tenso ."""
308
+ r"""Mtpy.core.z.Z object to hold impedance tensor ."""
283
309
284
310
if self .has_impedance ():
285
- return Z (
311
+ z_object = Z (
286
312
z = self .impedance .to_numpy (),
287
313
z_error = self .impedance_error .to_numpy (),
288
314
frequency = self .frequency ,
289
315
z_model_error = self .impedance_model_error .to_numpy (),
290
316
)
317
+ z_object .units = self .impedance_units
318
+ return z_object
291
319
return Z ()
292
320
293
321
@Z .setter
@@ -296,16 +324,24 @@ def Z(self, z_object):
296
324
297
325
recalculate phase tensor and invariants, which shouldn't change except
298
326
for strike angle.
327
+
328
+ Be sure to have appropriate units set
299
329
"""
330
+ # if a z object is given the underlying data is in mt units, even
331
+ # if the units are set to ohm.
332
+ self .impedance_units = z_object .units
300
333
if not isinstance (z_object .frequency , type (None )):
301
334
if self .frequency .size != z_object .frequency .size :
302
335
self .frequency = z_object .frequency
303
336
304
337
elif not (self .frequency == z_object .frequency ).all ():
305
338
self .frequency = z_object .frequency
306
- self .impedance = z_object .z
307
- self .impedance_error = z_object .z_error
308
- self .impedance_model_error = z_object .z_model_error
339
+ # set underlying data to units of mt
340
+ self .impedance = z_object ._dataset .transfer_function .values
341
+ self .impedance_error = z_object ._dataset .transfer_function_error .values
342
+ self .impedance_model_error = (
343
+ z_object ._dataset .transfer_function_model_error .values
344
+ )
309
345
310
346
@property
311
347
def Tipper (self ):
@@ -634,7 +670,7 @@ def plot_depth_of_penetration(self, **kwargs):
634
670
635
671
return PlotPenetrationDepth1D (self , ** kwargs )
636
672
637
- def to_dataframe (self , utm_crs = None , cols = None ):
673
+ def to_dataframe (self , utm_crs = None , cols = None , impedance_units = "mt" ):
638
674
"""Create a dataframe from the transfer function for use with plotting
639
675
and modeling.
640
676
:param cols:
@@ -644,6 +680,8 @@ def to_dataframe(self, utm_crs=None, cols=None):
644
680
:param eter utm_crs: The utm zone to project station to, could be a
645
681
name, pyproj.CRS, EPSG number, or anything that pyproj.CRS can intake.
646
682
:type eter utm_crs: string, int, :class:`pyproj.CRS`
683
+ :param impedance_units: ["mt" [mV/km/nT] | "ohm" [Ohms] ]
684
+ :type impedance_units: str
647
685
"""
648
686
if utm_crs is not None :
649
687
self .utm_crs = utm_crs
@@ -667,19 +705,21 @@ def to_dataframe(self, utm_crs=None, cols=None):
667
705
668
706
mt_df .dataframe .loc [:, "period" ] = self .period
669
707
if self .has_impedance ():
670
- mt_df .from_z_object (self .Z )
708
+ z_object = self .Z
709
+ z_object .units = impedance_units
710
+ mt_df .from_z_object (z_object )
671
711
if self .has_tipper ():
672
712
mt_df .from_t_object (self .Tipper )
673
713
674
714
return mt_df
675
715
676
- def from_dataframe (self , mt_df ):
716
+ def from_dataframe (self , mt_df , impedance_units = "mt" ):
677
717
"""Fill transfer function attributes from a dataframe for a single station.
678
718
:param mt_df:
679
719
:param df: DESCRIPTION.
680
720
:type df: TYPE
681
- :return: DESCRIPTION.
682
- :rtype: TYPE
721
+ :param impedance_units: ["mt" [mV/km/nT] | "ohm" [Ohms] ]
722
+ :type impedance_units: str
683
723
"""
684
724
685
725
if not isinstance (mt_df , MTDataFrame ):
@@ -713,11 +753,9 @@ def from_dataframe(self, mt_df):
713
753
714
754
self .tf_id = self .station
715
755
716
- # self._transfer_function = self._initialize_transfer_function(
717
- # mt_df.period
718
- # )
719
-
720
- self .Z = mt_df .to_z_object ()
756
+ z_obj = mt_df .to_z_object ()
757
+ z_obj .units = impedance_units
758
+ self .Z = z_obj
721
759
self .Tipper = mt_df .to_t_object ()
722
760
723
761
def compute_model_z_errors (
@@ -1072,9 +1110,7 @@ def add_white_noise(self, value, inplace=True):
1072
1110
] = self ._transfer_function .transfer_function .real * (
1073
1111
noise_real
1074
1112
) + (
1075
- 1j
1076
- * self ._transfer_function .transfer_function .imag
1077
- * noise_imag
1113
+ 1j * self ._transfer_function .transfer_function .imag * noise_imag
1078
1114
)
1079
1115
1080
1116
self ._transfer_function ["transfer_function_error" ] = (
@@ -1088,9 +1124,7 @@ def add_white_noise(self, value, inplace=True):
1088
1124
] = self ._transfer_function .transfer_function .real * (
1089
1125
noise_real
1090
1126
) + (
1091
- 1j
1092
- * self ._transfer_function .transfer_function .imag
1093
- * noise_imag
1127
+ 1j * self ._transfer_function .transfer_function .imag * noise_imag
1094
1128
)
1095
1129
1096
1130
self ._transfer_function ["transfer_function_error" ] = (
0 commit comments