def read_st(input, network=None, client_name=None): stream = read(input) try: if stream[0].stats._format == 'Q': for i, trace in enumerate(stream): stream[i].stats.distance= trace.stats.sh['DISTANCE'] stream[i].stats.depth = trace.stats.sh['DEPTH'] stream[i].stats.origin = trace.stats.sh['ORIGIN'] except: msg = 'No Q-file' if isinstance(network, str): if isinstance(client_name, str): client = Client(client_name) try: cat = cat4stream(stream, client_name) inv = inv4stream(stream, network, client_name) attach_coordinates_to_traces(stream, inv, cat[0]) attach_network_to_traces(stream , inv) print('Stream input with Meta-Information read.') return stream except: msg = 'Error with Input: network or client_name wrong?' raise IOError(msg) else: print('Stream input without Meta-Information read.') return stream
def data_request(client_name, cat_client_name, start, end, minmag, net=None, scode="*", channels="*", minlat=None, maxlat=None,minlon=None,maxlon=None, station_minlat=None, station_maxlat=None, station_minlon=None, station_maxlon=None, mindepth=None, maxdepth=None, radialcenterlat=None, radialcenterlon=None, minrad=None, maxrad=None, station_radialcenterlat=None, station_radialcenterlon=None, station_minrad=None, station_maxrad=None, azimuth=None, baz=False, t_before_first_arrival=1, t_after_first_arrival=9, savefile=False, file_format='SAC'): """ Searches in a given Database for seismic data. Restrictions in terms of starttime, endtime, network etc can be made. If data is found it returns a stream variable, with the waveforms, an inventory with all station and network information and a catalog with the event information. :param client_name: Name of desired fdsn client, for a list of all clients see: https://docs.obspy.org/tutorial/code_snippets/retrieving_data_from_datacenters.html :type client_name: string :param cat_client_name: Name of Event catalog :type cat_client_name: string :param start, end: starttime, endtime :type : UTCDateTime :param minmag: Minimum magnitude of event :type minmag: float :param net: Network code for which to search data for :type net: string :param scode: Station code for which to search data for :type scode: string :param channels: Used channels of stations :type channels: string :param minlat, maxlat, minlon, maxlon: Coordinate-window of interest :type : float :param mindepth, maxdepth: depth information of event in km :type : float :param radialcenterlat, radialcenterlon: Centercoordinates of a radialsearch, if radialsearch=True :type : float :param minrad, maxrad: Minimum and maximum radii for radialsearch :type : float :param azimuth: Desired range of azimuths of event, station couples in deg as a list [minimum azimuth, maximum azimuth] :type azimuth: list :param baz: Desired range of back-azimuths of event, station couples in deg as a list [minimum back azimuth, maximum back azimuth] :type baz: list :param t_before_first_arrival, t_before_after_arrival: Length of the seismograms, startingpoint, minutes before 1st arrival and minutes after 1st arrival. :type t_before_first_arrival, t_before_after_arrival: float, int :param savefile: if True, Stream, Inventory and Catalog will be saved local, in the current directory. :type savefile: bool :param format: File-format of the data, for supported formats see: https://docs.obspy.org/packages/autogen/obspy.core.stream.Stream.write.html#obspy.core.stream.Stream.write :type format: string returns :param: list_of_stream, Inventory, Catalog :type: list, obspy, obspy ### Example 1 ### from obspy import UTCDateTime from sipy.util.data_request import data_request start = UTCDateTime(2010,1,1,0,0) end = UTCDateTime(2010,12,31,0,0) minmag = 8 station = '034A' list_of_stream, inventory, cat = data_request('IRIS', start, end, minmag, net='TA', scode=station) st = list_of_stream[0] st = st.select(channel='BHZ') st.normalize() inv = inventory[0] st.plot() inv.plot() cat.plot() ### Example 2 ### from obspy import UTCDateTime from sipy.util.data_request import data_request start = UTCDateTime(2010,1,1,0,0) end = UTCDateTime(2010,12,31,0,0) minmag = 8 station = '034A' client = 'IRIS' cat_client = 'globalcmt' list_of_stream, inventory, cat = data_request(client, cat_client, start, end, minmag, net='TA', scode=station) st = list_of_stream[0] st = st.select(channel='BHZ') st.normalize() inv = inventory[0] st.plot() inv.plot() cat.plot() """ data =[] stream = Stream() streamall = [] #build in different approach for catalog search, using urllib if cat_client_name == 'globalcmt': catalog = request_gcmt(starttime=start, endtime=end, minmagnitude=minmag, mindepth=mindepth, maxdepth=maxdepth, minlatitude=minlat, maxlatitude=maxlat, minlongitude=minlon, maxlongitude=maxlon) client = Client(client_name) else: client = Client(client_name) try: catalog = client.get_events(starttime=start, endtime=end, minmagnitude=minmag, mindepth=mindepth, maxdepth=maxdepth, latitude=radialcenterlat, longitude=radialcenterlon, minradius=minrad, maxradius=maxrad,minlatitude=minlat, maxlatitude=maxlat, minlongitude=minlon, maxlongitude=maxlon) except: print("No events found for given parameters.") return print("Following events found: \n") print(catalog) m = TauPyModel(model="ak135") Plist = ["P", "Pdiff", "p"] for event in catalog: print("\n") print("########################################") print("Looking for available data for event: \n") print(event.short_str()) print("\n") origin_t = event.origins[0].time station_stime = UTCDateTime(origin_t - 3600*24) station_etime = UTCDateTime(origin_t + 3600*24) try: inventory = client.get_stations(network=net, station=scode, level="station", starttime=station_stime, endtime=station_etime, minlatitude=station_minlat, maxlatitude=station_maxlat, minlongitude=station_minlon, maxlongitude=station_maxlon, latitude=station_radialcenterlat, longitude=station_radialcenterlon, minradius=station_minrad, maxradius=station_maxrad) print("Inventory found.") except: print("No Inventory found for given parameters") return for network in inventory: elat = event.origins[0].latitude elon = event.origins[0].longitude depth = event.origins[0].depth/1000. array_fits = True if azimuth or baz: cog=center_of_gravity(network) slat = cog['latitude'] slon = cog['longitude'] epidist = locations2degrees(slat,slon,elat,elon) arrivaltime = m.get_travel_times(source_depth_in_km=depth, distance_in_degree=epidist, phase_list=Plist) P_arrival_time = arrivaltime[0] Ptime = P_arrival_time.time tstart = UTCDateTime(event.origins[0].time + Ptime - t_before_first_arrival * 60) tend = UTCDateTime(event.origins[0].time + Ptime + t_after_first_arrival * 60) center = geometrical_center(inv) clat = center['latitude'] clon = center['longitude'] if azimuth: print("Looking for events in the azimuth range of %f to %f" % (azimuth[0], azimuth[1]) ) center_az = gps2dist_azimuth(clat, clon, elat, elon)[1] if center_az > azimuth[1] and center_az < azimuth[0]: print("Geometrical center of Array out of azimuth bounds, \ncheking if single stations fit") array_fits = False elif baz: print("Looking for events in the back azimuth range of %f to %f" %(baz[0], baz[1])) center_baz = gps2dist_azimuth(clat, clon, elat, elon)[2] if center_baz > baz[1] and center_baz < baz[0]: print("Geometrical center of Array out of back azimuth bounds, \ncheking if single stations fit") array_fits = False # If array fits to azimuth/back azimuth or no azimuth/back azimuth is given no_of_stations = 0 if array_fits: for station in network: epidist = locations2degrees(station.latitude,station.longitude,elat,elon) arrivaltime = m.get_travel_times(source_depth_in_km=depth, distance_in_degree=epidist, phase_list=Plist) P_arrival_time = arrivaltime[0] Ptime = P_arrival_time.time tstart = UTCDateTime(event.origins[0].time + Ptime - t_before_first_arrival * 60) tend = UTCDateTime(event.origins[0].time + Ptime + t_after_first_arrival * 60) try: streamreq = client.get_waveforms(network=network.code, station=station.code, location='*', channel=channels, starttime=tstart, endtime=tend, attach_response=True) no_of_stations += 1 print("Downloaded data for %i of %i available stations!" % (no_of_stations, network.selected_number_of_stations), end='\r' ) sys.stdout.flush() stream += streamreq try: if inventory_used: inventory_used += client.get_stations(network=net, station=scode, level="station", starttime=station_stime, endtime=station_etime, minlatitude=station_minlat, maxlatitude=station_maxlat, minlongitude=station_minlon, maxlongitude=station_maxlon, latitude=station_radialcenterlat, longitude=station_radialcenterlon, minradius=station_minrad, maxradius=station_maxrad) except: inventory_used = client.get_stations(network=net, station=scode, level="station", starttime=station_stime, endtime=station_etime, minlatitude=station_minlat, maxlatitude=station_maxlat, minlongitude=station_minlon, maxlongitude=station_maxlon, latitude=station_radialcenterlat, longitude=station_radialcenterlon, minradius=station_minrad, maxradius=station_maxrad) except: continue # If not checking each station individually. else: for station in network: epidist = locations2degrees(station.latitude,station.longitude,elat,elon) arrivaltime = m.get_travel_times(source_depth_in_km=depth, distance_in_degree=epidist, phase_list=Plist) P_arrival_time = arrivaltime[0] Ptime = P_arrival_time.time tstart = UTCDateTime(event.origins[0].time + Ptime - t_before_first_arrival * 60) tend = UTCDateTime(event.origins[0].time + Ptime + t_after_first_arrival * 60) fit = False if azimuth: stat_az = gps2dist_azimuth(station.latitude, station.longitude, elat, elon)[1] if stat_az > azimuth[1] and stat_az < azimuth[0]: fit = True elif baz: stat_baz = gps2dist_azimuth(station.latitude, station.longitude, elat, elon)[2] if stat_baz > baz[1] and stat_baz < baz[0]: fit = True if fit: try: streamreq = client.get_waveforms(network = network.code, station = station.code, location='*', channel = channels, startime = tstart, endtime = tend, attach_response = True) no_of_stations += 1 print("Downloaded data for %i of %i available stations!" % (no_of_stations, network.selected_number_of_stations), end='\r' ) sys.stdout.flush() stream += streamreq try: if inventory_used: inventory_used += client.get_stations(network=net, station=scode, level="station", starttime=station_stime, endtime=station_etime, minlatitude=station_minlat, maxlatitude=station_maxlat, minlongitude=station_minlon, maxlongitude=station_maxlon, latitude=station_radialcenterlat, longitude=station_radialcenterlon, minradius=station_minrad, maxradius=station_maxrad) except: inventory_used = client.get_stations(network=net, station=scode, level="station", starttime=station_stime, endtime=station_etime, minlatitude=station_minlat, maxlatitude=station_maxlat, minlongitude=station_minlon, maxlongitude=station_maxlon, latitude=station_radialcenterlat, longitude=station_radialcenterlon, minradius=station_minrad, maxradius=station_maxrad) except: continue try: if invall: invall += inventory except: invall = inventory attach_network_to_traces(stream, inventory) attach_coordinates_to_traces(stream, inventory, event) streamall.append(stream) stream = Stream() if savefile: stname = str(origin_t).split('.')[0] + ".MSEED" invname = stname + "_inv.xml" catname = stname + "_cat.xml" stream.write(stname, format=file_format) inventory.write(invname, format="STATIONXML") catalog.write(catname, format="QUAKEML") plt.ion() #invall.plot() #catalog.plot() plt.ioff() inventory = invall list_of_stream = streamall return(list_of_stream, inventory, catalog)
def plot(st, inv=None, event=None, zoom=1, yinfo=False, epidistances=None, markphases=None, phaselabel=True, phaselabelclr='red', norm='all', clr='black', clrtrace=None, newfigure=True, savefig=False, dpi=400, xlabel=None, ylabel=None, t_axis=None, fs=15, tw=None, verbose=False): """ Alpha Version! Needs inventory and event of catalog for yinfo using param st: stream type st: obspy.core.stream.Stream param inv: inventory type inv: param event: event of the seismogram type event: param zoom: zoom factor of the traces type zoom: float param yinfo: Plotting with y info as distance of traces type yinfo: bool param markphases: Phases, that should be marked in the plot, default is "None" type markphases: list param norm: Depiction of traces; unprocessed or normalized. Normalization options are: all - normalized on biggest value of all traces trace - each trace is normalized on its biggest value type norm: string or bool param clr: Color of plot type clr: string param clrtrace: dict containing tracenumber and color, e.g.: >>> clrtrace = {1: 'red', 7: 'green'} >>> trace 1 in red >>> trace 7 in green type clrtrace: list """ #check for Data input if not isinstance(st, Stream): if not isinstance(st, Trace): try: if isinstance(yinfo,bool): yinfo = 1 plot_data(st, zoom=zoom, y_dist=yinfo, clr=clr, newfigure=newfigure, savefig=savefig, dpi=dpi, xlabel=xlabel, ylabel=ylabel, t_axis=t_axis, fs=fs) return except: msg = "Wrong data input, must be Stream or Trace" raise TypeError(msg) if newfigure: # Set axis information and bools. fig, ax = plt.subplots() if xlabel: ax.set_xlabel(xlabel, fontsize=fs) else: ax.set_xlabel("Time(s)", fontsize=fs) if ylabel: ax.set_ylabel(ylabel, fontsize=fs) ax.tick_params(axis='both', which='major', labelsize=fs) else: ax = plt.gca() fig = plt.gcf() if isinstance(st, Stream): # Check if just specific timewindow should be plotted. try: tw = np.array(tw) twdelta = tw.max() - tw.min() t_axis = np.linspace(tw.min(),tw.max(), twdelta/float(st[0].stats.delta)) npts_min = int(tw.min()/float(st[0].stats.delta)) npts_max = int(tw.max()/float(st[0].stats.delta)) except: t_axis_max = st[0].stats.delta * st[0].stats.npts t_axis = np.linspace(0,t_axis_max, st[0].stats.npts) tw = np.array([0, t_axis_max]) npts_min = 0 npts_max = st[0].stats.npts data = stream2array(st) spacing=2. ax.set_xlim(tw.min(), tw.max()) isinv = False isevent = False cclr = clr # Check if inventory and catalog is input, then calculate distances etc. if isinstance(inv, Inventory): isinv = True if isinstance(event,Event): isevent = True if isinv: # Calculates y-axis info using epidistance information of the stream. # Check if there is a network entry attach_network_to_traces(st,inv) attach_coordinates_to_traces(st, inv, event) else: for trace in st: try: if not trace.stats.distance: isinv = False break else: isinv = True except: isinv = False break try: depth = event.origins[0]['depth']/1000. isevent = True except AttributeError: try: depth = st[0].stats.depth isevent = True except AttributeError: isevent = False yold=0 # Normalize Data, if set to 'all' if norm in ['all']: data = data/data.max() if yinfo: ymin = st[0].stats.distance ymax = st[0].stats.distance for j, trace in enumerate(data): # Normalize trace, if set to 'trace' if norm in ['trace']: trace = trace/trace.max() try: y_dist = st[j].stats.distance except: y_dist = yold + 1 if markphases and isinv and isevent: try: origin = st[0].stats.origin except AttributeError: origin = event.origins[0]['time'] except: msg=('No origin-time found in stream or event-file') raise IOError(msg) m = TauPyModel('ak135') arrivals = m.get_travel_times(depth, y_dist, phase_list=markphases) timetable = [ [], [] ] for k, phase in enumerate(arrivals): phase_name = phase.name t = phase.time phase_time = origin + t - st[j].stats.starttime Phase_npt = int(phase_time/st[j].stats.delta) Phase = Phase_npt * st[j].stats.delta if Phase < t_axis.min() or Phase > t_axis.max(): continue else: timetable[0].append(phase_name) timetable[1].append(Phase) if not timetable[0] or not timetable[1]: print('Phases not in Seismogram') plt.close('all') return if yinfo: if not ylabel: ax.set_ylabel("Distance(deg)", fontsize=fs) if st[j].stats.distance < ymin: ymin = st[j].stats.distance if st[j].stats.distance > ymax: ymax = st[j].stats.distance try: if j in clrtrace: cclr = clrtrace[j] else: cclr = clr except: cclr = clr ax.annotate('%s' % st[j].stats.station, xy=(1 + tw.min(),y_dist+0.1)) ax.plot(t_axis,zoom*trace[npts_min: npts_max]+ y_dist, color=cclr) ax.plot( (timetable[1],timetable[1]),(-1+y_dist,1+y_dist), color=phaselabelclr ) if verbose: print(timetable[1] + st[j].stats.shifttime) ax.plot( (timetable[1] + st[j].stats.shifttime, timetable[1] + st[j].stats.shifttime), \ (-1+y_dist,1+y_dist), color=phaselabelclr ) if phaselabel: for time, key in enumerate(timetable[0]): ax.annotate('%s' % key, xy=(timetable[1][time],y_dist)) if verbose: ax.annotate('%s' % key, xy=(timetable[1][time] + st[j].stats.shifttime, y_dist)) else: continue else: if not ylabel: ax.set_ylabel("No. of trace", fontsize=fs) try: if j in clrtrace: cclr = clrtrace[j] else: cclr = clr except: cclr = clr fig.gca().yaxis.set_major_locator(plt.NullLocator()) ax.annotate('%s' % st[j].stats.station, xy=(1 + tw.min(),spacing*j+0.1)) ax.plot(t_axis,zoom*trace[npts_min: npts_max]+ spacing*j, color=cclr) ax.plot( (timetable[1],timetable[1]),(-1+spacing*j,1+spacing*j), color=phaselabelclr ) if verbose: print(st[j].stats.shifttime) print(timetable[1] + st[j].stats.shifttime) ax.plot( (timetable[1] + st[j].stats.shifttime, timetable[1] + st[j].stats.shifttime), \ (-1+spacing*j,1+spacing*j), color=phaselabelclr ) if phaselabel: for time, key in enumerate(timetable[0]): ax.annotate('%s' % key, xy=(timetable[1][time],spacing*j)) if verbose: ax.annotate('%s' % key, xy=(timetable[1][time] + st[j].stats.shifttime, spacing*j)) else: continue elif markphases and not isinv: msg='markphases needs Inventory Information, not found.' raise IOError(msg) elif markphases and not isevent: msg='markphases needs Event Information, not found.' raise IOError(msg) elif type(epidistances) == numpy.ndarray or type(epidistances)==list: y_dist = epidistances if not ylabel: ax.set_ylabel("Distance(deg)", fontsize=fs) try: if j in clrtrace: cclr = clrtrace[j] else: cclr = clr except: cclr = clr ax.annotate('%s' % st[j].stats.station, xy=(1 + tw.min(),y_dist[j]+0.1)) ax.plot(t_axis, zoom*trace[npts_min: npts_max] + y_dist[j], color=cclr) else: if yinfo: try: if not ylabel: ax.set_ylabel("Distance(deg)", fontsize=fs) try: if j in clrtrace: cclr = clrtrace[j] else: cclr = clr except: cclr = clr except: msg='Oops, something not found.' raise IOError(msg) if st[j].stats.distance < ymin: ymin = st[j].stats.distance if st[j].stats.distance > ymax: ymax = st[j].stats.distance ax.annotate('%s' % st[j].stats.station, xy=(1 + tw.min(),y_dist+0.1)) ax.plot(t_axis,zoom*trace[npts_min: npts_max]+ y_dist, color=cclr) else: if not ylabel: ax.set_ylabel("No. of trace", fontsize=fs) try: if j in clrtrace: cclr = clrtrace[j] else: cclr = clr except: cclr = clr fig.gca().yaxis.set_major_locator(plt.NullLocator()) ax.annotate('%s' % st[j].stats.station, xy=(1 + tw.min(),spacing*j+0.1)) ax.plot(t_axis,zoom*trace[npts_min: npts_max]+ spacing*j, color=cclr) yold = y_dist if yinfo: ylim = (ymin-1, ymax+1) ax.set_ylim(ylim) if savefig: fig.set_size_inches(8,7) fig.savefig(savefig, dpi=dpi) plt.close("all") else: plt.ion() plt.draw() plt.show() plt.ioff() elif isinstance(st, Trace): t_axis = np.linspace(0,st.stats.delta * st.stats.npts, st.stats.npts) data = st.data.copy() if norm in ['all', 'All', 'trace', 'Trace']: data = data/data.max() try: y_dist = st.stats.distance except: print("No distance information attached to trace, no phases are calculated!") markphases=False if markphases: origin = event.origins[0]['time'] depth = event.origins[0]['depth']/1000. m = TauPyModel('ak135') arrivals = m.get_travel_times(depth, y_dist, phase_list=markphases) timetable = [ [], [] ] for k, phase in enumerate(arrivals): phase_name = phase.name t = phase.time phase_time = origin + t - st.stats.starttime Phase_npt = int(phase_time/st.stats.delta) Phase = Phase_npt * st.stats.delta if Phase < t_axis.min() or Phase > t_axis.max(): continue else: timetable[0].append(phase_name) timetable[1].append(Phase) if not ylabel: ax.set_ylabel("Amplitude", fontsize=fs) title = st.stats.network+'.'+st.stats.station+'.'+st.stats.location+'.'+st.stats.channel ax.set_title(title, fontsize=fs) #plt.gca().yaxis.set_major_locator(plt.NullLocator()) ax.plot(t_axis,zoom*data, color=clr) ax.plot( (timetable[1],timetable[1]),(-0.5,0.5), color=phaselabelclr ) if phaselabel: for time, key in enumerate(timetable[0]): ax.annotate('%s' % key, xy=(timetable[1][time]+5,0.55)) else: if not ylabel: ax.set_ylabel("Amplitude", fontsize=fs) title = st.stats.network+'.'+st.stats.station+'.'+st.stats.location+'.'+st.stats.channel ax.set_title(title, fontsize=fs) ax.plot(t_axis, zoom*data, color=clr) if savefig: plt.savefig(savefig) plt.close("all") else: plt.ion() plt.draw() plt.show() plt.ioff()