Пример #1
0
    def test_warning_when_blockette_54_is_not_followed_by_57(self):
        filename = os.path.join(self.data_path, "RESP.SG.ST..LDO")
        # Fail if responses are explicitly not skipped.
        with CatchAndAssertWarnings():
            with self.assertRaises(InvalidResponseError) as e:
                obspy.read_inventory(filename, skip_invalid_responses=False)
        self.assertEqual(
            e.exception.args[0],
            "Stage 2: Invalid response specification. A blockette 54 "
            "must always be followed by a blockette 57 which is missing.")

        # Delete warning registry to reliably trigger the warning.
        if hasattr(obspy.io.xseed.parser, "__warningregistry__"):
            obspy.io.xseed.parser.__warningregistry__.clear()

        # Otherwise continue, but raise a warning.
        msg1 = (
            r"Epoch SG.ST..LDO "
            r"\[1997-02-01T00:00:00.000000Z - 2599-12-31T23:59:59.000000Z\]: "
            r"Response stage 2 does not end with blockette 58. Proceed at "
            r"your own risk.")
        msg2 = (
            r"Failed to calculate response for SG.ST..LDO with epoch "
            r"1997-02-01T00:00:00.000000Z - 2599-12-31T23:59:59.000000Z "
            r"because: Stage 2: Invalid response specification. A blockette "
            r"54 must always be followed by a blockette 57 which is missing.")
        # This actually raises two warnings - one that blockette 58 is
        # missing on stage 2 - this is a generic error that can be
        # potentially recovered from - then a second one that it actually
        # cannot recover.
        with CatchAndAssertWarnings(
                expected=[(Warning, msg1), (Warning, msg2)]):
            obspy.read_inventory(filename)
Пример #2
0
 def test_warning_with_no_blockettes_58(self):
     filename = os.path.join(self.data_path, "RESP.repeated_stage_0")
     msg = (r"Epoch BN.WR0..SHZ "
            r"\[1996-03-01T00:00:00.000000Z - "
            r"1999-01-03T00:00:00.000000Z\]: "
            r"Channel has multiple \(but identical\) blockettes 58 for "
            r"stage 0. Only one will be used.")
     with CatchAndAssertWarnings(expected=[(Warning, msg)]):
         obspy.read_inventory(filename)
Пример #3
0
 def test_warning_when_blockette_57_is_not_followed_by_58(self):
     filename = os.path.join(self.data_path, "RESP.decimation_without_gain")
     # Fail if responses are explicitly not skipped.
     with CatchAndAssertWarnings():
         with self.assertRaises(InvalidResponseError) as e:
             obspy.read_inventory(filename, skip_invalid_responses=False)
     self.assertEqual(
         e.exception.args[0],
         "Stage 1: A decimation stage with blockette 57 must be followed "
         "by a blockette 58 which is missing here.")
     # Otherwise continue, but raise a warning.
     msg = ("Failed to calculate response for XX.ABC..BHX with epoch "
            "1999-12-16T02:14:00.000000Z - 1999-12-21T19:10:59.000000Z "
            "because: Stage 1: A decimation stage with blockette 57 must "
            "be followed by a blockette 58 which is missing here.")
     # This triggers a number of warnings as the file is constructed and
     # misses all kinds of information.
     with CatchAndAssertWarnings(expected=[(Warning, msg)]):
         obspy.read_inventory(filename)
Пример #4
0
 def test_simple_read_seed(self):
     """
     Currently just tests that all test SEED files can be read without an
     error.
     """
     # One seed file is a bit faulty and thus raises a warning when read
     # - catch it.
     with CatchAndAssertWarnings():
         for f in self.seed_files:
             _read_seed(f)
Пример #5
0
 def test_warning_with_multiple_differing_blockettes_58_in_stage_0(self):
     filename = os.path.join(self.data_path,
                             "RESP.repeated_differing_stage_0")
     msg = (r"Epoch BN.WR0..SHZ "
            r"\[1996-03-01T00:00:00.000000Z - "
            r"1999-01-03T00:00:00.000000Z\]: "
            r"Channel has multiple different blockettes 58 for stage 0. "
            r"The last one will be chosen - this is a faulty file - try to "
            r"fix it!")
     with CatchAndAssertWarnings(expected=[(Warning, msg)]):
         obspy.read_inventory(filename)
Пример #6
0
 def test_blkts_53_and_54_in_one_stage(self):
     """
     This should naturally raise.
     """
     filename = os.path.join(self.data_path,
                             "RESP.blkt53_and_54_in_one_stage")
     with self.assertRaises(InvalidResponseError) as e:
         obspy.read_inventory(filename, skip_invalid_responses=False)
     self.assertEqual(
         e.exception.args[0],
         "Stage 1 has both, blockette 53 and 54. This is not valid.")
     # If invalid responses are skipped, check the warning.
     msg = (r"Failed to calculate response for BN.WR0..SHZ with epoch "
            r"1996-03-01T00:00:00.000000Z - 1999-01-03T00:00:00.000000Z "
            r"because: Stage 1 has both, blockette 53 and 54. "
            r"This is not valid.")
     with CatchAndAssertWarnings(expected=[(Warning, msg)]):
         inv = obspy.read_inventory(filename)
     self.assertIsNone(inv[0][0][0].response)
Пример #7
0
    def test_response_regression_segfault(self):
        """
        Another regression test.
        """
        filename = os.path.join(self.data_path, "RESP.regression_segfault")
        frequencies = np.logspace(-3, 3, 20)

        # Set the times for the response.
        # t = obspy.UTCDateTime(2009, 1, 23)

        for unit in ("DISP", "VEL", "ACC"):
            # This still sometimes triggers a segfault - but not if called
            # via our internal evalresp mapping via obspy.core.inventory.
            # e_r = evalresp_for_frequencies(
            #     t_samp=None, frequencies=frequencies, filename=filename,
            #     date=t, units=unit)

            with CatchAndAssertWarnings():
                r = obspy.read_inventory(filename)[0][0][0].response
            r.get_evalresp_response_for_frequencies(
                frequencies=frequencies, output=unit)
Пример #8
0
    def test_response_multiple_gain_blockettes(self):
        """
        Evalresp chooses the last one - make sure we do the same.
        """
        filename = os.path.join(self.data_path,
                                "RESP.multiple_gain_blockettes")
        frequencies = np.logspace(-3, 3, 20)

        # Set the times for the response.
        t = obspy.UTCDateTime(1996, 1, 1)

        for unit in ("DISP", "VEL", "ACC"):
            # This raises a warning that it has multiple gain blockettes.
            with CatchAndAssertWarnings():
                r = obspy.read_inventory(filename)[0][0][0].response
            e_r = evalresp_for_frequencies(
                t_samp=None, frequencies=frequencies, filename=filename,
                date=t, units=unit)
            i_r = r.get_evalresp_response_for_frequencies(
                frequencies=frequencies, output=unit)
            np.testing.assert_equal(e_r, i_r, "%s - %s" % (filename, unit))
Пример #9
0
    def test_response_calculation_from_seed_and_xseed(self):
        """
        Test the response calculations with the obspy.core interface.

        It does it by converting whatever it gets to RESP files and then
        uses evalresp to get the response. This is compared to using the
        ObsPy Response object - this also uses evalresp but the actual flow
        of the data is very different.

        This is an expensive test but worth it for the trust it builds and
        the bugs it found and prevents.
        """
        # Very broad range but the responses should be exactly identical as
        # they use the same code under the hood so it should prove no issue.
        frequencies = np.logspace(-3, 3, 20)

        for filename in self.seed_files + self.xseed_files:
            # Parse the files using the Parser object.
            with CatchAndAssertWarnings():
                p = Parser(filename)
                p_resp = {_i[0]: _i[1] for _i in p.get_resp()}
                # Also read using the core routines.
                inv = obspy.read_inventory(filename)

            # Get all the channels and epochs.
            channels = collections.defaultdict(list)
            for c in p.get_inventory()["channels"]:
                channels[c["channel_id"]].append(
                    (c["start_date"], c["end_date"]))

            # Loop over each.
            for channel, epochs in channels.items():
                with NamedTemporaryFile() as tf:
                    r = p_resp["RESP.%s" % channel]
                    r.seek(0, 0)
                    tf.write(r.read())

                    # Now loop over the epochs.
                    for start, end in epochs:
                        if end:
                            t = start + (end - start) / 2
                        else:
                            t = start + 10

                        # Find response
                        n, s, l, c = channel.split(".")
                        _inv_t = inv.select(network=n, station=s,
                                            location=l, channel=c,
                                            starttime=t - 1, endtime=t + 1)
                        # Should now only be a single channel.
                        self.assertEqual(_inv_t.get_contents()["channels"],
                                         [channel])
                        inv_r = _inv_t[0][0][0].response

                        for unit in ("DISP", "VEL", "ACC"):
                            # Directly call evalresp.
                            e_r = evalresp_for_frequencies(
                                t_samp=None, frequencies=frequencies,
                                filename=tf.name, date=t, units=unit)
                            i_r = inv_r.get_evalresp_response_for_frequencies(
                                frequencies=frequencies, output=unit)
                            # Adaptive absolute tolerance to deal with very
                            # small values.
                            atol = 1E-7 * max(np.abs(e_r).max(),
                                              np.abs(i_r).max())
                            np.testing.assert_allclose(
                                e_r.real, i_r.real,
                                err_msg="real - %s - %s" % (filename, unit),
                                rtol=1E-6, atol=atol)
                            np.testing.assert_allclose(
                                e_r.imag, i_r.imag,
                                err_msg="imag - %s - %s" % (filename, unit),
                                rtol=1E-6, atol=atol)

                            # Bonus: Also read the RESP file directly with
                            # obspy.core and test the response.
                            i_r_r = obspy.read_inventory(tf.name).select(
                                starttime=t - 1,
                                endtime=t + 1)[0][0][0].response\
                                .get_evalresp_response_for_frequencies(
                                frequencies=frequencies, output=unit)
                            np.testing.assert_allclose(
                                e_r.real, i_r_r.real,
                                err_msg="RESP real - %s - %s" % (filename,
                                                                 unit),
                                rtol=1E-6, atol=atol)
                            np.testing.assert_allclose(
                                e_r.imag, i_r_r.imag,
                                err_msg="RESP imag - %s - %s" % (filename,
                                                                 unit),
                                rtol=1E-6, atol=atol)