def gather_waveforms(source, network, station, location, channel, starttime, endtime, time_buffer=0, merge_fill_value=0, trim_fill_value=0, remove_response=False, return_failed_stations=False, watc_url=None, watc_username=None, watc_password=None): """ Gather seismic/infrasound waveforms from IRIS or WATC FDSN, or AVO Winston, and output a :class:`~obspy.core.stream.Stream` with station/element coordinates attached. Optionally remove the sensitivity. **NOTE** Usual RTM usage is to specify a starttime/endtime that brackets the estimated source origin time. Then time_buffer is used to download enough extra data to account for the time required for an infrasound signal to propagate to the farthest station. Args: source (str): Which source to gather waveforms from. Options are: * `'IRIS'` – IRIS FDSN * `'WATC'` – WATC FDSN * `'AVO'` – AVO Winston network (str): SEED network code [wildcards (``*``, ``?``) accepted] station (str): SEED station code [wildcards (``*``, ``?``) accepted] location (str): SEED location code [wildcards (``*``, ``?``) accepted] channel (str): SEED channel code [wildcards (``*``, ``?``) accepted] starttime (:class:`~obspy.core.utcdatetime.UTCDateTime`): Start time for data request endtime (:class:`~obspy.core.utcdatetime.UTCDateTime`): End time for data request time_buffer (int or float): Extra amount of data to download after `endtime` [s] merge_fill_value (bool, int, float, str, or None): Controls merging of :class:`~obspy.core.trace.Trace` objects with identical IDs. If `False`, no merging is performed. Otherwise, a merge is performed with the ``fill_value`` provided to this parameter. For details, see the docstring of :meth:`obspy.core.stream.Stream.trim` trim_fill_value (bool, int, float, or None): Controls trimming of the output :class:`~obspy.core.stream.Stream`, useful if precisely uniform start and end times are desired. If `False`, no trimming is performed. Otherwise, a trim is performed with the ``fill_value`` provided to this parameter. For details, see the docstring of :meth:`obspy.core.stream.Stream.merge` remove_response (bool): Toggle response removal via :meth:`~obspy.core.trace.Trace.remove_sensitivity` or a simple scalar multiplication return_failed_stations (bool): If `True`, returns a list of station codes that were requested but not downloaded. This disables the standard failed station warning message watc_url (str): URL for WATC FDSN server watc_username (str): Username for WATC FDSN server watc_password (str): Password for WATC FDSN server Returns: :class:`~obspy.core.stream.Stream` containing gathered waveforms. If `return_failed_stations` is `True`, additionally returns a list containing station codes that were requested but not downloaded """ # Check for issues with fill value args if merge_fill_value is True or trim_fill_value is True: raise ValueError('Cannot provide True to fill value parameters.') print('--------------') print('GATHERING DATA') print('--------------') # IRIS FDSN if source == 'IRIS': client = FDSN_Client('IRIS') print('Reading data from IRIS FDSN...') try: st_out = client.get_waveforms(network, station, location, channel, starttime, endtime + time_buffer, attach_response=True) except FDSNNoDataException: st_out = Stream() # Just create an empty Stream object # WATC FDSN elif source == 'WATC': print('Connecting to WATC FDSN...') client = FDSN_Client(base_url=watc_url, user=watc_username, password=watc_password) print('Successfully connected. Reading data from WATC FDSN...') try: st_out = client.get_waveforms(network, station, location, channel, starttime, endtime + time_buffer, attach_response=True) except FDSNNoDataException: st_out = Stream() # Just create an empty Stream object # AVO Winston elif source == 'AVO': client = EW_Client('pubavo1.wr.usgs.gov', port=16023) # 16023 is long-term print('Reading data from AVO Winston...') st_out = Stream() # Make empty Stream object to populate # Brute-force "dynamic grid search" over network/station/channel/location codes for nw in _restricted_matching('network', network, client): for sta in _restricted_matching('station', station, client, network=nw): for cha in _restricted_matching('channel', channel, client, network=nw, station=sta): for loc in _restricted_matching('location', location, client, network=nw, station=sta, channel=cha): try: st_out += client.get_waveforms( nw, sta, loc, cha, starttime, endtime + time_buffer) except KeyError: pass else: raise ValueError('Unrecognized source. Valid options are \'IRIS\', ' '\'WATC\', or \'AVO\'.') # Merge, if specified if merge_fill_value is not False: st_out.merge(fill_value=merge_fill_value) # Merge Traces with same ID warnings.warn(f'Merging with "fill_value={merge_fill_value}"', CollectionWarning) st_out.sort() # Check that all requested stations are present in Stream requested_stations = station.split(',') downloaded_stations = [tr.stats.station for tr in st_out] failed_stations = [] for sta in requested_stations: # The below check works with wildcards, but obviously cannot detect if # ALL stations corresponding to a given wildcard (e.g., O??K) were # downloaded. Thus, if careful station selection is desired, specify # each station explicitly and the below check will then be effective. if not fnmatch.filter(downloaded_stations, sta): if not return_failed_stations: # If we're not returning the failed stations, then show this # warning message to alert the user warnings.warn( f'Station {sta} not downloaded from {source} ' 'server for this time period.', CollectionWarning) failed_stations.append(sta) # If the Stream is empty, then we can stop here if st_out.count() == 0: print('No data downloaded.') if return_failed_stations: return st_out, failed_stations else: return st_out # Otherwise, show what the Stream contains print(st_out.__str__(extended=True)) # This syntax prints the WHOLE Stream # Trim, if specified if trim_fill_value is not False: st_out.trim(starttime, endtime + time_buffer, pad=True, fill_value=trim_fill_value) warnings.warn(f'Trimming with "fill_value={trim_fill_value}"', CollectionWarning) print('Assigning coordinates...') # Use IRIS inventory info for AVO data source if source == 'AVO': client = FDSN_Client('IRIS') try: inv = client.get_stations(network=network, station=station, location=location, channel=channel, starttime=starttime, endtime=endtime + time_buffer, level='channel') except FDSNNoDataException: inv = Inventory() # Make an empty inv warnings.warn('Creating empty inventory.', CollectionWarning) for tr in st_out: try: coords = inv.get_coordinates(tr.id) tr.stats.longitude = coords['longitude'] tr.stats.latitude = coords['latitude'] tr.stats.elevation = coords['elevation'] except Exception as e: if str(e) == 'No matching channel metadata found.': warnings.warn(f'No metadata for {tr.id} found in inventory.', CollectionWarning) else: raise # Check if any Trace did NOT get coordinates assigned, and try to use JSON # coordinates if available for tr in st_out: try: tr.stats.longitude, tr.stats.latitude, tr.stats.elevation except AttributeError: try: tr.stats.latitude, tr.stats.longitude,\ tr.stats.elevation = AVO_COORDS[tr.id] warnings.warn(f'Using coordinates from JSON file for {tr.id}.', CollectionWarning) except KeyError: print(f'No coordinates available for {tr.id}. Stopping.') raise # Remove sensitivity if remove_response: print('Removing sensitivity...') for tr in st_out: try: # Just removing sensitivity for now. remove_response() can lead # to errors. This should be sufficient for now. Plus some # IRIS-AVO responses are wonky. tr.remove_sensitivity() except ValueError: # No response information found # This is only set up for infrasound calibration values try: calib = AVO_INFRA_CALIBS[tr.id] tr.data = tr.data * calib warnings.warn( 'Using calibration value from JSON file for ' f'{tr.id}.', CollectionWarning) except KeyError: print(f'No calibration value available for {tr.id}. ' 'Stopping.') raise print('Done') # Return the Stream with coordinates attached (and responses removed if # specified) if return_failed_stations: return st_out, failed_stations else: return st_out
def gather_waveforms_bulk(lon_0, lat_0, max_radius, starttime, endtime, channel, network='*', station='*', location='*', time_buffer=0, merge_fill_value=0, trim_fill_value=0, remove_response=False, watc_url=None, watc_username=None, watc_password=None): """ Bulk gather infrasound waveforms within a specified maximum radius of a specified location. Waveforms are gathered from IRIS (and optionally WATC) FDSN, and AVO Winston. Outputs a :class:`~obspy.core.stream.Stream` with station/element coordinates attached. Optionally removes the sensitivity. (Output :class:`~obspy.core.stream.Stream` has the same properties as output :class:`~obspy.core.stream.Stream` from :func:`gather_waveforms`.) **NOTE 1** WATC database will NOT be used for station search NOR data download unless BOTH `watc_username` and `watc_password` are set. **NOTE 2** Usual RTM usage is to specify a starttime/endtime that brackets the estimated source origin time. Then time_buffer is used to download enough extra data to account for the time required for an infrasound signal to propagate to the farthest station. Args: lon_0 (int or float): Longitude of search center [deg.] lat_0 (int or float): Latitude of search center [deg.] max_radius (int or float): Maximum radius to search for stations within [km] starttime (:class:`~obspy.core.utcdatetime.UTCDateTime`): Start time for data request endtime (:class:`~obspy.core.utcdatetime.UTCDateTime`): End time for data request channel (str): SEED channel code [wildcards (``*``, ``?``) accepted] (REQUIRED PARAMETER!) network (str): SEED network code [wildcards (``*``, ``?``) accepted] station (str): SEED station code [wildcards (``*``, ``?``) accepted] location (str): SEED location code [wildcards (``*``, ``?``) accepted] time_buffer (int or float): Extra amount of data to download after `endtime` [s] merge_fill_value (bool, int, float, str, or None): Controls merging of :class:`~obspy.core.trace.Trace` objects with identical IDs. If `False`, no merging is performed. Otherwise, a merge is performed with the ``fill_value`` provided to this parameter. For details, see the docstring of :meth:`obspy.core.stream.Stream.trim` trim_fill_value (bool, int, float, or None): Controls trimming of the output :class:`~obspy.core.stream.Stream`, useful if precisely uniform start and end times are desired. If `False`, no trimming is performed. Otherwise, a trim is performed with the ``fill_value`` provided to this parameter. For details, see the docstring of :meth:`obspy.core.stream.Stream.merge` remove_response (bool): Toggle response removal via :meth:`~obspy.core.trace.Trace.remove_sensitivity` or a simple scalar multiplication watc_url (str): URL for WATC FDSN server watc_username (str): Username for WATC FDSN server watc_password (str): Password for WATC FDSN server Returns: :class:`~obspy.core.stream.Stream` containing bulk gathered waveforms """ # Check for issues with fill value args if merge_fill_value is True or trim_fill_value is True: raise ValueError('Cannot provide True to fill value parameters.') print('-------------------') print('BULK GATHERING DATA') print('-------------------') print('Creating station list...') inventories = [] # Create empty list of inventories # Grab IRIS inventory iris_client = FDSN_Client('IRIS') try: iris_inv = iris_client.get_stations(starttime=starttime, endtime=endtime + time_buffer, network=network, station=station, location=location, channel=channel, level='channel') inventories.append(iris_inv) # Add IRIS inventory to list except FDSNNoDataException: print('No stations found on IRIS FDSN.') # If the user supplied both a WATC password and WATC username, then search # through WATC database if watc_username and watc_password: # Grab WATC inventory print('Connecting to WATC FDSN...') watc_client = FDSN_Client(base_url=watc_url, user=watc_username, password=watc_password) print('Successfully connected.') try: watc_inv = watc_client.get_stations(starttime=starttime, endtime=endtime + time_buffer, network=network, station=station, location=location, channel=channel, level='channel') inventories.append(watc_inv) # Add WATC inventory to list except FDSNNoDataException: print('No stations found on WATC FDSN.') requested_station_list = [] # Initialize list of stations to request # Big loop through all channels in all inventories! for inv in inventories: for nw in inv: for stn in nw: for cha in stn: dist, _, _ = gps2dist_azimuth(lat_0, lon_0, cha.latitude, cha.longitude) # [m] if dist <= max_radius * KM2M: requested_station_list.append(stn.code) # Loop through each entry in AVO station coordinates JSON file for tr_id, coord in AVO_COORDS.items(): nw, sta, loc, cha = tr_id.split('.') # Extract codes from Trace.id # Only add station to requested stations list if it satisfies the # user-supplied query restrictions if (_matching([nw], network) and _matching([sta], station) and _matching([loc], location) and _matching([cha], channel)): dist, _, _ = gps2dist_azimuth(lat_0, lon_0, *coord[0:2]) # [m] if dist <= max_radius * KM2M: requested_station_list.append(sta) if not requested_station_list: raise ValueError('Station list is empty. Expand the station search ' 'and try again.') # Put into the correct format for ObsPy (e.g., 'HOM,O22K,DLL') requested_stations = ','.join(np.unique(requested_station_list)) print('Done') if time_buffer != 0: print(f'Using time buffer of {time_buffer:.1f} s ' f'(~{time_buffer * SEC2MIN:.0f} min)') print('Making calls to gather_waveforms()...') st_out = Stream() # Initialize empty Stream to populate # Gather waveforms from IRIS iris_st, iris_failed = gather_waveforms(source='IRIS', network=network, station=requested_stations, location=location, channel=channel, starttime=starttime, endtime=endtime, time_buffer=time_buffer, merge_fill_value=False, trim_fill_value=False, remove_response=remove_response, return_failed_stations=True) st_out += iris_st # If IRIS couldn't grab all stations in requested station list, try WATC # (if the user set username and password) if iris_failed: if watc_username and watc_password: # Gather waveforms from WATC watc_st, watc_failed = gather_waveforms( source='WATC', network=network, station=','.join(iris_failed), location=location, channel=channel, starttime=starttime, endtime=endtime, time_buffer=time_buffer, merge_fill_value=False, trim_fill_value=False, remove_response=remove_response, return_failed_stations=True, watc_url=watc_url, watc_username=watc_username, watc_password=watc_password) else: # Return an empty Stream and same failed stations watc_st = Stream() watc_failed = iris_failed st_out += watc_st # If WATC couldn't grab all stations missed by IRIS, try AVO if watc_failed: # Gather waveforms from AVO avo_st, remaining_failed = gather_waveforms( source='AVO', network=network, station=','.join(watc_failed), location=location, channel=channel, starttime=starttime, endtime=endtime, time_buffer=time_buffer, merge_fill_value=False, trim_fill_value=False, remove_response=remove_response, return_failed_stations=True) if remaining_failed: print('--------------') for sta in remaining_failed: warnings.warn( f'Station {sta} found in radius search but ' 'no data found.', CollectionWarning) st_out += avo_st # Merge, if specified if merge_fill_value is not False: st_out.merge(fill_value=merge_fill_value) # Merge Traces with same ID warnings.warn(f'Merging with "fill_value={merge_fill_value}"', CollectionWarning) # Trim, if specified if trim_fill_value is not False: st_out.trim(starttime, endtime + time_buffer, pad=True, fill_value=trim_fill_value) warnings.warn(f'Trimming with "fill_value={trim_fill_value}"', CollectionWarning) st_out.sort() print('--------------') print('Finishing gathering waveforms from station list. Check warnings ' 'for any missed stations.') return st_out
if n_processor > len(times): n_processor = len(times) with concurrent.futures.ThreadPoolExecutor( max_workers=n_processor) as executor: paths = executor.map(run_get_path2join_ppsd, times) utils.get_MassPPSD(self.my_storage, list(paths), self.dld_restrictions) if __name__ == "__main__": from obspy.clients.fdsn import Client as FDSN_Client from obspy.core.utcdatetime import UTCDateTime from .restrictions import (DownloadRestrictions, PPSDrestrictions) client_tuple = ('fdsn', FDSN_Client('http://10.100.100.232:8091')) dldR = DownloadRestrictions(network="CM", station="URMC,BAR2,RUS,PRA,PTA,DBB", location="00,10", channel="*", starttime=UTCDateTime(2019, 1, 1, 0), endtime=UTCDateTime(2019, 1, 2, 0), chunklength=86400, overlap=None, exclude=[("*", "DBB,BAR2", "[10]0", "HH[ENZ]") ], plot_trace=True) ppsdR = PPSDrestrictions(skip_on_gaps=False, db_bins=(-200, -50, 1.0), ppsd_length=3600.0, overlap=0.5,
if deltat + dtt > endtime: break else: times.append((deltat, deltat + dtt)) deltat += dtt - overlap_dt if deltat < endtime: times.append((deltat, endtime)) return times if __name__ == "__main__": from obspy.clients.fdsn import Client as FDSN_Client from obspy.core.utcdatetime import UTCDateTime from .restrictions import PreprocRestrictions client = FDSN_Client('http://sismo.sgc.gov.co:8080') st = client.get_waveforms(network="CM", station="BAR2", location="*", channel="*", starttime=UTCDateTime("2019-04-23T00:00:00.0"), endtime=UTCDateTime("2019-04-23T00:02:00.0")) ppc_restrictions = PreprocRestrictions(["CM.BAR2"], detrend={'type': 'simple'}) preproc_stream(st, ppc_restrictions) ######### inventory # json_path = "/home/ecastillo/repositories/AIpicker_modules/onejson.json" # client_baseurl = "http://sismo.sgc.gov.co:8080" # restrictions = DownloadRestrictions(network="CM", # station="BAR2",
""" import argparse import datetime import io import math import numpy as np from obspy.clients.fdsn import Client as FDSN_Client from obspy.taup import TauPyModel from obspy.io.quakeml.core import Unpickler import pycurl import pyproj import xml.etree.ElementTree as ET # Set up objects to use imported modules client = FDSN_Client("https://service.geonet.org.nz") spherical_velocity_model = TauPyModel(model="iasp91") quakeml_reader = Unpickler() # Set up pyproj coordinate system objects proj_wgs84_geog = pyproj.Proj(init="epsg:4326") proj_wgs84_geod = pyproj.Proj(init="epsg:4978") def parse_files( arrival_time_file=None, eventid_file=None, test_origins=None, network_file=None, velocity_model=None, grid_parameters=None,
def gather_waveforms(source, network, station, location, channel, starttime, endtime, time_buffer=0, merge=True, remove_response=False, return_failed_stations=False, watc_url=None, watc_username=None, watc_password=None): """ Gather seismic/infrasound waveforms from IRIS or WATC FDSN, or AVO Winston, and output a Stream object with station/element coordinates attached. Optionally remove the sensitivity. NOTE 1: Usual RTM usage is to specify a starttime/endtime that brackets the estimated source origin time. Then time_buffer is used to download enough extra data to account for the time required for an infrasound signal to propagate to the farthest station. Args: source: Which source to gather waveforms from - options are: 'IRIS' <-- IRIS FDSN 'WATC' <-- WATC FDSN 'AVO' <-- AVO Winston network: SEED network code station: SEED station code location: SEED location code channel: SEED channel code starttime: Start time for data request (UTCDateTime) endtime: End time for data request (UTCDateTime) time_buffer: [s] Extra amount of data to download after endtime (default: 0) merge: Toggle merging of Traces with identical IDs (default: True) remove_response: Toggle response removal via remove_sensitivity() or a simple scalar multiplication (default: False) return_failed_stations: If True, returns a list of station codes that were requested but not downloaded. This disables the standard failed station warning message (default: False) watc_url: URL for WATC FDSN server (default: None) watc_username: Username for WATC FDSN server (default: None) watc_password: Password for WATC FDSN server (default: None) Returns: st_out: Stream containing gathered waveforms failed_stations: (Optional) List containing station codes that were requested but not downloaded """ print('--------------') print('GATHERING DATA') print('--------------') # IRIS FDSN if source == 'IRIS': client = FDSN_Client('IRIS') print('Reading data from IRIS FDSN...') try: st_out = client.get_waveforms(network, station, location, channel, starttime, endtime + time_buffer, attach_response=True) except FDSNNoDataException: st_out = Stream() # Just create an empty Stream object # WATC FDSN elif source == 'WATC': print('Connecting to WATC FDSN...') client = FDSN_Client(base_url=watc_url, user=watc_username, password=watc_password) print('Successfully connected. Reading data from WATC FDSN...') try: st_out = client.get_waveforms(network, station, location, channel, starttime, endtime + time_buffer, attach_response=True) except FDSNNoDataException: st_out = Stream() # Just create an empty Stream object # AVO Winston elif source == 'AVO': client = EW_Client('pubavo1.wr.usgs.gov', port=16023) # 16023 is long-term print('Reading data from AVO Winston...') st_out = Stream() # Make empty Stream object to populate # Brute-force "dynamic grid search" over network/station/channel/location codes for nw in _restricted_matching('network', network, client): for sta in _restricted_matching('station', station, client, network=nw): for cha in _restricted_matching('channel', channel, client, network=nw, station=sta): for loc in _restricted_matching('location', location, client, network=nw, station=sta, channel=cha): try: st_out += client.get_waveforms( nw, sta, loc, cha, starttime, endtime + time_buffer) except KeyError: pass else: raise ValueError('Unrecognized source. Valid options are \'IRIS\', ' '\'WATC\', or \'AVO\'.') if merge: st_out.merge() # Merge Traces with the same ID st_out.sort() # Check that all requested stations are present in Stream requested_stations = station.split(',') downloaded_stations = [tr.stats.station for tr in st_out] failed_stations = [] for sta in requested_stations: # The below check works with wildcards, but obviously cannot detect if # ALL stations corresponding to a given wildcard (e.g., O??K) were # downloaded. Thus, if careful station selection is desired, specify # each station explicitly and the below check will then be effective. if not fnmatch.filter(downloaded_stations, sta): if not return_failed_stations: # If we're not returning the failed stations, then show this # warning message to alert the user warnings.warn( f'Station {sta} not downloaded from {source} ' 'server for this time period.', CollectionWarning) failed_stations.append(sta) # If the Stream is empty, then we can stop here if st_out.count() == 0: print('No data downloaded.') if return_failed_stations: return st_out, failed_stations else: return st_out # Otherwise, show what the Stream contains print(st_out.__str__(extended=True)) # This syntax prints the WHOLE Stream # Add zeros to ensure all Traces have same length st_out.trim(starttime, endtime + time_buffer, pad=True, fill_value=0) print('Assigning coordinates...') # Use IRIS inventory info for AVO data source if source == 'AVO': client = FDSN_Client('IRIS') try: inv = client.get_stations(network=network, station=station, location=location, channel=channel, starttime=starttime, endtime=endtime + time_buffer, level='channel') except FDSNNoDataException: inv = [] for tr in st_out: for nw in inv: for sta in nw: for cha in sta: # Being very thorough to check if everything matches! if (tr.stats.network == nw.code and tr.stats.station == sta.code and tr.stats.location == cha.location_code and tr.stats.channel == cha.code): tr.stats.longitude = cha.longitude tr.stats.latitude = cha.latitude tr.stats.elevation = cha.elevation # Check if any Trace did NOT get coordinates assigned, and try to use JSON # coordinates if available for tr in st_out: try: tr.stats.longitude, tr.stats.latitude, tr.stats.elevation except AttributeError: try: tr.stats.latitude, tr.stats.longitude,\ tr.stats.elevation = AVO_COORDS[tr.id] warnings.warn(f'Using coordinates from JSON file for {tr.id}.', CollectionWarning) except KeyError: print(f'No coordinates available for {tr.id}. Stopping.') raise # Remove sensitivity if remove_response: print('Removing sensitivity...') for tr in st_out: try: # Just removing sensitivity for now. remove_response() can lead # to errors. This should be sufficient for now. Plus some # IRIS-AVO responses are wonky. tr.remove_sensitivity() except ValueError: # No response information found # This is only set up for infrasound calibration values try: calib = AVO_INFRA_CALIBS[tr.id] tr.data = tr.data * calib warnings.warn( 'Using calibration value from JSON file for ' f'{tr.id}.', CollectionWarning) except KeyError: print(f'No calibration value available for {tr.id}. ' 'Stopping.') raise print('Done') # Return the Stream with coordinates attached (and responses removed if # specified) if return_failed_stations: return st_out, failed_stations else: return st_out
def gather_waveforms_bulk(lon_0, lat_0, max_radius, starttime, endtime, channel, network='*', station='*', location='*', time_buffer=0, merge=True, remove_response=False, watc_url=None, watc_username=None, watc_password=None): """ Bulk gather infrasound waveforms within a specified maximum radius of a specified location. Waveforms are gathered from IRIS (and optionally WATC) FDSN, and AVO Winston. Outputs a Stream object with station/element coordinates attached. Optionally removes the sensitivity. [Output Stream has the same properties as output Stream from gather_waveforms().] NOTE 1: WATC database will NOT be used for station search NOR data download unless BOTH watc_username and watc_password are set. NOTE 2: Usual RTM usage is to specify a starttime/endtime that brackets the estimated source origin time. Then time_buffer is used to download enough extra data to account for the time required for an infrasound signal to propagate to the farthest station. Args: lon_0: [deg] Longitude of search center lat_0: [deg] Latitude of search center max_radius: [km] Maximum radius to search for stations within starttime: Start time for data request (UTCDateTime) endtime: End time for data request (UTCDateTime) channel: SEED channel code (REQUIRED PARAMETER!) network: SEED network code (default: '*') station: SEED station code (default: '*') location: SEED location code (default: '*') time_buffer: [s] Extra amount of data to download after endtime (default: 0) merge: Toggle merging of Traces with identical IDs (default: True) remove_response: Toggle response removal via remove_sensitivity() or a simple scalar multiplication (default: False) watc_url: URL for WATC FDSN server (default: None) watc_username: Username for WATC FDSN server (default: None) watc_password: Password for WATC FDSN server (default: None) Returns: st_out: Stream containing bulk gathered waveforms """ print('-------------------') print('BULK GATHERING DATA') print('-------------------') print('Creating station list...') inventories = [] # Create empty list of inventories # Grab IRIS inventory iris_client = FDSN_Client('IRIS') try: iris_inv = iris_client.get_stations(starttime=starttime, endtime=endtime + time_buffer, network=network, station=station, location=location, channel=channel, level='channel') inventories.append(iris_inv) # Add IRIS inventory to list except FDSNNoDataException: print('No stations found on IRIS FDSN.') # If the user supplied both a WATC password and WATC username, then search # through WATC database if watc_username and watc_password: # Grab WATC inventory print('Connecting to WATC FDSN...') watc_client = FDSN_Client(base_url=watc_url, user=watc_username, password=watc_password) print('Successfully connected.') try: watc_inv = watc_client.get_stations(starttime=starttime, endtime=endtime + time_buffer, network=network, station=station, location=location, channel=channel, level='channel') inventories.append(watc_inv) # Add WATC inventory to list except FDSNNoDataException: print('No stations found on WATC FDSN.') requested_station_list = [] # Initialize list of stations to request # Big loop through all channels in all inventories! for inv in inventories: for nw in inv: for stn in nw: for cha in stn: dist, _, _ = gps2dist_azimuth(lat_0, lon_0, cha.latitude, cha.longitude) # [m] if dist <= max_radius * KM2M: requested_station_list.append(stn.code) # Loop through each entry in AVO station coordinates JSON file for tr_id, coord in AVO_COORDS.items(): nw, sta, loc, cha = tr_id.split('.') # Extract codes from Trace.id # Only add station to requested stations list if it satisfies the # user-supplied query restrictions if (_matching([nw], network) and _matching([sta], station) and _matching([loc], location) and _matching([cha], channel)): dist, _, _ = gps2dist_azimuth(lat_0, lon_0, *coord[0:2]) # [m] if dist <= max_radius * KM2M: requested_station_list.append(sta) if not requested_station_list: raise ValueError('Station list is empty. Expand the station search ' 'and try again.') # Put into the correct format for ObsPy (e.g., 'HOM,O22K,DLL') requested_stations = ','.join(np.unique(requested_station_list)) print('Done') if time_buffer != 0: print(f'Using time buffer of {time_buffer:.1f} s ' f'(~{time_buffer * SEC2MIN:.0f} min)') print('Making calls to gather_waveforms()...') st_out = Stream() # Initialize empty Stream to populate # Gather waveforms from IRIS iris_st, iris_failed = gather_waveforms(source='IRIS', network=network, station=requested_stations, location=location, channel=channel, starttime=starttime, endtime=endtime, time_buffer=time_buffer, remove_response=remove_response, return_failed_stations=True) st_out += iris_st # If IRIS couldn't grab all stations in requested station list, try WATC # (if the user set username and password) if iris_failed: if watc_username and watc_password: # Gather waveforms from WATC watc_st, watc_failed = gather_waveforms( source='WATC', network=network, station=','.join(iris_failed), location=location, channel=channel, starttime=starttime, endtime=endtime, time_buffer=time_buffer, remove_response=remove_response, return_failed_stations=True, watc_url=watc_url, watc_username=watc_username, watc_password=watc_password) else: # Return an empty Stream and same failed stations watc_st = Stream() watc_failed = iris_failed st_out += watc_st # If WATC couldn't grab all stations missed by IRIS, try AVO if watc_failed: # Gather waveforms from AVO avo_st, remaining_failed = gather_waveforms( source='AVO', network=network, station=','.join(watc_failed), location=location, channel=channel, starttime=starttime, endtime=endtime, time_buffer=time_buffer, remove_response=remove_response, return_failed_stations=True) if remaining_failed: print('--------------') for sta in remaining_failed: warnings.warn( f'Station {sta} found in radius search but ' 'no data found.', CollectionWarning) st_out += avo_st if merge: st_out.merge() # Merge Traces with the same ID st_out.sort() print('--------------') print('Finishing gathering waveforms from station list. Check warnings ' 'for any missed stations.') return st_out
def get_nordic(egf_table, t_event, xml_cat): cat = Catalog() wave_names = [] # The easiest way to solve this ---------------------------------------------------------------------------------------------------------- SAMBA_list = [ 'COSA', 'COVA', 'EORO', 'FRAN', 'GOVA', 'LABE', 'LARB', 'MTBA', 'MTFO', 'POCR2', 'SOLU', 'WHAT2', 'WHYM' ] ND_list = [ 'MOSQ', 'BELL', 'JACK', 'HURA', 'SHOT', 'MORG', 'TURI2', 'BRUN', 'GLOR' ] SD_list = [ 'OLIV', 'CASC', 'DATA', 'GORG', 'BARN', 'RICH', 'DELT', 'THOM', 'MONK', 'POMM' ] COSA_list = [ 'TEPE', 'HUVA', 'STBA', 'NOBU', 'ASPR', 'MORV', 'KING', 'HAAS' ] Alfa_list = [ 'BURA2', 'CAMEL', 'CASH', 'FBLA2', 'HATT', 'MTHA2', 'TURI', 'UMAT' ] Wizard_list = [ 'WZ01', 'WZ02', 'WZ03', 'WZ04', 'WZ05', 'WZ06', 'WZ07', 'WZ08', 'WZ09', 'WZ10', 'WZ11', 'WZ12', 'WZ13', 'WZ14', 'WZ15', 'WZ16', 'WZ17', 'WZ18', 'WZ19', 'WZ20' ] GeoN_list = [ 'JCZ', 'WKZ', 'MSZ', 'MLZ', 'RPZ', 'LBZ', 'EAZ', 'FOZ', 'WVZ', 'INZ', 'LTZ', 'DSZ', 'THZ', 'OXZ', 'NSBS', 'HDWS', 'MECS', 'LPLS', 'WNPS', 'GLNS', 'QTPS', 'TAFS', 'TWAS', 'MCNS', 'FGPS', 'FJDS', 'WHFS', 'WHAS', 'WHFS', 'HAFS', 'KOKS', 'APPS', 'HMCS', 'GMFS', 'ARPS', 'IFPS', 'SJFS', 'GLWS', 'TKAS', 'RDCS', 'WBCS', 'INGS', 'CSHS' ] # ---------------------------------------------------------------------------------------------------------------------------------------- for index1, egf in egf_table.iterrows(): st = Stream() date = datetime.datetime(int(egf['qyr']), int(egf['qmon']), int(egf['qdy']), int(egf['qhr']), int(egf['qmn']), int(egf['qsc'])) JDay = date.strftime('%j') #Change to UTCDateTime eventdt = UTCDateTime(date) print( '----------------------------------------------------------------------------------' ) print( '----------------------------------------------------------------------------------' ) print('Working in the EGF event: ', eventdt) print( '----------------------------------------------------------------------------------' ) print( '----------------------------------------------------------------------------------' ) # Time to get the waveforms print( '========================================== NOW IM READING THE NETWORKS DATA =======================================' ) egf_event = find_event(xml_cat, eventdt) stat_list = [] for j in range(len(egf_event.picks)): stat_list.append(egf_event.picks[j].waveform_id.station_code) stat_list = set(stat_list) print(stat_list) for stat in stat_list: if stat in SD_list or stat in ND_list: print('G E T T I N G S O U T H D W A R F S DATA') try: st += read( '/Volumes/GeoPhysics_11/users-data/chambeca/DWARFS/DWARFS_archive/Y' + eventdt.strftime('%Y') + '/R' + JDay + '.01/' + stat + '*', starttime=eventdt, endtime=eventdt + 50) except: print('NO DATA') pass elif stat in COSA_list: print('G E T T I N G C O S A DATA') try: st += read( '/Volumes/GeoPhysics_11/users-data/chambeca/COSA_archive/Y' + eventdt.strftime('%Y') + '/R' + JDay + '.01/' + stat + '*', starttime=eventdt, endtime=eventdt + 50) except: pass elif stat in SAMBA_list: print('G E T T I N G S A M B A DATA') st += read( '/Volumes/GeoPhysics_09/users-data/chambeca/SAMBA_archive/day_volumes_S/Y' + eventdt.strftime('%Y') + '/R' + JDay + '.01/' + stat + '*', starttime=eventdt, endtime=eventdt + 50) elif stat in GeoN_list: print('G E T T I N G G E O N E T DATA') client = FDSN_Client("GEONET") client_nrt = FDSN_Client("https://service-nrt.geonet.org.nz") try: st += client.get_waveforms(network="NZ", station=stat, location='*', channel='HH*', starttime=eventdt, endtime=eventdt + 50) except: pass print( '----------------------------------------------------------------------------------' ) print('The traces are:') print(st) print( '----------------------------------------------------------------------------------' ) for tr in st: tr.data = tr.data.astype(np.int32) for tr in st: if type(tr.data) == np.ma.core.MaskedArray: try: print('Masked data found for ' + tr.stats.station + ' ' + tr.stats.channel + ': padding empty spaces with zeros') tr.data = tr.split().detrend('simple').merge( fill_value=0)[0].data except: st.remove(tr) st.write( '/Users/home/juarezilma/Master/NETWORKS/DWARFS_S/Seisan_files/Target_Events/' + t_event[0:14] + '/Wav_files/' + eventdt.strftime('%Y') + eventdt.strftime('%m') + eventdt.strftime('%d') + eventdt.strftime('%H') + eventdt.strftime('%M') + eventdt.strftime('%S') + '_SD_multiplexed', format='MSEED') _write_nordic( event=egf_event, outdir= '/Users/home/juarezilma/Master/NETWORKS/DWARFS_S/Seisan_files/Target_Events/' + t_event[0:14] + '/S_files/', filename=None, userid="ICJG", evtype="L", wavefiles= '/Users/home/juarezilma/Master/NETWORKS/DWARFS_S/Seisan_files/Target_Events/' + t_event[0:14] + '/Wav_files/' + eventdt.strftime('%Y') + eventdt.strftime('%m') + eventdt.strftime('%d') + eventdt.strftime('%H') + eventdt.strftime('%M') + eventdt.strftime('%S') + '_SD_multiplexed') # To creat the select.out file wave_list = eventdt.strftime('%Y') + eventdt.strftime( '%m') + eventdt.strftime('%d') + eventdt.strftime( '%H') + eventdt.strftime('%M') + eventdt.strftime( '%S') + '_SD_multiplexed' wave_names.append(wave_list) cat.append(egf_event) #END FOT EGF write_select( catalog=cat, filename= '/Users/home/juarezilma/Master/NETWORKS/DWARFS_S/Seisan_files/Target_Events/' + t_event[0:14] + '/select_' + t_event[0:14] + '.out', userid='ICJG', evtype='L', wavefiles=wave_names)
import matplotlib.pyplot as plt import obspy from obspy.core.util import NamedTemporaryFile from obspy.clients.fdsn import Client as FDSN_Client from obspy.clients.iris import Client as OldIris_Client # MW 7.1 Darfield earthquake, New Zealand t1 = obspy.UTCDateTime("2010-09-3T16:30:00.000") t2 = obspy.UTCDateTime("2010-09-3T17:00:00.000") # Fetch waveform from IRIS FDSN web service into a ObsPy stream object fdsn_client = FDSN_Client("IRIS") st = fdsn_client.get_waveforms('NZ', 'BFZ', '10', 'HHZ', t1, t2) # Download and save instrument response file into a temporary file with NamedTemporaryFile() as tf: respf = tf.name old_iris_client = OldIris_Client() # fetch RESP information from "old" IRIS web service, see obspy.fdsn # for accessing the new IRIS FDSN web services old_iris_client.resp('NZ', 'BFZ', '10', 'HHZ', t1, t2, filename=respf) # make a copy to keep our original data st_orig = st.copy() # define a filter band to prevent amplifying noise during the deconvolution pre_filt = (0.005, 0.006, 30.0, 35.0) # this can be the date of your raw data or any date for which the # SEED RESP-file is valid