def test_get_vel():
    data_files, origin = read_data_dir("geonet", "us1000778i", "*.V1A")
    data_files.sort()
    streams = []
    for f in data_files:
        streams += read_data(f)

    sc = StreamCollection(streams)

    config = get_config()
    config["integration"]["frequency"] = True

    final_vel = []
    for st in sc:
        for tr in st:
            tmp_tr = get_vel(tr, config=config)
            final_vel.append(tmp_tr.data[-1])

    target_final_vel = np.array([
        -2.182293e-03,
        -1.417545e-03,
        2.111492e-03,
        -9.395322e-04,
        1.662219e-03,
        -2.690978e-04,
        1.376186e-04,
        -7.358185e-05,
        1.741465e-05,
    ])

    np.testing.assert_allclose(final_vel, target_final_vel, atol=1e-6)
def _get_person_agent(pr, config=None):
    '''Get the seis-prov entity for the user software.

    Args:
        pr (prov.model.ProvDocument):
            Existing ProvDocument.
        config (dict):
            Configuration options.

    Returns:
        prov.model.ProvDocument:
            Provenance document updated with gmprocess software name/version.
    '''
    username = getpass.getuser()
    if config is None:
        config = get_config()
    fullname = ''
    email = ''
    if 'user' in config:
        if 'name' in config['user']:
            fullname = config['user']['name']
        if 'email' in config['user']:
            email = config['user']['email']
    hashstr = '0000001'
    person_id = "seis_prov:sp001_pp_%s" % hashstr
    pr.agent(person_id,
             other_attributes=((("prov:label", username),
                                ("prov:type",
                                 prov.identifier.QualifiedName(
                                     prov.constants.PROV,
                                     "Person")), ("seis_prov:name", fullname),
                                ("seis_prov:email", email))))
    return pr
예제 #3
0
def read_data(filename, config=None, read_format=None, **kwargs):
    """
    Read strong motion data from a file.

    Args:
        filename (str):
            Path to file
        read_format (str):
            Format of file

    Returns:
        list: Sequence of obspy.core.stream.Streams read from file
    """
    _, file_ext = os.path.splitext(filename)
    if file_ext in EXCLUDED_EXTS:
        raise ValueError(f"Excluded extension: {filename}")

    # Check if file exists
    if not os.path.exists(filename):
        raise OSError(f"Not a file {filename!r}")
    # Get and validate format
    if config is None:
        config = get_config()
    if read_format is None:
        read_format = _get_format(filename, config)
    else:
        read_format = _validate_format(filename, config, read_format.lower())
    # Load reader and read file
    reader = "gmprocess.io." + read_format + ".core"
    reader_module = importlib.import_module(reader)
    read_name = "read_" + read_format
    read_method = getattr(reader_module, read_name)
    streams = read_method(filename, config, **kwargs)
    return streams
def test_correct_baseline():

    data_files, origin = read_data_dir("geonet", "us1000778i", "*.V1A")
    data_files.sort()
    streams = []
    for f in data_files:
        streams += read_data(f)

    sc = StreamCollection(streams)
    final_acc = []

    config = get_config()
    config["integration"]["frequency"] = True

    for st in sc:
        for tr in st:
            tmp_tr = correct_baseline(tr, config=config)
            final_acc.append(tmp_tr.data[-1])

    target_final_acc = np.array([
        0.599829,
        0.717284,
        -1.548017,
        0.377616,
        -0.685688,
        0.112147,
        0.024594,
        0.004697,
        -0.013296,
    ])

    np.testing.assert_allclose(final_acc, target_final_acc, atol=1e-6)
예제 #5
0
def test_fit_spectra():
    config = get_config()
    datapath = os.path.join("data", "testdata", "demo", "ci38457511", "raw")
    datadir = pkg_resources.resource_filename("gmprocess", datapath)
    event = get_event_object("ci38457511")
    sc = StreamCollection.from_directory(datadir)
    for st in sc:
        st = signal_split(st, event)
        end_conf = config["windows"]["signal_end"]
        st = signal_end(st,
                        event_time=event.time,
                        event_lon=event.longitude,
                        event_lat=event.latitude,
                        event_mag=event.magnitude,
                        **end_conf)
        st = compute_snr(st, 30)
        st = get_corner_frequencies(st,
                                    event,
                                    method="constant",
                                    constant={
                                        "highpass": 0.08,
                                        "lowpass": 20.0
                                    })

    for st in sc:
        spectrum.fit_spectra(st, event)
예제 #6
0
    def _load_config(self):
        if not os.path.isfile(self.PROJECTS_FILE):
            # If projects.conf file doesn't exist then we need to run the
            # initial setup.
            print('No project config file detected.')
            print('Please select a project setup option:')
            print('(1) Initialize the current directory as a gmrecords')
            print('    project, which will contain data and conf')
            print('    subdirectories.')
            print('(2) Setup a project with data and conf locations that')
            print('    are independent of the current directory.')
            response = int(input('> '))
            if response not in [1, 2]:
                print('Not a valid response. Exiting.')
                sys.exit(0)
            elif response == 1:
                InitModule().main(self)
                sys.exit(0)
            else:
                self._initial_setup()

        self.projects_conf = ConfigObj(self.PROJECTS_FILE, encoding='utf-8')
        self.project = self.projects_conf['project']
        self.current_project = self.projects_conf['projects'][self.project]
        self.conf_path = self.current_project['conf_path']
        self.data_path = self.current_project['data_path']
        self.conf_file = os.path.join(self.conf_path, 'config.yml')
        if not os.path.isfile(self.conf_file):
            print('Config file does not exist: %s' % self.conf_file)
            print('Exiting.')
            sys.exit(1)
        self.conf = get_config(self.conf_file)
def test_fit_spectra():
    config = get_config()
    datapath = os.path.join('data', 'testdata', 'demo', 'ci38457511', 'raw')
    datadir = pkg_resources.resource_filename('gmprocess', datapath)
    event = get_event_object('ci38457511')
    sc = StreamCollection.from_directory(datadir)
    for st in sc:
        st = signal_split(st, event)
        end_conf = config['windows']['signal_end']
        st = signal_end(st,
                        event_time=event.time,
                        event_lon=event.longitude,
                        event_lat=event.latitude,
                        event_mag=event.magnitude,
                        **end_conf)
        st = compute_snr(st, 30)
        st = get_corner_frequencies(st,
                                    method='constant',
                                    constant={
                                        'highpass': 0.08,
                                        'lowpass': 20.0
                                    })

    for st in sc:
        spectrum.fit_spectra(st, event)
예제 #8
0
def test_zero_crossings():
    datapath = os.path.join("data", "testdata", "zero_crossings")
    datadir = pkg_resources.resource_filename("gmprocess", datapath)
    sc = StreamCollection.from_directory(datadir)
    sc.describe()

    conf = get_config()

    update = {
        "processing": [
            {"detrend": {"detrending_method": "demean"}},
            {"check_zero_crossings": {"min_crossings": 1}},
        ]
    }
    update_dict(conf, update)

    edict = {
        "id": "ak20419010",
        "time": UTCDateTime("2018-11-30T17:29:29"),
        "lat": 61.346,
        "lon": -149.955,
        "depth": 46.7,
        "magnitude": 7.1,
    }
    event = get_event_object(edict)
    test = process_streams(sc, event, conf)
    for st in test:
        for tr in st:
            assert tr.hasParameter("ZeroCrossingRate")
    np.testing.assert_allclose(
        test[0][0].getParameter("ZeroCrossingRate")["crossing_rate"],
        0.008888888888888889,
        atol=1e-5,
    )
def test_integrate_taper():
    data_files, origin = read_data_dir("geonet", "us1000778i", "*.V1A")
    data_files.sort()
    streams = []
    for f in data_files:
        streams += read_data(f)

    sc = StreamCollection(streams)

    config = get_config()
    config["integration"]["taper"]["taper"] = True

    final_vel = []
    for st in sc:
        for tr in st:
            tmp_tr = tr.integrate(config=config)
            final_vel.append(tmp_tr.data[-1])

    target_final_vel = np.array([
        3.896186e00,
        -4.901823e00,
        -5.722080e-01,
        1.621672e-01,
        -1.654317e-01,
        -8.242356e-04,
        -1.482590e-02,
        1.504334e-01,
        1.021050e-01,
    ])

    np.testing.assert_allclose(final_vel, target_final_vel, atol=1e-6)
예제 #10
0
def is_obspy(filename, config=None):
    """Check to see if file is a format supported by Obspy (not KNET).

    Note: Currently only SAC and Miniseed are supported.

    Args:
        filename (str):
            Path to possible Obspy format.
        config (dict):
            Dictionary containing configuration.

    Returns:
        bool: True if obspy supported, otherwise False.
    """
    logging.debug("Checking if format is supported by obspy.")
    metadir = config["read"]["metadata_directory"]
    if config is None:
        config = get_config()
    if not os.path.isfile(filename):
        return False
    try:
        stream = read(filename)
        if stream[0].stats._format in IGNORE_FORMATS:
            return False
        if stream[0].stats._format in REQUIRES_XML:
            xmlfile = _get_station_file(filename, stream, metadir)
            if not os.path.isfile(xmlfile):
                return False
            return True
        else:
            return True
    except BaseException:
        return False

    return False
예제 #11
0
def test_all_pickers():
    streams = get_streams()
    picker_config = get_config(section='pickers')
    methods = ['ar', 'baer', 'power', 'kalkan']
    columns = ['Stream', 'Method', 'Pick_Time', 'Mean_SNR']
    df = pd.DataFrame(columns=columns)
    for stream in streams:
        print(stream.get_id())
        for method in methods:
            try:
                if method == 'ar':
                    loc, mean_snr = pick_ar(stream,
                                            picker_config=picker_config)
                elif method == 'baer':
                    loc, mean_snr = pick_baer(stream,
                                              picker_config=picker_config)
                elif method == 'power':
                    loc, mean_snr = pick_power(stream,
                                               picker_config=picker_config)
                elif method == 'kalkan':
                    loc, mean_snr = pick_kalkan(stream,
                                                picker_config=picker_config)
                elif method == 'yeck':
                    loc, mean_snr = pick_yeck(stream)
            except BaseException:
                loc = -1
                mean_snr = np.nan
            row = {
                'Stream': stream.get_id(),
                'Method': method,
                'Pick_Time': loc,
                'Mean_SNR': mean_snr
            }
            df = df.append(row, ignore_index=True)

    stations = df['Stream'].unique()
    cmpdict = {
        'TW.ECU.BN': 'kalkan',
        'TW.ELD.BN': 'power',
        'TW.EGF.BN': 'ar',
        'TW.EAS.BN': 'ar',
        'TW.EDH.BN': 'ar',
        'TK.4304.HN': 'ar',
        'TK.0921.HN': 'ar',
        'TK.5405.HN': 'ar',
        'NZ.HSES.HN': 'baer',
        'NZ.WTMC.HN': 'baer',
        'NZ.THZ.HN': 'power'
    }
    for station in stations:
        station_df = df[df['Stream'] == station]
        max_snr = station_df['Mean_SNR'].max()
        maxrow = station_df[station_df['Mean_SNR'] == max_snr].iloc[0]
        method = maxrow['Method']
        try:
            assert cmpdict[station] == method
        except Exception as e:
            pass
예제 #12
0
def test_all_pickers():
    streams = get_streams()
    picker_config = get_config(section="pickers")
    methods = ["ar", "baer", "power", "kalkan"]
    columns = ["Stream", "Method", "Pick_Time", "Mean_SNR"]
    df = pd.DataFrame(columns=columns)
    for stream in streams:
        print(stream.get_id())
        for method in methods:
            try:
                if method == "ar":
                    loc, mean_snr = pick_ar(stream,
                                            picker_config=picker_config)
                elif method == "baer":
                    loc, mean_snr = pick_baer(stream,
                                              picker_config=picker_config)
                elif method == "power":
                    loc, mean_snr = pick_power(stream,
                                               picker_config=picker_config)
                elif method == "kalkan":
                    loc, mean_snr = pick_kalkan(stream,
                                                picker_config=picker_config)
                elif method == "yeck":
                    loc, mean_snr = pick_yeck(stream)
            except BaseException:
                loc = -1
                mean_snr = np.nan
            row = {
                "Stream": stream.get_id(),
                "Method": method,
                "Pick_Time": loc,
                "Mean_SNR": mean_snr,
            }
            df = df.append(row, ignore_index=True)

    stations = df["Stream"].unique()
    cmpdict = {
        "TW.ECU.BN": "kalkan",
        "TW.ELD.BN": "power",
        "TW.EGF.BN": "ar",
        "TW.EAS.BN": "ar",
        "TW.EDH.BN": "ar",
        "TK.4304.HN": "ar",
        "TK.0921.HN": "ar",
        "TK.5405.HN": "ar",
        "NZ.HSES.HN": "baer",
        "NZ.WTMC.HN": "baer",
        "NZ.THZ.HN": "power",
    }
    for station in stations:
        station_df = df[df["Stream"] == station]
        max_snr = station_df["Mean_SNR"].max()
        maxrow = station_df[station_df["Mean_SNR"] == max_snr].iloc[0]
        method = maxrow["Method"]
        try:
            assert cmpdict[station] == method
        except Exception as e:
            pass
예제 #13
0
def pick_ar(stream, picker_config=None, config=None):
    """Wrapper around the AR P-phase picker.

    Args:
        stream (StationStream):
            Stream containing waveforms that need to be picked.
        picker_config (dict):
            Dictionary with parameters for AR P-phase picker. See picker.yml.
        config (dict):
            Configuration dictionary. Key value here is:
                windows:
                    window_checks:
                        min_noise_duration
    Returns:
        tuple:
            - Best estimate for p-wave arrival time (s since start of trace).
            - Mean signal to noise ratio based on the pick.
    """
    if picker_config is None:
        picker_config = get_config(section='pickers')
    if config is None:
        config = get_config()
    min_noise_dur = config['windows']['window_checks']['min_noise_duration']
    params = picker_config['ar']
    # Get the east, north, and vertical components from the stream
    st_e = stream.select(channel='??[E1]')
    st_n = stream.select(channel='??[N2]')
    st_z = stream.select(channel='??[Z3]')

    # Check if we found one of each component
    # If not, use the next picker in the order of preference
    if len(st_e) != 1 or len(st_n) != 1 or len(st_z) != 1:
        raise BaseException('Unable to perform AR picker.')

    minloc = ar_pick(st_z[0].data, st_n[0].data, st_e[0].data,
                     st_z[0].stats.sampling_rate,
                     **params)[0]
    if minloc < min_noise_dur:
        fmt = 'Noise window (%.1f s) less than minimum (%.1f)'
        tpl = (minloc, min_noise_dur)
        raise ValueError(fmt % tpl)
    mean_snr = calc_snr(stream, minloc)

    return (minloc, mean_snr)
예제 #14
0
def test_get_disp():

    data_files, origin = read_data_dir("geonet", "us1000778i", "*.V1A")
    data_files.sort()
    streams = []
    for f in data_files:
        streams += read_data(f)

    sc = StreamCollection(streams)

    config = get_config()
    config["integration"]["frequency"] = True

    final_disp = []
    for st in sc:
        for tr in st:
            tmp_tr = get_disp(tr, config=config)
            final_disp.append(tmp_tr.data[-1])

    target_final_disp = np.array([
        -0.07689,
        0.082552,
        -0.024509,
        -0.00047,
        -0.000257,
        -0.000152,
        -0.003425,
        0.000671,
        0.000178,
    ])

    np.testing.assert_allclose(final_disp, target_final_disp, atol=1e-6)

    config["integration"]["frequency"] = False
    config["integration"]["initial"] = 0.0
    config["integration"]["demean"] = True

    final_disp = []
    for st in sc:
        for tr in st:
            tmp_tr = get_disp(tr, config=config)
            final_disp.append(tmp_tr.data[-1])

    target_final_disp = np.array([
        -0.076882,
        0.082549,
        -0.024512,
        -0.000469,
        -0.000259,
        -0.000152,
        -0.003425,
        0.000672,
        0.000178,
    ])

    np.testing.assert_allclose(final_disp, target_final_disp, atol=1e-6)
예제 #15
0
def pick_baer(stream, picker_config=None, config=None):
    """Wrapper around the Baer P-phase picker.

    Args:
        stream (StationStream):
            Stream containing waveforms that need to be picked.
        picker_config (dict):
            Dictionary with parameters for Baer P-phase picker. See picker.yml.
        config (dict):
            Configuration dictionary. Key value here is:
                windows:
                    window_checks:
                        min_noise_duration
    Returns:
        tuple:
            - Best estimate for p-wave arrival time (s since start of trace).
            - Mean signal to noise ratio based on the pick.
    """
    if picker_config is None:
        picker_config = get_config(section='pickers')
    if config is None:
        config = get_config()
    min_noise_dur = config['windows']['window_checks']['min_noise_duration']
    params = picker_config['baer']
    locs = []
    for trace in stream:
        pick_sample = pk_baer(trace.data, trace.stats.sampling_rate,
                              **params)[0]
        loc = pick_sample * trace.stats.delta
        locs.append(loc)

    locs = np.array(locs)
    if np.any(locs >= 0):
        minloc = np.min(locs[locs >= 0])
    else:
        minloc = -1
    if minloc < min_noise_dur:
        fmt = 'Noise window (%.1f s) less than minimum (%.1f)'
        tpl = (minloc, min_noise_dur)
        raise ValueError(fmt % tpl)
    mean_snr = calc_snr(stream, minloc)

    return (minloc, mean_snr)
예제 #16
0
def check_instrument(st,
                     n_max=3,
                     n_min=1,
                     require_two_horiz=False,
                     config=None):
    """
    Test the channels of the station.

    The purpose of the maximum limit is to skip over stations with muliple
    strong motion instruments, which can occur with downhole or structural
    arrays since our code currently is not able to reliably group by location
    within an array.

    The purpose of the minimum and require_two_horiz checks are to ensure the
    channels are required for subsequent intensity measures such as ROTD.

    Args:
        st (StationStream):
            Stream of data.
        n_max (int):
            Maximum allowed number of streams; default to 3.
        n_min (int):
            Minimum allowed number of streams; default to 1.
        require_two_horiz (bool):
            Require two horizontal components; default to `False`.
        config (dict):
            Configuration dictionary (or None). See get_config().

    Returns:
        Stream with adjusted failed fields.
    """
    if not st.passed:
        return st

    if config is None:
        config = get_config()

    logging.debug("Starting check_instrument")
    logging.debug(f"len(st) = {len(st)}")

    for failed_test, message in [
        (len(st) > n_max, f"More than {n_max} traces in stream."),
        (len(st) < n_min, f"Less than {n_min} traces in stream."),
        (
            require_two_horiz and (st.num_horizontal != 2),
            "Not two horizontal components",
        ),
    ]:
        if failed_test:
            for tr in st:
                tr.fail(message)
            # Stop at first failed test
            break

    return st
예제 #17
0
    def __init__(
        self,
        time,
        lat,
        lon,
        depth,
        magnitude,
        config=None,
        rawdir=None,
        drop_non_free=True,
        stream_collection=True,
    ):
        """Create an FDSNFetcher instance.

        Download waveform data from the all available FDSN sites
        using the Obspy mass downloader functionality.

        Args:
            time (datetime):
                Origin time.
            lat (float):
                Origin latitude.
            lon (float):
                Origin longitude.
            depth (float):
                Origin depth.
            magnitude (float):
                Origin magnitude.
            config (dict):
                Dictionary containing configuration.
                If None, retrieve global config.
            rawdir (str):
                Path to location where raw data will be stored.
                If not specified, raw data will be deleted.
            drop_non_free (bool):
                Option to ignore non-free-field (borehole, sensors on
                structures, etc.)
            stream_collection (bool):
                Construct and return a StreamCollection instance?
        """
        if config is None:
            config = get_config()

        tz = pytz.UTC
        if isinstance(time, UTCDateTime):
            time = time.datetime
        self.time = tz.localize(time)
        self.lat = lat
        self.lon = lon
        self.depth = depth
        self.magnitude = magnitude
        self.config = config
        self.rawdir = rawdir
        self.drop_non_free = drop_non_free
        self.stream_collection = stream_collection
예제 #18
0
def pick_kalkan(stream, picker_config=None, config=None):
    """Wrapper around the Kalkan P-phase picker.

    Args:
        stream (StationStream):
            Stream containing waveforms that need to be picked.
        picker_config (dict):
            Dictionary with parameters for Kalkan P-phase picker.
            See picker.yml.
        config (dict):
            Configuration dictionary. Key value here is:
                windows:
                    window_checks:
                        min_noise_duration
    Returns:
        tuple:
            - Best estimate for p-wave arrival time (s since start of trace).
            - Mean signal to noise ratio based on the pick.
    """
    if picker_config is None:
        picker_config = get_config(section="pickers")
    if config is None:
        config = get_config()
    min_noise_dur = config["windows"]["window_checks"]["min_noise_duration"]
    params = picker_config["kalkan"]
    locs = []
    for trace in stream:
        loc = pphase_pick(trace, **params)
        if loc >= 0:
            locs.append(loc)
    locs = np.array(locs)
    if np.any(locs >= 0):
        minloc = np.min(locs[locs >= 0])
    else:
        minloc = -1
    if minloc < min_noise_dur:
        fmt = "Noise window (%.1f s) less than minimum (%.1f)"
        tpl = (minloc, min_noise_dur)
        raise ValueError(fmt % tpl)
    mean_snr = calc_snr(stream, minloc)

    return (minloc, mean_snr)
예제 #19
0
def pick_travel(stream, origin, model=None, picker_config=None):
    '''Use TauP travel time model to find P-Phase arrival time.

    Args:
        stream (StationStream):
            StationStream containing 1 or more channels of waveforms.
        origin (ScalarEvent):
            Event origin/magnitude information.
        model (TauPyModel):
            TauPyModel object for computing travel times.
    Returns:
        tuple:
            - Best estimate for p-wave arrival time (s since start of trace).
            - Mean signal to noise ratio based on the pick.
    '''
    if model is None:
        if picker_config is None:
            picker_config = get_config(section='pickers')
        model = TauPyModel(picker_config['travel_time']['model'])
    if stream[0].stats.starttime == NAN_TIME:
        return (-1, 0)
    lat = origin.latitude
    lon = origin.longitude
    depth = origin.depth_km
    if depth < 0:
        depth = 0
    etime = origin.time
    slat = stream[0].stats.coordinates.latitude
    slon = stream[0].stats.coordinates.longitude

    dist_deg = locations2degrees(lat, lon, slat, slon)
    try:
        arrivals = model.get_travel_times(
            source_depth_in_km=depth,
            distance_in_degree=dist_deg,
            phase_list=['P', 'p', 'Pn'])
    except BaseException as e:
        fmt = ('Exception "%s" generated by get_travel_times() '
               'dist=%.3f depth=%.1f')
        logging.warning(fmt % (str(e), dist_deg, depth))
        arrivals = []
    if not len(arrivals):
        return (-1, 0)

    # arrival time is time since origin
    arrival = arrivals[0]
    # we need time since start of the record
    minloc = arrival.time + (etime - stream[0].stats.starttime)
    mean_snr = calc_snr(stream, minloc)
    return (minloc, mean_snr)
예제 #20
0
def test_nnet():

    conf = get_config()

    update = {
        "processing": [
            {
                "detrend": {
                    "detrending_method": "demean"
                }
            },
            {
                "detrend": {
                    "detrending_method": "linear"
                }
            },
            {
                "compute_snr": {
                    "bandwidth": 20.0,
                    "check": {
                        "max_freq": 5.0,
                        "min_freq": 0.2,
                        "threshold": 3.0
                    },
                }
            },
            {
                "NNet_QA": {
                    "acceptance_threshold": 0.5,
                    "model_name": "CantWell"
                }
            },
        ]
    }
    update_dict(conf, update)

    data_files, origin = read_data_dir("geonet", "us1000778i", "*.V1A")
    streams = []
    for f in data_files:
        streams += read_data(f)

    sc = StreamCollection(streams)
    test = process_streams(sc, origin, conf)
    tstream = test.select(station="HSES")[0]
    nnet_dict = tstream.getStreamParam("nnet_qa")
    np.testing.assert_allclose(nnet_dict["score_HQ"],
                               0.99321798811740059,
                               rtol=1e-3)
예제 #21
0
def test_read():
    config = get_config()
    cosmos_files, _ = read_data_dir("cosmos", "ci14155260", "Cosmos12TimeSeriesTest.v1")
    cwb_files, _ = read_data_dir("cwb", "us1000chhc", "1-EAS.dat")
    dmg_files, _ = read_data_dir("dmg", "nc71734741", "CE89146.V2")
    geonet_files, _ = read_data_dir(
        "geonet", "us1000778i", "20161113_110259_WTMC_20.V1A"
    )
    knet_files, _ = read_data_dir("knet", "us2000cnnl", "AOM0011801241951.EW")
    smc_files, _ = read_data_dir("smc", "nc216859", "0111a.smc")

    file_dict = {}
    file_dict["cosmos"] = cosmos_files[0]
    file_dict["cwb"] = cwb_files[0]
    file_dict["dmg"] = dmg_files[0]
    file_dict["geonet"] = geonet_files[0]
    file_dict["knet"] = knet_files[0]
    file_dict["smc"] = smc_files[0]

    for file_format in file_dict:
        file_path = file_dict[file_format]
        assert _get_format(file_path, config) == file_format
        assert _validate_format(file_path, config, file_format) == file_format

    assert _validate_format(file_dict["knet"], config, "smc") == "knet"
    assert _validate_format(file_dict["dmg"], config, "cosmos") == "dmg"
    assert _validate_format(file_dict["cosmos"], config, "invalid") == "cosmos"

    for file_format in file_dict:
        try:
            stream = read_data(file_dict[file_format], config, file_format)[0]
        except Exception as e:
            pass
        assert stream[0].stats.standard["source_format"] == file_format
        stream = read_data(file_dict[file_format])[0]
        assert stream[0].stats.standard["source_format"] == file_format
    # test exception
    try:
        file_path = smc_files[0].replace("0111a.smc", "not_a_file.smc")
        read_data(file_path)[0]
        success = True
    except BaseException:
        success = False
    assert success == False
예제 #22
0
def test_nnet():

    conf = get_config()

    update = {
        'processing': [{
            'detrend': {
                'detrending_method': 'demean'
            }
        }, {
            'detrend': {
                'detrending_method': 'linear'
            }
        }, {
            'compute_snr': {
                'bandwidth': 20.0,
                'check': {
                    'max_freq': 5.0,
                    'min_freq': 0.2,
                    'threshold': 3.0
                }
            }
        }, {
            'NNet_QA': {
                'acceptance_threshold': 0.5,
                'model_name': 'CantWell'
            }
        }]
    }
    update_dict(conf, update)

    data_files, origin = read_data_dir('geonet', 'us1000778i', '*.V1A')
    streams = []
    for f in data_files:
        streams += read_data(f)

    sc = StreamCollection(streams)
    test = process_streams(sc, origin, conf)
    tstream = test.select(station='HSES')[0]
    nnet_dict = tstream.getStreamParam('nnet_qa')
    np.testing.assert_allclose(nnet_dict['score_HQ'],
                               0.99321798811740059,
                               rtol=1e-3)
예제 #23
0
def test_auto_fchp():

    data_files, origin = read_data_dir("geonet", "us1000778i", "*.V1A")
    data_files.sort()
    streams = []
    for f in data_files:
        streams += read_data(f)

    sc = StreamCollection(streams)
    output_fchp = []

    config = get_config()
    config["integration"]["frequency"] = True

    for st in sc:
        for tr in st:
            tr.setParameter(
                "corner_frequencies",
                {
                    "type": "constant",
                    "highpass": 0.001,
                    "lowpass": 20
                },
            )

        tmp_st = ridder_fchp(st, config=config)
        for tr in tmp_st:
            initial_corners = tr.getParameter("corner_frequencies")
            output_fchp.append(initial_corners["highpass"])

    target_fchp = np.array([
        0.021345158261480087,
        0.022839239726168643,
        0.02482398434993213,
        0.01399481102242619,
        0.026850167635921275,
        0.004817661513765862,
        0.008204101694236587,
        0.006429246474225982,
        0.004237087327289796,
    ])

    np.testing.assert_allclose(output_fchp, target_fchp, atol=1e-7)
예제 #24
0
def __disp_checks(
    tr, max_final_displacement=0.025, max_displacment_ratio=0.2, config=None
):
    # Need to find the high/low pass filtering steps in the config
    # to ensure that filtering here is done with the same options
    if config is None:
        config = get_config()
    processing_steps = config["processing"]
    ps_names = [list(ps.keys())[0] for ps in processing_steps]
    ind = int(np.where(np.array(ps_names) == "highpass_filter")[0][0])
    hp_args = processing_steps[ind]["highpass_filter"]
    ind = int(np.where(np.array(ps_names) == "lowpass_filter")[0][0])
    lp_args = processing_steps[ind]["lowpass_filter"]

    # Make a copy of the trace so we don't modify it in place with
    # filtering or integration
    trdis = tr.copy()

    # Filter
    trdis = lowpass_filter_trace(trdis, **lp_args)
    trdis = highpass_filter_trace(trdis, **hp_args)

    # Apply baseline correction
    trdis = correct_baseline(trdis, config)

    # Integrate to displacment
    trdis = get_disp(trdis, config=config)

    # Checks
    ok = True
    max_displacment = np.max(np.abs(trdis.data))
    final_displacement = np.abs(trdis.data[-1])
    disp_ratio = final_displacement / max_displacment

    if final_displacement > max_final_displacement:
        ok = False

    if disp_ratio > max_displacment_ratio:
        ok = False

    return ok
예제 #25
0
def pick_yeck(stream):
    """IN DEVELOPMENT! SNR based P-phase picker.

    Args:
        stream (StationStream):
            Stream containing waveforms that need to be picked.
    Returns:
        tuple:
            - Best estimate for p-wave arrival time (s since start of trace).
            - Mean signal to noise ratio based on the pick.
    """
    min_window = 5.0  # put into config
    config = get_config()
    min_noise_dur = config['windows']['window_checks']['min_noise_duration']
    locs = []
    for trace in stream:
        data = trace.data
        sr = trace.stats.sampling_rate
        pidx_start = int(min_window * sr)
        snr = np.zeros(len(data))
        for pidx in range(pidx_start, len(data) - pidx_start):
            snr_i = sub_calc_snr(data, pidx)
            snr[pidx] = snr_i
        snr = np.array(snr)
        pidx = snr.argmax()
        loc = pidx / sr
        locs.append(loc)

    locs = np.array(locs)
    if np.any(locs >= 0):
        minloc = np.min(locs[locs >= 0])
    else:
        minloc = -1
    if minloc < min_noise_dur:
        fmt = 'Noise window (%.1f s) less than minimum (%.1f)'
        tpl = (minloc, min_noise_dur)
        raise ValueError(fmt % tpl)
    mean_snr = calc_snr(stream, minloc)

    return (minloc, mean_snr)
예제 #26
0
def correct_baseline(trace, config=None):
    """
    Performs a baseline correction following the method of Ancheta
    et al. (2013). This removes low-frequency, non-physical trends
    that remain in the time series following filtering.

    Args:
        trace (obspy.core.trace.Trace):
            Trace of strong motion data.
        config (dict):
            Configuration dictionary (or None). See get_config().

    Returns:
        trace: Baseline-corrected trace.
    """
    if config is None:
        config = get_config()

    # Integrate twice to get the displacement time series
    disp = get_disp(trace, config=config)

    # Fit a sixth order polynomial to displacement time series, requiring
    # that the 1st and 0th order coefficients are zero
    time_values = (
        np.linspace(0, trace.stats.npts - 1, trace.stats.npts) * trace.stats.delta
    )
    poly_cofs = list(curve_fit(_poly_func, time_values, disp.data)[0])
    poly_cofs += [0, 0]

    # Construct a polynomial from the coefficients and compute
    # the second derivative
    polynomial = np.poly1d(poly_cofs)
    polynomial_second_derivative = np.polyder(polynomial, 2)

    # Subtract the second derivative of the polynomial from the
    # acceleration trace
    trace.data -= polynomial_second_derivative(time_values)
    trace.setParameter("baseline", {"polynomial_coefs": poly_cofs})

    return trace
    def from_directory(cls, directory, use_default_config=False):
        """Create a StreamCollection instance from a directory of data.

        Args:
            directory (str):
                Directory of ground motion files (streams) to be read.
            use_default_config (bool):
                Use default ("production") config.

        Returns:
            StreamCollection instance.
        """
        if use_default_config:
            config = get_config(use_default=True)
        else:
            config = None
        streams, missed_files, errors = directory_to_streams(directory,
                                                             config=config)

        # Might eventually want to include some of the missed files and
        # error info but don't have a sensible place to put it currently.
        return cls(streams, config=config)
def test_zero_crossings():
    datapath = os.path.join('data', 'testdata', 'zero_crossings')
    datadir = pkg_resources.resource_filename('gmprocess', datapath)
    sc = StreamCollection.from_directory(datadir)
    sc.describe()

    conf = get_config()

    update = {
        'processing': [{
            'detrend': {
                'detrending_method': 'demean'
            }
        }, {
            'check_zero_crossings': {
                'min_crossings': 1
            }
        }]
    }
    update_dict(conf, update)

    edict = {
        'id': 'ak20419010',
        'time': UTCDateTime('2018-11-30T17:29:29'),
        'lat': 61.346,
        'lon': -149.955,
        'depth': 46.7,
        'magnitude': 7.1
    }
    event = get_event_object(edict)
    test = process_streams(sc, event, conf)
    for st in test:
        for tr in st:
            assert tr.hasParameter('ZeroCrossingRate')
    np.testing.assert_allclose(
        test[0][0].getParameter('ZeroCrossingRate')['crossing_rate'],
        0.008888888888888889,
        atol=1e-5)
def _get_person_agent(pr, config=None):
    """Get the seis-prov entity for the user software.

    Args:
        pr (prov.model.ProvDocument):
            Existing ProvDocument.
        config (dict):
            Configuration options.

    Returns:
        prov.model.ProvDocument:
            Provenance document updated with gmprocess software name/version.
    """
    username = getpass.getuser()
    if config is None:
        config = get_config()
    fullname = ""
    email = ""
    if "user" in config:
        if "name" in config["user"]:
            fullname = config["user"]["name"]
        if "email" in config["user"]:
            email = config["user"]["email"]
    hashstr = "0000001"
    person_id = f"seis_prov:sp001_pp_{hashstr}"
    pr.agent(
        person_id,
        other_attributes=((
            ("prov:label", username),
            (
                "prov:type",
                prov.identifier.QualifiedName(prov.constants.PROV, "Person"),
            ),
            ("seis_prov:name", fullname),
            ("seis_prov:email", email),
        )),
    )
    return pr
def update_config(custom_cfg_file):
    """Merge custom config with default.

    Args:
        custom_cfg_file (str):
            Path to custom config.

    Returns:
        dict: Merged config dictionary.

    """
    config = get_config()

    if not os.path.isfile(custom_cfg_file):
        return config
    try:
        with open(custom_cfg_file, 'rt', encoding='utf-8') as f:
            custom_cfg = yaml.load(f, Loader=yaml.FullLoader)
            update_dict(config, custom_cfg)
    except yaml.parser.ParserError:
        return None

    return config