def get_derivative(self):
        """
        Calculated the derivative of each trace's data.

        Args:
            damping (float):
                Damping for spectral amplitude calculations. Default is None.
            period (float):
                Period for spectral amplitude calculations. Default is None.
            times (numpy.ndarray):
                Times for the spectral amplitude calculations. Default is None.
            allow_nans (bool):
                Should nans be allowed in the smoothed spectra. If False, then
                the number of points in the FFT will be computed to ensure
                that nans will not result in the smoothed spectra.

        Returns:
            stream: StationStream with the differentiated data.
        """
        stream = StationStream([])
        for trace in self.transform_data:
            differentiated_trace = trace.copy().differentiate()
            differentiated_trace.stats['units'] = 'acc'
            stream.append(differentiated_trace)
        return stream
Beispiel #2
0
    def get_arias(self):
        """
        Performs calculation of arias intensity.

        Returns:
            arias_intensities: Dictionary of arias intensity for each channel.
        """
        arias_intensities = {}
        arias_stream = StationStream([])
        for trace in self.reduction_data:
            dt = trace.stats["delta"]
            # convert from cm/s/s to m/s/s
            acc = trace.data * 0.01

            # Calculate Arias Intensity
            integrated_acc2 = integrate.cumtrapz(acc * acc, dx=dt)
            arias_intensity = integrated_acc2 * np.pi * GAL_TO_PCTG / 2

            # Create a copy of stats so we don't modify original data
            stats = trace.stats.copy()
            channel = stats.channel
            stats.standard.units_type = "vel"
            stats.npts = len(arias_intensity)
            arias_stream.append(StationTrace(arias_intensity, stats))
            arias_intensities[channel] = np.abs(np.max(arias_intensity))
        self.arias_stream = arias_stream
        return arias_intensities
Beispiel #3
0
def read_volume_one(filename, location='', alternate=False):
    """Read channel data from USC volume 1 text file.

    Args:
        filename (str):
            Input DMG V1 filename.

    Returns:
        tuple: (list of obspy Trace, int line offset)
    """
    volume = VOLUMES['V1']
    # count the number of lines in the file
    with open(filename) as f:
        line_count = sum(1 for _ in f)
    # read as many channels as are present in the file
    line_offset = 0
    stream = StationStream([])
    while line_offset < line_count:
        trace, line_offset = _read_channel(filename,
                                           line_offset,
                                           volume,
                                           location=location,
                                           alternate=alternate)
        # store the trace if the station type is in the valid_station_types
        # list or store the trace if there is no valid_station_types list
        if trace is not None:
            stream.append(trace)

    return [stream]
Beispiel #4
0
    def get_integral(self, config=None):
        """
        Calculated the integral of each trace's data.

        Returns:
            stream: StationStream with the integrated data.
        """
        stream = StationStream([])
        for trace in self.transform_data:
            integrated_trace = trace.copy().integrate(config=config)
            stream.append(integrated_trace)
        return stream
def split_station(grouped_trace_list):
    if grouped_trace_list[0].stats.network in NETWORKS_USING_LOCATION:
        streams_dict = {}
        for trace in grouped_trace_list:
            if trace.stats.location in streams_dict:
                streams_dict[trace.stats.location] += trace
            else:
                streams_dict[trace.stats.location] = StationStream(
                    traces=[trace])
        streams = list(streams_dict.values())
    else:
        streams = [StationStream(traces=grouped_trace_list)]
    return streams
Beispiel #6
0
def read_unam(filename, config=None, **kwargs):
    """Read the Mexican UNAM strong motion data format.

    Args:
        filename (str):
            Path to UNAM data file.
        config (dict):
            Dictionary containing configuration.
        kwargs (ref):
            Other arguments will be ignored.

    Returns:
        list: Sequence of one StationStream object containing 3
        StationTrace objects.
    """

    channels = _read_header(filename)
    npts = channels[0]["npts"]
    all_data = np.genfromtxt(filename, skip_header=ALL_HEADERS, max_rows=npts)
    trace1 = StationTrace(data=all_data[:, 0], header=channels[0])
    trace2 = StationTrace(data=all_data[:, 1], header=channels[1])
    trace3 = StationTrace(data=all_data[:, 2], header=channels[2])

    # tell the trace that data has already been converted to physical units
    response = {"input_units": "counts", "output_units": "cm/s^2"}
    trace1.setProvenance("remove_response", response)
    trace2.setProvenance("remove_response", response)
    trace3.setProvenance("remove_response", response)

    stream = StationStream(traces=[trace1, trace2, trace3])
    return [stream]
    def get_radial_transverse(self):
        """
        Performs radial transverse rotation.

        Returns:
            radial_transverse: StationStream with the radial and
                    transverse components.
        """
        st_copy = self.rotation_data.copy()
        st_n = st_copy.select(component="[N1]")
        st_e = st_copy.select(component="[E2]")

        # Check that we have one northing and one easting channel
        if len(st_e) != 1 or len(st_n) != 1:
            raise Exception(
                "Radial_Transverse: Stream must have one north and one east channel."
            )

        # Check that the orientations are orthogonal
        ho1 = st_e[0].stats.standard.horizontal_orientation
        ho2 = st_n[0].stats.standard.horizontal_orientation
        if abs(ho1 - ho2) not in [90, 270]:
            raise Exception("Radial_Transverse: Channels must be orthogonal.")

        # Check that the lengths of the two channels are the same
        if st_e[0].stats.npts != st_n[0].stats.npts:
            raise Exception(
                "Radial_Transverse: East and north channels must have same length."
            )

        # First, rotate to North-East components if not already
        if st_n[0].stats.standard.horizontal_orientation != 0:
            az_diff = 360 - st_n[0].stats.standard.horizontal_orientation
            az_diff = np.deg2rad(az_diff)
            rotation_matrix = np.array([
                [np.cos(az_diff), np.sin(az_diff)],
                [-np.sin(az_diff), np.cos(az_diff)],
            ])
            data = np.array([st_n[0].data, st_e[0].data])
            newdata = np.matmul(rotation_matrix, data)

            st_n[0].data = newdata[0]
            st_e[0].data = newdata[1]

        st_n[0].stats.channel = st_n[0].stats.channel[:-1] + "N"
        st_e[0].stats.channel = st_n[0].stats.channel[:-1] + "E"

        # For some reason the rotation does not update the channel
        # name in the rotation if it is not an obspy stream
        ne_stream = Stream([st_n[0], st_e[0]])
        # Calculate back azimuth and perform rotation to radial and transverse
        baz = gps2dist_azimuth(
            st_e[0].stats.coordinates.latitude,
            st_e[0].stats.coordinates.longitude,
            self.event.latitude,
            self.event.longitude,
        )[1]
        ne_stream.rotate(method="NE->RT", back_azimuth=baz)
        radial_transverse = StationStream([ne_stream[0], ne_stream[1]])
        return radial_transverse
Beispiel #8
0
def test_uneven_stream():
    inventory = get_inventory()
    channels = ["HN1", "HN2", "HNZ"]
    data1 = np.random.rand(1000)
    data2 = np.random.rand(1001)
    data3 = np.random.rand(1002)
    data = [data1, data2, data3]
    traces = []
    network = inventory.networks[0]
    station = network.stations[0]
    chlist = station.channels
    channelcodes = [ch.code for ch in chlist]
    for datat, channel in zip(data, channels):
        chidx = channelcodes.index(channel)
        channeldata = chlist[chidx]
        header = {
            "sampling_rate": channeldata.sample_rate,
            "npts": len(datat),
            "network": network.code,
            "location": channeldata.location_code,
            "station": station.code,
            "channel": channel,
            "starttime": UTCDateTime(2010, 1, 1, 0, 0, 0),
        }
        trace = Trace(data=datat, header=header)
        traces.append(trace)
    invstream = StationStream(traces=traces, inventory=inventory)
    x = 1
def read_bhrc(filename, config=None, **kwargs):
    """Read the Iran BHRC strong motion data format.

    Args:
        filename (str):
            Path to BHRC data file.
        config (dict):
            Dictionary containing configuration.
        kwargs (ref):
            Other arguments will be ignored.

    Returns:
        list: Sequence of one StationStream object containing 3
        StationTrace objects.
    """
    header1, offset = _read_header_lines(filename, 0)
    data1, offset = _read_data(filename, offset, header1)
    header2, offset = _read_header_lines(filename, offset)
    data2, offset = _read_data(filename, offset, header2)
    header3, offset = _read_header_lines(filename, offset)
    data3, offset = _read_data(filename, offset, header3)
    trace1 = StationTrace(data1, header1)
    trace2 = StationTrace(data2, header2)
    trace3 = StationTrace(data3, header3)
    stream = StationStream([trace1, trace2, trace3])

    for tr in stream:
        if tr.stats.standard.process_level != PROCESS_LEVELS["V0"]:
            response = {"input_units": "counts", "output_units": "cm/s^2"}
            tr.setProvenance("remove_response", response)

    return [stream]
    def get_integral(self):
        """
        Calculated the integral of each trace's data.

        Returns:
            stream: StationStream with the integrated data.
        """
        stream = StationStream([])
        for trace in self.transform_data:
            integrated_trace = trace.copy().integrate()
            if integrated_trace.stats.standard.units == 'acc':
                integrated_trace.stats.standard.units = 'vel'
            elif integrated_trace.stats.standard.units == 'vel':
                integrated_trace.stats.standard.units = 'disp'
            stream.append(integrated_trace)
        return stream
Beispiel #11
0
def test_uneven_stream():
    inventory = get_inventory()
    channels = ['HN1', 'HN2', 'HNZ']
    data1 = np.random.rand(1000)
    data2 = np.random.rand(1001)
    data3 = np.random.rand(1002)
    data = [data1, data2, data3]
    traces = []
    network = inventory.networks[0]
    station = network.stations[0]
    chlist = station.channels
    channelcodes = [ch.code for ch in chlist]
    for datat, channel in zip(data, channels):
        chidx = channelcodes.index(channel)
        channeldata = chlist[chidx]
        header = {
            'sampling_rate': channeldata.sample_rate,
            'npts': len(datat),
            'network': network.code,
            'location': channeldata.location_code,
            'station': station.code,
            'channel': channel,
            'starttime': UTCDateTime(2010, 1, 1, 0, 0, 0)
        }
        trace = Trace(data=datat, header=header)
        traces.append(trace)
    invstream = StationStream(traces=traces, inventory=inventory)
    x = 1
def read_bhrc(filename):
    """Read the Iran BHRC strong motion data format.

    Args:
        filename (str): path to BHRC data file.

    Returns:
        list: Sequence of one StationStream object containing 3
        StationTrace objects.
    """
    header1, offset = _read_header_lines(filename, 0)
    data1, offset = _read_data(filename, offset, header1)
    header2, offset = _read_header_lines(filename, offset)
    data2, offset = _read_data(filename, offset, header2)
    header3, offset = _read_header_lines(filename, offset)
    data3, offset = _read_data(filename, offset, header3)
    trace1 = StationTrace(data1, header1)
    trace2 = StationTrace(data2, header2)
    trace3 = StationTrace(data3, header3)
    stream = StationStream([trace1, trace2, trace3])

    for tr in stream:
        if tr.stats.standard.process_level != PROCESS_LEVELS['V0']:
            response = {'input_units': 'counts', 'output_units': 'cm/s^2'}
            tr.setProvenance('remove_response', response)

    return [stream]
Beispiel #13
0
def read_renadic(filename, config=None, **kwargs):
    """Read the Chilean RENADIC strong motion data format.

    Args:
        filename (str):
            path to RENADIC data file.
        config (dict):
            Dictionary containing configuration.
        kwargs (ref):
            Other arguments will be ignored.

    Returns:
        list: Sequence of one StationStream object containing 3
        StationTrace objects.
    """
    # This network does not include station coordinates in the data files,
    # but they did provide a PDF table with information about each station,
    # including structure type (free field or something else) and the
    # coordinates
    data_dir = pkg_resources.resource_filename("gmprocess", "data")
    tablefile = os.path.join(data_dir, "station_coordinates.xlsx")
    table = pd.read_excel(tablefile, engine="openpyxl")

    with open(filename, "rt", encoding=ENCODING) as f:
        lines1 = [next(f) for x in range(TEXT_HDR_ROWS)]
    header1 = _read_header(lines1, filename, table)
    ndata_rows = int(np.ceil((header1["npts"] * 2) / NCOLS))

    skip_rows = TEXT_HDR_ROWS + INT_HEADER_ROWS + FLOAT_HEADER_ROWS
    data1 = _read_data(filename, skip_rows, header1["npts"])

    skip_rows += ndata_rows + 1
    with open(filename, "rt", encoding=ENCODING) as f:
        [next(f) for x in range(skip_rows)]
        lines2 = [next(f) for x in range(TEXT_HDR_ROWS)]

    header2 = _read_header(lines2, filename, table)
    skip_rows += TEXT_HDR_ROWS + INT_HEADER_ROWS + FLOAT_HEADER_ROWS
    data2 = _read_data(filename, skip_rows, header1["npts"])

    skip_rows += ndata_rows + 1
    with open(filename, "rt", encoding=ENCODING) as f:
        [next(f) for x in range(skip_rows)]
        lines3 = [next(f) for x in range(TEXT_HDR_ROWS)]

    header3 = _read_header(lines3, filename, table)
    skip_rows += TEXT_HDR_ROWS + INT_HEADER_ROWS + FLOAT_HEADER_ROWS
    data3 = _read_data(filename, skip_rows, header1["npts"])

    trace1 = StationTrace(data=data1, header=header1)
    response = {"input_units": "counts", "output_units": "cm/s^2"}
    trace1.setProvenance("remove_response", response)
    trace2 = StationTrace(data=data2, header=header2)
    trace2.setProvenance("remove_response", response)
    trace3 = StationTrace(data=data3, header=header3)
    trace3.setProvenance("remove_response", response)
    stream = StationStream(traces=[trace1, trace2, trace3])
    return [stream]
Beispiel #14
0
def test_stream():
    inventory = get_inventory()
    channels = ["HN1", "HN2", "HNZ"]
    data = np.random.rand(1000)
    traces = []
    network = inventory.networks[0]
    station = network.stations[0]
    chlist = station.channels
    channelcodes = [ch.code for ch in chlist]
    for channel in channels:
        chidx = channelcodes.index(channel)
        channeldata = chlist[chidx]
        header = {
            "sampling_rate": channeldata.sample_rate,
            "npts": len(data),
            "network": network.code,
            "location": channeldata.location_code,
            "station": station.code,
            "channel": channel,
            "starttime": UTCDateTime(2010, 1, 1, 0, 0, 0),
        }
        trace = Trace(data=data, header=header)
        traces.append(trace)
    invstream = StationStream(traces=traces, inventory=inventory)
    inventory2 = invstream.getInventory()
    inv2_channel1 = inventory2.networks[0].stations[0].channels[0]
    inv_channel1 = inventory2.networks[0].stations[0].channels[0]
    assert inv_channel1.code == inv2_channel1.code

    # test the streamparam functionality
    statsdict = {"name": "Fred", "age": 34}
    invstream.setStreamParam("stats", statsdict)
    assert invstream.getStreamParamKeys() == ["stats"]
    cmpdict = invstream.getStreamParam("stats")
    assert statsdict == cmpdict
Beispiel #15
0
def test_stream():
    inventory = get_inventory()
    channels = ['HN1', 'HN2', 'HNZ']
    data = np.random.rand(1000)
    traces = []
    network = inventory.networks[0]
    station = network.stations[0]
    chlist = station.channels
    channelcodes = [ch.code for ch in chlist]
    for channel in channels:
        chidx = channelcodes.index(channel)
        channeldata = chlist[chidx]
        header = {
            'sampling_rate': channeldata.sample_rate,
            'npts': len(data),
            'network': network.code,
            'location': channeldata.location_code,
            'station': station.code,
            'channel': channel,
            'starttime': UTCDateTime(2010, 1, 1, 0, 0, 0)
        }
        trace = Trace(data=data, header=header)
        traces.append(trace)
    invstream = StationStream(traces=traces, inventory=inventory)
    inventory2 = invstream.getInventory()
    inv2_channel1 = inventory2.networks[0].stations[0].channels[0]
    inv_channel1 = inventory2.networks[0].stations[0].channels[0]
    assert inv_channel1.code == inv2_channel1.code

    # test the streamparam functionality
    statsdict = {'name': 'Fred', 'age': 34}
    invstream.setStreamParam('stats', statsdict)
    assert invstream.getStreamParamKeys() == ['stats']
    cmpdict = invstream.getStreamParam('stats')
    assert statsdict == cmpdict
Beispiel #16
0
def read_geonet(filename, config=None, **kwargs):
    """Read New Zealand GNS V1/V2 strong motion file.

    There is one extra key in the Stats object for each Trace -
    "process_level".
    This will be set to either "V1" or "V2".

    Args:
        filename (str):
            Path to possible GNS V1/V2 data file.
        config (dict):
            Dictionary containing configuration.
        kwargs (ref):
            Other arguments will be ignored.

    Returns:
        Stream: Obspy Stream containing three channels of acceleration data
        (cm/s**2).
    """
    logging.debug("Starting read_geonet.")
    if not is_geonet(filename, config):
        raise Exception(
            f"{filename} is not a valid GEONET strong motion data file.")
    trace1, offset1, _ = _read_channel(filename, 0)
    trace2, offset2, _ = _read_channel(filename, offset1)
    trace3, _, _ = _read_channel(filename, offset2)

    # occasionally, geonet horizontal components are
    # identical.  To handle this, we'll set the second
    # channel to whatever isn't the first one.
    channel1 = trace1.stats["channel"]
    channel2 = trace2.stats["channel"]
    channel3 = trace3.stats["channel"]
    if channel1 == channel2:
        if channel1.endswith("1"):
            trace2.stats["channel"] = trace2.stats["channel"][0:2] + "2"
        elif channel1.endswith("2"):
            trace2.stats["channel"] = trace2.stats["channel"][0:2] + "1"
        else:
            raise Exception(
                "GEONET: Could not resolve duplicate channels in %s" %
                trace1.stats["station"])
    if channel2 == channel3:
        if channel2.endswith("2"):
            trace3.stats["channel"] = trace2.stats["channel"][0:2] + "1"
        elif channel2.endswith("1"):
            trace3.stats["channel"] = trace2.stats["channel"][0:2] + "2"
        else:
            raise Exception(
                "GEONET: Could not resolve duplicate channels in %s" %
                trace1.stats["station"])

    traces = [trace1, trace2, trace3]
    stream = StationStream(traces)

    return [stream]
def read_renadic(filename):
    """Read the Chilean RENADIC strong motion data format.

    Args:
        filename (str):
            path to RENADIC data file.

    Returns:
        list: Sequence of one StationStream object containing 3
        StationTrace objects.
    """
    # This network does not include station coordinates in the data files,
    # but they did provide a PDF table with information about each station,
    # including structure type (free field or something else) and the
    # coordinates
    data_dir = pkg_resources.resource_filename('gmprocess', 'data')
    tablefile = os.path.join(data_dir, 'station_coordinates.xlsx')
    table = pd.read_excel(tablefile, engine="openpyxl")

    with open(filename, 'rt', encoding=ENCODING) as f:
        lines1 = [next(f) for x in range(TEXT_HDR_ROWS)]
    header1 = _read_header(lines1, filename, table)
    ndata_rows = int(np.ceil((header1['npts'] * 2) / NCOLS))

    skip_rows = TEXT_HDR_ROWS + INT_HEADER_ROWS + FLOAT_HEADER_ROWS
    data1 = _read_data(filename, skip_rows, header1['npts'])

    skip_rows += ndata_rows + 1
    with open(filename, 'rt', encoding=ENCODING) as f:
        [next(f) for x in range(skip_rows)]
        lines2 = [next(f) for x in range(TEXT_HDR_ROWS)]

    header2 = _read_header(lines2, filename, table)
    skip_rows += TEXT_HDR_ROWS + INT_HEADER_ROWS + FLOAT_HEADER_ROWS
    data2 = _read_data(filename, skip_rows, header1['npts'])

    skip_rows += ndata_rows + 1
    with open(filename, 'rt', encoding=ENCODING) as f:
        [next(f) for x in range(skip_rows)]
        lines3 = [next(f) for x in range(TEXT_HDR_ROWS)]

    header3 = _read_header(lines3, filename, table)
    skip_rows += TEXT_HDR_ROWS + INT_HEADER_ROWS + FLOAT_HEADER_ROWS
    data3 = _read_data(filename, skip_rows, header1['npts'])

    trace1 = StationTrace(data=data1, header=header1)
    response = {'input_units': 'counts', 'output_units': 'cm/s^2'}
    trace1.setProvenance('remove_response', response)
    trace2 = StationTrace(data=data2, header=header2)
    trace2.setProvenance('remove_response', response)
    trace3 = StationTrace(data=data3, header=header3)
    trace3.setProvenance('remove_response', response)
    stream = StationStream(traces=[trace1, trace2, trace3])
    return [stream]
    def from_traces(cls, traces):
        """Create a StreamCollection instance from a list of traces.

        Args:
            traces (list):
                List of StationTrace objects.

        Returns:
            StreamCollection instance.
        """

        streams = [StationStream([tr]) for tr in traces]
        return cls(streams)
def read_nsmn(filename, **kwargs):
    """Read the Turkish NSMN strong motion data format.

    Args:
        filename (str):
            path to NSMN data file.
        kwargs (ref):
            Other arguments will be ignored.

    Returns:
        list: Sequence of one StationStream object containing 3
        StationTrace objects.
    """
    header = _read_header(filename)
    header1 = copy.deepcopy(header)
    header2 = copy.deepcopy(header)
    header3 = copy.deepcopy(header)
    header1['standard']['horizontal_orientation'] = 0.0
    header1['standard']['vertical_orientation'] = np.nan
    header1['channel'] = get_channel_name(header['sampling_rate'], True, False,
                                          True)
    header1['standard']['units_type'] = get_units_type(header1['channel'])
    header2['standard']['horizontal_orientation'] = 90.0
    header2['standard']['vertical_orientation'] = np.nan
    header2['channel'] = get_channel_name(header['sampling_rate'], True, False,
                                          False)
    header2['standard']['units_type'] = get_units_type(header2['channel'])
    header3['standard']['horizontal_orientation'] = 0.0
    header3['standard']['vertical_orientation'] = np.nan
    header3['channel'] = get_channel_name(header['sampling_rate'], True, True,
                                          False)
    header3['standard']['units_type'] = get_units_type(header3['channel'])

    # three columns of NS, EW, UD
    # data = np.genfromtxt(filename, skip_header=TEXT_HDR_ROWS,
    #                      delimiter=[COLWIDTH] * NCOLS, encoding=ENCODING)
    data = np.loadtxt(filename, skiprows=TEXT_HDR_ROWS, encoding=ENCODING)
    data1 = data[:, 0]
    data2 = data[:, 1]
    data3 = data[:, 2]
    trace1 = StationTrace(data=data1, header=header1)
    response = {'input_units': 'counts', 'output_units': 'cm/s^2'}
    trace1.setProvenance('remove_response', response)
    trace2 = StationTrace(data=data2, header=header2)
    trace2.setProvenance('remove_response', response)
    trace3 = StationTrace(data=data3, header=header3)
    trace3.setProvenance('remove_response', response)
    stream = StationStream(traces=[trace1, trace2, trace3])
    return [stream]
Beispiel #20
0
def read_nsmn(filename, config=None):
    """Read the Turkish NSMN strong motion data format.

    Args:
        filename (str):
            path to NSMN data file.
        config (dict):
            Dictionary containing configuration.

    Returns:
        list: Sequence of one StationStream object containing 3 StationTrace
        objects.
    """
    header = _read_header(filename)
    header1 = copy.deepcopy(header)
    header2 = copy.deepcopy(header)
    header3 = copy.deepcopy(header)
    header1["standard"]["horizontal_orientation"] = 0.0
    header1["standard"]["vertical_orientation"] = np.nan
    header1["channel"] = get_channel_name(header["sampling_rate"], True, False,
                                          True)
    header1["standard"]["units_type"] = get_units_type(header1["channel"])
    header2["standard"]["horizontal_orientation"] = 90.0
    header2["standard"]["vertical_orientation"] = np.nan
    header2["channel"] = get_channel_name(header["sampling_rate"], True, False,
                                          False)
    header2["standard"]["units_type"] = get_units_type(header2["channel"])
    header3["standard"]["horizontal_orientation"] = 0.0
    header3["standard"]["vertical_orientation"] = np.nan
    header3["channel"] = get_channel_name(header["sampling_rate"], True, True,
                                          False)
    header3["standard"]["units_type"] = get_units_type(header3["channel"])

    # three columns of NS, EW, UD
    # data = np.genfromtxt(filename, skip_header=TEXT_HDR_ROWS,
    #                      delimiter=[COLWIDTH] * NCOLS, encoding=ENCODING)
    data = np.loadtxt(filename, skiprows=TEXT_HDR_ROWS, encoding=ENCODING)
    data1 = data[:, 0]
    data2 = data[:, 1]
    data3 = data[:, 2]
    trace1 = StationTrace(data=data1, header=header1)
    response = {"input_units": "counts", "output_units": "cm/s^2"}
    trace1.setProvenance("remove_response", response)
    trace2 = StationTrace(data=data2, header=header2)
    trace2.setProvenance("remove_response", response)
    trace3 = StationTrace(data=data3, header=header3)
    trace3.setProvenance("remove_response", response)
    stream = StationStream(traces=[trace1, trace2, trace3])
    return [stream]
Beispiel #21
0
def read_cosmos(filename, config=None, **kwargs):
    """Read COSMOS V1/V2 strong motion file.

    There is one extra key in the Stats object for each Trace -
    "process_level". This will be set to either "V1" or "V2".

    Args:
        filename (str):
            Path to possible COSMOS V1/V2 data file.
        config (dict):
            Dictionary containing configuration.
        kwargs (ref):
            valid_station_types (list): List of valid station types. See table
                6  in the COSMOS strong motion data format documentation for
                station type codes.
            Other arguments will be ignored.

    Returns:
        list: List of StationStreams containing three channels of acceleration
        data (cm/s**2).
    """
    logging.debug("Starting read_cosmos.")
    if not is_cosmos(filename, config):
        raise Exception(
            f"{filename} is not a valid COSMOS strong motion data file.")
    # get list of valid stations
    valid_station_types = kwargs.get("valid_station_types", None)
    # get list of valid stations
    location = kwargs.get("location", "")

    # count the number of lines in the file
    with open(filename, encoding="utf-8") as f:
        line_count = sum(1 for _ in f)

    # read as many channels as are present in the file
    line_offset = 0
    stream = StationStream([])
    while line_offset < line_count:
        trace, line_offset = _read_channel(filename,
                                           line_offset,
                                           location=location)
        # store the trace if the station type is in the valid_station_types
        # list or store the trace if there is no valid_station_types list
        if valid_station_types is not None:
            scode = trace.stats["format_specific"]["station_code"]
            if scode in valid_station_types:
                stream.append(trace)
        else:
            stream.append(trace)

    return [stream]
def test_exceptions():
    ddir = os.path.join('data', 'testdata', 'geonet')
    homedir = pkg_resources.resource_filename('gmprocess', ddir)
    datafile_v2 = os.path.join(homedir, 'us1000778i',
                               '20161113_110259_WTMC_20.V2A')
    stream_v2 = read_geonet(datafile_v2)[0]
    # Check for origin Error
    passed = True
    try:
        m = MetricsController('pga',
                              'radial_transverse',
                              stream_v2,
                              config=config)
    except PGMException as e:
        passed = False
    assert passed == False

    # -------- Horizontal Channel Errors -----------
    # Check for horizontal passthrough gm
    st2 = stream_v2.select(component='[N1]')
    st3 = stream_v2.select(component='Z')
    st1 = StationStream([st2[0], st3[0]])
    passed = True
    m = MetricsController('pga', 'geometric_mean', st1, config=config)
    pgm = m.pgms
    result = pgm['Result'].tolist()[0]
    assert np.isnan(result)
    # Check for horizontal passthrough rotd50
    m = MetricsController('pga', 'rotd50', st1, config=config)
    pgm = m.pgms
    result = pgm['Result'].tolist()[0]
    assert np.isnan(result)
    # Check for horizontal passthrough gmrotd50
    m = MetricsController('pga', 'gmrotd50', st1, config=config)
    pgm = m.pgms
    result = pgm['Result'].tolist()[0]
    assert np.isnan(result)
    # No horizontal channels
    try:
        m = MetricsController('sa3.0', 'channels', st3, config=config)
    except PGMException as e:
        passed = False
    assert passed == False
Beispiel #23
0
def test_exceptions():
    ddir = os.path.join("data", "testdata", "geonet")
    homedir = pkg_resources.resource_filename("gmprocess", ddir)
    datafile_v2 = os.path.join(homedir, "us1000778i",
                               "20161113_110259_WTMC_20.V2A")
    stream_v2 = read_geonet(datafile_v2)[0]
    # Check for origin Error
    passed = True
    try:
        m = MetricsController("pga",
                              "radial_transverse",
                              stream_v2,
                              config=config)
    except PGMException as e:
        passed = False
    assert passed == False

    # -------- Horizontal Channel Errors -----------
    # Check for horizontal passthrough gm
    st2 = stream_v2.select(component="[N1]")
    st3 = stream_v2.select(component="Z")
    st1 = StationStream([st2[0], st3[0]])
    passed = True
    m = MetricsController("pga", "geometric_mean", st1, config=config)
    pgm = m.pgms
    result = pgm["Result"].tolist()[0]
    assert np.isnan(result)
    # Check for horizontal passthrough rotd50
    m = MetricsController("pga", "rotd50", st1, config=config)
    pgm = m.pgms
    result = pgm["Result"].tolist()[0]
    assert np.isnan(result)
    # Check for horizontal passthrough gmrotd50
    m = MetricsController("pga", "gmrotd50", st1, config=config)
    pgm = m.pgms
    result = pgm["Result"].tolist()[0]
    assert np.isnan(result)
    # No horizontal channels
    try:
        m = MetricsController("sa3.0", "channels", st3, config=config)
    except PGMException as e:
        passed = False
    assert passed == False
Beispiel #24
0
def test_check_clipping():
    data_files, _ = read_data_dir("clipping_samples", "hv70907436", "*.mseed")
    data_files.sort()
    origin = get_event_object("hv70907436")
    streams = []
    for f in data_files:
        streams += read_data(f)

    codes = ["HV.TOUO", "HV.MOKD", "HV.MLOD", "HV.HOVE", "HV.HUAD", "HV.HSSD"]
    passed = []
    for code in codes:
        traces = []
        for ss in streams:
            tcode = f"{ss[0].stats.network}.{ss[0].stats.station}"
            if tcode == code:
                traces.append(ss[0])
        st = StationStream(traces)
        check_clipping(st, origin)
        passed.append(st.passed)

    assert np.all(~np.array(passed))
Beispiel #25
0
    def __init__(
        self,
        streams=None,
        config=None,
    ):
        """Initialize StreamCollection.

        Args:
            streams (list):
                List of StationStream objects.
            config (dict):
                Configuration options.
        """
        self.config = config
        if not isinstance(streams, list):
            raise TypeError("streams must be a list of StationStream objects.")
        newstreams = []
        for st in streams:
            if not isinstance(st, StationStream):
                raise TypeError(
                    "streams must be a list of StationStream objects.")
            else:
                if hasattr(st, "tag"):
                    stream_tag = st.tag
                else:
                    stream_tag = None
                stream_params_keys = st.getStreamParamKeys()
                for tr in st:
                    new_st = StationStream(traces=[tr])
                    new_st.id = ".".join([
                        tr.stats.network,
                        tr.stats.station,
                        tr.stats.location,
                        tr.stats.channel,
                    ], )
                    if stream_tag is not None:
                        new_st.tag = stream_tag
                    if len(stream_params_keys):
                        for k in stream_params_keys:
                            new_st.setStreamParam(k, st.getStreamParam(k))
                    new_st.use_array = True
                    newstreams.append(new_st)
        self.streams = newstreams
Beispiel #26
0
def test_duration():
    ddir = os.path.join("data", "testdata")
    datadir = pkg_resources.resource_filename("gmprocess", ddir)
    data_file = os.path.join(datadir, "duration_data.json")
    with open(data_file, "rt", encoding="utf-8") as f:
        jdict = json.load(f)

    time = np.array(jdict["time"])
    # input output is m/s/s
    acc = np.array(jdict["acc"]) / 100
    target_d595 = jdict["d595"]
    delta = time[2] - time[1]
    sr = 1 / delta
    header = {
        "delta": delta,
        "sampling_rate": sr,
        "npts": len(acc),
        "channel": "HN1",
        "standard": {
            "corner_frequency": np.nan,
            "station_name": "",
            "source": "json",
            "source_file": "",
            "instrument": "",
            "instrument_period": np.nan,
            "source_format": "json",
            "comments": "",
            "structure_type": "",
            "sensor_serial_number": "",
            "process_level": "raw counts",
            "process_time": "",
            "horizontal_orientation": np.nan,
            "vertical_orientation": np.nan,
            "units": "m/s/s",
            "units_type": "acc",
            "instrument_sensitivity": np.nan,
            "volts_to_counts": np.nan,
            "instrument_damping": np.nan,
        },
    }
    # input is cm/s/s output is m/s/s
    trace = StationTrace(data=acc * 100, header=header)
    trace2 = trace.copy()
    trace2.stats.channel = "HN2"
    stream = StationStream([trace, trace2])

    for tr in stream:
        response = {"input_units": "counts", "output_units": "cm/s^2"}
        tr.setProvenance("remove_response", response)

    station = StationSummary.from_stream(stream, ["ARITHMETIC_MEAN"],
                                         ["duration5-95"])
    pgms = station.pgms
    d595 = pgms.loc["DURATION5-95", "ARITHMETIC_MEAN"].Result

    np.testing.assert_allclose(d595, target_d595, atol=1e-4, rtol=1e-4)

    # Test other components
    data_files, _ = read_data_dir("cwb", "us1000chhc", "2-ECU.dat")
    stream = read_data(data_files[0])[0]
    station = StationSummary.from_stream(
        stream,
        [
            "channels",
            "gmrotd",
            "rotd50",
            "greater_of_two_horizontals",
            "ARITHMETIC_MEAN",
            "geometric_mean",
        ],
        ["duration5-95"],
    )
    # Currently disallowed
    assert "gmrotd" not in station.pgms.index.get_level_values(1)
    assert "rotd50" not in station.pgms.index.get_level_values(1)
    print(station)
Beispiel #27
0
def read_dmg(filename, **kwargs):
    """Read DMG strong motion file.

    Notes:
        CSMIP is synonymous to as DMG in this reader.

    Args:
        filename (str):
            Path to possible DMG data file.
        kwargs (ref):
            units (str): String determining which timeseries is return. Valid
                    options include 'acc', 'vel', 'disp'. Default is 'acc'.
            Other arguments will be ignored.

    Returns:
        Stream: Obspy Stream containing three channels of acceleration data
        (cm/s**2).
    """
    logging.debug("Starting read_dmg.")
    if not is_dmg(filename):
        raise Exception(
            '%s is not a valid DMG strong motion data file.' % filename)

    # Check for units and location
    units = kwargs.get('units', 'acc')
    location = kwargs.get('location', '')

    if units not in UNITS:
        raise Exception('DMG: Not a valid choice of units.')

    # Check for DMG format and determine volume type
    line = open(filename, 'rt', encoding='utf-8').readline()
    if is_dmg(filename):
        if line.lower().find('uncorrected') >= 0:
            reader = 'V1'
        elif line.lower().find('corrected') >= 0:
            reader = 'V2'
        elif line.lower().find('response') >= 0:
            reader = 'V3'

    # Count the number of lines in the file
    with open(filename, encoding='utf-8') as f:
        line_count = sum(1 for _ in f)

    # Read as many channels as are present in the file
    line_offset = 0
    trace_list = []
    while line_offset < line_count:
        if reader == 'V2':
            traces, line_offset = _read_volume_two(
                filename, line_offset, location=location, units=units)
            if traces is not None:
                trace_list += traces
        elif reader == 'V1':
            traces, line_offset = _read_volume_one(
                filename, line_offset, location=location, units=units)
            if traces is not None:
                trace_list += traces
        else:
            raise ValueError('DMG: Not a supported volume.')

    stream = StationStream([])
    for trace in trace_list:
        # For our purposes, we only want acceleration, so lets only return
        # that; we may need to change this later if others start using this
        # code and want to read in the other data.
        if trace.stats['standard']['units'] == units:
            stream.append(trace)
    return [stream]
    def __handle_duplicates(
        self,
        max_dist_tolerance,
        preference_order,
        process_level_preference,
        format_preference,
    ):
        """
        Removes duplicate data from the StreamCollection, based on the
        process level and format preferences.

        Args:
            max_dist_tolerance (float):
                Maximum distance tolerance for determining whether two streams
                are at the same location (in meters).
            preference_order (list):
                A list containing 'process_level', 'source_format',
                'starttime', 'npts', 'sampling_rate', 'location_code' in the
                desired order for choosing the preferred trace.
            process_level_preference (list):
                A list containing 'V0', 'V1', 'V2', with the order determining
                which process level is the most preferred (most preferred goes
                first in the list).
            format_preference (list):
                A list continaing strings of the file source formats (found
                in gmprocess.io). Does not need to list all of the formats.
                Example: ['cosmos', 'dmg'] indicates that cosmos files are
                preferred over dmg files.
        """

        # If arguments are None, check the config
        # If not in the config, use the default values at top of the file
        preferences = {
            "max_dist_tolerance": max_dist_tolerance,
            "preference_order": preference_order,
            "process_level_preference": process_level_preference,
            "format_preference": format_preference,
        }

        for key, val in preferences.items():
            if val is None:
                if self.config is None:
                    self.config = get_config()
                preferences[key] = self.config["duplicate"][key]

        stream_params = gather_stream_parameters(self.streams)

        traces = []
        for st in self.streams:
            for tr in st:
                traces.append(tr)
        preferred_traces = []

        for tr_to_add in traces:
            is_duplicate = False
            for tr_pref in preferred_traces:
                if are_duplicates(tr_to_add, tr_pref,
                                  preferences["max_dist_tolerance"]):
                    is_duplicate = True
                    break

            if is_duplicate:
                if (choose_preferred(
                        tr_to_add,
                        tr_pref,
                        preferences["preference_order"],
                        preferences["process_level_preference"],
                        preferences["format_preference"],
                ) == tr_to_add):
                    preferred_traces.remove(tr_pref)
                    logging.info(
                        "Trace %s (%s) is a duplicate and "
                        "has been removed from the StreamCollection." %
                        (tr_pref.id, tr_pref.stats.standard.source_file))
                    preferred_traces.append(tr_to_add)
                else:
                    logging.info(
                        "Trace %s (%s) is a duplicate and "
                        "has been removed from the StreamCollection." %
                        (tr_to_add.id, tr_to_add.stats.standard.source_file))

            else:
                preferred_traces.append(tr_to_add)

        streams = [StationStream([tr]) for tr in preferred_traces]
        streams = insert_stream_parameters(streams, stream_params)
        self.streams = streams
Beispiel #29
0
def test_fas():
    """
    Testing based upon the work provided in
    https://github.com/arkottke/notebooks/blob/master/effective_amp_spectrum.ipynb
    """
    ddir = os.path.join('data', 'testdata')
    datadir = pkg_resources.resource_filename('gmprocess', ddir)
    fas_file = os.path.join(datadir, 'fas_arithmetic_mean.pkl')
    p1 = os.path.join(datadir, 'peer', 'RSN763_LOMAP_GIL067.AT2')
    p2 = os.path.join(datadir, 'peer', 'RSN763_LOMAP_GIL337.AT2')

    stream = StationStream([])
    for idx, fpath in enumerate([p1, p2]):
        with open(fpath, encoding='utf-8') as file_obj:
            for _ in range(3):
                next(file_obj)
            meta = re.findall(r'[.0-9]+', next(file_obj))
            dt = float(meta[1])
            accels = np.array(
                [col for line in file_obj for col in line.split()])
        trace = StationTrace(data=accels,
                             header={
                                 'channel': 'H' + str(idx),
                                 'delta': dt,
                                 'units': 'acc',
                                 'standard': {
                                     'corner_frequency': np.nan,
                                     'station_name': '',
                                     'source': 'json',
                                     'instrument': '',
                                     'instrument_period': np.nan,
                                     'source_format': 'json',
                                     'comments': '',
                                     'structure_type': '',
                                     'sensor_serial_number': '',
                                     'source_file': '',
                                     'process_level': 'raw counts',
                                     'process_time': '',
                                     'horizontal_orientation': np.nan,
                                     'vertical_orientation': np.nan,
                                     'units': 'acc',
                                     'units_type': 'acc',
                                     'instrument_sensitivity': np.nan,
                                     'instrument_damping': np.nan
                                 }
                             })
        stream.append(trace)

    for tr in stream:
        response = {'input_units': 'counts', 'output_units': 'cm/s^2'}
        tr.setProvenance('remove_response', response)

    target_df = pd.read_pickle(fas_file)
    ind_vals = target_df.index.values
    per = np.unique(
        [float(i[0].split(')')[0].split('(')[1]) for i in ind_vals])
    freqs = 1 / per
    imts = ['fas' + str(p) for p in per]
    summary = StationSummary.from_stream(stream, ['arithmetic_mean'],
                                         imts,
                                         bandwidth=30)

    pgms = summary.pgms
    # pgms.to_pickle(fas_file)
    for idx, f in enumerate(freqs):
        fstr = 'FAS(%.3f)' % (1 / f)
        fval1 = pgms.loc[fstr, 'ARITHMETIC_MEAN'].Result
        fval2 = target_df.loc[fstr, 'ARITHMETIC_MEAN'].Result
        np.testing.assert_allclose(fval1, fval2, rtol=1e-5, atol=1e-5)
def test_fas():
    """
    Testing based upon the work provided in
    https://github.com/arkottke/notebooks/blob/master/effective_amp_spectrum.ipynb
    """
    ddir = os.path.join("data", "testdata")
    datadir = pkg_resources.resource_filename("gmprocess", ddir)
    fas_file = os.path.join(datadir, "fas_geometric_mean.pkl")
    p1 = os.path.join(datadir, "peer", "RSN763_LOMAP_GIL067.AT2")
    p2 = os.path.join(datadir, "peer", "RSN763_LOMAP_GIL337.AT2")

    stream = StationStream([])
    for idx, fpath in enumerate([p1, p2]):
        with open(fpath, encoding="utf-8") as file_obj:
            for _ in range(3):
                next(file_obj)
            meta = re.findall(r"[.0-9]+", next(file_obj))
            dt = float(meta[1])
            accels = np.array(
                [col for line in file_obj for col in line.split()],
                dtype=float)
        trace = StationTrace(
            data=accels,
            header={
                "channel": "H" + str(idx),
                "delta": dt,
                "units": "acc",
                "standard": {
                    "corner_frequency": np.nan,
                    "station_name": "",
                    "source": "json",
                    "instrument": "",
                    "instrument_period": np.nan,
                    "source_format": "json",
                    "comments": "",
                    "structure_type": "",
                    "sensor_serial_number": "",
                    "source_file": "",
                    "process_level": "raw counts",
                    "process_time": "",
                    "horizontal_orientation": np.nan,
                    "vertical_orientation": np.nan,
                    "units": "acc",
                    "units_type": "acc",
                    "instrument_sensitivity": np.nan,
                    "instrument_damping": np.nan,
                },
            },
        )
        stream.append(trace)

    for tr in stream:
        response = {"input_units": "counts", "output_units": "cm/s^2"}
        tr.setProvenance("remove_response", response)

    target_df = pd.read_pickle(fas_file)
    ind_vals = target_df.index.values
    per = np.unique(
        [float(i[0].split(")")[0].split("(")[1]) for i in ind_vals])
    freqs = 1 / per
    imts = ["fas" + str(p) for p in per]
    summary = StationSummary.from_stream(stream, ["geometric_mean"],
                                         imts,
                                         bandwidth=30)

    pgms = summary.pgms
    # pgms.to_pickle(fas_file)
    for idx, f in enumerate(freqs):
        fstr = f"FAS({1 / f:.3f})"
        fval1 = pgms.loc[fstr, "GEOMETRIC_MEAN"].Result
        fval2 = target_df.loc[fstr, "GEOMETRIC_MEAN"].Result
        np.testing.assert_allclose(fval1, fval2, rtol=1e-5, atol=1e-5)