Exemplo n.º 1
0
Arquivo: io.py Projeto: lsawade/lwsspy
def flex_read_stations(filenames: str or list):
    """ Takes in a list of strings and tries to read them as inventories
    Creates a single inventory, not an aggregate of inventories

    :param filename: station file(s). wildcards permitted.
    :return: `obspy.Inventory`
    """

    if type(filenames) is str:
        filenames = [filenames]

    inv = Inventory()
    for _file in filenames:
        try:
            add_inv = read_inventory(_file)
            for network in add_inv:
                if len(inv.select(network=network.code)) == 0:
                    inv.networks.append(network)
                else:
                    new_network = inv.select(network=network.code)[0]
                    # print(new_network)
                    for station in network:
                        if len(new_network.select(station=station.code)) == 0:
                            new_network.stations.append(station)

                    inv = inv.remove(network=network.code)
                    inv.networks.append(new_network)

        except Exception as e:
            print("%s could not be read. Error: %s" % (_file, e))

    return inv
Exemplo n.º 2
0
def get_inventory(
        client,
        tribe: Union[RealTimeTribe, Tribe],
        triggering_event: Event = None,
        location: dict = None,
        starttime: UTCDateTime = None,
        max_distance: float = 1000.,
        n_stations: int = 10,
        duration: float = 10,
        level: str = "channel",
        channel_list: Union[list, tuple] = ("EH?", "HH?"),
) -> Inventory:
    """
    Get a suitable inventory for a tribe - selects the most used, closest
    stations.


    Parameters
    ----------
    client:
        Obspy client with a get_stations service.
    tribe:
        Tribe or RealTimeTribe of templates to query for stations.
    triggering_event:
        Event with at least an origin to calculate distances from - if not
        specified will use `location`
    location:
        Dictionary with "latitude" and "longitude" keys - only used if
        `triggering event` is not specified.
    starttime:
        Start-time for station search - only used if `triggering_event` is
        not specified.
    max_distance:
        Maximum distance from `triggering_event.preferred_origin` or
        `location` to find stations. Units: km
    n_stations:
        Maximum number of stations to return
    duration:
        Duration stations must be active for. Units: days
    level:
        Level for inventory parsable by `client.get_stations`.
    channel_list
        List of channel-codes to be acquired.  If `None` then all channels
        will be searched.

    Returns
    -------
    Inventory of the most used, closest stations.
    """
    inv = Inventory(networks=[], source=None)
    if triggering_event is not None:
        try:
            origin = (
                triggering_event.preferred_origin() or
                triggering_event.origins[0])
        except IndexError:
            Logger.error("Triggering event has no origin")
            return inv
        lat = origin.latitude
        lon = origin.longitude
        _starttime = origin.time
    else:
        lat = location["latitude"]
        lon = location["longitude"]
        _starttime = starttime

    for channel_str in channel_list or ["*"]:
        try:
            inv += client.get_stations(
                startbefore=_starttime,
                endafter=_starttime + (duration * 86400),
                channel=channel_str, latitude=lat,
                longitude=lon,
                maxradius=kilometer2degrees(max_distance),
                level=level)
        except FDSNNoDataException:
            continue
    if len(inv) == 0:
        return inv
    # Calculate distances
    station_count = Counter(
        [pick.waveform_id.station_code for template in tribe
         for pick in template.event.picks])

    sta_dist = []
    for net in inv:
        for sta in net:
            dist = locations2degrees(
                lat1=lat, long1=lon, lat2=sta.latitude, long2=sta.longitude)
            sta_dist.append((sta.code, dist, station_count[sta.code]))
    sta_dist.sort(key=lambda _: (-_[2], _[1]))
    inv_out = inv.select(station=sta_dist[0][0])
    for sta in sta_dist[1:n_stations]:
        inv_out += inv.select(station=sta[0])
    return inv_out