Beispiel #1
0
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
Beispiel #2
0
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",
Beispiel #5
0
"""

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,
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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)
Beispiel #9
0
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