Exemplo n.º 1
0
Arquivo: pgapgv.py Projeto: rizac/sod
def _sn_spectra(segment, config):
    """
    Computes the signal and noise spectra, as dict of strings mapped to tuples (x0, dx, y).
    Does not modify the segment's stream or traces in-place

    -Being decorated with '@gui.sideplot' or '@gui.customplot', this function must return
     a numeric sequence y taken at successive equally spaced points in any of these forms:
        - a Trace object
        - a Stream object
        - the tuple (x0, dx, y) or (x0, dx, y, label), where
            - x0 (numeric, `datetime` or `UTCDateTime`) is the abscissa of the first point
            - dx (numeric or `timedelta`) is the sampling period
            - y (numpy array or numeric list) are the sequence values
            - label (string, optional) is the sequence name to be displayed on the plot legend.
              (if x0 is numeric and `dx` is a `timedelta` object, then x0 will be converted
              to `UTCDateTime(x0)`; if x0 is a `datetime` or `UTCDateTime` object and `dx` is
              numeric, then `dx` will be converted to `timedelta(seconds=dx)`)
        - a dict of any of the above types, where the keys (string) will denote each sequence
          name to be displayed on the plot legend.

    :return: a dict with two keys, 'Signal' and 'Noise', mapped respectively to the tuples
    (f0, df, frequencies)

    :raise: an Exception if `segment.stream()` is empty or has more than one trace (possible
    gaps/overlaps)
    """
    arrival_time = UTCDateTime(segment.arrival_time) + config['sn_windows']['arrival_time_shift']
    strace, ntrace = sn_split(segment.stream()[0],  # assumes stream has only one trace
                              arrival_time, config['sn_windows']['signal_window'])
    x0_sig, df_sig, sig = _spectrum(strace, config)
    x0_noi, df_noi, noi = _spectrum(ntrace, config)
    return {'Signal': (x0_sig, df_sig, sig), 'Noise': (x0_noi, df_noi, noi)}
Exemplo n.º 2
0
def signal_noise_spectra(segment, config):
    """
    Computes the signal and noise spectra, as dict of strings mapped to tuples (x0, dx, y).
    Does not modify the segment's stream or traces in-place

    :return: a dict with two keys, 'Signal' and 'Noise', mapped respectively to the tuples
    (f0, df, frequencies)

    :raise: an Exception if `segment.stream()` is empty or has more than one trace (possible
    gaps/overlaps)
    """
    o_trace = segment.stream()[0]
    trace = o_trace  # divide_sensitivity(o_trace, segment.inventory())
    # get sn windows: PLEASE NOTE!! sn_windows might calculate the cumulative of segment.stream(),
    # thus the latter should have been preprocessed (e.g. remove response, bandpass):
    arrival_time = UTCDateTime(
        segment.arrival_time) + config['sn_windows']['arrival_time_shift']
    signal_trace, noise_trace = sn_split(
        trace,  # assumes stream has only one trace
        arrival_time,
        config['sn_windows']['signal_window'])

    # compute psd values for both noise and signal:
    psd_n_x, psd_n_y = psd(noise_trace, segment.inventory())
    psd_s_x, psd_s_y = psd(signal_trace, segment.inventory())
    nlnm_x, nlnm_y = get_nlnm()
    nlnm_x, nlnm_y = nlnm_x[::-1], nlnm_y[::-1]
    nhnm_x, nhnm_y = get_nhnm()
    nhnm_x, nhnm_y = nhnm_x[::-1], nhnm_y[::-1]

    # sample at equally spaced periods. First get bounds:
    period_min = 2.0 / trace.stats.sampling_rate
    period_max = min(psd_n_x[-1] - psd_n_x[0], psd_s_x[-1] - psd_s_x[0])

    n_pts = config['num_psd_periods']  # 1024
    periods = np.linspace(period_min, period_max, n_pts, endpoint=True)
    psd_n_y = np.interp(np.log10(periods), np.log10(psd_n_x), psd_n_y)
    psd_s_y = np.interp(np.log10(periods), np.log10(psd_s_x), psd_s_y)
    nlnm_y = np.interp(np.log10(periods), np.log10(nlnm_x), nlnm_y)
    nhnm_y = np.interp(np.log10(periods), np.log10(nhnm_x), nhnm_y)

    x0, dx = periods[0], periods[1] - periods[0]

    return {
        'Signal': (x0, dx, psd_s_y),
        'Noise': (x0, dx, psd_n_y),
        'nlnm': (x0, dx, nlnm_y),
        'nhnm': (x0, dx, nhnm_y)
    }
Exemplo n.º 3
0
def signal_noise_spectra(segment, config):
    """
    Computes the signal and noise spectra, as dict of strings mapped to tuples (x0, dx, y).
    Does not modify the segment's stream or traces in-place

    :return: a dict with two keys, 'Signal' and 'Noise', mapped respectively to the tuples
    (f0, df, frequencies)

    :raise: an Exception if `segment.stream()` is empty or has more than one trace (possible
    gaps/overlaps)
    """
    # get sn windows: PLEASE NOTE!! sn_windows might calculate the cumulative of segment.stream(),
    # thus the latter should have been preprocessed (e.g. remove response, bandpass):
    arrival_time = UTCDateTime(
        segment.arrival_time) + config['sn_windows']['arrival_time_shift']
    signal_trace, noise_trace = sn_split(
        segment.stream()[0],  # assumes stream has only one trace
        arrival_time,
        config['sn_windows']['signal_window'])
    x0_sig, df_sig, sig = _spectrum(signal_trace, config)
    x0_noi, df_noi, noi = _spectrum(noise_trace, config)
    return {'Signal': (x0_sig, df_sig, sig), 'Noise': (x0_noi, df_noi, noi)}
Exemplo n.º 4
0
    def exec_func(self, func, session, invcache, config):
        '''Executes the given function on the given segment identified by seg_id
           Returns the function result (or exception) after updating self, if needed.
           Raises if func raises
        '''
        seg_id = self.segment_id
        segment = getseg(session, seg_id)
        # if stream has not been loaded, do it now in order to pass a copy of it to
        # `func`: this prevents in-place modifications:
        stream = self.data.get('stream', None)
        if stream is None:
            try:
                stream = segment.stream()
            except Exception as exc:
                stream = exc
            self.data['stream'] = stream
        segment._stream = stream.copy() if isinstance(stream, Stream) else stream
        inventory = invcache.get(seg_id, None)
        segment.station._inventory = inventory

        try:
            return func(segment, config)
        finally:
            # set back values if needed, even if we had exceptions.
            # Any of these values might be also an exception. Call the
            # 'private' attribute cause the relative method, if exists, most likely raises
            # the exception, it does not return it
            sn_windows = self.data.get('sn_windows', None)
            if sn_windows is None:
                try:
                    if len(segment.stream()) != 1:
                        raise ValueError(("Unable to get sn-windows: %d traces in stream "
                                          "(possible gaps/overlaps)") % len(segment.stream()))
                    wndw = config['sn_windows']
                    arrival_time = \
                        UTCDateTime(segment.arrival_time) + wndw['arrival_time_shift']
                    self.data['sn_windows'] = sn_split(segment.stream()[0],
                                                       arrival_time,
                                                       wndw['signal_window'],
                                                       return_windows=True)
#                     self.data['sn_windows'] = segment.sn_windows(wndw['signal_window'],
#                                                                  wndw['arrival_time_shift'])
                except Exception as exc:
                    self.data['sn_windows'] = exc

            if inventory is None:
                invcache[segment] = segment.station._inventory  # might be exc, or None
            # reset segment stream to None, for safety: we do not know if it refers
            # to a pre-processed stream or not, and thus segment._stream needs to be set from
            # self.data each time we are here. Note that this should not be a problem as
            # the web app re-initializes the session each time (thus each segment SHOULD have
            # no _stream attribute), but for safety we remove it:
            segment._stream = None
            if not self.data.get('plot_title_prefix', None):
                title = None
                if isinstance(segment._stream, Stream):
                    title = segment._stream[0].get_id()
                    for trace in segment._stream:
                        if trace.get_id() != title:
                            title = None
                            break
                if title is None:
                    title = segment.seed_id
                if title is not None:
                    # try to get it from the stream. Otherwise, get it from the segment
                    self.data['plot_title_prefix'] = title