def prep_data(self, f1=0.05, f2ps=0.5, f2pps=0.25, f2pss=0.2, nbaz=36 + 1, nslow=40 + 1): """ Method to pre-process the data and calculate the CCP points for each of the receiver functions. Pre-processing includes the binning to back-azimuth and slowness bins to reduce processing time and generate cleaner stacks, as well as filtering to emphasize the energy of the various phases as a function of depth. As a general rule, the high frequency corner of the 2 reverberated phases (Pps and Pss) should be approximately half of the high frequency corner of the direct (Ps) phase. At the end of this step, the object is updated with the amplitude at the lat, lon and depth values corresponding to the raypath for each receiver function. The object is now ready for the method ``prestack``, with the corresponding flag updated. Parameters ---------- f1 : float Low-frequency corner of the bandpass filter used for all phases (Hz) f2ps : float High-frequency corner of the bandpass filter used for the Ps phase (Hz) f2pps : float High-frequency corner of the bandpass filter used for the Pps phase (Hz) f2pss : float High-frequency corner of the bandpass filter used for the Pss phase (Hz) nbaz : int Number of increments in the back-azimuth bins nslow : int Number of increments in the slowness bins The following attributes are added to the object: Other Parameters ---------------- amp_ps_depth : :class:`numpy.ndarray` 2D array of amplitudes as a function of depth for the Ps phase amp_pps_depth : :class:`numpy.ndarray` 2D array of amplitudes as a function of depth for the Pps phase amp_pss_depth : :class:`numpy.ndarray` 2D array of amplitudes as a function of depth for the Pss phase lon_depth : :class:`numpy.ndarray` 2D array of longitude as a function of depth (i.e., piercing points) lat_depth : :class:`numpy.ndarray` 2D array of latitude as a function of depth (i.e., piercing points) is_ready_for_presstack : boolean Flag specifying that the object is ready for the presstack() method n_traces : float Total number of traces used in creating the CCP image. """ if not self.is_ready_for_prep: raise (Exception("CCPimage not ready for pre-prep")) ikey = 0 total_traces = 0 # Process streams one at a time for RF in self.radialRF: # Bin RFs into back-azimuth and slowness bins to speed up # calculations RFbin = binning.bin_baz_slow(RF, nbaz=nbaz, nslow=nslow)[0] n_traces = len(RFbin) total_traces += n_traces amp_ps_tr = np.empty([n_traces, self.nz]) amp_pps_tr = np.empty([n_traces, self.nz]) amp_pss_tr = np.empty([n_traces, self.nz]) lon_tr = np.empty([n_traces, self.nz]) lat_tr = np.empty([n_traces, self.nz]) st_ps = RFbin.copy() st_pps = RFbin.copy() st_pss = RFbin.copy() # Filter Ps, Pps and Pss st_ps.filter('bandpass', freqmin=f1, freqmax=f2ps, corners=4, zerophase=True) st_pps.filter('bandpass', freqmin=f1, freqmax=f2pps, corners=4, zerophase=True) st_pss.filter('bandpass', freqmin=f1, freqmax=f2pss, corners=4, zerophase=True) del RFbin print("Station: " + st_ps[0].stats.station) for itr in _progressbar(range(len(st_ps)), '', 25): # Get raypath and travel time for all phases tt_ps, tt_pps, tt_pss, plon, plat = \ raypath(st_ps[itr], dep=self.zarray, vp=self.vp, vs=self.vs) # Now get amplitude of RF at corresponding travel # time along the raypath lon_tr[itr, :] = plon lat_tr[itr, :] = plat amp_ps = [] amp_pps = [] amp_pss = [] # Loop through travel times and shift RFs to get amplitudes for tt in tt_ps: a, phase = timeshift(st_ps[itr], tt) amp_ps.append(a) amp_ps_tr[itr, :] = amp_ps # Loop through travel times and shift RFs to get amplitudes for tt in tt_pps: a, phase = timeshift(st_pps[itr], tt) amp_pps.append(a) amp_pps_tr[itr, :] = amp_pps # Loop through travel times and shift RFs to get amplitudes for tt in tt_pss: a, phase = timeshift(st_pss[itr], tt) amp_pss.append(a) amp_pss_tr[itr, :] = amp_pss if ikey == 0: amp_ps_depth = amp_ps_tr.transpose() amp_pps_depth = amp_pps_tr.transpose() amp_pss_depth = amp_pss_tr.transpose() lon_depth = lon_tr.transpose() lat_depth = lat_tr.transpose() elif ikey > 0: amp_ps_depth = np.concatenate( (amp_ps_depth, amp_ps_tr.transpose()), axis=1) amp_pps_depth = np.concatenate( (amp_pps_depth, amp_pps_tr.transpose()), axis=1) amp_pss_depth = np.concatenate( (amp_pss_depth, amp_pss_tr.transpose()), axis=1) lon_depth = np.concatenate((lon_depth, lon_tr.transpose()), axis=1) lat_depth = np.concatenate((lat_depth, lat_tr.transpose()), axis=1) ikey += 1 self.amp_ps_depth = amp_ps_depth self.amp_pps_depth = amp_pps_depth self.amp_pss_depth = amp_pss_depth self.lon_depth = lon_depth self.lat_depth = lat_depth self.is_ready_for_prestack = True self.n_traces = total_traces del self.radialRF
def main(): print() print("#########################################") print("# __ _ _ #") print("# _ __ / _|_ __ _ _ | |__ | | __ #") print("# | '__| |_| '_ \| | | | | '_ \| |/ / #") print("# | | | _| |_) | |_| | | | | | < #") print("# |_| |_| | .__/ \__, |___|_| |_|_|\_\ #") print("# |_| |___/_____| #") print("# #") print("#########################################") print() # Run Input Parser args = arguments.get_hk_arguments() # Load Database db = stdb.io.load_db(fname=args.indb) # Construct station key loop allkeys = db.keys() sorted(allkeys) # Extract key subset if len(args.stkeys) > 0: stkeys = [] for skey in args.stkeys: stkeys.extend([s for s in allkeys if skey in s]) else: stkeys = db.keys() sorted(stkeys) # Loop over station keys for stkey in list(stkeys): # Extract station information from dictionary sta = db[stkey] # Define path to see if it exists if args.phase in ['P', 'PP', 'allP']: datapath = Path('P_DATA') / stkey elif args.phase in ['S', 'SKS', 'allS']: datapath = Path('S_DATA') / stkey if not datapath.is_dir(): print('Path to ' + str(datapath) + ' doesn`t exist - continuing') continue # Define save path if args.save: savepath = Path('HK_DATA') / stkey if not savepath.is_dir(): print('Path to ' + str(savepath) + ' doesn`t exist - creating it') savepath.mkdir(parents=True) # Get search start time if args.startT is None: tstart = sta.startdate else: tstart = args.startT # Get search end time if args.endT is None: tend = sta.enddate else: tend = args.endT if tstart > sta.enddate or tend < sta.startdate: continue # Temporary print locations tlocs = sta.location if len(tlocs) == 0: tlocs = [''] for il in range(0, len(tlocs)): if len(tlocs[il]) == 0: tlocs[il] = "--" sta.location = tlocs # Update Display print(" ") print(" ") print("|===============================================|") print("|===============================================|") print("| {0:>8s} |".format( sta.station)) print("|===============================================|") print("|===============================================|") print("| Station: {0:>2s}.{1:5s} |".format( sta.network, sta.station)) print("| Channel: {0:2s}; Locations: {1:15s} |".format( sta.channel, ",".join(tlocs))) print("| Lon: {0:7.2f}; Lat: {1:6.2f} |".format( sta.longitude, sta.latitude)) print("| Start time: {0:19s} |".format( sta.startdate.strftime("%Y-%m-%d %H:%M:%S"))) print("| End time: {0:19s} |".format( sta.enddate.strftime("%Y-%m-%d %H:%M:%S"))) print("|-----------------------------------------------|") rfRstream = Stream() datafiles = [x for x in datapath.iterdir() if x.is_dir()] for folder in datafiles: # Skip hidden folders if folder.name.startswith('.'): continue date = folder.name.split('_')[0] year = date[0:4] month = date[4:6] day = date[6:8] dateUTC = UTCDateTime(year + '-' + month + '-' + day) if dateUTC > tstart and dateUTC < tend: # Load meta data metafile = folder / "Meta_Data.pkl" if not metafile.is_file(): continue meta = pickle.load(open(metafile, 'rb')) # Skip data not in list of phases if meta.phase not in args.listphase: continue # QC Thresholding if meta.snrh < args.snrh: continue if meta.snr < args.snr: continue if meta.cc < args.cc: continue # # Check bounds on data # if meta.slow < args.slowbound[0] and meta.slow > args.slowbound[1]: # continue # if meta.baz < args.bazbound[0] and meta.baz > args.bazbound[1]: # continue # If everything passed, load the RF data filename = folder / "RF_Data.pkl" if filename.is_file(): file = open(filename, "rb") rfdata = pickle.load(file) rfRstream.append(rfdata[1]) file.close() if rfdata[0].stats.npts != 1451: print(folder) if len(rfRstream) == 0: continue if args.no_outl: t1 = 0. t2 = 30. varR = [] for i in range(len(rfRstream)): taxis = rfRstream[i].stats.taxis tselect = (taxis > t1) & (taxis < t2) varR.append(np.var(rfRstream[i].data[tselect])) varR = np.array(varR) # Remove outliers wrt variance within time range medvarR = np.median(varR) madvarR = 1.4826 * np.median(np.abs(varR - medvarR)) robustR = np.abs((varR - medvarR) / madvarR) outliersR = np.arange(len(rfRstream))[robustR > 2.5] for i in outliersR[::-1]: rfRstream.remove(rfRstream[i]) print('') print("Number of radial RF data: " + str(len(rfRstream))) print('') # Try binning if specified if args.calc_dip: rf_tmp = binning.bin_baz_slow(rfRstream, nbaz=args.nbaz + 1, nslow=args.nslow + 1, pws=args.pws) rfRstream = rf_tmp[0] else: rf_tmp = binning.bin(rfRstream, typ='slow', nbin=args.nslow + 1, pws=args.pws) rfRstream = rf_tmp[0] # Get a copy of the radial component and filter if args.copy: rfRstream_copy = rfRstream.copy() rfRstream_copy.filter('bandpass', freqmin=args.bp_copy[0], freqmax=args.bp_copy[1], corners=2, zerophase=True) # Check bin counts: for tr in rfRstream: if (tr.stats.nbin < args.binlim): rfRstream.remove(tr) # Continue if stream is too short if len(rfRstream) < 5: continue if args.save_plot and not Path('HK_PLOTS').is_dir(): Path('HK_PLOTS').mkdir(parents=True) print('') print("Number of radial RF bins: " + str(len(rfRstream))) print('') # Filter original stream rfRstream.filter('bandpass', freqmin=args.bp[0], freqmax=args.bp[1], corners=2, zerophase=True) # Initialize the HkStack object try: hkstack = HkStack(rfRstream, rfV2=rfRstream_copy, strike=args.strike, dip=args.dip, vp=args.vp) except: hkstack = HkStack(rfRstream, strike=args.strike, dip=args.dip, vp=args.vp) # Update attributes hkstack.hbound = args.hbound hkstack.kbound = args.kbound hkstack.dh = args.dh hkstack.dk = args.dk hkstack.weights = args.weights # Stack with or without dip if args.calc_dip: hkstack.stack_dip() else: hkstack.stack() # Average stacks hkstack.average(typ=args.typ) if args.plot: hkstack.plot(args.save_plot, args.title, args.form) if args.save: filename = savepath / (hkstack.rfV1[0].stats.station + \ ".hkstack."+args.typ+".pkl") hkstack.save(file=filename)
def prep_data(self, f1, f2ps, f2pps, f2pss, n_depth=120): # Process streams one at a time for RF in self.radialRF: # Bin RFs into back-azimuth and slowness bins to speed up # calculations RFbin = binning.bin_baz_slow( RF, nbaz=36+1, nslow=40+1, pws=True)[0] n_traces = len(RFbin) amp_ps_tr = np.empty([n_traces, n_depth]) amp_pps_tr = np.empty([n_traces, n_depth]) amp_pss_tr = np.empty([n_traces, n_depth]) lon_tr = np.empty([n_traces, n_depth]) lat_tr = np.empty([n_traces, n_depth]) st_ps = RFbin.copy() st_pps = RFbin.copy() st_pss = RFbin.copy() # Filter Ps, Pps and Pss st_ps.filter( 'bandpass', freqmin=f1, freqmax=f2ps, corners=4, zerophase=True) st_pps.filter( 'bandpass', freqmin=f1, freqmax=f2pps, corners=4, zerophase=True) st_pss.filter( 'bandpass', freqmin=f1, freqmax=f2pss, corners=4, zerophase=True) del RFbin for itr in range(len(st_ps)): print('tr ', itr+1, ' out of ', len(st_ps)) # Get raypath and travel time for all phases tt_ps, tt_pps, tt_pss, plon, plat, idep = \ raypath(st_ps[itr], nz=n_depth, dep=self.dep, vp=self.vp, vs=self.vs) # Now get amplitude of RF at corresponding travel # time along the raypath depth_array = np.asarray(idep) lon_tr[itr, :] = plon lat_tr[itr, :] = plat amp_ps = [] amp_pps = [] amp_pss = [] # Loop through travel times and shift RFs to get amplitudes for tt in tt_ps: a, phase = timeshift(tr_ps[itr], tt) amp_ps.append(self.weights[0]*a) amp_ps_tr[itr, :] = amp_ps # Loop through travel times and shift RFs to get amplitudes for tt in tt_pps: a, phase = timeshift(tr_pps[itr], tt) amp_pps.append(self.weights[1]*a) amp_pps_tr[itr, :] = amp_pps # Loop through travel times and shift RFs to get amplitudes for tt in tt_pss: a, phase = timeshift(tr_pss[itr], tt) amp_pss.append(self.weights[2]*a) amp_pss_tr[itr, :] = amp_pss if i_key == 0: amp_ps_depth = amp_ps_tr.transpose() amp_pps_depth = amp_pps_tr.transpose() amp_pss_depth = amp_pss_tr.transpose() lon_depth = lon_tr.transpose() lat_depth = lat_tr.transpose() elif i_key > 0: amp_ps_depth = np.concatenate( (amp_ps_depth, amp_ps_tr.transpose()), axis=1) amp_pps_depth = np.concatenate( (amp_pps_depth, amp_pps_tr.transpose()), axis=1) amp_pss_depth = np.concatenate( (amp_pss_depth, amp_pss_tr.transpose()), axis=1) lon_depth = np.concatenate( (lon_depth, lon_tr.transpose()), axis=1) lat_depth = np.concatenate( (lat_depth, lat_tr.transpose()), axis=1) i_key += 1 self.amp_ps_depth = amp_ps_depth self.amp_pps_depth = amp_pps_depth self.amp_pss_depth = amp_pss_depth self.lon_depth = lon_depth self.lat_depth = lat_depth self.depth_array = depth_array del self.radialRF