def test_percent_in_str(self): """ Tests if __str__ method is working with percent sign (%). """ tr = Trace() tr.stats.station = '%t3u' self.assertTrue(tr.__str__().startswith(".%t3u.. | 1970"))
def test_writing_blockette_100(self): """ Tests that blockette 100 is written correctly. It is only used if the sampling rate is higher than 32727 Hz or smaller than 1.0 / 32727.0 Hz. """ # Three traces, only the middle one needs it. tr = Trace(data=np.linspace(0, 100, 101)) st = Stream(traces=[tr.copy(), tr.copy(), tr.copy()]) st[1].stats.sampling_rate = 60000.0 with io.BytesIO() as buf: st.write(buf, format="mseed") buf.seek(0, 0) st2 = read(buf) self.assertTrue(np.allclose(st[0].stats.sampling_rate, st2[0].stats.sampling_rate)) self.assertTrue(np.allclose(st[1].stats.sampling_rate, st2[1].stats.sampling_rate)) self.assertTrue(np.allclose(st[2].stats.sampling_rate, st2[2].stats.sampling_rate)) st[1].stats.sampling_rate = 1.0 / 60000.0 with io.BytesIO() as buf: st.write(buf, format="mseed") buf.seek(0, 0) st2 = read(buf) self.assertTrue(np.allclose(st[0].stats.sampling_rate, st2[0].stats.sampling_rate)) self.assertTrue(np.allclose(st[1].stats.sampling_rate, st2[1].stats.sampling_rate)) self.assertTrue(np.allclose(st[2].stats.sampling_rate, st2[2].stats.sampling_rate))
def test_rtrim_with_padding(self): """ Tests the _rtrim() method of the Trace class with padding. It has already been tested in the two sided trimming tests. This is just to have an explicit test. Also tests issue #429. """ # set up trace = Trace(data=np.arange(10)) start = UTCDateTime(2000, 1, 1, 0, 0, 0, 0) trace.stats.starttime = start trace.stats.sampling_rate = 1.0 trace.verify() # Pad with no fill_value will mask the additional values. tr = trace.copy() end = tr.stats.endtime tr._rtrim(end + 10, pad=True) self.assertEqual(tr.stats.endtime, trace.stats.endtime + 10) np.testing.assert_array_equal(tr.data[0:10], np.arange(10)) # Check that the first couple of entries are not masked. self.assertFalse(tr.data[0:10].mask.any()) # All the other entries should be masked. self.assertTrue(tr.data[10:].mask.all()) # Pad with fill_value. tr = trace.copy() end = tr.stats.endtime tr._rtrim(end + 10, pad=True, fill_value=-33) self.assertEqual(tr.stats.endtime, trace.stats.endtime + 10) # The first ten entries should not have changed. np.testing.assert_array_equal(tr.data[0:10], np.arange(10)) # The rest should be filled with the fill_value. np.testing.assert_array_equal(tr.data[10:], np.ones(10) * -33)
def test_issue_193(self): """ Test for issue #193: if non-contiguous array is written correctly. """ warnings.filterwarnings("ignore", "Detected non contiguous data") # test all plugins with both read and write method formats_write = \ set(_get_default_eps('obspy.plugin.waveform', 'writeFormat')) formats_read = \ set(_get_default_eps('obspy.plugin.waveform', 'readFormat')) formats = set.intersection(formats_write, formats_read) # mseed will raise exception for int64 data, thus use int32 only data = np.arange(10, dtype=np.int32) # make array non-contiguous data = data[::2] tr = Trace(data=data) for format in formats: # XXX: skip SEGY and SU formats for now as they need some special # headers. if format in ['SEGY', 'SU', 'SEG2']: continue with NamedTemporaryFile() as tf: tempfile = tf.name tr.write(tempfile, format) if format == "Q": tempfile = tempfile + ".QHD" tr_test = read(tempfile, format)[0] if format == 'Q': os.remove(tempfile[:-4] + '.QBN') os.remove(tempfile[:-4] + '.QHD') np.testing.assert_array_equal(tr.data, tr_test.data)
def test_long_year_range(self): """ Tests reading and writing years 1900 to 2100. """ tr = Trace(np.arange(5, dtype=np.float32)) # Year 2056 is non-deterministic for days 1, 256 and 257. These three # dates are simply simply not supported right now. See the libmseed # documentation for more details. # Use every 5th year. Otherwise the test takes too long. Use 1901 as # start to get year 2056. years = range(1901, 2101, 5) for year in years: for byteorder in ["<", ">"]: memfile = io.BytesIO() # Get some random time with the year and the byte order as the # seed. random.seed(year + ord(byteorder)) tr.stats.starttime = UTCDateTime( year, julday=random.randrange(1, 365), hour=random.randrange(0, 24), minute=random.randrange(0, 60), second=random.randrange(0, 60)) if year == 2056: tr.stats.starttime = UTCDateTime(2056, 2, 1) tr.write(memfile, format="mseed") st2 = read(memfile) self.assertEqual(len(st2), 1) tr2 = st2[0] # Remove the mseed specific header fields. These are obviously # not equal. del tr2.stats.mseed del tr2.stats._format self.assertEqual(tr, tr2)
def test_len(self): """ Tests the __len__ and count methods of the Trace class. """ trace = Trace(data=np.arange(1000)) self.assertEquals(len(trace), 1000) self.assertEquals(trace.count(), 1000)
def test_microsecond_accuracy_reading_and_writing_before_1970(self): """ Tests that reading and writing data with microsecond accuracy and before 1970 works as expected. """ # Test a couple of timestamps. Positive and negative ones. timestamps = [123456.789123, -123456.789123, 1.123400, 1.123412, 1.123449, 1.123450, 1.123499, -1.123400, -1.123412, -1.123449, -1.123450, -1.123451, -1.123499] for timestamp in timestamps: starttime = UTCDateTime(timestamp) self.assertEqual(starttime.timestamp, timestamp) tr = Trace(data=np.linspace(0, 100, 101)) tr.stats.starttime = starttime with io.BytesIO() as fh: tr.write(fh, format="mseed") fh.seek(0, 0) tr2 = read(fh)[0] del tr2.stats.mseed del tr2.stats._format self.assertEqual(tr2.stats.starttime, starttime) self.assertEqual(tr2, tr)
def __init__(self, year, doy, time=None): """ Set which day's midnight (00:00 hours) is used as a day break in the testing (to split the test data into two files). If `time` is specified it overrides `year` and `doy`. """ if time: self.time = time else: self.time = UTCDateTime("%d-%03dT00:00:00" % (year, doy)) delta = 1.0 / self.sampling_rate self.stream = Stream() for net in self.networks: for sta in self.stations: for loc in self.locations: for cha in self.channels: tr = Trace( data=np.arange(100, dtype=np.int32), header=dict( network=net, station=sta, location=loc, channel=cha, sampling_rate=self.sampling_rate, starttime=self.time - 30 * delta)) # cut into two seamless traces tr1 = tr.slice(endtime=self.time + 5 * delta) tr2 = tr.slice(starttime=self.time + 6 * delta) self.stream.append(tr1) self.stream.append(tr2)
def __init__(self, year, doy): """ Set which day's midnight (00:00 hours) is used as a day break in the testing (to split the test data into two files). """ self.time = UTCDateTime("%d-%03dT00:00:00" % (year, doy)) sampling_rate = 0.1 delta = 1 / sampling_rate networks = ("AB", "CD") stations = ("XYZ", "ZZZ3") locations = ("", "00") channels = ("HHZ", "HHN", "HHE", "BHZ", "BHN", "BHE") self.stream = Stream() for net in networks: for sta in stations: for loc in locations: for cha in channels: tr = Trace( data=np.arange(100, dtype=np.int32), header=dict( network=net, station=sta, location=loc, channel=cha, sampling_rate=sampling_rate, starttime=self.time - 30 * delta)) # cut into two seamless traces tr1 = tr.slice(endtime=self.time + 5 * delta) tr2 = tr.slice(starttime=self.time + 6 * delta) self.stream.append(tr1) self.stream.append(tr2)
def test_sac_instrument_correction(self): # SAC recommends to taper the transfer function if a pure # deconvolution is done instead of simulating a different # instrument. This test checks the difference between the # result from removing the instrument response using SAC or # ObsPy. Visual inspection shows that the traces are pretty # much identical but differences remain (rms ~ 0.042). Haven't # found the cause for those, yet. One possible reason is the # floating point arithmetic of SAC vs. the double precision # arithmetic of Python. However differences still seem to be # too big for that. pzf = os.path.join(self.path, 'SAC_PZs_KARC_BHZ') sacf = os.path.join(self.path, 'KARC.LHZ.SAC.asc.gz') testsacf = os.path.join(self.path, 'KARC_corrected.sac.asc.gz') plow = 160. phigh = 4. fl1 = 1.0 / (plow + 0.0625 * plow) fl2 = 1.0 / plow fl3 = 1.0 / phigh fl4 = 1.0 / (phigh - 0.25 * phigh) # Uncomment the following to run the sac-commands # that created the testing file # if 1: # import subprocess as sp # p = sp.Popen('sac',shell=True,stdin=sp.PIPE) # cd1 = p.stdin # print("r %s"%sacf, file=cd1) # print("rmean", file=cd1) # print("rtrend", file=cd1) # print("taper type cosine width 0.03", file=cd1) # print("transfer from polezero subtype %s to none \ # freqlimits %f %f %f %f" % (pzf, fl1, fl2, fl3, fl4), file=cd1) # print("w over ./data/KARC_corrected.sac", file=cd1) # print("quit", file=cd1) # cd1.close() # p.wait() stats = {'network': 'KA', 'delta': 0.99999988079072466, 'station': 'KARC', 'location': 'S1', 'starttime': UTCDateTime(2001, 2, 13, 0, 0, 0, 993700), 'calib': 1.00868e+09, 'channel': 'BHZ'} with gzip.open(sacf) as f: tr = Trace(np.loadtxt(f), stats) attach_paz(tr, pzf, tovel=False) tr.data = simulate_seismometer( tr.data, tr.stats.sampling_rate, paz_remove=tr.stats.paz, remove_sensitivity=False, pre_filt=(fl1, fl2, fl3, fl4)) with gzip.open(testsacf) as f: data = np.loadtxt(f) # import matplotlib.pyplot as plt # plt.plot(tr.data) # plt.plot(data) # plt.show() rms = np.sqrt(np.sum((tr.data - data) ** 2) / np.sum(tr.data ** 2)) self.assertTrue(rms < 0.0421)
def test_plotBinningError(self): """ Tests the plotting of a trace with a certain amount of sampling that had a binning problem. """ tr = Trace(data=np.sin(np.linspace(0, 200, 432000))) outfile = os.path.join(self.path, 'binning_error.png') tr.plot(outfile=outfile)
def test_integrate(self): """ Test integration method of trace """ data = np.ones(101) * 0.01 tr = Trace(data=data) tr.stats.delta = 0.1 tr.integrate(type='cumtrapz') np.testing.assert_almost_equal(tr.data[-1], 0.1)
def test_taper(self): """ Test taper method of trace """ data = np.ones(10) tr = Trace(data=data) tr.taper() for i in range(len(data)): self.assertTrue(tr.data[i] <= 1.) self.assertTrue(tr.data[i] >= 0.)
def test_plot(self): """ Tests plot method if matplotlib is installed """ try: import matplotlib except ImportError: return tr = Trace(data=np.arange(25)) tr.plot(show=False)
def test_differentiate(self): """ Test differentiation method of trace """ t = np.linspace(0., 1., 11) data = 0.1 * t + 1. tr = Trace(data=data) tr.stats.delta = 0.1 tr.differentiate(type='gradient') np.testing.assert_array_almost_equal(tr.data, np.ones(11) * 0.1)
def test_spectrogram(self): """ Tests spectrogram method if matplotlib is installed """ try: import matplotlib except ImportError: return tr = Trace(data=np.arange(25)) tr.stats.sampling_rate = 20 tr.spectrogram(show=False)
def xcorr(self, itrace0=None, itrace1=None, shift_len=1001, include_auto=False): """ Cross correlate traces """ if itrace0 is None: itrace0 = range(len(self.traces)) if itrace1 is None: itrace1 = range(len(self.traces)) st = Stream() if include_auto: k = 0 else: k = 1 i0, i1 = np.triu_indices(len(itrace0), k=k, m=len(itrace1)) logging.info("Cross correlating {:} trace pairs...", len(self.traces)) for _itr0, _itr1 in zip(i0, i1): itr0 = itrace0[_itr0] itr1 = itrace1[_itr1] tr0 = self.traces[itr0] tr1 = self.traces[itr1] assert tr0.stats['sampling_rate']\ == tr1.stats['sampling_rate'],\ 'Sampling rates for traces {:} ({:}) and {:} ({:})'\ .format(itr0, tr0.id, itr1, tr1.id)\ + ' are not equal.' logging.info('... {:} with {:}...', tr0.id, tr1.id) i, c, _xc = xcorr(self.traces[itr1], self.traces[itr0], shift_len, full_xcorr=True) xc = Trace(data=_xc, header=tr0.stats) xc.stats['npts'] = len(_xc) xc.stats['xcorr_imax'] = i xc.stats['xcorr_max'] = c for k in ['network', 'station', 'channel']: if tr0.stats[k] != tr1.stats[k]: xc.stats[k] = '{:}-{:}'.format(tr0.stats[k], tr1.stats[k]) st.extend([xc]) return st
def test_writeSACXYWithMinimumStats(self): """ Write SACXY with minimal stats header, no inhereted from SAC file """ tr = Trace() tr.stats.delta = 0.01 tr.data = np.arange(0, 3000) sac_file = NamedTemporaryFile().name tr.write(sac_file, 'SACXY') st = read(sac_file) os.remove(sac_file) self.assertEquals(st[0].stats.delta, 0.01) self.assertEquals(st[0].stats.sampling_rate, 100.0)
def test_write_sac_xy_with_minimum_stats(self): """ Write SACXY with minimal stats header, no inhereted from SAC file """ tr = Trace() tr.stats.delta = 0.01 tr.data = np.arange(0, 3000) with NamedTemporaryFile() as tf: sac_file = tf.name tr.write(sac_file, 'SACXY') st = read(sac_file) self.assertEqual(st[0].stats.delta, 0.01) self.assertEqual(st[0].stats.sampling_rate, 100.0)
def test_slice(self): """ Tests the slicing of trace objects. """ tr = Trace(data=np.arange(10, dtype='int32')) mempos = tr.data.ctypes.data t = tr.stats.starttime tr1 = tr.slice(t + 2, t + 8) tr1.data[0] = 10 self.assertEqual(tr.data[2], 10) self.assertEqual(tr.data.ctypes.data, mempos) self.assertEqual(tr.data[2:9].ctypes.data, tr1.data.ctypes.data) self.assertEqual(tr1.data.ctypes.data - 8, mempos)
def test_write_and_read_correct_network(self): """ Tests that writing and reading the STA2 line works (otherwise the network code of the data is missing), even if some details like e.g. latitude are not present. """ tr = Trace(np.arange(5, dtype=np.int32)) tr.stats.network = "BW" with NamedTemporaryFile() as tf: tmpfile = tf.name tr.write(tmpfile, format='GSE2') tr = read(tmpfile)[0] self.assertEqual(tr.stats.network, "BW")
def test_channel_loop(self): """Test trigger generation in internal loop.""" import numpy as np from eqcorrscan.utils.trigger import _channel_loop from eqcorrscan.utils.trigger import TriggerParameters from obspy import Trace parameters = [TriggerParameters({'station': 'TEST', 'channel': 'SHZ', 'sta_len': 0.3, 'lta_len': 10.0, 'thr_on': 10, 'thr_off': 3, 'lowcut': 2, 'highcut': 20})] tr = Trace() tr.data = np.random.randn(2000) tr.data[1000:1010] = [100, -80, 70, -65, 60, -52, 45, -30, 15, 5] tr.stats.sampling_rate = 100 tr.stats.station = parameters[0]['station'] tr.stats.channel = parameters[0]['channel'] # Test without despike triggers = _channel_loop(tr=tr, parameters=parameters, max_trigger_length=100, despike=False, debug=0) self.assertEqual(len(triggers), 1) # Test with despike triggers = _channel_loop(tr=tr, parameters=parameters, max_trigger_length=100, despike=True, debug=0) self.assertEqual(len(triggers), 1) # Test with no filter parameters[0]['lowcut'] = None parameters[0]['highcut'] = None triggers = _channel_loop(tr=tr, parameters=parameters, max_trigger_length=100, despike=False, debug=0) self.assertEqual(len(triggers), 1) # Test with lowpass parameters[0]['highcut'] = 20 triggers = _channel_loop(tr=tr, parameters=parameters, max_trigger_length=100, despike=False, debug=0) self.assertEqual(len(triggers), 1) # Test with highpass parameters[0]['highcut'] = None parameters[0]['lowcut'] = 2 triggers = _channel_loop(tr=tr, parameters=parameters, max_trigger_length=100, despike=False, debug=0) self.assertEqual(len(triggers), 1)
def test_trimAllDoesNotChangeDtype(self): """ If a Trace is completely trimmed, e.g. no data samples are remaining, the dtype should remain unchanged. A trace with no data samples is not really senseful but the dtype should not be changed anyways. """ # Choose non native dtype. tr = Trace(np.arange(100, dtype='int16')) tr.trim(UTCDateTime(10000), UTCDateTime(20000)) # Assert the result. self.assertEqual(len(tr.data), 0) self.assertEqual(tr.data.dtype, 'int16')
def test_valid_sac_from_minimal_existing_sac_header(self): """ An incomplete manually-produced SAC header should still produce a valid SAC file, including values from the ObsPy header. Issue 1204. """ tr = Trace(np.arange(100)) t = UTCDateTime() tr.stats.starttime = t tr.stats.station = 'AAA' tr.stats.network = 'XX' tr.stats.channel = 'BHZ' tr.stats.location = '00' tr.stats.sac = AttribDict() tr.stats.sac.iztype = 9 tr.stats.sac.nvhdr = 6 tr.stats.sac.leven = 1 tr.stats.sac.lovrok = 1 tr.stats.sac.iftype = 1 tr.stats.sac.stla = 1. tr.stats.sac.stlo = 2. with NamedTemporaryFile() as tf: tempfile = tf.name with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') tr.write(tempfile, format='SAC') self.assertEqual(len(w), 1) self.assertIn('reftime', str(w[-1].message)) tr1 = read(tempfile)[0] # starttime made its way to SAC file nztimes, microsecond = utcdatetime_to_sac_nztimes(t) self.assertEqual(tr1.stats.sac.nzyear, nztimes['nzyear']) self.assertEqual(tr1.stats.sac.nzjday, nztimes['nzjday']) self.assertEqual(tr1.stats.sac.nzhour, nztimes['nzhour']) self.assertEqual(tr1.stats.sac.nzmin, nztimes['nzmin']) self.assertEqual(tr1.stats.sac.nzsec, nztimes['nzsec']) self.assertEqual(tr1.stats.sac.nzmsec, nztimes['nzmsec']) self.assertEqual(tr1.stats.sac.kstnm, 'AAA') self.assertEqual(tr1.stats.sac.knetwk, 'XX') self.assertEqual(tr1.stats.sac.kcmpnm, 'BHZ') self.assertEqual(tr1.stats.sac.khole, '00') self.assertEqual(tr1.stats.sac.iztype, 9) self.assertEqual(tr1.stats.sac.nvhdr, 6) self.assertEqual(tr1.stats.sac.leven, 1) self.assertEqual(tr1.stats.sac.lovrok, 1) self.assertEqual(tr1.stats.sac.iftype, 1) self.assertEqual(tr1.stats.sac.stla, 1.0) self.assertEqual(tr1.stats.sac.stlo, 2.0)
def test_write_small_trace(self): """ Tests writing Traces containing 0, 1, 2, 3, 4 samples only. """ for format in ['SAC', 'SACXY']: for num in range(5): tr = Trace(data=np.arange(num)) with NamedTemporaryFile() as tf: tempfile = tf.name tr.write(tempfile, format=format) # test results st = read(tempfile, format=format) self.assertEqual(len(st), 1) np.testing.assert_array_equal(tr.data, st[0].data)
def test_writeSmallTrace(self): """ Tests writing Traces containing 0, 1 or 2 samples only. """ for format in ["SLIST", "TSPAIR"]: for num in range(0, 4): tr = Trace(data=np.arange(num)) tempfile = NamedTemporaryFile().name tr.write(tempfile, format=format) # test results st = read(tempfile, format=format) self.assertEquals(len(st), 1) self.assertEquals(len(st[0]), num) os.remove(tempfile)
def test_write_small_trace(self): """ Tests writing Traces containing 0, 1 or 2 samples only. """ for format in ['SLIST', 'TSPAIR']: for num in range(0, 4): tr = Trace(data=np.arange(num)) with NamedTemporaryFile() as tf: tempfile = tf.name tr.write(tempfile, format=format) # test results st = read(tempfile, format=format) self.assertEqual(len(st), 1) self.assertEqual(len(st[0]), num)
def test_times(self): """ Test if the correct times array is returned for normal traces and traces with gaps. """ tr = Trace(data=np.ones(100)) tr.stats.sampling_rate = 20 start = UTCDateTime(2000, 1, 1, 0, 0, 0, 0) tr.stats.starttime = start tm = tr.times() self.assertAlmostEquals(tm[-1], tr.stats.endtime - tr.stats.starttime) tr.data = np.ma.ones(100) tr.data[30:40] = np.ma.masked tm = tr.times() self.assertTrue(np.alltrue(tr.data.mask == tm.mask))
def _convert_adj_to_trace(adj, starttime, chan_id): """ Convert AdjointSource to Trace,for internal use only """ tr = Trace() tr.data = adj.adjoint_source tr.stats.starttime = starttime tr.stats.delta = adj.dt tr.stats.channel = str(chan_id.split(".")[-1]) tr.stats.station = adj.station tr.stats.network = adj.network tr.stats.location = chan_id.split(".")[2] return tr
def test_sac_file_from_new_header(self): """ Writing to disk a new Trace object shouldn't ignore custom header fields, if an arrival time is set. See ObsPy issue #1519 """ tr = Trace(np.zeros(1000)) tr.stats.delta = 0.01 tr.stats.station = 'XXX' tr.stats.sac = {'stla': 10., 'stlo': -5., 'a': 12.34} with io.BytesIO() as tf: tr.write(tf, format='SAC') tf.seek(0) tr1 = read(tf)[0] self.assertAlmostEqual(tr1.stats.sac.stla, 10., places=4) self.assertAlmostEqual(tr1.stats.sac.stlo, -5., places=4) self.assertAlmostEqual(tr1.stats.sac.a, 12.34, places=5)
def test_invalidEncoding(self): """ An invalid encoding should raise an exception. """ npts = 6000 np.random.seed(815) # make test reproducible with NamedTemporaryFile() as tf: tempfile = tf.name data = np.random.randint(-1000, 1000, npts).astype(np.int32) st = Stream([Trace(data=data)]) # Writing should fail with invalid record lengths. # Wrong number. self.assertRaises(ValueError, _write_mseed, st, tempfile, format="MSEED", encoding=2) # Wrong Text. self.assertRaises(ValueError, _write_mseed, st, tempfile, format="MSEED", encoding='FLOAT_64')
def test_writing_too_long_trace(self): """ Test nice exception message when trying to write a too long trace (#1393) """ x = np.arange(32768, dtype=np.int32) tr = Trace(x) tr.stats.sampling_rate = 100 st = Stream([tr]) bio = io.BytesIO() with self.assertRaises(ValueError) as e: _write_segy(st, bio, data_encoding=2) self.assertEqual( str(e.exception), "Can not write traces with more than 32767 samples (trace at " "index 0):\n... | 1970-01-01T00:00:00.000000Z - " "1970-01-01T00:05:27.670000Z | 100.0 Hz, 32768 samples")
def test_attach_paz(self): fvelhz = io.StringIO("""ZEROS 3 -5.032 0.0 POLES 6 -0.02365 0.02365 -0.02365 -0.02365 -39.3011 0. -7.74904 0. -53.5979 21.7494 -53.5979 -21.7494 CONSTANT 2.16e18""") tr = Trace() attach_paz(tr, fvelhz, torad=True, todisp=True) np.testing.assert_array_almost_equal(tr.stats.paz['zeros'][0], -31.616988, decimal=6) self.assertEqual(len(tr.stats.paz['zeros']), 4)
def get_preview(self, apply_calibration=False): try: data = pickle.loads(self.preview) except Exception: data = np.array([]) if apply_calibration: data = data * self.calib tr = Trace(data=data) tr.stats.starttime = UTCDateTime(self.starttime) tr.stats.delta = 30.0 tr.stats.network = self.network tr.stats.station = self.station tr.stats.location = self.location tr.stats.channel = self.channel tr.stats.calib = self.calib tr.stats.preview = True return tr
def stack_all(stream, pws=False): """ Stacks all traces in ``Stream`` objects. Args: stream (:class:`~obspy.core.Stream`) Contains traces to stack pws (bool): Enables Phase-Weighted Stacking Returns: (tuple): tuple containing: stack (:class:`~obspy.core.Trace`): Stacked trace """ # Copy stats from stream str_stats = stream[0].stats # Initialize arrays tmp = np.zeros(len(stream[0].data)) weight = np.zeros(len(stream[0].data), dtype=complex) # Stack all traces for tr in stream: tmp += tr.data hilb = hilbert(tr.data) phase = np.arctan2(hilb.imag, hilb.real) weight += np.exp(1j * phase) # Normalize tmp = tmp / np.float(len(stream)) # Phase-weighting if pws: weight = weight / np.float(len(stream)) weight = np.real(abs(weight)) else: weight = np.ones(len(stream[0].data)) # Put back into traces stack = Trace(data=weight * tmp, header=str_stats) return stack
def get_obspy_trace(self): """ Return class contents as obspy.Trace object """ stat = Stats() stat.network = self.net.split(b'\x00')[0].decode() stat.station = self.sta.split(b'\x00')[0].decode() location = self.loc.split(b'\x00')[0].decode() if location == '--': stat.location = '' else: stat.location = location stat.channel = self.chan.split(b'\x00')[0].decode() stat.starttime = UTCDateTime(self.start) stat.sampling_rate = self.rate stat.npts = len(self.data) return Trace(data=self.data, header=stat)
def test_writeIntegers(self): """ Write integer array via L{obspy.mseed.mseed.writeMSEED}. """ npts = 1000 # data array of integers - float won't work! np.random.seed(815) # make test reproducable data = np.random.randint(-1000, 1000, npts).astype('int32') st = Stream([Trace(data=data)]) with NamedTemporaryFile() as tf: tempfile = tf.name # write writeMSEED(st, tempfile, format="MSEED") # read again stream = readMSEED(tempfile) stream.verify() np.testing.assert_array_equal(stream[0].data, data)
def test_write_with_date_time_before_1970(self): """ Write an stream via libmseed with a datetime before 1970. This test depends on the platform specific localtime()/gmtime() function. """ # create trace tr = Trace(data=np.empty(1000)) tr.stats.starttime = UTCDateTime("1969-01-01T00:00:00") # write file with NamedTemporaryFile() as tf: tempfile = tf.name _write_mseed(Stream([tr]), tempfile, format="MSEED") # read again stream = _read_mseed(tempfile) stream.verify()
def test_spectogram(self): """ Create spectogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproduceable np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE' } tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True with ImageComparison(self.path, 'spectogram_log.png') as ic: with warnings.catch_warnings(record=True) as w: warnings.resetwarnings() np_err = np.seterr(all="warn") spectrogram.spectrogram(st[0].data, log=True, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False) np.seterr(**np_err) self.assertEqual(len(w), 2) self.assertEqual(w[0].category, UserWarning) self.assertEqual( str(w[0].message), 'aspect is not supported for Axes with ' 'xscale=linear, yscale=log') self.assertEqual(w[1].category, RuntimeWarning) self.assertEqual(str(w[1].message), 'underflow encountered in multiply') # 2 - using log=False reltol = 1 if MATPLOTLIB_VERSION < [1, 3, 0]: reltol = 3 with ImageComparison(self.path, 'spectogram.png', reltol=reltol) as ic: spectrogram.spectrogram(st[0].data, log=False, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False)
def _internal_get_sample_data(): """ Returns some real data (trace and poles and zeroes) for PPSD testing. Data was downsampled to 100Hz so the PPSD is a bit distorted which does not matter for the purpose of testing. """ # load test file file_data = os.path.join(PATH, 'BW.KW1._.EHZ.D.2011.090_downsampled.asc.gz') # parameters for the test with gzip.open(file_data) as f: data = np.loadtxt(f) stats = { '_format': 'MSEED', 'calib': 1.0, 'channel': 'EHZ', 'delta': 0.01, 'endtime': UTCDateTime(2011, 3, 31, 2, 36, 0, 180000), 'location': '', 'mseed': { 'dataquality': 'D', 'record_length': 512, 'encoding': 'STEIM2', 'byteorder': '>' }, 'network': 'BW', 'npts': 936001, 'sampling_rate': 100.0, 'starttime': UTCDateTime(2011, 3, 31, 0, 0, 0, 180000), 'station': 'KW1' } tr = Trace(data, stats) paz = { 'gain': 60077000.0, 'poles': [(-0.037004 + 0.037016j), (-0.037004 - 0.037016j), (-251.33 + 0j), (-131.04 - 467.29j), (-131.04 + 467.29j)], 'sensitivity': 2516778400.0, 'zeros': [0j, 0j] } return tr, paz
def continuous_signal(time, low, high, dt): """ Continuous source-signal """ sig = (np.random.rand(time.size) * 2 - 1) tr = Trace() tr.data = sig tr.stats.delta = dt tr.stats.starttime = 0 tr.filter('bandpass', freqmin=low, freqmax=high, corners=4) tr.normalize() return tr
def test_normal_template_loop(self): """Check that perfect correlations are carried through. """ from obspy import Stream, Trace import numpy as np from eqcorrscan.core.match_filter import _template_loop template = Stream(Trace(np.random.randn(100) * 10.0)) template[0].stats.station = 'test' template[0].stats.channel = 'SZ' image = np.zeros(1000) image[200] = 1.0 image = np.convolve(image, template[0].data) image += np.random.randn(1099) # Add random noise chan = image i, ccc = _template_loop(template=template, chan=chan, station=template[0].stats.station, channel=template[0].stats.channel) self.assertNotEqual(ccc.max(), 1.0)
def test_issue376(self): """ Tests writing Traces containing 1 or 2 samples only. """ # one samples tr = Trace(data=np.ones(1)) tempfile = NamedTemporaryFile().name tr.write(tempfile, format="MSEED") st = read(tempfile) self.assertEqual(len(st), 1) self.assertEqual(len(st[0]), 1) os.remove(tempfile) # two samples tr = Trace(data=np.ones(2)) with NamedTemporaryFile() as tf: tempfile = tf.name tr.write(tempfile, format="MSEED") st = read(tempfile) self.assertEqual(len(st), 1) self.assertEqual(len(st[0]), 2)
def get3Ctr(wf_db, sta, chan3, tstart, tend): """ Input: db wfdisc pointer, station name, 3 channels, start,end Output: Obspy Stream with 3 waveform traces (segments) """ logger = logging.getLogger('dbarrival_params') st3c = Stream() if chan3 == None: return None for chan in chan3: cline = "{}:{} {} - {}".format(sta, chan, stock.epoch2str(tstart, "%D %H:%M:%S.%s"), stock.epoch2str(tend, "%D %H:%M:%S.%s")) logger.debug("get3Ctr: Getting data for {}".format(cline)) with ds.trdestroying(wf_db.trloadchan(tstart, tend, sta, chan)) as tr: if tr.record_count == 0: logger.warning("get3Ctr: Could not load data for {}".format(cline)) return None #tr.trfilter(pfile['filter']) tr.record = 0 try: time, samprate = tr.getv('time', 'samprate') except DbgetvError: logger.warning("get3Ctr: Could not get value 'samprate' for {}".format(cline)) return None data = [] for segment in tr.iter_record(): tmp_data = list(segment.trdata()) data += list(segment.trdata()) tr.trfree() data = array(data) stats = {'station': sta, 'channel': chan, 'sampling_rate': samprate} stats['starttime'] = UTCDateTime(time) otr = Trace(data=data, header=stats) st3c += otr ns = len(st3c[0].data) # TODO: write subroutine to check ns, if close (w/i a few samples) try again if len(st3c[1].data) != ns or len(st3c[2].data) != ns: logger.warning('get3Ctr: {0}'.format(cline)) logger.warning('get3Ctr: Length of data arrays not equal {0} {1} {2}'.format(len(st3c[0].data),len(st3c[1].data),len(st3c[2].data))) return None return st3c
def test_stretch(self): h = {'sampling_rate': 100} h['network1'] = h['network2'] = 'NET' h['station1'] = h['station2'] = h['network'] = h['location'] = 'STA' h['location1'] = h['location2'] = '' h['channel1'] = h['channel2'] = h['location'] = h['channel'] = 'HHZ' h['dist'] = h['azi'] = h['baz'] = 0 vel_changes = [0, 1, -1] traces = [] dt = 24 * 3600 t0 = UTC() for i, v in enumerate(vel_changes): mul = 1 + v / 100 t = np.linspace(-10 * mul, 10 * mul, 10001) data = np.cos(2 * np.pi * t) h['starttime'] = t0 + i * dt tr = Trace(data, header=h) traces.append(tr) d = stretch(Stream(traces), max_stretch=1.1, num_stretch=2201, tw=(1, 5), sides='both', reftr=traces[0]) expect = np.array(vel_changes) np.testing.assert_allclose(d['velchange_vs_time'], expect) np.testing.assert_allclose(d['corr_vs_time'], (1, 1, 1)) self.assertAlmostEqual(d['velchange_values'][-1], 1.1) self.assertEqual(len(d['velchange_values']), 2201) # test writing and reading with tempfile.TemporaryDirectory(prefix='yam_') as tmpdir: fname = os.path.join(tmpdir, 'stretch.h5') d['attrs']['key'] = 'test' write_dict(d, fname) d2 = read_dicts(fname)[0] for key in d: if key == 'sim_mat': np.testing.assert_allclose(d2[key], d[key], rtol=1e-3) elif isinstance(d2[key], np.ndarray): np.testing.assert_equal(d2[key], d[key]) else: self.assertEqual(d2[key], d[key]) d2['attrs']['key'] = 'test2' write_dict(d2, fname)
def test_exclude_last_sample(self): start = UTCDateTime("2017-01-01T00:00:00") header = { "starttime": start, "network": "GR", "station": "FUR", "channel": "BHZ" } # 49 segments of 30 minutes to allow 30 minutes overlap in next day tr = Trace(data=np.arange(30 * 60 * 4, dtype=np.int32), header=header) ppsd = PPSD(tr.stats, read_inventory()) ppsd.add(tr) self.assertEqual(3, len(ppsd._times_processed)) self.assertEqual(3600, ppsd.len) for i, time in enumerate(ppsd._times_processed): current = start.ns + (i * 30 * 60) * 1e9 self.assertTrue(time == current)
def test_bugfix_setStats3(self): """ Third test related to issue #4. """ st = Stream([Trace(header={'station': 'BGLD'})]) self.assertEqual(st[0].stats.station, 'BGLD') st = st + st st[0].stats.station = 'AAA' st = st + st st[3].stats.station = 'BBB' # changed in rev. 1625: adding streams doesn't deepcopy # therefore all traces in the test stream are idential # (python list behavior) for tr in st: self.assertTrue(tr == st[0]) self.assertEqual(tr.stats.station, 'BBB') self.assertEqual(tr.stats['station'], 'BBB') self.assertEqual(tr.stats.get('station'), 'BBB') self.assertTrue('BBB' in list(tr.stats.values()))
def readCSS(filename, **kwargs): """ Reads a CSS waveform file and returns a Stream object. .. warning:: This function should NOT be called directly, it registers via the ObsPy :func:`~obspy.core.stream.read` function, call this instead. :type filename: str :param filename: CSS file to be read. :rtype: :class:`~obspy.core.stream.Stream` :returns: Stream with Traces specified by given file. """ # read metafile with info on single traces with open(filename, "rb") as fh: lines = fh.readlines() basedir = os.path.dirname(filename) traces = [] # read single traces for line in lines: npts = int(line[79:87]) dirname = line[148:212].strip().decode() filename = line[213:245].strip().decode() filename = os.path.join(basedir, dirname, filename) offset = int(line[246:256]) dtype = DTYPE[line[143:145]] fmt = b">" + dtype * npts with open(filename, "rb") as fh: fh.seek(offset) size = struct.calcsize(fmt) data = fh.read(size) data = struct.unpack(fmt, data) data = np.array(data) header = {} header['station'] = line[0:6].strip().decode() header['channel'] = line[7:15].strip().decode() header['starttime'] = UTCDateTime(float(line[16:33])) header['sampling_rate'] = float(line[88:99]) header['calib'] = float(line[100:116]) header['calper'] = float(line[117:133]) tr = Trace(data, header=header) traces.append(tr) return Stream(traces=traces)
def test_bugfix_set_stats_3(self): """ Third test related to issue #4. """ st = Stream([Trace(header={'station': 'BGLD'})]) assert st[0].stats.station == 'BGLD' st = st + st st[0].stats.station = 'AAA' st = st + st st[3].stats.station = 'BBB' # changed in rev. 1625: adding streams doesn't deepcopy # therefore all traces in the test stream are identical # (python list behavior) for tr in st: assert tr == st[0] assert tr.stats.station == 'BBB' assert tr.stats['station'] == 'BBB' assert tr.stats.get('station') == 'BBB' assert 'BBB' in tr.stats.values()
def test_writing_micro_seconds(self): """ Test case for #194. Check that microseconds are written to the SAC header b """ np.random.seed(815) head = {'network': 'NL', 'station': 'HGN', 'channel': 'BHZ', 'sampling_rate': 200.0, 'starttime': UTCDateTime(2003, 5, 29, 2, 13, 22, 999999)} data = np.random.randint(0, 5000, 100).astype(np.int32) st = Stream([Trace(header=head, data=data)]) # write them as SAC with NamedTemporaryFile() as tf: tmpfile = tf.name st.write(tmpfile, format="SAC") st2 = read(tmpfile, format="SAC") # check all the required entries (see url in docstring) self.assertEqual(st2[0].stats.starttime, st[0].stats.starttime) self.assertAlmostEqual(st2[0].stats.sac.b, 0.000999)
def test_decimate(self): """ Tests the decimate method of the Trace object. """ # create test Trace tr = Trace(data=np.arange(20)) tr_bkp = deepcopy(tr) # some test that should fail and leave the original trace alone self.assertRaises(ValueError, tr.decimate, 7, strict_length=True) self.assertRaises(ValueError, tr.decimate, 9, strict_length=True) self.assertRaises(ArithmeticError, tr.decimate, 18) # some tests in place tr.decimate(4, no_filter=True) np.testing.assert_array_equal(tr.data, np.arange(0, 20, 4)) self.assertEqual(tr.stats.npts, 5) self.assertEqual(tr.stats.sampling_rate, 0.25) self.assertTrue("decimate" in tr.stats.processing[0]) self.assertTrue("factor=4" in tr.stats.processing[0]) tr = tr_bkp.copy() tr.decimate(10, no_filter=True) np.testing.assert_array_equal(tr.data, np.arange(0, 20, 10)) self.assertEqual(tr.stats.npts, 2) self.assertEqual(tr.stats.sampling_rate, 0.1) self.assertTrue("decimate" in tr.stats.processing[0]) self.assertTrue("factor=10" in tr.stats.processing[0]) # some tests with automatic prefiltering tr = tr_bkp.copy() tr2 = tr_bkp.copy() tr.decimate(4) df = tr2.stats.sampling_rate tr2.data, fp = lowpassCheby2(data=tr2.data, freq=df * 0.5 / 4.0, df=df, maxorder=12, ba=False, freq_passband=True) # check that iteratively determined pass band frequency is correct self.assertAlmostEqual(0.0811378285461, fp, places=7) tr2.decimate(4, no_filter=True) np.testing.assert_array_equal(tr.data, tr2.data)
def get_dropouts(stations,working_dir,net): ''' loop over all sites get drops, put in an mseed file ''' from obspy import Stream,Trace #Summary file f=open(working_dir+'_drops.summary','w') f.write('# Station, samples streamed, samples dropped, % received\n') for k in range(len(stations)): station_file=working_dir+stations[k]+'.LXE.mseed' try: t0,drops,Nsamples=dropouts(station_file) st=Stream(Trace()) st[0].data=drops st[0].stats.starttime=t0 st[0].stats.delta=1.0 st[0].stats.station=stations[k] st[0].stats.network=net st[0].stats.channel='ZXD' out_file=working_dir+stations[k]+'.'+st[0].stats.channel+'.mseed' st[0].write(out_file,format='MSEED') #add to summary file line='%s\t%d\t%d\t%.1f\n' % (stations[k],Nsamples,len(drops),100-100*len(drops)/Nsamples) f.write(line) except: print('... no data for'+station_file) f.close()
def _internal_read_knet_ascii(buf, **kwargs): """ Reads a K-NET/KiK-net ASCII file and returns an ObsPy Stream object. .. warning:: This function should NOT be called directly, it registers via the ObsPy :func:`~obspy.core.stream.read` function, call this instead. :param buf: File to read. :type buf: Open file or open file like object. """ data = [] hdrdict = {} cur_pos = buf.tell() buf.seek(0, 2) size = buf.tell() buf.seek(cur_pos, 0) # First read the headerlines headerlines = [] while buf.tell() < size: line = buf.readline().decode() headerlines.append(line) if line.startswith('Memo'): hdrdict = _read_knet_hdr(headerlines, **kwargs) break while buf.tell() < size: line = buf.readline() parts = line.strip().split() data += [float(p) for p in parts] hdrdict['npts'] = len(data) # The FDSN network code for the National Research Institute for Earth # Science and Disaster Prevention (NEID JAPAN) is BO (Bosai-Ken Network) hdrdict['network'] = 'BO' data = np.array(data) stats = Stats(hdrdict) trace = Trace(data, header=stats) return Stream([trace])
def test_spectrogram(self): """ Create spectrogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproduceable np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE' } tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True reltol = 1 if MATPLOTLIB_VERSION < [1, 2, 0]: reltol = 2000 with ImageComparison(self.path, 'spectrogram_log.png', reltol=reltol) as ic: with warnings.catch_warnings(record=True): warnings.resetwarnings() np_err = np.seterr(all="warn") spectrogram.spectrogram(st[0].data, log=True, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False) np.seterr(**np_err) # 2 - using log=False reltol = 1 if MATPLOTLIB_VERSION < [1, 3, 0]: reltol = 3 with ImageComparison(self.path, 'spectrogram.png', reltol=reltol) as ic: spectrogram.spectrogram(st[0].data, log=False, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False)
def test_plot_synth_real(self): from eqcorrscan.utils.synth_seis import seis_sim synth = Stream(Trace(seis_sim(sp=100, flength=200))) synth[0].stats.station = 'RJOB' synth[0].stats.channel = 'EHZ' synth[0].stats.sampling_rate = 100 synth = synth.filter('bandpass', freqmin=2, freqmax=8) real = self.st.select( station='RJOB', channel='EHZ').detrend('simple').filter('bandpass', freqmin=2, freqmax=8) real.trim(starttime=real[0].stats.starttime + 4.9, endtime=real[0].stats.starttime + 6.9) fig = plot_synth_real(real_template=real, synthetic=synth, size=(7, 4), show=False, return_figure=True) return fig
def test_plotBinningError(self): """ Tests the plotting of a trace with a certain amount of sampling that had a binning problem. """ tr = Trace(data=np.sin(np.linspace(0, 200, 432000))) # create and compare image with NamedTemporaryFile(suffix='.png') as tf: tr.plot(outfile=tf.name) # compare images expected_image = os.path.join(self.path, 'waveform_binning_error.png') compare_images(tf.name, expected_image, 0.001) tr = Trace(data=np.sin(np.linspace(0, 200, 431979))) # create and compare image with NamedTemporaryFile(suffix='.png') as tf: tr.plot(outfile=tf.name) # compare images expected_image = os.path.join(self.path, 'waveform_binning_error_2.png') compare_images(tf.name, expected_image, 0.001)
def df_to_trace(station, data): station = station.split('.') net, sta, loc, cha = station[0], station[1], station[2], station[3] data_x = data['Date'].values data_sta = data['Data_Sta'].values delta_t = data_x[1] - data_x[0] fs = round(numpy.timedelta64(1, 's') / delta_t, 1) starttime = UTCDateTime(str(data_x[0])) tr = Trace(data_sta) tr.stats.network = net tr.stats.station = sta tr.stats.location = loc tr.stats.channel = cha tr.stats.sampling_rate = fs tr.stats.starttime = starttime return tr
def createMSeed(DataArray, StartDateTime, EndDateTime, nSamples): ActualSampleFrequency = float(nSamples) / (EndDateTime - StartDateTime) # Fill header attributes stats = { 'network': 'EM', 'station': '01', 'location': ' ', 'channel': '1', 'npts': nSamples, 'sampling_rate': ActualSampleFrequency, 'mseed': { 'dataquality': 'D' } } # set current time stats['starttime'] = StartDateTime st = Stream([Trace(data=DataArray[0:nSamples], header=stats)]) return st
def test_invalid_record_length(self): """ An invalid record length should raise an exception. """ npts = 6000 np.random.seed(815) # make test reproducible with NamedTemporaryFile() as tf: tempfile = tf.name data = np.random.randint(-1000, 1000, npts).astype(np.int32) st = Stream([Trace(data=data)]) # Writing should fail with invalid record lengths. # Not a power of 2. self.assertRaises(ValueError, _write_mseed, st, tempfile, format="MSEED", reclen=1000) # Too small. self.assertRaises(ValueError, _write_mseed, st, tempfile, format="MSEED", reclen=8) # Not a number. self.assertRaises(ValueError, _write_mseed, st, tempfile, format="MSEED", reclen='A')
def create_trace(st, sta_code, sta_coordinate, channel, eve_coordinate, eve_ot, freq4, ratio1, ratio2): tr = st.select(station=sta_code, channel=channel) dist = locations2degrees(eve_coordinate[0], eve_coordinate[1], sta_coordinate[0], sta_coordinate[1]) if (len(tr) == 1): tr = tr[0] tr.stats.data_available = 1 if (hasattr(tr.stats, 'response')): tr.stats.metadata_available = 1 vel = tr.copy().detrend('demean').taper(0.05). \ remove_response(pre_filt=freq4,output="VEL") disp = tr.copy().detrend('demean').taper(0.05). \ remove_response(pre_filt=freq4,output="DISP") disp.resample(2.0) sig_win_len = 0.36 * dist * 111.194929703 + 60 noise_win_len = 3 * 60 tr.stats.sn_test1 = sn_test(vel, noise_win_len, sig_win_len, ratio1) tr.stats.sn_test2 = sn_test(disp, noise_win_len, sig_win_len, ratio2) else: tr.stats.metadata_available = 0 tr.stats.sn_test1 = 0 tr.stats.sn_test2 = 0 else: tr = Trace() tr.stats.data_available = 0 tr.stats.metadata_available = 0 tr.stats.sn_test1 = 0 tr.stats.sn_test2 = 0 tr.trim(starttime=eve_ot - 7 * 60, endtime=eve_ot + 7 * 60, pad=True, fill_value=0.0) tr.stats.distance = dist tr.stats.eve_coord = eve_coordinate tr.stats.eve_ot = eve_ot tr.stats["coordinates"] = {} tr.stats["coordinates"]["latitude"] = sta_coordinate[0] tr.stats["coordinates"]["longitude"] = sta_coordinate[1] return tr