Example #1
0
def main(segment, config):
    '''main function'''
    # annoying print statementin obspy 1.1.1  when calling the function 'psd'
    # (see below) and when adding a trace shorter than
    # the ppsd_length: workaround? redirect to stderr (which is captured by the caller):
    temp = sys.stdout
    try:
        sys.stdout = sys.stderr

        stream = segment.stream(True)
        assert1trace(
            stream)  # raise and return if stream has more than one trace
        # raw_trace = stream[0]

        ret = get_psd_values_df(segment, config)
        # pd.concat(data, sort=False, ignore_index=True, copy=True, axis=0)

        ret['amplitude_ratio'] = ampratio(segment.stream()[0])
        ret['event_id'] = segment.event_id
        ret['station_id'] = segment.station.id
        ret['event_time'] = segment.event.time
        # store channel's channel via data_seed_id (might be faster):
        # calculate it here so in case of error we avoid unnecessary calculations
        net_sta_loc_cha = segment.data_seed_id.split('.')
        ret['location_code'] = net_sta_loc_cha[2]
        ret['channel_code'] = net_sta_loc_cha[3]
        ret['magnitude'] = segment.event.magnitude
        ret['distance_km'] = segment.event_distance_km
        ret['dataset_id'] = config['dataset_id']
        return ret
    finally:
        sys.stdout = temp
Example #2
0
def main2(segment, config):
    '''calls _main with the normal inventory and all possible
    wrong inventories'''

    # annoying print statementin obspy 1.1.1  when calling the function 'psd'
    # (see below) and when adding a trace shorter than
    # the ppsd_length: workaround? redirect to stderr (which is captured by the caller):
    temp = sys.stdout
    try:
        sys.stdout = sys.stderr

        stream = segment.stream(True)
        assert1trace(
            stream)  # raise and return if stream has more than one trace
        raw_trace = stream[0].copy()

        # store channel's channel via data_seed_id (might be faster):
        # calculate it here so in case of error we avoid unnecessary calculations
        channel_code = segment.data_seed_id.split('.')[3]
        loc_code = segment.data_seed_id.split('.')[2]

        # compute amplitude ratio only once on the raw trace:
        amp_ratio = ampratio(raw_trace)
        #         if amp_ratio >= config['amp_ratio_threshold']:
        #             saturated = True  # @UnusedVariable

        data = []
        # bandpass the trace, according to the event magnitude.
        # This modifies the segment.stream() permanently:
        data.append(_main(segment, config, raw_trace, segment.inventory()))

        ret = pd.concat(data, sort=False, ignore_index=True, copy=True, axis=0)
        ret['amplitude_ratio'] = amp_ratio
        ret['event_id'] = segment.event_id
        ret['station_id'] = segment.station.id
        ret['event_time'] = segment.event.time
        ret['location_code'] = loc_code
        ret['channel_code'] = channel_code
        ret['magnitude'] = segment.event.magnitude
        ret['distance_km'] = segment.event_distance_km
        return ret

    finally:
        sys.stdout = temp
Example #3
0
def main(segment, config):
    """{{ PROCESS_PY_MAINFUNC | indent }}
    """
    stream = segment.stream()
    assert1trace(stream)  # raise and return if stream has more than one trace
    trace = stream[0]  # work with the (surely) one trace now

    # discard saturated signals (according to the threshold set in the config file):
    amp_ratio = ampratio(trace)
    if amp_ratio >= config['amp_ratio_threshold']:
        raise ValueError('possibly saturated (amp. ratio exceeds)')

    # bandpass the trace, according to the event magnitude.
    # WARNING: this modifies the segment.stream() permanently!
    # If you want to preserve the original stream, store trace.copy() beforehand.
    # Also, use a 'try catch': sometimes Inventories are corrupted and obspy raises
    # a TypeError, which would break the WHOLE processing execution.
    # Raising a ValueError will stop the execution of the currently processed
    # segment only (logging the error message):
    try:
        trace = bandpass_remresp(segment, config)
    except TypeError as type_error:
        raise ValueError("Error in 'bandpass_remresp': %s" % str(type_error))

    spectra = signal_noise_spectra(segment, config)
    normal_f0, normal_df, normal_spe = spectra['Signal']
    noise_f0, noise_df, noise_spe = spectra['Noise']
    evt = segment.event
    fcmin = mag2freq(evt.magnitude)
    fcmax = config['preprocess'][
        'bandpass_freq_max']  # used in bandpass_remresp
    snr_ = snr(normal_spe,
               noise_spe,
               signals_form=config['sn_spectra']['type'],
               fmin=fcmin,
               fmax=fcmax,
               delta_signal=normal_df,
               delta_noise=noise_df)
    snr1_ = snr(normal_spe,
                noise_spe,
                signals_form=config['sn_spectra']['type'],
                fmin=fcmin,
                fmax=1,
                delta_signal=normal_df,
                delta_noise=noise_df)
    snr2_ = snr(normal_spe,
                noise_spe,
                signals_form=config['sn_spectra']['type'],
                fmin=1,
                fmax=10,
                delta_signal=normal_df,
                delta_noise=noise_df)
    snr3_ = snr(normal_spe,
                noise_spe,
                signals_form=config['sn_spectra']['type'],
                fmin=10,
                fmax=fcmax,
                delta_signal=normal_df,
                delta_noise=noise_df)
    if snr_ < config['snr_threshold']:
        raise ValueError('low snr %f' % snr_)

    # calculate cumulative

    cum_labels = [0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99]
    cum_trace = cumsumsq(
        trace, normalize=True,
        copy=True)  # copy=True prevent original trace from being modified
    cum_times = timeswhere(cum_trace, *cum_labels)

    # double event
    try:
        (score, t_double, tt1, tt2) = \
            get_multievent_sg(
                cum_trace, cum_times[1], cum_times[-2],
                config['savitzky_golay'], config['multievent_thresholds']
            )
    except IndexError as _ierr:
        raise ValueError("Error in 'get_multievent_sg': %s" % str(_ierr))
    if score in {1, 3}:
        raise ValueError('Double event detected %d %s %s %s' %
                         (score, t_double, tt1, tt2))

    # calculate PGA and times of occurrence (t_PGA):
    # note: you can also provide tstart tend for slicing
    t_PGA, PGA = maxabs(trace, cum_times[1], cum_times[-2])
    trace_int = trace.copy()
    trace_int.integrate()
    t_PGV, PGV = maxabs(trace_int, cum_times[1], cum_times[-2])
    meanoff = meanslice(trace_int, 100, cum_times[-1], trace_int.stats.endtime)

    # calculates amplitudes at the frequency bins given in the config file:
    required_freqs = config['freqs_interp']
    ampspec_freqs = normal_f0 + np.arange(len(normal_spe)) * normal_df
    required_amplitudes = np.interp(np.log10(required_freqs),
                                    np.log10(ampspec_freqs),
                                    normal_spe) / segment.sample_rate

    # compute synthetic WA.
    trace_wa = synth_wood_anderson(segment, config, trace.copy())
    t_WA, maxWA = maxabs(trace_wa)

    # write stuff to csv:
    ret = OrderedDict()

    ret['snr'] = snr_
    ret['snr1'] = snr1_
    ret['snr2'] = snr2_
    ret['snr3'] = snr3_
    for cum_lbl, cum_t in zip(cum_labels[slice(1, 8, 3)],
                              cum_times[slice(1, 8, 3)]):
        ret['cum_t%f' % cum_lbl] = float(
            cum_t)  # convert cum_times to float for saving

    ret['dist_deg'] = segment.event_distance_deg  # dist
    ret['dist_km'] = d2km(segment.event_distance_deg)  # dist_km
    # t_PGA is a obspy UTCDateTime. This type is not supported in HDF output, thus
    # convert it to Python datetime. Note that in CSV output, the value will be written as
    # str(t_PGA.datetime): another option might be to store it as string
    # with str(t_PGA) (returns the iso-formatted string, supported in all output formats):
    ret['t_PGA'] = t_PGA.datetime  # peak info
    ret['PGA'] = PGA
    # (for t_PGV, see note above for t_PGA)
    ret['t_PGV'] = t_PGV.datetime  # peak info
    ret['PGV'] = PGV
    # (for t_WA, see note above for t_PGA)
    ret['t_WA'] = t_WA.datetime
    ret['maxWA'] = maxWA
    ret['channel'] = segment.channel.channel
    ret['channel_component'] = segment.channel.channel[-1]
    # event metadata:
    ret['ev_id'] = segment.event.id
    ret['ev_lat'] = segment.event.latitude
    ret['ev_lon'] = segment.event.longitude
    ret['ev_dep'] = segment.event.depth_km
    ret['ev_mag'] = segment.event.magnitude
    ret['ev_mty'] = segment.event.mag_type
    # station metadata:
    ret['st_id'] = segment.station.id
    ret['st_name'] = segment.station.station
    ret['st_net'] = segment.station.network
    ret['st_lat'] = segment.station.latitude
    ret['st_lon'] = segment.station.longitude
    ret['st_ele'] = segment.station.elevation
    ret['score'] = score
    ret['d2max'] = float(tt1)
    ret['offset'] = np.abs(meanoff / PGV)
    for freq, amp in zip(required_freqs, required_amplitudes):
        ret['f_%.5f' % freq] = float(amp)

    return ret
Example #4
0
File: pgapgv.py Project: rizac/sod
def main2(segment, config):
    '''calls _main with the normal inventory and all possible
    wrong inventories'''
    
    # annoying print statementin obspy 1.1.1  when calling the function 'psd'
    # (see below) and when adding a trace shorter than
    # the ppsd_length: workaround? redirect to stderr (which is captured by the caller):
    temp = sys.stdout
    try:
        sys.stdout = sys.stderr

        stream = segment.stream(True)
        assert1trace(stream)  # raise and return if stream has more than one trace
        raw_trace = stream[0].copy()
        trace = stream[0]  # work with the (surely) one trace now

        # compute amplitude ratio only once on the raw trace:
        amp_ratio = ampratio(trace)
#         if amp_ratio >= config['amp_ratio_threshold']:
#             saturated = True  # @UnusedVariable

        data = []
        # bandpass the trace, according to the event magnitude.
        # This modifies the segment.stream() permanently:
        trace = _bandpass_remresp(segment, config, trace, segment.inventory())
        data.append(_main(segment, config, raw_trace.copy(), segment.inventory()))
        data[-1]['amplitude_ratio'] = amp_ratio

        # add gain (1). Decide whether to compute gain x2,10,100 or x1/2.1/10,1/100
        # (not both, try to speed up a bit the computations)
        # "randomly" according to the segment id (even or odd)
        gain_factors = config['stage_gain_factors']
        if segment.id % 2 == 0:
            gain_factors = gain_factors[:3]
        else:
            gain_factors = gain_factors[3:]
        for gain_factor in gain_factors:
            newtrace = trace.copy()
            newtrace.data *= float(gain_factor)
            stream[0] = newtrace
            assert segment.stream()[0] is newtrace
            # need to change alkso the raw trace for the noisepsd, otherwise
            # we calculate the same psd as if we did not change the gain:
            raw_trace_ = raw_trace.copy()
            raw_trace_dtype_ = raw_trace_.data.dtype
            raw_trace_.data = raw_trace_.data * float(gain_factor)
            if np.issubdtype(raw_trace_dtype_, np.integer):
                raw_trace_.data = (0.5 + raw_trace_.data).astype(raw_trace_dtype_)
            data.append(_main(segment, config, raw_trace_, segment.inventory()))
            data[-1]['outlier'] = 1
            data[-1]['modified'] = "STAGEGAIN:X%s" % str(gain_factor)
            data[-1]['amplitude_ratio'] = amp_ratio

        # acceleromters/velocimeters:
        if segment.station.id in config['station_ids_both_accel_veloc']:
            # reload inventory (takes more time, but we won't modify cached version):
            inventory = get_inventory(segment.station)
            cha_obj = get_cha_obj(segment, inventory)
            resp_tmp = cha_obj.response
            for other_cha in get_other_chan_objs(segment, inventory):
                cha_obj.response = other_cha.response
                # force reloading the segment stream:
                stream = segment.stream(True)
                # re-apply bandpass with the "wrong" inventory
                # (modifying segment.stream() inplace):
                _test_trace = _bandpass_remresp(segment, config, stream[0], inventory)
                assert _test_trace is segment.stream()[0]
                data.append(_main(segment, config, raw_trace.copy(), inventory))
                data[-1]['outlier'] = 1
                data[-1]['modified'] = "CHARESP:%s" % other_cha.code
                data[-1]['amplitude_ratio'] = amp_ratio
            cha_obj.response = resp_tmp

        if segment.station.id in config['station_ids_with_wrong_local_inventory']:
            channels_ = config['station_ids_with_wrong_local_inventory'][segment.station.id]
            filename = channels_.get(segment.data_seed_id, None)
            if filename is None:
                raise ValueError('%s not found in wrong inventories dict' % segment.data_seed_id)
            if filename is not None:
                inventories_dir = config['inventories_dir']
                wrong_inventory = read_inventory(os.path.join(os.getcwd(), inventories_dir,
                                                              filename))
                # force reloading the segment stream:
                stream = segment.stream(True)
                # re-apply bandpass with the "wrong" inventory
                # (modifying segment.stream() inplace):
                _test_trace = _bandpass_remresp(segment, config, stream[0], wrong_inventory)
                assert _test_trace is segment.stream()[0]
                data.append(_main(segment, config, raw_trace.copy(), wrong_inventory))
                data[-1]['outlier'] = 1
                data[-1]['modified'] = "INVFILE:%s" % filename
                data[-1]['amplitude_ratio'] = amp_ratio

        return pd.DataFrame(data)

    finally:
        sys.stdout = temp
Example #5
0
def main2(segment, config):
    '''calls _main with the normal inventory and all possible
    wrong inventories'''

    # annoying print statementin obspy 1.1.1  when calling the function 'psd'
    # (see below) and when adding a trace shorter than
    # the ppsd_length: workaround? redirect to stderr (which is captured by the caller):
    temp = sys.stdout
    try:
        sys.stdout = sys.stderr

        stream = segment.stream(True)
        assert1trace(
            stream)  # raise and return if stream has more than one trace
        raw_trace = stream[0].copy()

        # store channel's channel via data_seed_id (might be faster):
        # calculate it here so in case of error we avoid unnecessary calculations
        channel_code = segment.data_seed_id.split('.')[3]
        location_code = segment.data_seed_id.split('.')[2]

        # compute amplitude ratio only once on the raw trace:
        amp_ratio = ampratio(raw_trace)
        #         if amp_ratio >= config['amp_ratio_threshold']:
        #             saturated = True  # @UnusedVariable

        # data = []
        # bandpass the trace, according to the event magnitude.
        # This modifies the segment.stream() permanently:
        # data.append(_main(segment, config, raw_trace, segment.inventory()))

        # add gain (1). Decide whether to compute gain x2,10,100 or x1/2.1/10,1/100
        # (not both, try to speed up a bit the computations)
        # "randomly" according to the segment id (even or odd)
        #         gain_factors = config['stage_gain_factors']
        #         if segment.id % 2 == 0:
        #             gain_factors = gain_factors[:3]
        #         else:
        #             gain_factors = gain_factors[3:]
        #         for gain_factor in gain_factors:
        #             # need to change alkso the raw trace for the noisepsd, otherwise
        #             # we calculate the same psd as if we did not change the gain:
        #             raw_trace_ = raw_trace.copy()
        #             raw_trace_dtype_ = raw_trace_.data.dtype
        #             raw_trace_.data = raw_trace_.data * float(gain_factor)
        #             if np.issubdtype(raw_trace_dtype_, np.integer):
        #                 raw_trace_.data = (0.5 + raw_trace_.data).astype(raw_trace_dtype_)
        #             data.append(_main(segment, config, raw_trace_, segment.inventory()))
        #             data[-1]['outlier'] = True
        #             data[-1]['modified'] = "STAGEGAIN:X%s" % str(gain_factor)
        #
        #         # acceleromters/velocimeters:
        #         if segment.station.id in config['station_ids_both_accel_veloc']:
        #             # reload inventory (takes more time, but we won't modify cached version):
        #             inventory = get_inventory(segment.station)
        #             cha_obj = get_cha_obj(segment, inventory)
        #             resp_tmp = cha_obj.response
        #             for other_cha in get_other_chan_objs(segment, inventory):
        #                 cha_obj.response = other_cha.response
        #                 data.append(_main(segment, config, raw_trace, inventory))
        #                 data[-1]['outlier'] = True
        #                 data[-1]['modified'] = "CHARESP:%s" % other_cha.code
        #             cha_obj.response = resp_tmp
        #
        #         if segment.station.id in config['station_ids_with_wrong_local_inventory']:
        #             channels_ = config['station_ids_with_wrong_local_inventory'][segment.station.id]
        #             filename = channels_.get(segment.data_seed_id, None)
        #             if filename is None:
        #                 raise ValueError('%s not found in wrong inventories dict' % segment.data_seed_id)
        #             if filename is not None:
        #                 inventories_dir = config['inventories_dir']
        #                 wrong_inventory = read_inventory(os.path.join(os.getcwd(), inventories_dir,
        #                                                               filename))
        #                 data.append(_main(segment, config, raw_trace, wrong_inventory))
        #                 data[-1]['outlier'] = True
        #                 data[-1]['modified'] = "INVFILE:%s" % filename

        ret = _main(segment, config, raw_trace, segment.inventory())
        # data[-1]['outlier'] = True

        # ret = pd.concat(data, sort=False, ignore_index=True, copy=True, axis=0)
        ret['amplitude_ratio'] = amp_ratio
        ret['event_id'] = segment.event_id
        ret['station_id'] = segment.station.id
        ret['event_time'] = segment.event.time
        ret['channel_code'] = channel_code
        ret['location_code'] = location_code
        ret['magnitude'] = segment.event.magnitude
        ret['distance_km'] = segment.event_distance_km
        return ret

    finally:
        sys.stdout = temp