def test_evalresp_with_output_from_seed(self): """ The StationXML file has been converted to SEED with the help of a tool provided by IRIS: https://seiscode.iris.washington.edu/projects/stationxml-converter """ t_samp = 0.05 nfft = 16384 # Test for different output units. units = ["DISP", "VEL", "ACC"] filenames = ["IRIS_single_channel_with_response", "XM.05", "AU.MEEK"] for filename in filenames: xml_filename = os.path.join(self.data_dir, filename + os.path.extsep + "xml") seed_filename = os.path.join(self.data_dir, filename + os.path.extsep + "seed") p = Parser(seed_filename) # older systems don't like an end date in the year 2599 t_ = UTCDateTime(2030, 1, 1) if p.blockettes[50][0].end_effective_date > t_: p.blockettes[50][0].end_effective_date = None if p.blockettes[52][0].end_date > t_: p.blockettes[52][0].end_date = None resp_filename = p.get_resp()[0][-1] inv = read_inventory(xml_filename) network = inv[0].code station = inv[0][0].code location = inv[0][0][0].location_code channel = inv[0][0][0].code date = inv[0][0][0].start_date for unit in units: resp_filename.seek(0, 0) seed_response, seed_freq = evalresp( t_samp, nfft, resp_filename, date=date, station=station, channel=channel, network=network, locid=location, units=unit, freq=True) xml_response, xml_freq = \ inv[0][0][0].response.get_evalresp_response(t_samp, nfft, output=unit) self.assertTrue(np.allclose(seed_freq, xml_freq, rtol=1E-5)) self.assertTrue(np.allclose(seed_response, xml_response, rtol=1E-5))
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 warnings.catch_warnings(record=True): 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)