Пример #1
0
def test_geo2XYZ():

    X, Y, Z = COO.geo2xyz(-112.567, 43.36, 27.2, unit='dec_deg')
    # gamit convertc results  -1782430.03490 -4288974.18902  4356684.78382
    assert np.sqrt((X - -1782430.03490)**2) < 0.00002
    assert np.sqrt((Y - -4288974.18902)**2) < 0.00002
    assert np.sqrt((Z - 4356684.78382)**2) < 0.00002
Пример #2
0
    def substract_pole(self,W=None,type='rot'):
        """
        Substract the velocity predicted by an Euler pole or a rotation rate vector
        """
        import numpy as np
        if isinstance(W,list):W=np.array(W)
        
        if len(W.shape)==1:W=W.reshape(3,1)


        import pyacs.lib.coordinates as Coordinates
        import pyacs.lib.euler as euler
        import numpy as np

        ltype=['euler','rot'] # type is either Euler pole (long. lat in dec. degrees and deg/Myr or cartesian rotation rate vector in rad/yr)
        if (type not in ltype):
            print("==> type should be either 'euler' or 'rot' ")
        if (type == 'euler'):
            # convert to rotation rate vector
            (lon, lat, omega)=(W[0,0],W[1,0],W[2,0])
            (wx,wy,wz)=euler.euler2rot(lon, lat, omega)
            W=np.zeros([3,1])
            W[0,0]=wx
            W[1,0]=wy
            W[2,0]=wz

        import math

        

        R=Coordinates.mat_rot_general_to_local(math.radians(self.lon),math.radians(self.lat),0.)
        (x,y,z)=Coordinates.geo2xyz(math.radians(self.lon),math.radians(self.lat),0.)
        # Observation equation in local frame
        
        Ai=np.zeros([3,3],float)
        Ai[0,1]= z
        Ai[0,2]=-y
        Ai[1,0]=-z
        Ai[1,2]= x
        Ai[2,0]= y
        Ai[2,1]=-x
        
        RAi=np.dot(R,Ai)
        # Predicted velocity
        Pi=np.dot(RAi,W)
        pve=Pi[0,0]*1.E3
        pvn=Pi[1,0]*1.E3
        
        import copy
        N=copy.deepcopy(self)
        
        N.Ve=self.Ve-pve
        N.Vn=self.Vn-pvn

        return(N)
Пример #3
0
    def proj_profile(self,
                     slon,
                     slat,
                     elon,
                     elat,
                     d,
                     save=None,
                     verbose=False):
        ###################################################################
        """
        project velocity components along a great circle defined by initial/stop points (slon,slat,elon,elat)
        
        :param slon,slat: coordinates of profile start point (decimal degrees) 
        :param elon,elat: coordinates of profile end   point (decimal degrees)
        :param d        : maximum distance for a point to be considered
        :param save     : output file name (optional)
        
        :return         :  numpy 1D array with
        np_code, np_distance_along_profile, np_distance_to_profile , \
                np_Ve , np_Vn , np_SVe , np_SVn , \
                np_v_parallele , np_v_perpendicular , \
                np_sigma_v_parallele , np_sigma_v_perpendicular , np_lazimuth
        """

        lcode = []
        ldistance_along_profile = []
        ldistance_to_profile = []

        lVe = []
        lVn = []
        lSVe = []
        lSVn = []
        lv_parallele = []
        lv_perpendicular = []
        lsigma_v_parallele = []
        lsigma_v_perpendicular = []
        lazimuth = []

        # Rt in meters

        Rt = 6371.0E3

        # import

        import numpy as np
        from pyacs.lib import coordinates as Coordinates
        from pyacs.lib import vectors
        from pyacs.lib.gmtpoint import GMT_Point

        (xi, yi, zi) = Coordinates.geo2xyz(np.radians(slon), np.radians(slat),
                                           0.0)
        Xi = np.array([xi, yi, zi])
        MS = GMT_Point(lon=slon, lat=slat)

        (xs, ys, zs) = Coordinates.geo2xyz(np.radians(elon), np.radians(elat),
                                           0.0)
        Xs = np.array([xs, ys, zs])
        ME = GMT_Point(lon=elon, lat=elat)

        length_arc = MS.spherical_distance(ME) / 1000.0

        POLE = vectors.vector_product(Xi, Xs)
        POLE = vectors.normalize(POLE)

        # LOOP ON SITES

        H_distance = {}

        for M in self.sites:
            if verbose:
                print('-- projecting ', M.code)
            (x, y, z) = Coordinates.geo2xyz(np.radians(M.lon),
                                            np.radians(M.lat), 0.0)

            R = Coordinates.mat_rot_general_to_local(np.radians(M.lon),
                                                     np.radians(M.lat),
                                                     unit='radians')
            OM = np.array([x, y, z])

            OM = vectors.normalize(OM)

            unit_parallele_xyz = vectors.vector_product(POLE, OM)
            unit_parallele_enu = np.dot(R, unit_parallele_xyz)

            v_parallele = M.Ve * unit_parallele_enu[
                0] + M.Vn * unit_parallele_enu[1]
            v_perpendicular = M.Ve * unit_parallele_enu[
                1] - M.Vn * unit_parallele_enu[0]

            azimuth = np.arctan2(unit_parallele_enu[0], unit_parallele_enu[1])

            # longitude of M in the system having AOB as equator and P as north pole
            # to do that, we write the XYZ coordinates of M in the POLE/EQUATOR frame
            #
            x_m = vectors.scal_prod(OM, vectors.normalize(Xi))
            y_m = vectors.scal_prod(
                OM, vectors.normalize(vectors.vector_product(Xi, -POLE)))

            longitud_m = np.arctan2(y_m, x_m)
            distance_along_profile = longitud_m * Rt

            # distance to profile is obtained from the latitude in POLE/EQUATOR frame

            z_m = vectors.scal_prod(OM, POLE)
            latitud_m = np.arcsin(z_m)

            # distance_to_profile= np.fabs(latitud_m) * Rt
            distance_to_profile = latitud_m * Rt

            # now propagates the vcv go get the uncertainty in each direction
            # we use the value of local azimuth of profile and the law of variance propagation

            local_R = np.array([[np.cos(azimuth + np.pi / 2.), np.sin(azimuth + np.pi / 2.)], \
                              [-np.sin(azimuth + np.pi / 2.), np.cos(azimuth + np.pi / 2.)]])

            cov = M.SVe * M.SVn * M.SVen
            vcv_en = np.array([[M.SVe**2, cov], [cov, M.SVn**2]])
            vcv_profile = np.dot(np.dot(local_R, vcv_en), local_R.T)

            sigma_v_parallele = np.sqrt(vcv_profile[0, 0])
            sigma_v_perpendicular = np.sqrt(vcv_profile[1, 1])

            if (np.fabs(distance_to_profile / 1000.0) <
                    d) and (distance_along_profile / 1000.0 >= 0.0) and (
                        distance_along_profile / 1000.0 <= length_arc):

                lcode.append(M.code)
                ldistance_along_profile.append(distance_along_profile / 1000.0)
                ldistance_to_profile.append(distance_to_profile / 1000.0)
                lVe.append(M.Ve)
                lVn.append(M.Vn)
                lSVe.append(M.SVe)
                lSVn.append(M.SVn)
                lv_parallele.append(v_parallele)
                lv_perpendicular.append(v_perpendicular)
                lsigma_v_parallele.append(sigma_v_parallele)
                lsigma_v_perpendicular.append(sigma_v_perpendicular)
                lazimuth.append(np.degrees(azimuth))

                H_distance[distance_along_profile] = \
                ("%4s           %10.3lf               %10.3lf        %10.2lf %10.2lf %10.2lf %10.2lf    %10.2lf          %10.2lf              %10.2lf            %10.2lf          %10.1lf\n"  \
                % (M.code, distance_along_profile / 1000.0, distance_to_profile / 1000.0, M.Ve, M.Vn , M.SVe, M.SVn, v_parallele, v_perpendicular, sigma_v_parallele, sigma_v_perpendicular, np.degrees(azimuth)))

        if save is not None:
            print("-- writing results to ", save)
            fs = open(save, 'w')

            fs.write(
                "#site  profile_distance_to_A (km)  distance_to_profile (km)       Ve         Vn        SVe        SVn    V_parallele     V_perpendicular            SV_parallele            SV_perpendicular        azimuth \n"
            )
            fs.write(
                "#-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n"
            )

            for distance in sorted(H_distance.keys()):
                fs.write("%s" % H_distance[distance])

            fs.close()

        np_distance_along_profile = np.array(ldistance_along_profile)
        lindex = np.argsort(np_distance_along_profile)

        np_code = np.array(lcode, dtype=str)[lindex]
        np_distance_along_profile = np_distance_along_profile[lindex]
        np_distance_to_profile = np.array(ldistance_to_profile)[lindex]
        np_Ve = np.array(lVe)[lindex]
        np_Vn = np.array(lVn)[lindex]
        np_SVe = np.array(lSVe)[lindex]
        np_SVn = np.array(lSVn)[lindex]
        np_v_parallele = np.array(lv_parallele)[lindex]
        np_v_perpendicular = np.array(lv_perpendicular)[lindex]
        np_sigma_v_parallele = np.array(lsigma_v_parallele)[lindex]
        np_sigma_v_perpendicular = np.array(lsigma_v_perpendicular)[lindex]
        np_lazimuth = np.array(lazimuth)[lindex]

        return  np_code, np_distance_along_profile, np_distance_to_profile , \
                np_Ve , np_Vn , np_SVe , np_SVn , \
                np_v_parallele , np_v_perpendicular , \
                np_sigma_v_parallele , np_sigma_v_perpendicular , np_lazimuth
Пример #4
0
    def substract_pole(self, W=None, type_euler='rot'):
        ###################################################################
        """
        substract the prediction of an Euler pole to the velocity field
        """

        import pyacs.lib.coordinates as Coordinates
        import pyacs.lib.euler as euler

        import numpy as np

        W = np.array(W).reshape(3, 1)

        ltype = [
            'euler', 'rot'
        ]  # type is either Euler pole (lon. lat in dec. degrees and deg/Myr or cartesian rotation rate vector in rad/yr)
        if (type_euler not in ltype):
            raise ValueError(
                "!!! type_euler should be either euler or rot. type_euler=%s",
                type_euler)

        if (type_euler == 'euler'):
            # convert to rotation rate vector
            (lon, lat, omega) = (W[0, 0], W[1, 0], W[2, 0])
            (wx, wy, wz) = euler.euler2rot(lon, lat, omega)
            W = np.zeros([3, 1])
            W[0, 0] = wx
            W[1, 0] = wy
            W[2, 0] = wz

        # create a new velocity field

        lGpoint = []

        for M in self.sites:
            R = Coordinates.mat_rot_general_to_local(np.radians(M.lon),
                                                     np.radians(M.lat))
            (x, y, z) = Coordinates.geo2xyz(np.radians(M.lon),
                                            np.radians(M.lat), M.he)
            # Observation equation in local frame

            Ai = np.zeros([3, 3], float)
            Ai[0, 1] = z
            Ai[0, 2] = -y
            Ai[1, 0] = -z
            Ai[1, 2] = x
            Ai[2, 0] = y
            Ai[2, 1] = -x

            RAi = np.dot(R, Ai)
            # Predicted velocity
            Pi = np.dot(RAi, W)
            pve = Pi[0, 0] * 1.E3
            pvn = Pi[1, 0] * 1.E3

            N = M.copy()

            N.Ve = M.Ve - pve
            N.Vn = M.Vn - pvn

            lGpoint.append(N)

        res_vel = Velocity_Field(lgmt_points=lGpoint)

        return res_vel
Пример #5
0
    def pole(self, lexclude=[], method='WLS', exp='pLate', log=None):
        ###################################################################
        """
        Euler pole calculation; available optimization methods are WLS: weighted least squares, LS: least-squares, Dikin: L1 linear estimator
        """

        import numpy as np
        import pyacs.lib.coordinates as Coordinates
        import numpy.linalg as nplinalg
        import pyacs.lib.euler as euler

        np.set_printoptions(precision=2, threshold=10000, linewidth=250)

        # Gets dimensions for the systems
        if lexclude:
            nsites = 0
            for M in self.sites:
                if not (M.code in lexclude):
                    nsites = nsites + 1
        else:
            nsites = self.nsites()

        A = np.zeros([2 * nsites, 3], float)
        B = np.zeros([2 * nsites, 1], float)
        VCV_B = np.zeros([2 * nsites, 2 * nsites], float)

        # starts loop on sites to build the linear system

        index = 0
        H_sites = {}
        for M in self.sites:
            if not (M.code in lexclude):
                # XYZ -> local frame rotation matrix
                H_sites[M.code] = M
                R = Coordinates.mat_rot_general_to_local(
                    np.radians(M.lon), np.radians(M.lat))
                (x, y, z) = Coordinates.geo2xyz(np.radians(M.lon),
                                                np.radians(M.lat), M.he)
                # Observation equation in local frame

                Ai = np.zeros([3, 3], float)
                Ai[0, 1] = z
                Ai[0, 2] = -y
                Ai[1, 0] = -z
                Ai[1, 2] = x
                Ai[2, 0] = y
                Ai[2, 1] = -x

                Ai = Ai / 1000.0

                RAi = np.dot(R, Ai)

                # fill the observation i into the general design matrix A

                A[2 * index, 0] = RAi[0, 0]
                A[2 * index, 1] = RAi[0, 1]
                A[2 * index, 2] = RAi[0, 2]
                A[2 * index + 1, 0] = RAi[1, 0]
                A[2 * index + 1, 1] = RAi[1, 1]
                A[2 * index + 1, 2] = RAi[1, 2]

                B[2 * index, 0] = M.Ve
                B[2 * index + 1, 0] = M.Vn

                M.assign_index(index)

                VCV_B[2 * index, 2 * index] = M.SVe**2
                VCV_B[2 * index + 1, 2 * index + 1] = M.SVn**2
                cov = M.SVe * M.SVn * M.SVen
                VCV_B[2 * index + 1, 2 * index] = cov
                VCV_B[2 * index, 2 * index + 1] = cov

                index = index + 1

        # solves linear system

        P = nplinalg.inv(VCV_B)

        ATP = np.dot((A.T), P)

        N = np.dot(ATP, A)
        M = np.dot(ATP, B)

        # Inversion
        Q = nplinalg.inv(N)
        X = np.dot(Q, M)

        # Model Prediction
        MP = np.dot(A, X)

        # Residuals
        RVen = (B - MP)

        VCV_POLE_X = Q * 1.E-12
        chi2 = np.dot(np.dot(RVen.T, P), RVen)
        dof = 2 * nsites - 3
        reduced_chi2 = np.sqrt(chi2 / float(dof))

        (wx, wy, wz) = (X[0, 0] * 1.E-6, X[1, 0] * 1.E-6, X[2, 0] * 1.E-6)

        # Convert rotation rate in the geocentric cartesian frame to Euler pole in geopgraphical coordinates

        (llambda, phi, omega) = euler.rot2euler(wx, wy, wz)
        (max_sigma, min_sigma, azimuth,
         s_omega) = euler.euler_uncertainty([wx, wy, wz], VCV_POLE_X)

        # Write log

        if (not log): flog_name = exp + '.log'
        else: flog_name = log
        flog = open(flog_name, 'w')

        flog.write("\nROTATION RATE VECTOR\n")
        flog.write("Wx (rad/yr): %11.5G +- %10.5G\n" %
                   (wx, np.sqrt(VCV_POLE_X[0, 0])))
        flog.write("Wy (rad/yr): %11.5G +- %10.5G\n" %
                   (wy, np.sqrt(VCV_POLE_X[1, 1])))
        flog.write("Wz (rad/yr): %11.5G +- %10.5G\n" %
                   (wz, np.sqrt(VCV_POLE_X[2, 2])))

        # flog.write("Wx Wy Wz : %10.5G %10.5G %10.5G\n", % (wx,wy,wz))
        flog.write("ASSOCIATED VARIANCE-COVARIANCE MATRIX (rad/yr)**2\n")
        flog.write("        Wx          Wy            Wz\n")
        flog.write("---------------------------------------\n")
        flog.write("Wx |%11.5G %11.5G %11.5G\n" %
                   (VCV_POLE_X[0, 0], VCV_POLE_X[1, 0], VCV_POLE_X[2, 0]))
        flog.write("Wy |           %11.5G %11.5G\n" %
                   (VCV_POLE_X[1, 1], VCV_POLE_X[2, 1]))
        flog.write("Wz |                      %11.5G\n" % VCV_POLE_X[2, 2])
        flog.write("---------------------------------------\n")

        flog.write("\nEULER POLE\n")
        flog.write("longitude (dec. degree)    : %6.2lf\n" % llambda)
        flog.write("latitude  (dec. degree)    : %6.2lf\n" % phi)
        flog.write("angular velocity (deg/Myr ): %6.3lf\n" % omega)
        flog.write("ASSOCIATED ERROR ELLIPSE\n")
        flog.write("semi major axis            : %5.2lf\n" % max_sigma)
        flog.write("semi minor axis            : %5.2lf\n" % min_sigma)
        flog.write("azimuth of semi major axis : %5.1lf\n" % azimuth)
        flog.write("std(angular velocity)      : %5.3lf\n" % s_omega)

        # Calculating a few statistics

        flog.write("\nSTATISTICS\n")
        flog.write("----------\n")

        flog.write("Number of sites     = %10d\n" % nsites)
        flog.write("Chi**2              = %10.1lf\n" % chi2)
        flog.write("Reduced Chi**2      = %10.1lf\n" % reduced_chi2)
        flog.write("Deg. of. freedom    = %10d\n" % dof)
        if (dof == 0):
            flog.write("A post. var. factor = No meaning (dof=0)\n")
        else:
            sigma_0 = np.sqrt(chi2 / dof)
            flog.write("A post. var. factor = %10.1lf\n" % sigma_0)

        # rms & wrms

        flog.write("\nRESIDUALS\n")
        flog.write("----------\n")
        flog.write(
            "site                    pred_e     pred_n         Ve         Vn       R_ve       R_vn       S_ve       S_vn      RN_ve      RN_vn\n"
        )
        flog.write(
            "------------------------------------------------------------------------------------------------------------------------------------\n"
        )

        cpt_site = 0

        rms = 0.0
        wrms = 0.0
        dwrms = 0.0

        for site, M in sorted(H_sites.items()):
            M = H_sites[site]
            if not (M.code in lexclude):
                i = M.get_index()

                mpe = MP[2 * i, 0]
                mpn = MP[2 * i + 1, 0]

                oe = B[2 * i, 0]
                on = B[2 * i + 1, 0]

                rve = RVen[2 * i, 0]
                rvn = RVen[2 * i + 1, 0]
                sve = M.SVe
                svn = M.SVn

                flog.write("%-19s %10.2lf %10.2lf %10.2lf %10.2lf %10.2lf %10.2lf %10.2lf %10.2lf %10.2lf %10.2lf\n" % \
                           (M.code, mpe,mpn,oe,on,rve, rvn, sve, svn, rve / sve, rvn / svn))

                cpt_site = cpt_site + 1

                rms = rms + rve**2 + rvn**2
                wrms = wrms + (rve / sve)**2 + (rvn / svn)**2
                dwrms = dwrms + 1.0 / sve**2 + 1.0 / svn**2
        flog.write(
            "------------------------------------------------------------------------------------------------------------------------------------\n"
        )

        rms = np.sqrt(rms / 2 / cpt_site)
        wrms = np.sqrt(wrms / dwrms)

        flog.write("rms = %10.2lf mm/yr    wrms = %10.2lf mm/yr\n\n" %
                   (rms, wrms))

        flog.close()

        print("-- Rotation rate results logged in %s" % flog_name)

        return (X * 1.E-6, VCV_POLE_X)
Пример #6
0
    def pole(self,W=None,SW=None,type_euler='rot',option='predict'):
###################################################################

        """Substract the prediction of a given Euler pole"""
        
        import pyacs.lib.coordinates as Coordinates
        import pyacs.lib.euler
        import numpy as np
        
        
        ltype=['euler','rot'] # type is either Euler pole (long. lat in dec. degrees and deg/Myr or cartesian rotation rate vector in rad/yr)
        if (type_euler not in ltype):
            raise ValueError(
                "!!! Error. type_euler should be either euler " +
                "or rot (Euler pole (long. lat in dec. degrees and deg/Myr)" +
                " or cartesian rotation rate vector in rad/yr. type_euler = %s )"
                , type_euler )

        loption=['remove','predict','add'] #
        if (option not in loption):
            raise ValueError(
            "!!! Error. option should be either predict, remove or  add. option = %s " ,
            option
            )
            
        
        if (type_euler == 'euler'):
            if (len(W.shape)!=2):
                W=W.reshape(3,1)

            # convert to rotation rate vector
            (lon, lat, omega)=(W[0,0],W[1,0],W[2,0])
            (wx,wy,wz)=pyacs.lib.euler.euler2rot(lon, lat, omega)
            
            # W
            W=np.zeros((3,1))
            W[0,0]=wx
            W[1,0]=wy
            W[2,0]=wz


        # get spherical coordinates
        
        (x,y,z)=Coordinates.geo2xyz(self.lon,self.lat,self.he,unit='dec_deg')
        (l,p,_)=Coordinates.xyz2geospheric(x,y,z,unit='radians')
        R=Coordinates.mat_rot_general_to_local(l,p)

        # Observation equation in local frame
                
        Ai=np.zeros([3,3],float)
        Ai[0,1]= z
        Ai[0,2]=-y
        Ai[1,0]=-z
        Ai[1,2]= x
        Ai[2,0]= y
        Ai[2,1]=-x
                
        RAi=np.dot(R,Ai)
            
        # Predicted velocity
                
        Pi=np.dot(RAi,W)
            
        pve=Pi[0,0]*1.E3
        pvn=Pi[1,0]*1.E3
        
        N=self.copy()
            
        if (option=='remove'):                
            N.Ve=self.Ve-pve
            N.Vn=self.Vn-pvn
        if (option=='add'):                
            N.Ve=self.Ve+pve
            N.Vn=self.Vn+pvn
        if (option=='predict'):                
            N.Ve=pve
            N.Vn=pvn

        if SW != None:
            # uses pole variance-covariance matrix
            VCV=SW
            #print VCV.shape,Ai.shape
#            VCV=np.zeros((3,3))
#            VCV[0,0]=SW[0]
#            VCV[1,1]=SW[1]
#            VCV[2,2]=SW[2]
        
#            VCV[1,2]=SW[3]
#            VCV[1,3]=SW[4]
#            VCV[2,3]=SW[5]
            
#            VCV_PREDICTION=np.dot(np.dot(Ai,VCV),Ai.T)
            VCV_PREDICTION_ENU=np.dot(np.dot(RAi,VCV),RAi.T)
            (N.SVe,N.SVn)=(np.sqrt(VCV_PREDICTION_ENU[0,0])*1000.0,np.sqrt(VCV_PREDICTION_ENU[1,1])*1000.0 )  

        return(N)