def run_get_waveform(c, event, idb, ref_time_place, min_dist=20, max_dist=300, min_az=0, max_az=360, before=100, after=300, network='*', station='*', channel='BH*', ifresample=False, resample_freq=20, ifrotateRTZ=True, ifrotateUVW=False, ifCapInp=True, ifRemoveResponse=True, ifDetrend=True, ifDemean=True, Taper=False, ifEvInfo=True, scale_factor=10.0**2, ipre_filt=1, pre_filt=(0.005, 0.006, 10.0, 15.0), icreateNull=1, ifFilter=False, fmin=.02, fmax=1, filter_type='bandpass', zerophase=False, corners=4, iplot_response=False, ifplot_spectrogram=False, outformat='VEL', ifsave_sacpaz=False): """ Get SAC waveforms for an event basic usage: run_get_waveform(event) event - obspy Event object min_dist - minimum station distance (default = 20) max_dist - maximum station distance (default =300) before - time window length before the event time (default= 100) after - time window length after the event time (default = 300) network - network codes of potential stations (default=*) channel - component(s) to get, accepts comma separated (default='BH*') ifresample_TF - Boolean. Request resample or not. Default = False resample_freq - sampling frequency to resample waveforms (default 20.0) ifrotate - Boolean, if true will output sac files rotated to baz unrotated sac files will also be written ifCapInp - Boolean, make weight files for CAP ifEvInfo - Boolean, output 'ev_info.dat' containg event info (True) ifRemoveResponse - Boolean, will remove response (True) ifDetrend - Boolean, will remove linear trend from data (True) ifDemean - Boolean, will insult the data (True) scale_factor - scale all data by one value (10.0**2) This usually puts the data in the units required by CAP From m/s to cm/s pre_filt - list, corner frequencies of filter to apply before deconv a good idea when deconvolving (ifRemoveResponse=True) """ evtime = event.origins[0].time reftime = ref_time_place.origins[0].time if idb == 1: print("Preparing request for IRIS ...") # BK network doesn't return data when using the IRIS client. # this option switches to NCEDC if BK is if "BK" in network: client_name = "NCEDC" print( "\nWARNING. Request for BK network. Switching to NCEDC client") c = Client("NCEDC") else: client_name = "IRIS" print("Download stations...") stations = c.get_stations(network=network, station=station, channel=channel, starttime=reftime - before, endtime=reftime + after, level="response") inventory = stations # so that llnl and iris scripts can be combined print("Printing stations") print(stations) print("Done Printing stations...") sta_limit_distance(ref_time_place, stations, min_dist=min_dist, max_dist=max_dist, min_az=min_az, max_az=max_az) print("Downloading waveforms...") bulk_list = make_bulk_list_from_stalist(stations, reftime - before, reftime + after, channel=channel) stream_raw = c.get_waveforms_bulk(bulk_list) elif idb == 3: client_name = "LLNL" print("Preparing request for LLNL ...") # Get event an inventory from the LLNL DB. event_number = int(event.event_descriptions[0].text) # event = llnl_db_client.get_obspy_event(event) inventory = c.get_inventory() print("--> Total stations in LLNL DB: %i" % (len(inventory.get_contents()["stations"]))) sta_limit_distance(event, inventory, min_dist=min_dist, max_dist=max_dist, min_az=min_az, max_az=max_az) print("--> Stations after filtering for distance: %i" % (len(inventory.get_contents()["stations"]))) stations = set([sta.code for net in inventory for sta in net]) _st = c.get_waveforms_for_event(event_number) stream_raw = obspy.Stream() for tr in _st: if tr.stats.station in stations: stream_raw.append(tr) # set reftime stream = obspy.Stream() stream = set_reftime(stream_raw, evtime) print("--> Adding SAC metadata...") st2 = add_sac_metadata(stream, idb=idb, ev=event, stalist=inventory) # Do some waveform QA # - (disabled) Throw out traces with missing data # - log waveform lengths and discrepancies # - Fill-in missing data -- Carl request do_waveform_QA(st2, client_name, event, evtime, before, after) if ifDemean: st2.detrend('demean') if ifDetrend: st2.detrend('linear') if ifFilter: prefilter(st2, fmin, fmax, zerophase, corners, filter_type) if ifRemoveResponse: resp_plot_remove(st2, ipre_filt, pre_filt, iplot_response, scale_factor, stations, outformat) else: # output RAW waveforms decon = False print("WARNING -- NOT correcting for instrument response") if scale_factor > 0: amp_rescale(st2, scale_factor) if idb == 3: amp_rescale_llnl(st2, scale_factor) # Set the sac header KEVNM with event name # This applies to the events from the LLNL database # NOTE this command is needed at the time of writing files, so it has to # be set early st2, evname_key = rename_if_LLNL_event(st2, evtime) # Get list of unique stations + locaiton (example: 'KDAK.00') stalist = [] for tr in st2.traces: #stalist.append(tr.stats.station) stalist.append(tr.stats.network + '.' + tr.stats.station + '.' + tr.stats.location + '.' + tr.stats.channel[:-1]) # Crazy way of getting a unique list of stations stalist = list(set(stalist)) # match start and end points for all traces st2 = trim_maxstart_minend(stalist, st2, client_name, event, evtime, ifresample, resample_freq, before, after) if len(st2) == 0: raise ValueError("no waveforms left to process!") if ifresample == True: # NOTE !!! tell the user if BOTH commands are disabled NOTE !!! if (client_name == "IRIS"): resample(st2, freq=resample_freq) elif (client_name == "LLNL"): resample_cut(st2, resample_freq, evtime, before, after) else: print("WARNING. Will not resample. Using original rate from the data") # save raw waveforms in SAC format path_to_waveforms = evname_key + "/RAW" write_stream_sac_raw(stream_raw, path_to_waveforms, evname_key, idb, event, stations=inventory) # Taper waveforms (optional; Generally used when data is noisy- example: HutchisonGhosh2016) # https://docs.obspy.org/master/packages/autogen/obspy.core.trace.Trace.taper.html # To get the same results as the default taper in SAC, use max_percentage=0.05 and leave type as hann. if Taper: st2.taper(max_percentage=Taper, type='hann', max_length=None, side='both') # save processed waveforms in SAC format path_to_waveforms = evname_key write_stream_sac(st2, path_to_waveforms, evname_key) if ifrotateRTZ: rotate_and_write_stream(st2, evname_key, icreateNull, ifrotateUVW) if ifCapInp: write_cap_weights(st2, evname_key, client_name, event) if ifEvInfo: write_ev_info(event, evname_key) if ifplot_spectrogram: plot_spectrogram(st2, evname_key) if ifsave_sacpaz: write_resp(inventory, evname_key) # save station inventory as XML file xmlfilename = evname_key + "/stations.xml" stations.write(xmlfilename, format="stationxml", validate=True)
def run_get_waveform(self): """ Get SAC waveforms for an event basic usage: run_get_waveform(event) c - client event - obspy Event object ref_time_place - reference time and place (other than origin time and place - for station subsetting) """ c = self.client event = self.ev ref_time_place = self.ref_time_place evtime = event.origins[0].time reftime = ref_time_place.origins[0].time if self.idb == 1: print("Preparing request for IRIS ...") # BK network doesn't return data when using the IRIS client. # this option switches to NCEDC if BK is if "BK" in self.network: client_name = "NCEDC" print( "\nWARNING. Request for BK network. Switching to NCEDC client" ) c = Client("NCEDC") else: client_name = "IRIS" print("Download stations...") stations = c.get_stations(network=self.network, station=self.station, channel=self.channel, starttime=reftime - self.tbefore_sec, endtime=reftime + self.tafter_sec, minlatitude=self.min_lat, maxlatitude=self.max_lat, minlongitude=self.min_lon, maxlongitude=self.max_lon, level="response") inventory = stations # so that llnl and iris scripts can be combined if self.ifverbose: print("Printing stations") print(stations) print("Done Printing stations...") sta_limit_distance(ref_time_place, stations, min_dist=self.min_dist, max_dist=self.max_dist, min_az=self.min_az, max_az=self.max_az, ifverbose=self.ifverbose) #print("Printing stations NEW") #print(stations) #print("Done Printing stations...") #stations.plotprojection="local") # Find P and S arrival times phases = self.phases t1s, t2s = get_phase_arrival_times(stations, event, self.phases, self.phase_window, self.taupmodel, reftime, self.tbefore_sec, self.tafter_sec) print("Downloading waveforms...") # this needs to change bulk_list = make_bulk_list_from_stalist(stations, t1s, t2s, channel=self.channel) stream_raw = c.get_waveforms_bulk(bulk_list) # save ev_info object pickle.dump( self, open(self.evname + '/' + self.evname + '_ev_info.obj', 'wb')) elif self.idb == 3: client_name = "LLNL" print("Preparing request for LLNL ...") # Get event an inventory from the LLNL DB. event_number = int(event.event_descriptions[0].text) # event = llnl_db_client.get_obspy_event(event) inventory = c.get_inventory() nsta_llnl = len(inventory.get_contents()["stations"]) print("--> Total stations in LLNL DB: %i" % nsta_llnl) sta_limit_distance(event, inventory, min_dist=self.min_dist, max_dist=self.max_dist, min_az=self.min_az, max_az=self.max_az) print("--> Stations after filtering for distance: %i" % (len(inventory.get_contents()["stations"]))) stations = set([sta.code for net in inventory for sta in net]) _st = c.get_waveforms_for_event(event_number) stream_raw = obspy.Stream() for tr in _st: if tr.stats.station in stations: stream_raw.append(tr) # set reftime stream = obspy.Stream() stream = set_reftime(stream_raw, evtime) print("--> Adding SAC metadata...") if self.ifverbose: print(inventory) st2 = add_sac_metadata(stream, idb=self.idb, ev=event, stalist=inventory, taup_model=self.taupmodel, phases=phases, phase_write=self.write_sac_phase) # Do some waveform QA do_waveform_QA(st2, client_name, event, evtime, self.tbefore_sec, self.tafter_sec) if self.demean: st2.detrend('demean') if self.detrend: st2.detrend('linear') if self.ifFilter: prefilter(st2, self.f1, self.f2, self.zerophase, self.corners, self.filter_type) if self.remove_response: resp_plot_remove(st2, self.ipre_filt, self.pre_filt, self.iplot_response, self.water_level, self.scale_factor, stations, self.outformat, self.ifverbose) else: # output RAW waveforms decon = False print("WARNING -- NOT correcting for instrument response") if self.scale_factor > 0: amp_rescale(st2, self.scale_factor) if self.idb == 3: amp_rescale_llnl(st2, self.scale_factor) # Set the sac header KEVNM with event name # This applies to the events from the LLNL database # NOTE this command is needed at the time of writing files, so it has to # be set early st2, evname_key = rename_if_LLNL_event(st2, evtime) self.evname = evname_key # save station plot # Note: Plotted are stations in the inventory and NOT the ones with the traces # It could be possible that there might not be waveforms for some of these stations. try: fig = inventory.plot(projection="local", resolution="i", label=False, show=False) Catalog([self.ev]).plot(fig=fig, outfile=self.evname + '/station_map.pdf') except: print("There is a problem with creating the station map!") # Get list of unique stations + locaiton (example: 'KDAK.00') stalist = [] for tr in stream.traces: if self.ifverbose: print(tr) station_key = "%s.%s.%s.%s" % (tr.stats.network, tr.stats.station, tr.stats.location, tr.stats.channel[:-1]) stalist.append(station_key) # Crazy way of getting a unique list of stations stalist = list(set(stalist)) # Resample if self.resample_TF == True: # NOTE !!! tell the user if BOTH commands are disabled NOTE !!! if (client_name == "IRIS"): resample(st2, freq=self.resample_freq) elif (client_name == "LLNL"): resample_cut(st2, self.resample_freq, evtime, self.tbefore_sec, self.tafter_sec) else: print( "WARNING. Will not resample. Using original rate from the data" ) # match start and end points for all traces st2 = trim_maxstart_minend(stalist, st2, client_name, event, evtime, self.resample_TF, self.resample_freq, self.tbefore_sec, self.tafter_sec, self.ifverbose) if len(st2) == 0: raise ValueError("no waveforms left to process!") # save raw waveforms in SAC format if self.isave_raw: path_to_waveforms = evname_key + "/RAW" write_stream_sac_raw(stream_raw, path_to_waveforms, evname_key, self.idb, event, stations=inventory) # Taper waveforms (optional; Generally used when data is noisy- example: HutchisonGhosh2016) # https://docs.obspy.org/master/packages/autogen/obspy.core.trace.Trace.taper.html # To get the same results as the default taper in SAC, use max_percentage=0.05 and leave type as hann. # Note: Tapering also happens while resampling (see util_write_cap.py) if self.taper: st2.taper(max_percentage=self.taper, type='hann', max_length=None, side='both') # save processed waveforms in SAC format # evname_key/RAW_processed = traces after waveform_QA + demean + detrend + # resample + remove response + filtering + # resampling + scaling + tapering # NOTE: The orientation is same as that of extracted waveforms # Waveforms are rotated to ENZ, in case they are not already orientated, # in the next step (self.rotateRTZ) if self.isave_raw_processed: path_to_waveforms = os.path.join(evname_key, 'RAW_processed') write_stream_sac(st2, path_to_waveforms, evname_key) # Rotate to ENZ (save: optional) #if self.rotateENZ: st2 = rotate2ENZ(st2, evname_key, self.isave_ENZ, self.icreateNull, self.ifverbose) # rotate to UVW and save if self.rotateUVW: rotate2UVW(st2, evname_key) # Rotate to RTZ and save if self.rotateRTZ: rotate2RTZ(st2, evname_key, self.ifverbose) # save CAP weight files if self.output_cap_weight_file: write_cap_weights(st2, evname_key, client_name, event, self.ifverbose) # save event info if self.output_event_info: write_ev_info(event, evname_key) # Plot spectrograms if self.ifplot_spectrogram: plot_spectrogram(st2, evname_key) # save pole zero file (Needed for MouseTrap) if self.ifsave_sacpaz: write_resp(inventory, evname_key) # save station inventory as XML file if self.ifsave_stationxml: xmlfilename = evname_key + "/stations.xml" try: inventory.write(xmlfilename, format="stationxml", validate=True) except: print('Could not create stationxml file') # Path to the asdf_converter script if self.ifsave_asdf: # save RTZ asdf_filename = evname_key + "/" + evname_key + ".h5" os.system("../asdf_converters/asdf_converters/sac2asdf.py " + evname_key + " " + asdf_filename + " observed") # save NEZ nez_dir = evname_key + "/ENZ/" nez_asdf_filename = nez_dir + evname_key + ".h5" os.system("../asdf_converters/asdf_converters/sac2asdf.py " + nez_dir + " " + nez_asdf_filename + " observed")
def run_get_waveform(self): """ Get SAC waveforms for an event basic usage: run_get_waveform(event) c - client event - obspy Event object ref_time_place - reference time and place (other than origin time and place - for station subsetting) """ c = self.client event = self.ev ref_time_place = self.ref_time_place evtime = event.origins[0].time reftime = ref_time_place.origins[0].time if (self.idb == 1) or (self.idb == 5): # 2019-03-12 I added idb #5 here and not in a separate block since # the station retrieval is common to #1 and #5 and I rather not repeat the same block. # note that CH stations may not provide all sensor metadata (required when using idb #1) and this crashes with later requests in the code # another option is to add sta retrieval after #3 below but unsure if this creates conflicts. # TODO use 'is' instead of 'in' to avoid wrong calls (eg FZ or GFZ) if ("BK" in self.network) or ("BG" in self.network) or ( "BP" in self.network): # NOTE BK network doesn't return data when using the IRIS client. # this option switches to NCEDC if BK is in networkname. client_name = "NCEDC" elif "CH" in self.network: client_name = "ETH" elif "GFZ" in self.network: client_name = "GFZ" elif "Z3" in self.network: # 2019-07-31 for AlpArray client_name = "ORFEUS" #client_name = "GFZ" #client_name = "ETH" elif "IV" in self.network: client_name = "INGV" elif "DE" in self.network: client_name = "EMSC" # or BGR GFZ LMU ... else: client_name = "IRIS" # default c = Client(client_name) #----------------------------------------------------------- # Check if requesting AlpArray data # the following are ongoing TESTS (alparray data) #c = Client(client_name, password='******') #c = Client(client_name, password='******') #c = Client(client_name, password='******') #c = RoutingClient('iris-federator') # 2019-06-18 This downloads a list of station data, but no waveforms. Also it requires removing radius-related infor (below) and doesn't have a field for eidatoken. #c = RoutingClient('iris-federator', credentials={'EIDA_TOKEN': './eidatoken'}, debug=True) #c = RoutingClient('iris-federator', credentials={'EIDA_TOKEN': './eidatoken'}) #c = RoutingClient('eida-routing', credentials={'EIDA_TOKEN': '/home/calvizur/.eidatoken'}, debug=True) # 2019-07-31 TEST? ## try again AlpArray, arclink # NB doesnt work. 'response' level is not accepted which means I would have to prepare data manually # option: use script similar to Veronica's #c = Client(user='******') # test, AlpArray Client #c.max_status_requests = 2000 if "Z3" in self.network: # 2019-07-31 WORKS! (bondo event) # replace client if requesting AlpArray data c = RoutingClient( 'iris-federator', credentials={'EIDA_TOKEN': '/home/calvizur/.eidatoken'}, debug=True) #----------------------------------------------------------- print(c) print("\n** WARNING ** Preparing request for client", client_name) print("Download stations...") if "Z3" in self.network: # *** alparray only *** stations = c.get_stations(network=self.network, station=self.station, channel=self.channel, starttime=reftime - self.tbefore_sec, endtime=reftime + self.tafter_sec, level="response") else: # default stations = c.get_stations( network=self.network, station=self.station, channel=self.channel, starttime=reftime - self.tbefore_sec, endtime=reftime + self.tafter_sec, #---------------------------------------------------------- # NOTE RoutingClient (AlpArray) does not have the following minlatitude=self.min_lat, maxlatitude=self.max_lat, minlongitude=self.min_lon, maxlongitude=self.max_lon, longitude=self.elon, # required for maxradius latitude=self.elat, # required for maxradius maxradius=18, # note 18 deg ~ 2000 km #---------------------------------------------------------- level="response") inventory = stations # so that llnl and iris scripts can be combined if self.ifverbose: print("Printing stations") print(stations) print("Done Printing stations...") sta_limit_distance(ref_time_place, stations, min_dist=self.min_dist, max_dist=self.max_dist, min_az=self.min_az, max_az=self.max_az, ifverbose=self.ifverbose) #print("Printing stations NEW") #print(stations) #print("Done Printing stations...") #stations.plotprojection="local") # Find P and S arrival times t1s = [] t2s = [] phases = self.phases if self.phase_window: #model = TauPyModel(model=taupmodel) model = TauPyModel(model=self.taupmodel) for net in stations: for sta in net: dist, az, baz = obspy.geodetics.gps2dist_azimuth( event.origins[0].latitude, event.origins[0].longitude, sta.latitude, sta.longitude) dist_deg = kilometer2degrees(dist / 1000, radius=6371) Phase1arrivals = model.get_travel_times( source_depth_in_km=event.origins[0].depth / 1000, distance_in_degree=dist_deg, phase_list=[phases[0]]) if len(Phase1arrivals) == 0: if phases[0] == "P": phases[0] = "p" elif phases[0] == "p": phases[0] = "P" elif phases[0] == "S": phases[0] = "s" elif phases[0] == "s": phases[0] = "S" Phase1arrivals = model.get_travel_times( source_depth_in_km=event.origins[0].depth / 1000, distance_in_degree=dist_deg, phase_list=[phases[0]]) Phase2arrivals = model.get_travel_times( source_depth_in_km=event.origins[0].depth / 1000, distance_in_degree=dist_deg, phase_list=[phases[1]]) if len(Phase2arrivals) == 0: if phases[1] == "P": phases[1] = "p" elif phases[1] == "p": phases[1] = "P" elif phases[1] == "S": phases[1] = "s" elif phases[1] == "s": phases[1] = "S" Phase2arrivals = model.get_travel_times( source_depth_in_km=event.origins[0].depth / 1000, distance_in_degree=dist_deg, phase_list=[phases[1]]) #somearr = model.get_travel_times(source_depth_in_km=event.origins[0].depth/1000,distance_in_degree=dist_deg) #print("Print arrivals") #print(somearr) try: if Phase2arrivals[0].time < Phase1arrivals[0].time: # You are assuming that the first index is the first arrival. Check this later. t1s.append(event.origins[0].time + Phase2arrivals[0].time - self.tbefore_sec) t2s.append(event.origins[0].time + Phase1arrivals[0].time + self.tafter_sec) else: t1s.append(event.origins[0].time + Phase1arrivals[0].time - self.tbefore_sec) t2s.append(event.origins[0].time + Phase2arrivals[0].time + self.tafter_sec) except: t1s.append(reftime - self.tbefore_sec) t2s.append(reftime + self.tafter_sec) else: t1s = [reftime - self.tbefore_sec] t2s = [reftime + self.tafter_sec] print("Downloading waveforms...") # this needs to change bulk_list = make_bulk_list_from_stalist(stations, t1s, t2s, channel=self.channel) stream_raw = c.get_waveforms_bulk(bulk_list) # save ev_info object pickle.dump( self, open(self.evname + '/' + self.evname + '_ev_info.obj', 'wb')) elif self.idb == 3: client_name = "LLNL" print("Preparing request for LLNL ...") # Get event an inventory from the LLNL DB. event_number = int(event.event_descriptions[0].text) # event = llnl_db_client.get_obspy_event(event) inventory = c.get_inventory() nsta_llnl = len(inventory.get_contents()["stations"]) print("--> Total stations in LLNL DB: %i" % nsta_llnl) sta_limit_distance(event, inventory, min_dist=self.min_dist, max_dist=self.max_dist, min_az=self.min_az, max_az=self.max_az) print("--> Stations after filtering for distance: %i" % (len(inventory.get_contents()["stations"]))) stations = set([sta.code for net in inventory for sta in net]) _st = c.get_waveforms_for_event(event_number) stream_raw = obspy.Stream() for tr in _st: if tr.stats.station in stations: stream_raw.append(tr) #----------------------------------------------------------- elif self.idb == 99: # IRIS federator to figure out who has waveform data for that # particular query and subsequently call the individual data # centers to actually get the data. # https://docs.obspy.org/packages/obspy.clients.fdsn.html print("Preparing request through iris-federator") c = RoutingClient('iris-federator', debug=True) stations = c.get_stations( #network = self.network, #station = self.station, channel=self.channel, starttime=reftime - self.tbefore_sec, endtime=reftime + self.tafter_sec, #minlatitude = self.min_lat, #maxlatitude = self.max_lat, #minlongitude = self.min_lon, #maxlongitude = self.max_lon, longitude=self.elon, # required for maxradius latitude=self.elat, # required for maxradius #maxradius = 18, # note 18 deg ~ 2000 km maxradius=18, # note 18 deg ~ 2000 km level="response") print("Downloading waveforms...") # this needs to change bulk_list = make_bulk_list_from_stalist(stations, t1s, t2s, channel=self.channel) stream_raw = c.get_waveforms_bulk(bulk_list) # save ev_info object pickle.dump( self, open(self.evname + '/' + self.evname + '_ev_info.obj', 'wb')) #----------------------------------------------------------- # set reftime stream = obspy.Stream() stream = set_reftime(stream_raw, evtime) print("--> Adding SAC metadata...") if self.ifverbose: print(inventory) st2 = add_sac_metadata(stream, idb=self.idb, ev=event, stalist=inventory, taup_model=self.taupmodel, phases=phases, phase_write=self.write_sac_phase) # Do some waveform QA do_waveform_QA(st2, client_name, event, evtime, self.tbefore_sec, self.tafter_sec) if self.demean: st2.detrend('demean') if self.detrend: st2.detrend('linear') if self.remove_response: resp_plot_remove(st2, self.ipre_filt, self.pre_filt, self.iplot_response, self.scale_factor, stations, self.outformat, self.ifverbose) else: # output RAW waveforms decon = False print("WARNING -- NOT correcting for instrument response") if self.ifFilter: prefilter(st2, self.f1, self.f2, self.zerophase, self.corners, self.filter_type) if self.scale_factor > 0: amp_rescale(st2, self.scale_factor) if self.idb == 3: amp_rescale_llnl(st2, self.scale_factor) # Set the sac header KEVNM with event name # This applies to the events from the LLNL database # NOTE this command is needed at the time of writing files, so it has to # be set early st2, evname_key = rename_if_LLNL_event(st2, evtime) self.evname = evname_key # save station plot # Note: Plotted are stations in the inventory and NOT the ones with the traces # It could be possible that there might not be waveforms for some of these stations. try: fig = inventory.plot(projection="local", resolution="i", label=False, show=False) Catalog([self.ev]).plot(fig=fig, outfile=self.evname + '/station_map.pdf') except: print("There is a problem with creating the station map!") # Get list of unique stations + locaiton (example: 'KDAK.00') stalist = [] for tr in stream.traces: if self.ifverbose: print(tr) station_key = "%s.%s.%s.%s" % (tr.stats.network, tr.stats.station, tr.stats.location, tr.stats.channel[:-1]) stalist.append(station_key) # Crazy way of getting a unique list of stations stalist = list(set(stalist)) # Resample if self.resample_TF == True: # NOTE !!! tell the user if BOTH commands are disabled NOTE !!! if (client_name == "IRIS"): resample(st2, freq=self.resample_freq) elif (client_name == "LLNL"): resample_cut(st2, self.resample_freq, evtime, self.tbefore_sec, self.tafter_sec) else: print( "WARNING. Will not resample. Using original rate from the data" ) # match start and end points for all traces st2 = trim_maxstart_minend(stalist, st2, client_name, event, evtime, self.resample_TF, self.resample_freq, self.tbefore_sec, self.tafter_sec, self.ifverbose) if len(st2) == 0: raise ValueError("no waveforms left to process!") # save raw waveforms in SAC format if self.isave_raw: path_to_waveforms = evname_key + "/RAW" write_stream_sac_raw(stream_raw, path_to_waveforms, evname_key, self.idb, event, stations=inventory) # Taper waveforms (optional; Generally used when data is noisy- example: HutchisonGhosh2016) # https://docs.obspy.org/master/packages/autogen/obspy.core.trace.Trace.taper.html # To get the same results as the default taper in SAC, use max_percentage=0.05 and leave type as hann. if self.taper: st2.taper(max_percentage=self.taper, type='hann', max_length=None, side='both') # save processed waveforms in SAC format # evname_key/RAW_processed = traces after waveform_QA + demean + detrend + # resample + remove response + filtering + # resampling + scaling + tapering # NOTE: The orientation is same as that of extracted waveforms # Waveforms are rotated to ENZ, in case they are not already orientated, # in the next step (self.rotateRTZ) if self.isave_raw_processed: path_to_waveforms = os.path.join(evname_key, 'RAW_processed') write_stream_sac(st2, path_to_waveforms, evname_key) # Rotate to ENZ (save: optional) #if self.rotateENZ: st2 = rotate2ENZ(st2, evname_key, self.isave_ENZ, self.icreateNull, self.ifverbose) # rotate to UVW and save if self.rotateUVW: rotate2UVW(st2, evname_key) # Rotate to RTZ and save if self.rotateRTZ: rotate2RTZ(st2, evname_key, self.ifverbose) # save CAP weight files if self.output_cap_weight_file: write_cap_weights(st2, evname_key, client_name, event, self.ifverbose) # save event info if self.output_event_info: write_ev_info(event, evname_key) # Plot spectrograms if self.ifplot_spectrogram: plot_spectrogram(st2, evname_key) # save pole zero file (Needed for MouseTrap) if self.ifsave_sacpaz: write_resp(inventory, evname_key) # save station inventory as XML file if self.ifsave_stationxml: xmlfilename = evname_key + "/stations.xml" try: inventory.write(xmlfilename, format="stationxml", validate=True) except: print('Could not create stationxml file') print("### DEBUG ###")