def eccentricity(z_array = None, z_object = None, pt_array= None, pt_object = None): if z_array is not None: pt_obj = MTpt.PhaseTensor(z_array = z_array) elif z_object is not None: if not isinstance(z_object, MTz.Z): raise MTex.MTpyError_Z('Input argument is not an instance of the Z class') pt_obj = MTpt.PhaseTensor(z_object = z_object) elif pt_array is not None: pt_obj = MTpt.PhaseTensor(pt_array= pt_array) elif pt_object is not None: if not isinstance(pt_object, MTpt.PhaseTensor): raise MTex.MTpyError_PT('Input argument is not an instance of the PhaseTensor class') pt_obj = pt_object lo_ecc = [] lo_eccerr = [] if not isinstance(pt_obj, MTpt.PhaseTensor): raise MTex.MTpyError_PT('Input argument is not an instance of the PhaseTensor class') for idx_f in range(len(pt_obj.pt)): lo_ecc.append( pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f] ) ecc_err = None if (pt_obj._pi1()[1] is not None) and (pt_obj._pi2()[1] is not None): ecc_err = np.sqrt( (pt_obj._pi1()[1][idx_f] /pt_obj._pi1()[0][idx_f] )**2 + (pt_obj._pi2()[1][idx_f] /pt_obj._pi2()[0][idx_f])**2) lo_eccerr.append(ecc_err) return np.array(lo_ecc), np.array(lo_eccerr)
def __init__(self, pt_object1 = None, pt_object2 = None): """ Initialise an instance of the ResidualPhaseTensor class. Optional input: pt_object1 : instance of the PhaseTensor class pt_object2 : instance of the PhaseTensor class Initialise the attributes with None """ self.residual_pt = None self.rpt = None self.rpt_err = None self._pt1 = None self._pt2 = None self._pt1err = None self._pt2err = None self.freq = None if pt_object1 is not None or pt_object2 is not None: if not ((isinstance(pt_object1, PhaseTensor) and\ isinstance(pt_object2, PhaseTensor))): print type(pt_object1), type(pt_object2) raise MTex.MTpyError_PT('ERROR - arguments must be instances ' 'of the PhaseTensor class') self.compute_residual_pt(pt_object1, pt_object2)
def read_pts(self, pt1, pt2, pt1err = None, pt2err = None): """ Read two PT arrays and calculate the ResPT array (incl. uncertainties). Input: - 2x PT array Optional: - 2x pt_error array """ try: if pt1.shape != pt2.shape: raise except: raise MTex.MTpyError_PT('ERROR - could not build ResPT array from given PT arrays - check shapes! ') #TODO - check arrays here: pt_o1 = PhaseTensor(pt_array = pt1, pt_err_array = pt1err) pt_o2 = PhaseTensor(pt_array = pt2, pt_err_array = pt2err) self.compute_residual_pt(pt_o1,pt_o2)
def _set_pt_err(self, pt_err_array): """ Set the attribute 'pt_err'. Input: Phase-Tensor-error array Test for shape, but no test for consistency! """ self._pt_err = pt_err_array #check dimensions if pt_err_array is not None: if not len(pt_err_array.shape) in [2,3]: raise MTex.MTpyError_PT('ERROR - I cannot set new pt_err array! '+\ 'Invalid dimensions') if not pt_err_array.shape[-2:] == (2,2): raise MTex.MTpyError_PT('ERROR - I cannot set new pt_err array! '+\ 'Invalid dimensions') try: if not pt_err_array.dtype in ['float']: raise ('ERROR - I cannot set new pt_err array! '+\ 'Invalid type') except: raise MTex.MTpyError_PT('ERROR - I cannot set new pt_err array! '+\ 'Invalid data type (float expected)') if self.pt is not None: if self.pt.shape != pt_err_array.shape: raise MTex.MTpyError_PT('ERROR - I cannot set new pt_err '+\ 'array! Invalid dimensions') if len(pt_err_array.shape) == 3: self.pt_err = pt_err_array else: self.pt_err = np.zeros((1,self.pt.shape[0],self.pt.shape[1])) self.pt_err[0] = pt_err_array else: pass
def strike_angle(z_array=None, z_object=None, pt_array=None, pt_object=None, beta_threshold=5, eccentricity_threshold=0.1): if z_array is not None: pt_obj = MTpt.PhaseTensor(z_array=z_array) elif z_object is not None: if not isinstance(z_object, MTz.Z): raise MTex.MTpyError_Z( 'Input argument is not an instance of the Z class') pt_obj = MTpt.PhaseTensor(z_object=z_object) elif pt_array is not None: pt_obj = MTpt.PhaseTensor(pt_array=pt_array) elif pt_object is not None: if not isinstance(pt_object, MTpt.PhaseTensor): raise MTex.MTpyError_PT( 'Input argument is not an instance of the PhaseTensor class') pt_obj = pt_object lo_dims = dimensionality(pt_object=pt_obj, beta_threshold=beta_threshold, eccentricity_threshold=eccentricity_threshold) lo_strikes = [] for idx, dim in enumerate(lo_dims): if dim == 1: lo_strikes.append((np.nan, np.nan)) continue a = pt_obj.alpha[0][idx] b = pt_obj.beta[0][idx] strike1 = (a - b) % 90 if 0 < strike1 < 45: strike2 = strike1 + 90 else: strike2 = strike1 - 90 s1 = min(strike1, strike2) s2 = max(strike1, strike2) lo_strikes.append((s1, s2)) return np.array(lo_strikes)
def dimensionality(z_array=None, z_object=None, pt_array=None, pt_object=None, beta_threshold=5, eccentricity_threshold=0.1): """ beta_threshold: angle in degrees - if beta is smaller than this, it's 2d eccentricity_threshold: fraction of eccentricity (0: circle - 1: line) - if eccentricity (ellipticity) is small than this, it's a 1D geometry. """ lo_dimensionality = [] if z_array is not None: pt_obj = MTpt.PhaseTensor(z_array=z_array) elif z_object is not None: if not isinstance(z_object, MTz.Z): raise MTex.MTpyError_Z( 'Input argument is not an instance of the Z class') pt_obj = MTpt.PhaseTensor(z_object=z_object) elif pt_array is not None: pt_obj = MTpt.PhaseTensor(pt_array=pt_array) elif pt_object is not None: if not isinstance(pt_object, MTpt.PhaseTensor): raise MTex.MTpyError_PT( 'Input argument is not an instance of the PhaseTensor class') pt_obj = pt_object #use criteria from Bibby et al. 2005 for determining the dimensionality for each frequency of the pt/z array: for idx_f in range(len(pt_obj.pt)): #1. determine beta value... beta = pt_obj.beta[0][idx_f] #compare with threshold for 3D if beta > beta_threshold: lo_dimensionality.append(3) else: #2.check for eccentricity: ecc = pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f] if ecc > eccentricity_threshold: lo_dimensionality.append(2) else: lo_dimensionality.append(1) return np.array(lo_dimensionality)
def dimensionality(z_array=None, z_object=None, pt_array=None, pt_object=None, skew_threshold=5, eccentricity_threshold=0.1): """ Esitmate dimensionality of an impedance tensor, frequency by frequency. Dimensionality is estimated from the phase tensor given the threshold criteria on the skew angle and eccentricity following Bibby et al., 2005 and Booker, 2014. Arguments ------------ **z_array** : np.ndarray(nf, 2, 2) numpy array of impedance elements *default* is None **z_object** : mtpy.core.z.Z z_object *default* is None **pt_array** : np.ndarray(nf, 2, 2) numpy array of phase tensor elements *default* is None **pt_object** : mtpy.analysis.pt.PT phase tensor object *default* is None **skew_threshold** : float threshold on the skew angle in degrees, anything above this value is 3-D or azimuthally anisotropic *default* is 5 degrees **eccentricity_threshold** : float threshold on eccentricty in dimensionaless units, anything below this value is 1-D *default* is 0.1 Returns ---------- **dimensions** : np.ndarray(nf, dtype=int) an array of dimesions for each frequency the values are [ 1 | 2 | 3 ] Examples ---------- :Estimate Dimesions: :: >>> import mtpy.analysis.geometry as geometry >>> dim = geometry.dimensionality(z_object=z_obj, >>> skew_threshold=3) """ lo_dimensionality = [] if z_array is not None: pt_obj = MTpt.PhaseTensor(z_array=z_array) elif z_object is not None: if not isinstance(z_object, MTz.Z): raise MTex.MTpyError_Z( 'Input argument is not an instance of the Z class') pt_obj = MTpt.PhaseTensor(z_object=z_object) elif pt_array is not None: pt_obj = MTpt.PhaseTensor(pt_array=pt_array) elif pt_object is not None: if not isinstance(pt_object, MTpt.PhaseTensor): raise MTex.MTpyError_PT( 'Input argument is not an instance of the PhaseTensor class') pt_obj = pt_object # use criteria from Bibby et al. 2005 for determining the dimensionality # for each frequency of the pt/z array: for idx_f in range(len(pt_obj.pt)): #1. determine skew value... skew = pt_obj.beta[idx_f] #compare with threshold for 3D if np.abs(skew) > skew_threshold: lo_dimensionality.append(3) else: # 2.check for eccentricity: ecc = pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f] if ecc > eccentricity_threshold: lo_dimensionality.append(2) else: lo_dimensionality.append(1) return np.array(lo_dimensionality)
def eccentricity(z_array=None, z_object=None, pt_array=None, pt_object=None): """ Estimate eccentricy of a given impedance or phase tensor object Arguments ------------ **z_array** : np.ndarray(nf, 2, 2) numpy array of impedance elements *default* is None **z_object** : mtpy.core.z.Z z_object *default* is None **pt_array** : np.ndarray(nf, 2, 2) numpy array of phase tensor elements *default* is None **pt_object** : mtpy.analysis.pt.PT phase tensor object *default* is None Returns ---------- **eccentricity** : np.ndarray(nf) **eccentricity_err** : np.ndarray(nf) Examples ---------- :Estimate Dimesions: :: >>> import mtpy.analysis.geometry as geometry >>> ec, ec_err= geometry.eccentricity(z_object=z_obj) """ if z_array is not None: pt_obj = MTpt.PhaseTensor(z_array=z_array) elif z_object is not None: if not isinstance(z_object, MTz.Z): raise MTex.MTpyError_Z( 'Input argument is not an instance of the Z class') pt_obj = MTpt.PhaseTensor(z_object=z_object) elif pt_array is not None: pt_obj = MTpt.PhaseTensor(pt_array=pt_array) elif pt_object is not None: if not isinstance(pt_object, MTpt.PhaseTensor): raise MTex.MTpyError_PT( 'Input argument is not an instance of the PhaseTensor class') pt_obj = pt_object lo_ecc = [] lo_eccerr = [] if not isinstance(pt_obj, MTpt.PhaseTensor): raise MTex.MTpyError_PT( 'Input argument is not an instance of the PhaseTensor class') for idx_f in range(len(pt_obj.pt)): lo_ecc.append(pt_obj._pi1()[0][idx_f] / pt_obj._pi2()[0][idx_f]) ecc_err = None if (pt_obj._pi1()[1] is not None) and (pt_obj._pi2()[1] is not None): ecc_err = np.sqrt((pt_obj._pi1()[1][idx_f] / pt_obj._pi1()[0][idx_f]) ** 2 +\ (pt_obj._pi2()[1][idx_f] / pt_obj._pi2()[0][idx_f]) ** 2) lo_eccerr.append(ecc_err) return np.array(lo_ecc), np.array(lo_eccerr) * np.array(lo_ecc)
def strike_angle(z_array=None, z_object=None, pt_array=None, pt_object=None, skew_threshold=5, eccentricity_threshold=0.1): """ Estimate strike angle from 2D parts of the phase tensor given the skew and eccentricity thresholds Arguments ------------ **z_array** : np.ndarray(nf, 2, 2) numpy array of impedance elements *default* is None **z_object** : mtpy.core.z.Z z_object *default* is None **pt_array** : np.ndarray(nf, 2, 2) numpy array of phase tensor elements *default* is None **pt_object** : mtpy.analysis.pt.PT phase tensor object *default* is None **skew_threshold** : float threshold on the skew angle in degrees, anything above this value is 3-D or azimuthally anisotropic *default* is 5 degrees **eccentricity_threshold** : float threshold on eccentricty in dimensionaless units, anything below this value is 1-D *default* is 0.1 Returns ---------- **strike** : np.ndarray(nf) an array of strike angles in degrees for each frequency assuming 0 is north, and e is 90. There is a 90 degree ambiguity in the angle. Examples ---------- :Estimate Dimesions: :: >>> import mtpy.analysis.geometry as geometry >>> strike = geometry.strike_angle(z_object=z_obj, >>> skew_threshold=3) """ if z_array is not None: pt_obj = MTpt.PhaseTensor(z_array=z_array) elif z_object is not None: if not isinstance(z_object, MTz.Z): raise MTex.MTpyError_Z( 'Input argument is not an instance of the Z class') pt_obj = MTpt.PhaseTensor(z_object=z_object) elif pt_array is not None: pt_obj = MTpt.PhaseTensor(pt_array=pt_array) elif pt_object is not None: if not isinstance(pt_object, MTpt.PhaseTensor): raise MTex.MTpyError_PT( 'Input argument is not an instance of the PhaseTensor class') pt_obj = pt_object lo_dims = dimensionality(pt_object=pt_obj, skew_threshold=skew_threshold, eccentricity_threshold=eccentricity_threshold) lo_strikes = [] for idx, dim in enumerate(lo_dims): if dim == 1: lo_strikes.append((np.nan, np.nan)) # continue elif dim == 3: lo_strikes.append((np.nan, np.nan)) else: a = pt_obj.alpha[idx] b = pt_obj.beta[idx] strike1 = (a - b) % 180 # change so that values range from -90 to +90 # add alternative strikes to account for ambiguity if strike1 > 90: strike1 -= 180 strike2 = strike1 + 90 else: strike2 = strike1 - 90 lo_strikes.append((strike1, strike2)) return np.array(lo_strikes)
def compute_residual_pt(self, pt_o1, pt_o2): """ Read in two instance of the MTpy PhaseTensor class. Update attributes: rpt, rpt_err, _pt1, _pt2, _pt1err, _pt2err """ if not ((isinstance(pt_o1, PhaseTensor)) and \ (isinstance(pt_o2, PhaseTensor)) ): raise MTex.MTpyError_PT('ERROR - both arguments must be instances' 'of the PhaseTensor class') pt1 = pt_o1.pt pt2 = pt_o2.pt self.freq = pt_o1.freq #--> compute residual phase tensor if pt1 is not None and pt2 is not None: if pt1.dtype not in [float,int]: raise ValueError if pt2.dtype not in [float,int]: raise ValueError if not pt1.shape == pt2.shape: raise MTex.MTpyError_PT('PT arrays not the same shape') if (not len(pt1.shape) in [2,3]) : raise MTex.MTpyError_PT('PT array is not a valid shape') if len(pt1.shape) == 3: self.rpt = np.zeros_like(pt1) for idx in range(len(pt1)): try: self.rpt[idx] = np.eye(2)-np.dot(np.matrix(pt1[idx]).I, np.matrix(pt2[idx])) except np.linalg.LinAlgError: #print 'Singular matrix at index {0}, frequency {1:.5g}'.format(idx, self.freq[idx]) #print 'Setting residual PT to zeros. ' self.rpt[idx] = np.zeros((2, 2)) self._pt1 = pt1 self._pt2 = pt2 else: self.rpt = np.zeros((1,2,2)) try: self.rpt[0] = np.eye(2)-np.dot(np.matrix(pt1).I, np.matrix(pt2)) except np.linalg.LinAlgError: #print 'Singular matrix at frequency {0:.5g}'.format(self.freq) #print 'Setting residual PT to zeros. ' pass self._pt1 = np.zeros((1,2,2)) self._pt1[0] = pt1 self._pt2 = np.zeros((1,2,2)) self._pt2[0] = pt2 else: print ('Could not determine ResPT - both PhaseTensor objects must' 'contain PT arrays of the same shape') #--> compute residual error pt1err = pt_o1.pt_err pt2err = pt_o2.pt_err if pt1err is not None and pt2err is not None: self.rpt_err = np.zeros(self.rpt.shape) try: if (pt1err.dtype not in [float,int]) or \ (pt2err.dtype not in [float,int]): raise MTex.MTpyError_value if not pt1err.shape == pt2err.shape: raise MTex.MTpyError_value if (not len(pt1err.shape) in [2,3] ): raise MTex.MTpyError_value if self.rpt_err is not None: if self.rpt_err.shape != pt1err.shape: raise MTex.MTpyError_value if len(pt1err.shape) == 3: self.rpt_err = np.zeros((len(pt1),2,2)) for idx in range(len(pt1err)): matrix1 = pt1[idx] matrix1err = pt1err[idx] try: matrix2, matrix2err = MTcc.invertmatrix_incl_errors( pt2[idx], inmatrix_err = pt2err[idx]) summand1,err1 = MTcc.multiplymatrices_incl_errors( matrix2, matrix1, inmatrix1_err = matrix2err, inmatrix2_err = matrix1err) summand2,err2 = MTcc.multiplymatrices_incl_errors( matrix1, matrix2, inmatrix1_err = matrix1err, inmatrix2_err = matrix2err) self.rpt_err[idx] = np.sqrt(0.25*err1**2 +0.25*err2**2) except MTex.MTpyError_inputarguments: self.rpt_err[idx] = 1e10 self._pt_err1 = pt1err self._pt_err2 = pt2err else: self.rpt_err = np.zeros((1, 2, 2)) try: self.rpt_err[0] = np.eye(2) - 0.5 * np.array( np.dot( np.matrix(pt2).I, np.matrix(pt1) ) + np.dot( np.matrix(pt1), np.matrix(pt2).I)) matrix1 = pt1 matrix1err = pt1err matrix2, matrix2err = MTcc.invertmatrix_incl_errors( pt2, inmatrix_err = pt2err) summand1,err1 = MTcc.multiplymatrices_incl_errors( matrix2, matrix1, inmatrix1_err = matrix2err, inmatrix2_err = matrix1err) summand2,err2 = MTcc.multiplymatrices_incl_errors( matrix1, matrix2, inmatrix1_err = matrix1err, inmatrix2_err = matrix2err) self.rpt_err = np.sqrt(0.25*err1**2 +0.25*err2**2) except MTex.MTpyError_inputarguments: self.rpt_err[idx] = 1e10 self._pt1err = np.zeros((1,2,2)) self._pt1err[0] = pt1err self._pt2err = np.zeros((1,2,2)) self._pt2err[0] = pt2err except MTex.MTpyError_value: raise MTex.MTpyError_PT('ERROR - both PhaseTensor objects must' 'contain PT-error arrays of the same shape') else: print ('Could not determine Residual PT uncertainties - both' ' PhaseTensor objects must contain PT-error arrays of the' 'same shape') #--> make a pt object that is the residual phase tensor self.residual_pt = PhaseTensor(pt_array=self.rpt, pt_err_array=self.rpt_err, freq=self.freq)
def z2pt(z_array, z_err_array = None): """ Calculate Phase Tensor from Z array (incl. uncertainties) Input: - Z : 2x2 complex valued Numpy array Optional: - Z-error : 2x2 real valued Numpy array Return: - PT : 2x2 real valued Numpy array - PT-error : 2x2 real valued Numpy array """ if z_array is not None: try: if not len(z_array.shape) in [2,3]: raise if not z_array.shape[-2:] == (2,2): raise if not z_array.dtype in ['complex', 'float']: raise except: raise MTex.MTpyError_PT('Error - incorrect z array: %s;%s instead of (N,2,2);complex'%(str(z_array.shape), str(z_array.dtype))) if z_err_array is not None: try: if not len(z_err_array.shape) in [2,3]: raise if not z_err_array.shape[-2:] == (2,2): raise if not z_err_array.dtype in ['float']: raise except: raise MTex.MTpyError_PT('Error - incorrect z-err-array: %s;%s instead of (N,2,2);real'%(str(z_err_array.shape), str(z_err_array.dtype))) if not z_array.shape == z_err_array.shape: raise MTex.MTpyError_PT('Error - z-array and z-err-array have different shape: %s;%s'%(str(z_array.shape), str(z_err_array.shape))) #for a single matrix as input: if len(z_array.shape) == 2: pt_array = np.zeros((2,2)) realz = np.real(z_array) imagz = np.imag(z_array) detreal = np.linalg.det(realz) if detreal == 0 : if np.linalg.norm(realz) == 0 and np.linalg.norm(imagz) == 0: pt_err_array = np.zeros_like(pt_array) if z_err_array is None: pt_err_array = None return pt_array, pt_err_array else: raise MTex.MTpyError_PT('Error - z-array contains a singular matrix, thus it cannot be converted into a PT!' ) pt_array[0,0] = realz[1,1] * imagz[0,0] - realz[0,1] * imagz[1,0] pt_array[0,1] = realz[1,1] * imagz[0,1] - realz[0,1] * imagz[1,1] pt_array[1,0] = realz[0,0] * imagz[1,0] - realz[1,0] * imagz[0,0] pt_array[1,1] = realz[0,0] * imagz[1,1] - realz[1,0] * imagz[0,1] pt_array /= detreal if z_err_array is None: return pt_array, None pt_err_array = np.zeros_like(pt_array) #Z entries are independent -> use Gaussian error propagation (squared sums/2-norm) pt_err_array[0,0] = 1/np.abs(detreal) * np.sqrt(np.sum([np.abs(-pt_array[0,0] * realz[1,1] * z_err_array[0,0])**2, np.abs( pt_array[0,0] * realz[0,1] * z_err_array[1,0])**2, np.abs(((imagz[0,0] * realz[1,0] - realz[0,0] * imagz[1,0]) / np.abs(detreal) * realz[0,0] ) * z_err_array[0,1])**2, np.abs(((imagz[1,0] * realz[0,0] - realz[1,0] * imagz[1,1]) / np.abs(detreal) * realz[0,1] ) * z_err_array[1,1])**2, np.abs(realz[1,1] * z_err_array[0,0])**2, np.abs(realz[0,1] * z_err_array[1,0])**2 ])) pt_err_array[0,1] = 1/np.abs(detreal) * np.sqrt( np.sum([np.abs( -pt_array[0,1] * realz[1,1] * z_err_array[0,0])**2, np.abs( pt_array[0,1] * realz[0,1] * z_err_array[1,0])**2, np.abs( ( (imagz[0,1] * realz[1,0] - realz[0,0] * imagz[1,1]) / np.abs(detreal) * realz[1,1] ) * z_err_array[0,1])**2, np.abs( ( (imagz[1,1] * realz[0,0] - realz[0,1] * imagz[1,0]) / np.abs(detreal) * realz[0,1] ) * z_err_array[1,1])**2, np.abs( realz[1,1] * z_err_array[0,1])**2, np.abs( realz[0,1] * z_err_array[1,1])**2 ])) pt_err_array[1,0] = 1/np.abs(detreal) * np.sqrt( np.sum([np.abs( pt_array[1,0] * realz[1,0] * z_err_array[0,1])**2, np.abs( -pt_array[1,0] * realz[0,0] * z_err_array[1,1])**2, np.abs( ( (imagz[0,0] * realz[1,1] - realz[0,1] * imagz[1,1]) / np.abs(detreal) * realz[1,0] ) * z_err_array[0,0])**2, np.abs( ( (imagz[1,0] * realz[0,1] - realz[1,1] * imagz[0,0]) / np.abs(detreal) * realz[0,0] ) * z_err_array[0,1])**2, np.abs( realz[1,0] * z_err_array[0,0])**2, np.abs( realz[0,0] * z_err_array[1,0])**2 ])) pt_err_array[1,1] = 1/np.abs(detreal) * np.sqrt( np.sum([np.abs( pt_array[1,1] * realz[1,0] * z_err_array[0,1])**2, np.abs( -pt_array[1,1] * realz[0,0] * z_err_array[1,1])**2, np.abs( ( (imagz[0,1] * realz[1,1] - realz[0,1] * imagz[1,1]) / np.abs(detreal) * realz[1,0] ) * z_err_array[0,0])**2, np.abs( ( (imagz[1,1] * realz[0,1] - realz[1,1] * imagz[0,1]) / np.abs(detreal) * realz[0,0] ) * z_err_array[0,1])**2, np.abs( - realz[1,0] * z_err_array[0,1])**2, np.abs( realz[0,0] * z_err_array[1,1])**2 ])) return pt_array, pt_err_array #else: pt_array = np.zeros((z_array.shape[0],2,2)) for idx_f in range(len(z_array)): realz = np.real(z_array[idx_f]) imagz = np.imag(z_array[idx_f]) detreal = np.linalg.det(realz) if detreal == 0 : raise MTex.MTpyError_Z('Warning - z-array no. {0} contains a singular matrix,'\ ' thus it cannot be converted into a PT!'.format(idx_f)) pt_array[idx_f,0,0] = realz[1,1] * imagz[0,0] - realz[0,1] * imagz[1,0] pt_array[idx_f,0,1] = realz[1,1] * imagz[0,1] - realz[0,1] * imagz[1,1] pt_array[idx_f,1,0] = realz[0,0] * imagz[1,0] - realz[1,0] * imagz[0,0] pt_array[idx_f,1,1] = realz[0,0] * imagz[1,1] - realz[1,0] * imagz[0,1] pt_array /= detreal if z_err_array is None: return pt_array, pt_err_array pt_err_array = np.zeros_like(pt_array) pt_err_array[idx_f,0,0] = 1/detreal * (np.abs( -pt_array[idx_f,0,0] * realz[1,1] * z_err_array[0,0]) + \ np.abs( pt_array[idx_f,0,0] * realz[0,1] * z_err_array[1,0]) + \ np.abs( (imagz[0,0] - pt_array[idx_f,0,0] * realz[0,0] ) * z_err_array[1,1]) +\ np.abs( (-imagz[1,0]+ pt_array[idx_f,0,0] * realz[1,0] ) * z_err_array[0,1]) + \ np.abs( realz[1,1] * z_err_array[0,0]) + np.abs( realz[0,1] * z_err_array[1,0]) ) pt_err_array[idx_f,0,1] = 1/detreal * (np.abs( -pt_array[idx_f,0,1] * realz[1,1] * z_err_array[0,0]) + \ np.abs( pt_array[idx_f,0,1] * realz[0,1] * z_err_array[1,0]) + \ np.abs( (imagz[0,1] - pt_array[idx_f,0,1] * realz[0,0] ) * z_err_array[1,1]) +\ np.abs( (-imagz[1,1]+ pt_array[idx_f,0,1] * realz[1,0] ) * z_err_array[0,1]) + \ np.abs( realz[1,1] * z_err_array[0,1]) + np.abs( realz[0,1] * z_err_array[1,1]) ) pt_err_array[idx_f,1,0] = 1/detreal * (np.abs( (imagz[1,0] - pt_array[idx_f,1,0] * realz[1,1] ) * z_err_array[0,0]) +\ np.abs( pt_array[idx_f,1,0] * realz[1,0] * z_err_array[0,1]) + \ np.abs( (-imagz[0,0] + pt_array[idx_f,1,0] * realz[0,1] ) * z_err_array[1,0]) + \ np.abs( -pt_array[idx_f,1,0] * realz[0,0] * z_err_array[1,1]) + \ np.abs( realz[0,0] * z_err_array[1,0]) + np.abs( -realz[1,0] * z_err_array[0,0]) ) pt_err_array[idx_f,1,1] = 1/detreal * (np.abs( (imagz[1,1] - pt_array[idx_f,1,1] * realz[1,1] ) * z_err_array[0,0]) +\ np.abs( pt_array[idx_f,1,1] * realz[1,0] * z_err_array[0,1]) + \ np.abs( (-imagz[0,1] + pt_array[idx_f,1,1] * realz[0,1] ) * z_err_array[1,0]) + \ np.abs( -pt_array[idx_f,1,1] * realz[0,0] * z_err_array[1,1]) + \ np.abs( realz[0,0] * z_err_array[1,1]) + np.abs( -realz[1,0] * z_err_array[0,1]) ) return pt_array, pt_err_array
def _set_pt(self, pt_array): """ Set the attribute 'pt'. Input: Phase-Tensor array Test for shape, but no test for consistency! """ self._pt = pt_array #check for dimensions if pt_array is not None: #--> large array if not len(pt_array.shape) in [2,3]: raise MTex.MTpyError_PT('ERROR - I cannot set new pt array!'+\ ' Invalid dimensions') #--> single matrix if not pt_array.shape[-2:] == (2,2): raise MTex.MTpyError_PT('ERROR - I cannot set new pt array!'+\ ' Invalid dimensions') #--> make sure values are floats try: if not pt_array.dtype in ['float']: raise MTex.MTpyError_PT('ERROR - I cannot set new pt array!'+\ 'Invalid dimensions') except: raise MTex.MTpyError_PT('ERROR - I cannot set new pt array!'+\ 'Invalid data type (float expected)') if len(pt_array.shape) == 3: self._pt = pt_array else: self._pt = np.zeros((1,pt_array.shape[0],pt_array.shape[1])) self._pt[0] = pt_array #testing existing atributes for consistent shapes: try: if np.shape(self.pt) != np.shape(self.pt_err): raise MTex.MTpyError_inputarguments('pt and pt_err are not'+\ ' the same shape') except: print 'Shape of new PT array and existing pt_error do not match'+\ '- setting pt_error to "None"' self._pt_err = None try: if len(self.pt) != len(self.freq): raise MTex.MTpyError_inputarguments('pt and freq are'+\ 'not the same shape') except: print 'Shape of new PT array and existing "freq" do not'+\ 'match - setting freq to "None"' self._freq = None try: if len(self.pt) != len(self.rotation_angle): raise MTex.MTpyError_inputarguments('pt and rotation angles'+\ 'are not the same shape') except: print 'Shape of new PT array and existing "Rotation_angle" do '+\ 'not match - setting rotation_angle to "None"' self.rotation_angle = None else: pass