def get_unr(self, lcode): """ :param lcode: list of GNSS site codes to be downloaded from UNR web site :return: new Sgts instance """ # import from pyacs.gts.Gts import Gts from pyacs.gts.Sgts import Sgts # initialize Sgts ts = Sgts(read=False) # loop on sites for code in lcode: print("-- downloading %s from UNR" % code) try: ts.append(Gts().get_unr(code)) except: print("!!!ERROR downloading %s from UNR" % code) # return return ts
def gts(self, method, *args, **kwargs): ################################################################### """ apply a gts method to all Gts instance of the current Sgts object :param method: Gts method to be applied as string :param *arg: arguments for the Gts method to be applied :param **kwarg: keyword arguments for the Gts method to be applied :example : ts.gts('detrend',periods=[2010.0,2013.0]) """ from pyacs.gts.Sgts import Sgts verbose = kwargs.get('verbose', False) new_ts = Sgts(read=False) lsite = self.lcode() for site in sorted(lsite): if verbose: print('-- processing ', site) try: func = getattr(self.__dict__[site], method) new_ts.append(func(*args, **kwargs)) except: print( '!!!WARNING: problem with method %s on gts %s. Removed from output' % (method, site)) return (new_ts)
def add_offsets_dates(self,dates,verbose=False): ################################################################### """ add_offsets_dates to every Gts in current Sgts """ # import from pyacs.gts.Sgts import Sgts from pyacs.gts.Gts import Gts New_Sgts=Sgts(read=False) for gts in self.lGts(): if verbose:print("-- Processing ",gts.code) try: new_gts=gts new_gts.offsets_dates=dates except (RuntimeError, TypeError, NameError): print("!!! Error processing ",gts.code) continue if isinstance(new_gts,Gts): New_Sgts.append(new_gts) else: print("!!! Error processing ",gts.code, "!!! No time series created.") return( New_Sgts )
def sel_rectangle(self, bounds, verbose=True): ################################################################### """ selects the time series for sites within a rectangles :param bounds: [lon_min,lon_max,lat_min,lat_max] :pram verbose: verbose mode :return: a new Sgts instance """ # import from pyacs.gts.Sgts import Sgts [lon_min, lon_max, lat_min, lat_max] = bounds new_Sgts = Sgts(read=False) for gts in self.lGts(): current_lon = gts.lon current_lat = gts.lat if current_lon >= lon_min and current_lon <= lon_max <= lon_max and current_lat >= lat_min and current_lat <= lat_max: if verbose: print("-- ", gts.code, " selected") new_Sgts.append(gts) return (new_Sgts)
def obs_tensor2sgts(T_OBS_RAW, np_names_t_obs, np_obs_date_s, verbose=True): """ Converts a obs_tensor object into a Sgts """ # import import numpy as np from pyacs.gts.Gts import Gts from pyacs.gts.Sgts import Sgts import pyacs.lib.astrotime as at # import pyeq.message.message as MESSAGE # import pyeq.message.verbose_message as VERBOSE # import pyeq.message.error as ERROR # import pyeq.message.debug_message as DEBUG # initialize Sgts sgts = Sgts(read=False) # loop on sites for i in np.arange(np_names_t_obs.shape[0]): code = np_names_t_obs[i] #DEBUG('converting %s ' % code) # get the index of valid dates lindex = np.where(np.isfinite(T_OBS_RAW[:, i, 0]))[0] data = np.zeros((lindex.shape[0], 10)) # obs_tensor is ENU and Gts are NEU data[:, 2] = T_OBS_RAW[lindex, i, 0] * 1E-3 data[:, 1] = T_OBS_RAW[lindex, i, 1] * 1E-3 data[:, 3] = T_OBS_RAW[lindex, i, 2] * 1E-3 data[:, 5] = T_OBS_RAW[lindex, i, 3] * 1E-3 data[:, 4] = T_OBS_RAW[lindex, i, 4] * 1E-3 data[:, 6] = T_OBS_RAW[lindex, i, 5] * 1E-3 data[:, 0] = at.datetime2decyear( at.seconds2datetime(np_obs_date_s[lindex])) sgts.append(Gts(code=code, data=data)) #VERBOSE("converted %d time series " % ( len( sgts.lcode() )) ) return sgts
def sub(self, lexclude=[], linclude=[]): ################################################################### """ Returns a new Sgts instance excluding Gts with code in lexclude and keeping Gts with code in include :param lexclude: list of sites to be excluded :param linclude: list of sites to be included, excluding all other. """ from pyacs.gts.Sgts import Sgts if linclude != []: sub_Sgts = Sgts(read=False) for code in linclude: if (code not in lexclude) and (self.has_ts(code)): sub_Sgts.append(self.__dict__[code].copy()) else: sub_Sgts = self.copy() for code in lexclude: if self.has_ts(code): sub_Sgts.delts(code) return (sub_Sgts)
Rn = Rn * 1.E-3 Ru = Ru * 1.E-3 if l_res_ts.has_ts(code): l_res_ts.__dict__[code].add_obs( date, [Rn, Re, Ru, 1.E-3, 1.E-3, 1.E-3, 0., 0., 0.], in_place=True, check=False, verbose=False) else: new_ts = Gts(code=code) new_ts.add_obs(date, [Rn, Re, Ru, 1.E-3, 1.E-3, 1.E-3, 0., 0., 0.], in_place=True, check=False, verbose=False) l_res_ts.append(new_ts) H_res_helmert[sinex_basename] = [date] + list(H_stat['wrms']) ########################################################################### # WRITING HELMERT SUMMARY AND STORING TSG VALUE ########################################################################### VERBOSE("writing Helmert summary") if isinstance(T, np.ndarray): pyacs.sol.log.helmert_residuals(Residuals, H_stat, free_sinex.name, sum_helmert_file, verbose=verbose)
def same_site(self, dc=10, in_place=True, verbose=False): ################################################################### """ Check that all gts in the current Sgts are actually the same site. If a given time series is found to be of two separate sites, then a new gts is added to the return Sgts instance. param dc: critical distance to decide to split the time series param in_place: if True modify current Sgts, False retuen a new Sgts param verbose: verbose mode return: a new Sgts instance """ # import import numpy as np from pyacs.gts.Sgts import Sgts from pyacs.gts.Gts import Gts if not in_place: new_Sgts = Sgts(read=False) # start loop on sites lcode = self.lcode() for site in lcode: if verbose: print('-- Processing ', site) my_ts = self.__dict__[site].copy() if my_ts.data_xyz is not None: data = my_ts.data_xyz[:, 1:4] ddata = np.copy(my_ts.data_xyz[:, 1:4]) else: # if no data_xyz go to next gts print( "!!! WARNING: data_xyz attribute required for method same_site and not found gts %s" % (site)) # ensure median calculation if np.mod(data.shape[0], 2) == 0: # duplicates the last date ddata = np.vstack((ddata, ddata[-1, :])) median = np.median(ddata, axis=0) dist_data = np.sqrt(np.sum((data - median)**2, axis=1)) lindex = np.where(dist_data > dc * 1.E3) # case gts needs to be split if len(lindex[0]) > 0: # create a new code new_code = my_ts.code[:3] + '_' if new_code in self.lcode(): print( "!!! ERROR: try to create a new gts with code %s and it already exists." % (new_code)) new_code = my_ts.code[:2] + '__' if verbose: print( "-- time series for site %s appears to include different sites because there are coordinates at %d dates %.1lf km from the median position" % (site, len(lindex), np.max(ddata) * 1.E-3)) print( "-- %s time series will be split into code %s and code %s" % (site, site, new_code)) # create a new gts new_gts = Gts(code=new_code, data_xyz=np.copy(my_ts.data_xyz[lindex])) new_gts.xyz2neu(corr=True) # remove the line from my_ts my_ts.data_xyz = np.delete(my_ts.data_xyz, lindex, axis=0) my_ts.xyz2neu(corr=True) # update the ouput if in_place: self.append(new_gts) else: new_Sgts.append(new_gts) if in_place: self.__dict__[site] = my_ts else: new_Sgts.append(my_ts) if in_place: return self else: return new_Sgts
def medvel(self, outdir=None, verbose=False): ################################################################### """ Automatic velocity estimates using median estimator. The code is adapted from the MIDAS approach (Blewitt et al., 2016). medvel fills the velocity attribute of every Gts from the current Sgts instance. returns the modified Sgts instance Optionally, if outdir option is provided, writes the results in outdir :param: outdir: output directory, default None :param: verbose: boolean, verbose mode :param: warning: output warning file :reference: Blewitt, G., Kreemer, C., Hammond, W. C., & Gazeaux, J. (2016). MIDAS robust trend estimator for accurate GPS station velocities without step detection. Journal of Geophysical Research: Solid Earth, 121(3), 2054-2068. """ # import from pyacs.gts.Sgts import Sgts import sys, os # initialize new Sgts new_sgts = Sgts(read=False) # create output directory if outdir is not None: if os.path.isdir(outdir): print('!!! ', outdir, ' directory already exists') sys.exit() elif os.path.isfile(outdir): print('!!! ', outdir, ' file already exists') sys.exit() else: if verbose: print('-- creating ', outdir) os.mkdir(outdir) # output file names out_cgps = outdir + '/vel_cgps.dat' out_sgps = outdir + '/vel_sgps.dat' out_cgps_up = outdir + '/vel_cgps_up.dat' out_sgps_up = outdir + '/vel_sgps_up.dat' # open warning file fwarning = open(outdir + '/warning.dat', 'w+') # start loop on sites lcode = self.lcode() for site in lcode: if verbose: print('-- Processing ', site) # check whether there is at least one year of data if (self.__dict__[site].data[-1, 0] - self.__dict__[site].data[0, 0]) < 1.0: if verbose: print("-- Less than one year of data for site: %s" % site) if outdir is not None: fwarning.write("-- Less than one year of data for site: %s\n" % site) continue # check whether there are at least three data if (self.__dict__[site].data.shape[0]) < 3: if verbose: print("-- Less than 3 data for site: %s" % site) if outdir is not None: fwarning.write("-- Less than 3 data for site: %s\n" % site) # continue # detrended = self.__dict__[site].detrend_median(auto=True) if (detrended.velocity is None): print("-- Problem in detrend_median for site : %s " % site) continue if (outdir is not None): detrended.save_velocity(out_cgps, verbose=verbose) detrended.save_velocity(out_cgps_up, verbose=verbose, up=True) new_sgts.append(detrended) return (new_sgts)
def frame(self, frame=None, euler=None, w=None, verbose=False): ################################################################### """ Rotates the time series according to an Euler pole. User must provide either frame, euler or w. :param frame: str, implemented values are 'soam','nas','nazca','inca','nas_wrt_soam','inca_wrt_soam'. :param euler: Euler values provided either as a \ string 'euler_lon/euler_lat/euler_w', a list [euler_lon,euler_lat,euler_w] or \ a 1D numpy array np.array([euler_lon,euler_lat,euler_w]) :param w: rotation rate vector in rad/yr, provided either as a \ string 'wx/wy/wz', a list [wx,wy,wz] or \ a 1D numpy array np.array([wx,wy,wz]) :return: the new Sgts instance in new frame :ref: All values for frames are from Nocquet et al., Nat Geosc., 2014. """ # import import numpy as np import pyacs.lib.euler from pyacs.gts.Sgts import Sgts from pyacs.gts.Gts import Gts # check arguments are OK if [frame, euler, w].count(None) != 2: print('!!! ERROR: define either argument frame, euler or w ') return (None) # Euler poles taken from pygvel_pole_info.py lEuler = {} # from Jarrin et al., 2022 lEuler['soam'] = [-133.29, -18.41, 0.121] lEuler['nas'] = [-133.999, 12.404, 0.158] # from Nocquet et al., 2021 lEuler['soam_nocquet_2014'] = [-132.21, -18.83, 0.121] lEuler['nas_nocquet_2014'] = [-97.52, 6.48, 0.359] lEuler['nazca_nocquet_2014'] = [-94.4, 61.0, 0.57] lEuler['inca_nocquet_2014'] = [-103.729, -1.344, 0.1659] lEuler['nas_wrt_soam_nocquet_2014'] = [-83.40, 15.21, 0.287] lEuler['inca_wrt_soam_nocquet_2014'] = [-63.76, 22.47, 0.092] # check frame case is OK if (frame not in list(lEuler.keys())) and (frame is not None): print("!!! ERROR: requested frame ", frame, " not known") print("!!! ERROR: available frames are: ", list(lEuler.keys())) return (None) # initialize new gts New_Sgts = Sgts(read=False) # convert to Euler vector whatever the provided argument # case frame if frame is not None: euler_vector = np.array(lEuler[frame]) # case w as rotation rate vector if w != None: if (isinstance(w, str)) and '/' in w: w = np.array(list(map(float, w.split('/')))) if isinstance(w, list): w = np.array(w) if not isinstance(w, np.ndarray): print('!!! ERROR: argument w not understood: ', w) return (None) euler_vector = np.array(pyacs.lib.euler.rot2euler([w[0], w[1], w[2]])) # case euler vector if euler is not None: if (isinstance(euler, str)) and '/' in euler: euler = np.array(list(map(float, euler.split('/')))) if isinstance(euler, list): euler = np.array(euler) if not isinstance(euler, np.ndarray): print('!!! ERROR: argument euler not understood: ', euler) return (None) euler_vector = np.array(euler) # converts the gts for gts in self.lGts(): if verbose: print("-- Processing ", gts.code) try: new_gts = gts.remove_pole(euler_vector, pole_type='euler', in_place=False, verbose=verbose) except (RuntimeError, TypeError, NameError): print("!!! Error processing ", gts.code) continue if isinstance(new_gts, Gts): New_Sgts.append(new_gts) else: print("!!! Error processing ", gts.code, "!!! No time series created.") return (New_Sgts)