Ejemplo n.º 1
0
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) 
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
    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