def test_searchFlagInBlockette(self): """ Test case for obspy.io.mseed.util._search_flag_in_blockette """ # Write dummy file npts = 2000 np.random.seed(42) # make test reproducible data = np.random.randint(-1000, 1000, npts).astype(np.int32) # This header ensures presence of blockettes 1000 and 1001 stat_header = { 'network': 'NE', 'station': 'STATI', 'location': 'LO', 'channel': 'CHA', 'npts': len(data), 'sampling_rate': 1, 'mseed': { 'dataquality': 'D', 'blkt1001': { 'timing_quality': 63 } } } stat_header['starttime'] = UTCDateTime( datetime(2012, 8, 1, 12, 0, 0, 42)) trace1 = Trace(data=data, header=stat_header) st = Stream([trace1]) with NamedTemporaryFile() as tf: st.write(tf, format="mseed", encoding=11, reclen=512) tf.seek(0, os.SEEK_SET) file_name = tf.name with open(file_name, "rb") as file_desc: file_desc.seek(0, os.SEEK_SET) # Test from file start read_bytes = util._search_flag_in_blockette( file_desc, 48, 1001, 4, 1) self.assertFalse(read_bytes is None) self.assertEqual(unpack(native_str(">B"), read_bytes)[0], 63) # Test from middle of a record header file_desc.seek(14, os.SEEK_CUR) file_pos = file_desc.tell() read_bytes = util._search_flag_in_blockette( file_desc, 34, 1000, 6, 1) self.assertFalse(read_bytes is None) self.assertEqual(unpack(native_str(">B"), read_bytes)[0], 9) # Check that file_desc position has not changed self.assertEqual(file_desc.tell(), file_pos) # Test from middle of a record data file_desc.seek(60, os.SEEK_CUR) read_bytes = util._search_flag_in_blockette( file_desc, -26, 1001, 5, 1) self.assertFalse(read_bytes is None) self.assertEqual(unpack(native_str(">B"), read_bytes)[0], 42) # Test another record. There is at least 3 records in a # mseed with 2000 data points and 512 bytes record length file_desc.seek(1040, os.SEEK_SET) read_bytes = util._search_flag_in_blockette( file_desc, 32, 1001, 4, 1) self.assertEqual(unpack(native_str(">B"), read_bytes)[0], 63) # Test missing blockette read_bytes = util._search_flag_in_blockette( file_desc, 32, 201, 4, 4) self.assertIs(read_bytes, None)
def test_set_flags_in_fixed_header(self): """ Test case for obspy.io.mseed.util.set_flags_in_fixed_headers """ # Write mseed file with several traces npts = 1000 np.random.seed(42) # make test reproducible data = np.random.randint(-1000, 1000, npts).astype(np.int32) # Test valid data stat_header = { 'network': 'NE', 'station': 'STATI', 'location': 'LO', 'channel': 'CHA', 'npts': len(data), 'sampling_rate': 1, 'mseed': { 'dataquality': 'D', 'blkt1001': { 'timing_quality': 63 } } } stat_header['starttime'] = UTCDateTime( datetime(2012, 8, 1, 12, 0, 0, 0)) trace1 = Trace(data=data, header=stat_header) stat_header['channel'] = 'CHB' trace2 = Trace(data=data, header=stat_header) stat_header['station'] = 'STATJ' trace3 = Trace(data=data, header=stat_header) st = Stream([trace1, trace2, trace3]) with NamedTemporaryFile() as tf: st.write(tf, format="mseed", encoding=11, reclen=512) tf.seek(0, os.SEEK_SET) file_name = tf.name # Initialize dummy flags with known binary value # Matching bytes are 0x15, 0x28, 0x88 classic_flags = { 'activity_flags': { 'calib_signal': True, 'begin_event': True, 'positive_leap': True, 'negative_leap': False }, 'io_clock_flags': { 'start_of_time_series': True, 'clock_locked': True }, 'data_qual_flags': { 'glitches_detected': True, 'time_tag_questionable': True } } expected_classic = pack(native_str('BBB'), 0x15, 0x28, 0x88) expected_leap_mod = pack(native_str('BBB'), 0x05, 0x28, 0x88) expected_glitch_mod = pack(native_str('BBB'), 0x15, 0x28, 0x88) # Test update all traces all_traces = {'...': copy.deepcopy(classic_flags)} set_flags_in_fixed_headers(file_name, all_traces) # Check that values changed self._check_values(tf, '...', [], expected_classic, 512) # Update one trace one_trace = {'NE.STATI.LO.CHA': copy.deepcopy(classic_flags)} cur_dict = one_trace['NE.STATI.LO.CHA']['activity_flags'] cur_dict['positive_leap'] = False set_flags_in_fixed_headers(file_name, one_trace) # Check that values changed self._check_values(tf, 'NE.STATI.LO.CHA', [], expected_leap_mod, 512) # Check that values that should not change, have not self._check_values(tf, 'NE.STATI.LO.CHB', [], expected_classic, 512) self._check_values(tf, 'NE.STATJ.LO.CHB', [], expected_classic, 512) # Put back previous values set_flags_in_fixed_headers(file_name, all_traces) # Update specific trace without paying attention to station name no_sta = {'NE..LO.CHB': copy.deepcopy(classic_flags)} no_sta['NE..LO.CHB']['activity_flags']['positive_leap'] = False set_flags_in_fixed_headers(file_name, no_sta) self._check_values(tf, 'NE.STATI.LO.CHA', [], expected_classic, 512) self._check_values(tf, 'NE.STATI.LO.CHB', [], expected_leap_mod, 512) self._check_values(tf, 'NE.STATJ.LO.CHB', [], expected_leap_mod, 512) # Put back previous values set_flags_in_fixed_headers(file_name, all_traces) # Wildcard plus specific traces wild_plus = { 'NE..LO.CHB': copy.deepcopy(classic_flags), 'NE.STATI.LO.CHB': copy.deepcopy(classic_flags) } wild_plus['NE..LO.CHB']['activity_flags']['positive_leap'] = False cur_dict = wild_plus['NE.STATI.LO.CHB']['data_qual_flags'] cur_dict['glitches_detected'] = True set_flags_in_fixed_headers(file_name, wild_plus) self._check_values(tf, 'NE.STATI.LO.CHA', [], expected_classic, 512) self._check_values(tf, 'NE.STATI.LO.CHB', [], expected_glitch_mod, 512) self._check_values(tf, 'NE.STATJ.LO.CHB', [], expected_leap_mod, 512) # Put back previous values set_flags_in_fixed_headers(file_name, all_traces) # Update trace not present in the file not_pres = {'NE.NOSTA.LO.CHA': copy.deepcopy(classic_flags)} cur_dict = not_pres['NE.NOSTA.LO.CHA']['data_qual_flags'] cur_dict['glitches_detected'] = False set_flags_in_fixed_headers(file_name, not_pres) self._check_values(tf, '...', [], expected_classic, 512) # Put back previous values set_flags_in_fixed_headers(file_name, all_traces) self._check_values(tf, '...', [], expected_classic, 512) # Non-existing flag values wrong_flag = {'...': copy.deepcopy(classic_flags)} wrong_flag['...']['activity_flags']['inexistent'] = True wrong_flag['...']['wrong_flag_group'] = {} wrong_flag['...']['wrong_flag_group']['inexistent_too'] = True self.assertRaises(ValueError, set_flags_in_fixed_headers, file_name, wrong_flag) # Put back previous values set_flags_in_fixed_headers(file_name, all_traces) # Test dated flags dated_flags = { 'activity_flags': { # calib should be at first record 'calib_signal': UTCDateTime("2012-08-01T12:00:30.0"), # begin event should be at second record 'begin_event': { "INSTANT": [ datetime(2012, 8, 1, 12, 13, 20, 0), datetime(2012, 8, 1, 12, 13, 20, 0) ] }, # positive leap should span from first to second record 'positive_leap': { "DURATION": [ UTCDateTime("2012-08-01T12:00:30.0"), datetime(2012, 8, 1, 12, 13, 20, 0) ] }, 'negative_leap': False } } expected_first = pack(native_str('BBB'), 0x11, 0x00, 0x00) expected_second = pack(native_str('BBB'), 0x10, 0x00, 0x00) expected_fourth = pack(native_str('BBB'), 0x14, 0x00, 0x00) expected_afterfourth = pack(native_str('BBB'), 0x00, 0x00, 0x00) # Test update all traces dated_traces = {'NE.STATI.LO.CHA': copy.deepcopy(dated_flags)} set_flags_in_fixed_headers(file_name, dated_traces) # Verification of the expected flags self._check_values(tf, 'NE.STATI.LO.CHA', [0], expected_first, 512) self._check_values(tf, 'NE.STATI.LO.CHA', [1, 2], expected_second, 512) self._check_values(tf, 'NE.STATI.LO.CHA', [3], expected_fourth, 512) self._check_values(tf, 'NE.STATI.LO.CHA', [10], expected_afterfourth, 512) # Incorrect trace identification wrong_trace = {'not_three_points': copy.deepcopy(classic_flags)} self.assertRaises(ValueError, set_flags_in_fixed_headers, file_name, wrong_trace)
def timeseries(self, network, station, location, channel, starttime, endtime, filter=[], filename=None, output='miniseed', **kwargs): """ Low-level interface for `timeseries` Web service of IRIS (http://service.iris.edu/irisws/timeseries/)- release 1.3.5 (2012-06-07). This method fetches segments of seismic data and returns data formatted in either MiniSEED, ASCII or SAC. It can optionally filter the data. **Channel and temporal constraints (required)** The four SCNL parameters (Station - Channel - Network - Location) are used to determine the channel of interest, and are all required. Wildcards are not accepted. :type network: str :param network: Network code, e.g. ``'IU'``. :type station: str :param station: Station code, e.g. ``'ANMO'``. :type location: str :param location: Location code, e.g. ``'00'`` :type channel: str :param channel: Channel code, e.g. ``'BHZ'``. :type starttime: :class:`~obspy.core.utcdatetime.UTCDateTime` :param starttime: Start date and time. :type endtime: :class:`~obspy.core.utcdatetime.UTCDateTime` :param endtime: End date and time. **Filter Options** The following parameters act as filters upon the time series. :type filter: list of str, optional :param filter: Filter list. List order matters because each filter operation is performed in the order given. For example ``filter=["demean", "lp=2.0"]`` will demean and then apply a low-pass filter, while ``filter=["lp=2.0", "demean"]`` will apply the low-pass filter first, and then demean. ``"taper=WIDTH,TYPE"`` Apply a time domain symmetric tapering function to the time series data. The width is specified as a fraction of the trace length from 0 to 0.5. The window types HANNING (default), HAMMING, or COSINE may be optionally followed, e.g. ``"taper=0.25"`` or ``"taper=0.5,COSINE"``. ``"envelope=true"`` Calculate the envelope of the time series. This calculation uses a Hilbert transform approximated by a time domain filter. ``"lp=FREQ"`` Low-pass filter the time-series using an IIR 4th order filter, using this value (in Hertz) as the cutoff, e.g. ``"lp=1.0"``. ``"hp=FREQ"`` High-pass filter the time-series using an IIR 4th order filter, using this value (in Hertz) as the cutoff, e.g. ``"hp=3.0"``. ``"bp=FREQ1,FREQ2"`` Band pass frequencies, in Hz, e.g. ``"bp=0.1,1.0"``. ``"demean"`` Remove mean value from data. ``"scale"`` Scale data samples by specified factor, e.g. ``"scale=2.0"`` If ``"scale=AUTO"``, the data will be scaled by the stage-zero gain. Cannot specify both ``scale`` and ``divscale``. Cannot specify both ``correct`` and ``scale=AUTO``. ``"divscale"`` Scale data samples by the inverse of the specified factor, e.g ``"divscale=2.0"``. You cannot specify both ``scale`` and ``divscale``. ``"correct"`` Apply instrument correction to convert to earth units. Uses either deconvolution or polynomial response correction. Cannot specify both ``correct`` and ``scale=AUTO``. Correction on > 10^7 samples will result in an error. At a sample rate of 20 Hz, 10^7 samples is approximately 5.8 days. ``"freqlimits=FREQ1,FREQ2,FREQ3,FREQ4"`` Specify an envelope for a spectrum taper for deconvolution, e.g. ``"freqlimits=0.0033,0.004,0.05,0.06"``. Frequencies are specified in Hertz. This cosine taper scales the spectrum from 0 to 1 between FREQ1 and FREQ2 and from 1 to 0 between FREQ3 and FREQ4. Can only be used with the correct option. Cannot be used in combination with the ``autolimits`` option. ``"autolimits=X,Y"`` Automatically determine frequency limits for deconvolution, e.g. ``"autolimits=3.0,3.0"``. A pass band is determined for all frequencies with the lower and upper corner cutoffs defined in terms of dB down from the maximum amplitude. This algorithm is designed to work with flat responses, i.e. a response in velocity for an instrument which is flat to velocity. Other combinations will likely result in unsatisfactory results. Cannot be used in combination with the ``freqlimits`` option. ``"units=UNIT"`` Specify output units. Can be DIS, VEL, ACC or DEF, where DEF results in no unit conversion, e.g. ``"units=VEL"``. Option ``units`` can only be used with ``correct``. ``"diff"`` Differentiate using 2 point (uncentered) method ``"int"`` Integrate using trapezoidal (midpoint) method ``"decimate=SAMPLERATE"`` Specify the sample-rate to decimate to, e.g. ``"decimate=2.0"``. The sample-rate of the source divided by the given sample-rate must be factorable by 2,3,4,7. **Miscelleneous options** :type filename: str, optional :param filename: Name of a output file. If this parameter is given nothing will be returned. Default is ``None``. :type output: str, optional :param output: Output format if parameter ``filename`` is used. ``'ascii'`` Data format, 1 column (values) ``'ascii2'`` ASCII data format, 2 columns (time, value) ``'ascii'`` Same as ascii2 ``'audio'`` audio WAV file ``'miniseed'`` IRIS MiniSEED format ``'plot'`` A simple plot of the time series ``'saca'`` SAC, ASCII format ``'sacbb'`` SAC, binary big-endian format ``'sacbl'`` SAC, binary little-endian format :rtype: :class:`~obspy.core.stream.Stream` or ``None`` :return: ObsPy Stream object if no ``filename`` is given. .. rubric:: Example >>> from obspy.clients.iris import Client >>> from obspy import UTCDateTime >>> dt = UTCDateTime("2005-01-01T00:00:00") >>> client = Client() >>> st = client.timeseries("IU", "ANMO", "00", "BHZ", dt, dt+10) >>> print(st[0].data) # doctest: +ELLIPSIS [ 24 20 19 19 19 15 10 4 -4 -11 ... >>> st = client.timeseries("IU", "ANMO", "00", "BHZ", dt, dt+10, ... filter=["correct", "demean", "lp=2.0"]) >>> print(st[0].data) # doctest: +ELLIPSIS [ -1.57488682e-06 -1.26318002e-06 -7.84807128e-07 ... """ kwargs['network'] = str(network) kwargs['station'] = str(station) if location: kwargs['location'] = str(location)[0:2] else: kwargs['location'] = '--' kwargs['channel'] = str(channel) # convert UTCDateTime to string for query kwargs['starttime'] = UTCDateTime(starttime).format_iris_web_service() kwargs['endtime'] = UTCDateTime(endtime).format_iris_web_service() # output if filename: kwargs['output'] = output else: kwargs['output'] = 'miniseed' # build up query try: data = self._fetch("timeseries", param_list=filter, **kwargs) except urllib_request.HTTPError as e: msg = "No waveform data available (%s: %s)" msg = msg % (e.__class__.__name__, e) raise Exception(msg) # write directly if file name is given if filename: return self._to_file_or_data(filename, data, True) # create temporary file for writing data with NamedTemporaryFile() as tf: tf.write(data) # read stream using obspy.io.mseed tf.seek(0) try: stream = read(tf.name, 'MSEED') except Exception: stream = Stream() return stream
def evalresp(self, network, station, location, channel, time=UTCDateTime(), minfreq=0.00001, maxfreq=None, nfreq=200, units='def', width=800, height=600, annotate=True, output='plot', filename=None, **kwargs): """ Low-level interface for `evalresp` Web service of IRIS (http://service.iris.edu/irisws/evalresp/) - release 1.0.0 (2011-08-11). This method evaluates instrument response information stored at the IRIS DMC and outputs ASCII data or `Bode Plots <https://en.wikipedia.org/wiki/Bode_plots>`_. :type network: str :param network: Network code, e.g. ``'IU'``. :type station: str :param station: Station code, e.g. ``'ANMO'``. :type location: str :param location: Location code, e.g. ``'00'``. Use ``'--'`` for empty location codes. :type channel: str :param channel: Channel code, e.g. ``'BHZ'``. :type time: :class:`~obspy.core.utcdatetime.UTCDateTime` :param time: Evaluate the response at the given time. If not specified, the current time is used. :type minfreq: float, optional :param minfreq: The minimum frequency (Hz) at which response will be evaluated. Must be positive and less than the ``maxfreq`` value. Defaults to ``0.00001`` Hz (1/day ~ 0.000012 Hz). :type maxfreq: float, optional :param maxfreq: The maximum frequency (Hz) at which response will be evaluated. Must be positive and greater than the ``minfreq`` value. Defaults to the channel sample-rate or the frequency of sensitivity, which ever is larger. :type nfreq: int, optional :param nfreq: Number frequencies at which response will be evaluated. Must be a positive integer no greater than ``10000``. The instrument response is evaluated on a equally spaced logarithmic scale. Defaults to ``200``. :type units: str, optional :param units: Output Unit. Defaults to ``'def'``. ``'def'`` default units indicated in response metadata ``'dis'`` converts to units of displacement ``'vel'`` converts to units of velocity ``'acc'`` converts to units of acceleration If units are not specified, then the units will default to those indicated in the response metadata :type width: int, optional :param width: The width of the generated plot. Defaults to ``800``. Can only be used with the ``output='plot'``, ``output='plot-amp'`` and ``output='plot-phase'`` options. Cannot be larger than ``5000`` and the product of width and height cannot be larger than ``6,000,000``. :type height: int, optional :param height: The height of the generated plot. Defaults to ``600``. Can only be used with the ``output='plot'``, ``output='plot-amp'`` and ``output='plot-phase'`` options. Cannot be larger than ``5000`` and the product of width and height cannot be larger than ``6,000,000``. :type annotate: bool, optional :param annotate: Can be either ``True`` or ``False``. Defaults to ``True``. * Draws vertical lines at the Nyquist frequency (one half the sample rate). * Draw a vertical line at the stage-zero frequency of sensitivity. * Draws a horizontal line at the stage-zero gain. Can only be used with the ``output='plot'``, ``output='plot-amp'`` and ``output='plot-phase'`` options. :type output: str :param output: Output Options. Defaults to ``'plot'``. ``'fap'`` Three column ASCII (frequency, amplitude, phase) ``'cs'`` Three column ASCII (frequency, real, imaginary) ``'plot'`` Amplitude and phase plot ``'plot-amp'`` Amplitude only plot ``'plot-phase'`` Phase only plot Plots are stored to the file system if the parameter ``filename`` is set, otherwise it will try to use matplotlib to directly plot the returned image. :type filename: str, optional :param filename: Name of a output file. If this parameter is given nothing will be returned. Default is ``None``. :rtype: :class:`numpy.ndarray`, str or `None` :returns: Returns either a NumPy :class:`~numpy.ndarray`, image string or nothing, depending on the ``output`` parameter. .. rubric:: Examples (1) Returning frequency, amplitude, phase of first point. >>> from obspy.clients.iris import Client >>> client = Client() >>> dt = UTCDateTime("2005-01-01") >>> data = client.evalresp("IU", "ANMO", "00", "BHZ", dt, ... output='fap') >>> data[0] # frequency, amplitude, phase of first point array([ 1.00000000e-05, 1.05599900e+04, 1.79200700e+02]) (2) Returning amplitude and phase plot. >>> from obspy.clients.iris import Client >>> client = Client() >>> dt = UTCDateTime("2005-01-01") >>> client.evalresp("IU", "ANMO", "00", "BHZ", dt) # doctest: +SKIP .. plot:: from obspy import UTCDateTime from obspy.clients.iris import Client client = Client() dt = UTCDateTime("2005-01-01") client.evalresp("IU", "ANMO", "00", "BHZ", dt) """ kwargs['network'] = str(network) kwargs['station'] = str(station) if location: kwargs['location'] = str(location)[0:2] else: kwargs['location'] = '--' kwargs['channel'] = str(channel) try: kwargs['time'] = UTCDateTime(time).format_iris_web_service() except Exception: kwargs['time'] = time kwargs['minfreq'] = float(minfreq) if maxfreq: kwargs['maxfreq'] = float(maxfreq) kwargs['nfreq'] = int(nfreq) if units in ['def', 'dis', 'vel', 'acc']: kwargs['units'] = units else: kwargs['units'] = 'def' if output in ['fap', 'cs', 'plot', 'plot-amp', 'plot-phase']: kwargs['output'] = output else: kwargs['output'] = 'plot' # height, width and annotate work only for plots if 'plot' in output: kwargs['width'] = int(width) kwargs['height'] = int(height) kwargs['annotate'] = bool(annotate) data = self._fetch("evalresp", **kwargs) # check output if 'plot' in output: # image if filename is None: # ugly way to show an image from matplotlib import image import matplotlib.pyplot as plt # create new figure fig = plt.figure() # new axes using full window ax = fig.add_axes([0, 0, 1, 1]) # need temporary file for reading into matplotlib with NamedTemporaryFile() as tf: tf.write(data) # force matplotlib to use internal PNG reader. image.imread # will use PIL if available img = image._png.read_png(tf.name) # add image to axis ax.imshow(img) # hide axes ax.axison = False # show plot plt.show() else: self._to_file_or_data(filename, data, binary=True) else: # ASCII data if filename is None: return np.loadtxt(io.BytesIO(data), ndmin=1) else: return self._to_file_or_data(filename, data, binary=True)
def test_writing_of_blockette_100(self): """ Tests the writing of blockette 100 if necessary. """ def has_blkt_100(filename): ms = _MSStruct(filename) ms.read(-1, 0, 1, 0) blkt_link = ms.msr.contents.blkts has_blkt_100 = False while True: try: if blkt_link.contents.blkt_type == 100: has_blkt_100 = True break blkt_link = blkt_link.contents.next except ValueError: break del ms return has_blkt_100 tr = read()[0] tr.data = tr.data[:10] with NamedTemporaryFile() as tf: tempfile = tf.name # A "clean" sampling rate does not require blockette 100. sr = 200.0 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertFalse(has_blkt_100(tempfile)) # A more detailed one does. sr = 199.9997 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertTrue(has_blkt_100(tempfile)) # A very large (but "clean") one does not need it. sr = 1E6 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertFalse(has_blkt_100(tempfile)) # Same for a very small but "clean" one. sr = 1E-6 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertFalse(has_blkt_100(tempfile)) # But small perturbations resulting in "unclean" sampling rates # will cause blockette 100 to be written. sr = 1E6 + 0.123456 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertTrue(has_blkt_100(tempfile)) sr = 1E-6 + 0.325247 * 1E-7 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertTrue(has_blkt_100(tempfile)) # Three more "clean" ones. sr = 1.0 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertFalse(has_blkt_100(tempfile)) sr = 0.5 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertFalse(has_blkt_100(tempfile)) sr = 0.1 tr.stats.sampling_rate = sr tr.write(tempfile, format="mseed") self.assertEqual(np.float32(read(tempfile)[0].stats.sampling_rate), np.float32(sr)) self.assertFalse(has_blkt_100(tempfile))
def getWaveformNSCL(self, seedname, starttime, duration): """ Gets a regular expression of channels from a start time for a duration in seconds. The regular expression must represent all characters of the 12-character NNSSSSSCCCLL pattern e.g. "US.....[BSHE]HZ.." is valid, but "US.....[BSHE]H" is not. Complex regular expressions are permitted "US.....BHZ..|CU.....[BH]HZ.." .. rubric:: Notes For detailed information regarding the usage of regular expressions in the query, see also the documentation for CWBQuery ("CWBQuery.doc") available at ftp://hazards.cr.usgs.gov/CWBQuery/. Using ".*" regular expression might or might not work. If the 12 character seed name regular expression is less than 12 characters it might get padded with spaces on the server side. :type seedname: str :param seedname: The 12 character seedname or 12 character regexp matching channels :type start: :class:`~obspy.core.utcdatetime.UTCDateTime` :param start: The starting date/time to get :type duration: float :param duration: The duration in seconds to get :rtype: :class:`~obspy.core.stream.Stream` :returns: Stream object with requested data .. rubric:: Example >>> from obspy.neic import Client >>> from obspy import UTCDateTime >>> client = Client() >>> t = UTCDateTime() - 5 * 3600 # 5 hours before now >>> st = client.getWaveformNSCL("IUANMO BH.00", t, 10) >>> print st # doctest: +ELLIPSIS 3 Trace(s) in Stream: IU.ANMO.00.BH... | 20.0 Hz, 201 samples IU.ANMO.00.BH... | 20.0 Hz, 201 samples IU.ANMO.00.BH... | 20.0 Hz, 201 samples """ start = str(UTCDateTime(starttime)).replace("T", " ").replace("Z", "") line = "'-dbg' '-s' '%s' '-b' '%s' '-d' '%s'\t" % \ (seedname, start, duration) if self.debug: print ascdate() + " " + asctime() + " line=" + line success = False while not success: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) with NamedTemporaryFile() as tf: if self.debug: print ascdate(), asctime(), "connecting temp file", \ tf.name s.connect((self.host, self.port)) s.setblocking(0) s.send(line) if self.debug: print ascdate(), asctime(), "Connected - start reads" slept = 0 maxslept = self.timeout / 0.05 totlen = 0 while True: try: data = s.recv(102400) if self.debug: print ascdate(), asctime(), "read len", \ str(len(data)), " total", str(totlen) if data.find("EOR") >= 0: if self.debug: print ascdate(), asctime(), "<EOR> seen" tf.write(data[0:data.find("<EOR>")]) totlen += len(data[0:data.find("<EOR>")]) tf.seek(0) try: st = read(tf.name, 'MSEED') except Exception, e: st = Stream() st.trim(starttime, starttime + duration) s.close() success = True break else: totlen += len(data) tf.write(data) slept = 0 except socket.error as e: if slept > maxslept: print ascdate(), asctime(), \ "Timeout on connection", \ "- try to reconnect" slept = 0 s.close() sleep(0.05) slept += 1
class Client(object): """ IRIS Web service request client. :type base_url: str, optional :param base_url: Base URL of the IRIS Web service (default is ``'http://service.iris.edu/irisws'``). :type user: str, optional :param user: The user name used for authentication with the Web service (default an empty string). :type password: str, optional :param password: A password used for authentication with the Web service (default is an empty string). :type timeout: int, optional :param timeout: Seconds before a connection timeout is raised (default is ``10`` seconds). This works only for Python >= 2.6.x. :type debug: bool, optional :param debug: Enables verbose output (default is ``False``). :type user_agent: str, optional :param user_agent: Sets an client identification string which may be used on server side for statistical analysis (default contains the current module version and basic information about the used operation system, e.g. ``'ObsPy 0.4.7.dev-r2432 (Windows-7-6.1.7601-SP1, Python 2.7.1)'``. :type major_versions: dict :param major_versions: Allows to specify custom major version numbers for individual services (e.g. `major_versions={'evalresp': 2, 'sacpz': 3}`), otherwise the latest version at time of implementation will be used. .. rubric:: Example >>> from obspy.iris import Client >>> client = Client() >>> result = client.distaz(stalat=1.1, stalon=1.2, evtlat=3.2, ... evtlon=1.4) >>> print(result['distance']) 2.09554 >>> print(result['backazimuth']) 5.46946 >>> print(result['azimuth']) 185.47692 """ def __init__(self, base_url="http://service.iris.edu/irisws", user="", password="", timeout=20, debug=False, user_agent=DEFAULT_USER_AGENT, major_versions={}): """ Initializes the IRIS Web service client. See :mod:`obspy.iris` for all parameters. """ self.base_url = base_url self.timeout = timeout self.debug = debug self.user_agent = user_agent self.major_versions = DEFAULT_SERVICE_VERSIONS self.major_versions.update(major_versions) # Create an OpenerDirector for Basic HTTP Authentication password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() password_mgr.add_password(None, base_url, user, password) auth_handler = urllib2.HTTPBasicAuthHandler(password_mgr) opener = urllib2.build_opener(auth_handler) # install globally urllib2.install_opener(opener) def _fetch(self, service, data=None, headers={}, param_list=[], **params): """ Send a HTTP request via urllib2. :type service: str :param service: Name of service :type data: str :param data: Channel list as returned by `availability` Web service :type headers: dict, optional :param headers: Additional header information for request """ headers['User-Agent'] = self.user_agent # replace special characters remoteaddr = "/".join([ self.base_url.rstrip("/"), service, str(self.major_versions[service]), "query" ]) options = '&'.join(param_list) if params: if options: options += '&' options += urllib.urlencode(params) if options: remoteaddr = "%s?%s" % (remoteaddr, options) if self.debug: print('\nRequesting %s' % (remoteaddr)) req = urllib2.Request(url=remoteaddr, data=data, headers=headers) response = urllib2.urlopen(req, timeout=self.timeout) doc = response.read() return doc def _toFileOrData(self, filename, data, binary=False): """ Either writes data into a file if filename is given or directly returns it. :type filename: String or open file-like object. :param filename: File or object being written to. If None, a string will be returned. :type data: String or Bytes :param data: The data being written or returned. :type binary: Boolean, optional :param binary: Whether to write the data as binary or text. Defaults to binary. """ if filename is None: return data if binary: method = 'wb' else: method = 'wt' file_opened = False # filename is given, create fh, write to file and return nothing if hasattr(filename, "write") and callable(filename.write): fh = filename elif isinstance(filename, basestring): fh = open(filename, method) file_opened = True else: msg = ("Parameter 'filename' must be either a string or an open " "file-like object.") raise TypeError(msg) try: fh.write(data) finally: # Only close if also opened. if file_opened is True: fh.close() def getWaveform(self, network, station, location, channel, starttime, endtime, quality='B'): """ SHUT DOWN ON SERVER SIDE! This service was shut down on the server side in december 2013, please use :mod:`obspy.fdsn` instead. Further information: http://www.iris.edu/dms/nodes/dmc/news/2013/03/\ new-fdsn-web-services-and-retirement-of-deprecated-services/ """ raise Exception(DEPR_WARNS['get_waveform']) def saveWaveform(self, filename, network, station, location, channel, starttime, endtime, quality='B'): """ SHUT DOWN ON SERVER SIDE! This service was shut down on the server side in december 2013, please use :mod:`obspy.fdsn` instead. Further information: http://www.iris.edu/dms/nodes/dmc/news/2013/03/\ new-fdsn-web-services-and-retirement-of-deprecated-services/ """ raise Exception(DEPR_WARNS['get_waveform']) def saveResponse(self, filename, network, station, location, channel, starttime, endtime, format='RESP'): """ SHUT DOWN ON SERVER SIDE! This service was shut down on the server side in december 2013, please use :mod:`obspy.fdsn` instead. Further information: http://www.iris.edu/dms/nodes/dmc/news/2013/03/\ new-fdsn-web-services-and-retirement-of-deprecated-services/ """ raise Exception(DEPR_WARNS['get_stations']) def getEvents(self, format='catalog', **kwargs): """ SHUT DOWN ON SERVER SIDE! This service was shut down on the server side in december 2013, please use :mod:`obspy.fdsn` instead. Further information: http://www.iris.edu/dms/nodes/dmc/news/2013/03/\ new-fdsn-web-services-and-retirement-of-deprecated-services/ """ raise Exception(DEPR_WARNS['get_events']) def timeseries(self, network, station, location, channel, starttime, endtime, filter=[], filename=None, output='miniseed', **kwargs): """ Low-level interface for `timeseries` Web service of IRIS (http://service.iris.edu/irisws/timeseries/)- release 1.3.5 (2012-06-07). This method fetches segments of seismic data and returns data formatted in either MiniSEED, ASCII or SAC. It can optionally filter the data. **Channel and temporal constraints (required)** The four SCNL parameters (Station - Channel - Network - Location) are used to determine the channel of interest, and are all required. Wildcards are not accepted. :type network: str :param network: Network code, e.g. ``'IU'``. :type station: str :param station: Station code, e.g. ``'ANMO'``. :type location: str :param location: Location code, e.g. ``'00'`` :type channel: str :param channel: Channel code, e.g. ``'BHZ'``. :type starttime: :class:`~obspy.core.utcdatetime.UTCDateTime` :param starttime: Start date and time. :type endtime: :class:`~obspy.core.utcdatetime.UTCDateTime` :param endtime: End date and time. **Filter Options** The following parameters act as filters upon the timeseries. :type filter: list of str, optional :param filter: Filter list. List order matters because each filter operation is performed in the order given. For example ``filter=["demean", "lp=2.0"]`` will demean and then apply a low-pass filter, while ``filter=["lp=2.0", "demean"]`` will apply the low-pass filter first, and then demean. ``"taper=WIDTH,TYPE"`` Apply a time domain symmetric tapering function to the timeseries data. The width is specified as a fraction of the trace length from 0 to 0.5. The window types HANNING (default), HAMMING, or COSINE may be optionally followed, e.g. ``"taper=0.25"`` or ``"taper=0.5,COSINE"``. ``"envelope=true"`` Calculate the envelope of the time series. This calculation uses a Hilbert transform approximated by a time domain filter. ``"lp=FREQ"`` Low-pass filter the time-series using an IIR 4th order filter, using this value (in Hertz) as the cutoff, e.g. ``"lp=1.0"``. ``"hp=FREQ"`` High-pass filter the time-series using an IIR 4th order filter, using this value (in Hertz) as the cutoff, e.g. ``"hp=3.0"``. ``"bp=FREQ1,FREQ2"`` Band pass frequencies, in Hz, e.g. ``"bp=0.1,1.0"``. ``"demean"`` Remove mean value from data. ``"scale"`` Scale data samples by specified factor, e.g. ``"scale=2.0"`` If ``"scale=AUTO"``, the data will be scaled by the stage-zero gain. Cannot specify both ``scale`` and ``divscale``. Cannot specify both ``correct`` and ``scale=AUTO``. ``"divscale"`` Scale data samples by the inverse of the specified factor, e.g ``"divscale=2.0"``. You cannot specify both ``scale`` and ``divscale``. ``"correct"`` Apply instrument correction to convert to earth units. Uses either deconvolution or polynomial response correction. Cannot specify both ``correct`` and ``scale=AUTO``. Correction on > 10^7 samples will result in an error. At a sample rate of 20 Hz, 10^7 samples is approximately 5.8 days. ``"freqlimits=FREQ1,FREQ2,FREQ3,FREQ4"`` Specify an envelope for a spectrum taper for deconvolution, e.g. ``"freqlimits=0.0033,0.004,0.05,0.06"``. Frequencies are specified in Hertz. This cosine taper scales the spectrum from 0 to 1 between FREQ1 and FREQ2 and from 1 to 0 between FREQ3 and FREQ4. Can only be used with the correct option. Cannot be used in combination with the ``autolimits`` option. ``"autolimits=X,Y"`` Automatically determine frequency limits for deconvolution, e.g. ``"autolimits=3.0,3.0"``. A pass band is determined for all frequencies with the lower and upper corner cutoffs defined in terms of dB down from the maximum amplitude. This algorithm is designed to work with flat responses, i.e. a response in velocity for an instrument which is flat to velocity. Other combinations will likely result in unsatisfactory results. Cannot be used in combination with the ``freqlimits`` option. ``"units=UNIT"`` Specify output units. Can be DIS, VEL, ACC or DEF, where DEF results in no unit conversion, e.g. ``"units=VEL"``. Option ``units`` can only be used with ``correct``. ``"diff"`` Differentiate using 2 point (uncentered) method ``"int"`` Integrate using trapezoidal (midpoint) method ``"decimate=SAMPLERATE"`` Specify the sample-rate to decimate to, e.g. ``"decimate=2.0"``. The sample-rate of the source divided by the given sample-rate must be factorable by 2,3,4,7. **Miscelleneous options** :type filename: str, optional :param filename: Name of a output file. If this parameter is given nothing will be returned. Default is ``None``. :type output: str, optional :param output: Output format if parameter ``filename`` is used. ``'ascii'`` Data format, 1 column (values) ``'ascii2'`` ASCII data format, 2 columns (time, value) ``'ascii'`` Same as ascii2 ``'audio'`` audio WAV file ``'miniseed'`` IRIS miniSEED format ``'plot'`` A simple plot of the timeseries ``'saca'`` SAC, ASCII format ``'sacbb'`` SAC, binary big-endian format ``'sacbl'`` SAC, binary little-endian format :rtype: :class:`~obspy.core.stream.Stream` or ``None`` :return: ObsPy Stream object if no ``filename`` is given. .. rubric:: Example >>> from obspy.iris import Client >>> from obspy import UTCDateTime >>> dt = UTCDateTime("2005-01-01T00:00:00") >>> client = Client() >>> st = client.timeseries("IU", "ANMO", "00", "BHZ", dt, dt+10) >>> print(st[0].data) # doctest: +ELLIPSIS [ 24 20 19 19 19 15 10 4 -4 -11 ... >>> st = client.timeseries("IU", "ANMO", "00", "BHZ", dt, dt+10, ... filter=["correct", "demean", "lp=2.0"]) >>> print(st[0].data) # doctest: +ELLIPSIS [ -1.38267058e-06 -1.10900783e-06 -6.89020794e-07 ... """ kwargs['network'] = str(network) kwargs['station'] = str(station) if location: kwargs['location'] = str(location)[0:2] else: kwargs['location'] = '--' kwargs['channel'] = str(channel) # convert UTCDateTime to string for query kwargs['starttime'] = UTCDateTime(starttime).formatIRISWebService() kwargs['endtime'] = UTCDateTime(endtime).formatIRISWebService() # output if filename: kwargs['output'] = output else: kwargs['output'] = 'miniseed' # build up query try: data = self._fetch("timeseries", param_list=filter, **kwargs) except HTTPError, e: msg = "No waveform data available (%s: %s)" msg = msg % (e.__class__.__name__, e) raise Exception(msg) # write directly if filename is given if filename: return self._toFileOrData(filename, data, True) # create temporary file for writing data with NamedTemporaryFile() as tf: tf.write(data) # read stream using obspy.mseed tf.seek(0) try: stream = read(tf.name, 'MSEED') except: stream = Stream() return stream
def test_issue296(self): """ Tests issue #296. """ with NamedTemporaryFile() as tf: tempfile = tf.name # 1 - transform to np.float64 values st = read() for tr in st: tr.data = tr.data.astype(np.float64) # write a single trace automatically detecting encoding st[0].write(tempfile, format="MSEED") # write a single trace automatically detecting encoding st.write(tempfile, format="MSEED") # write a single trace with encoding 5 st[0].write(tempfile, format="MSEED", encoding=5) # write a single trace with encoding 5 st.write(tempfile, format="MSEED", encoding=5) # 2 - transform to np.float32 values st = read() for tr in st: tr.data = tr.data.astype(np.float32) # write a single trace automatically detecting encoding st[0].write(tempfile, format="MSEED") # write a single trace automatically detecting encoding st.write(tempfile, format="MSEED") # write a single trace with encoding 4 st[0].write(tempfile, format="MSEED", encoding=4) # write a single trace with encoding 4 st.write(tempfile, format="MSEED", encoding=4) # 3 - transform to np.int32 values st = read() for tr in st: tr.data = tr.data.astype(np.int32) # write a single trace automatically detecting encoding st[0].write(tempfile, format="MSEED") # write a single trace automatically detecting encoding st.write(tempfile, format="MSEED") # write a single trace with encoding 3 st[0].write(tempfile, format="MSEED", encoding=3) # write the whole stream with encoding 3 st.write(tempfile, format="MSEED", encoding=3) # write a single trace with encoding 10 st[0].write(tempfile, format="MSEED", encoding=10) # write the whole stream with encoding 10 st.write(tempfile, format="MSEED", encoding=10) # write a single trace with encoding 11 st[0].write(tempfile, format="MSEED", encoding=11) # write the whole stream with encoding 11 st.write(tempfile, format="MSEED", encoding=11) # 4 - transform to np.int16 values st = read() for tr in st: tr.data = tr.data.astype(np.int16) # write a single trace automatically detecting encoding st[0].write(tempfile, format="MSEED") # write a single trace automatically detecting encoding st.write(tempfile, format="MSEED") # write a single trace with encoding 1 st[0].write(tempfile, format="MSEED", encoding=1) # write the whole stream with encoding 1 st.write(tempfile, format="MSEED", encoding=1) # 5 - transform to ASCII values st = read() for tr in st: tr.data = tr.data.astype(native_str('|S1')) # write a single trace automatically detecting encoding st[0].write(tempfile, format="MSEED") # write a single trace automatically detecting encoding st.write(tempfile, format="MSEED") # write a single trace with encoding 0 st[0].write(tempfile, format="MSEED", encoding=0) # write the whole stream with encoding 0 st.write(tempfile, format="MSEED", encoding=0)
from obspy.fdsn import Client as FDSN_Client from obspy.iris import Client as OldIris_Client from obspy.core import UTCDateTime from obspy.core.util import NamedTemporaryFile import matplotlib.pyplot as plt # MW 7.1 Darfield earthquake, New Zealand t1 = UTCDateTime("2010-09-3T16:30:00.000") t2 = UTCDateTime("2010-09-3T17:00:00.000") # Fetch waveform from IRIS FDSN web service into a ObsPy stream object fdsn_client = FDSN_Client("IRIS") st = fdsn_client.get_waveforms('NZ', 'BFZ', '10', 'HHZ', t1, t2) # Download and save instrument response file into a temporary file with NamedTemporaryFile() as tf: respf = tf.name old_iris_client = OldIris_Client() # fetch RESP information from "old" IRIS web service, see obspy.fdsn # for accessing the new IRIS FDSN web services old_iris_client.resp('NZ', 'BFZ', '10', 'HHZ', t1, t2, filename=respf) # make a copy to keep our original data st_orig = st.copy() # define a filter band to prevent amplifying noise during the deconvolution pre_filt = (0.005, 0.006, 30.0, 35.0) # this can be the date of your raw data or any date for which the # SEED RESP-file is valid date = t1
def getWaveform(self, network, station, location, channel, starttime, endtime, format="MSEED"): """ Retrieves waveform data from the NERIES Web service and returns a ObsPy Stream object. :type network: str :param network: Network code, e.g. ``'BW'``. :type station: str :param station: Station code, e.g. ``'MANZ'``. :type location: str :param location: Location code, e.g. ``'01'``. Location code may contain wild cards. :type channel: str :param channel: Channel code, e.g. ``'EHE'``. . Channel code may contain wild cards. :type starttime: :class:`~obspy.core.utcdatetime.UTCDateTime` :param starttime: Start date and time. :type endtime: :class:`~obspy.core.utcdatetime.UTCDateTime` :param endtime: End date and time. :type format: ``'FSEED'`` or ``'MSEED'``, optional :param format: Output format. Either as full SEED (``'FSEED'``) or Mini-SEED (``'MSEED'``) volume. Defaults to ``'MSEED'``. :return: ObsPy :class:`~obspy.core.stream.Stream` object. .. rubric:: Example >>> from obspy.neries import Client >>> client = Client(user='******') >>> dt = UTCDateTime("2009-04-01T00:00:00") >>> st = client.getWaveform("NL", "WIT", "", "BH*", dt, dt+30) >>> print st # doctest: +ELLIPSIS 3 Trace(s) in Stream: NL.WIT..BHZ | 2009-04-01T00:00:00.010200Z - ... | 40.0 Hz, 1201 samples NL.WIT..BHN | 2009-04-01T00:00:00.010200Z - ... | 40.0 Hz, 1201 samples NL.WIT..BHE | 2009-04-01T00:00:00.010200Z - ... | 40.0 Hz, 1201 samples """ with NamedTemporaryFile() as tf: self.saveWaveform(tf._fileobj, network, station, location, channel, starttime, endtime, format=format) # read stream using obspy.mseed tf.seek(0) try: stream = read(tf.name, 'MSEED') except: stream = Stream() # trim stream stream.trim(starttime, endtime) return stream
def read_events(pathname_or_url=None, format=None, **kwargs): """ Read event files into an ObsPy Catalog object. The :func:`~obspy.core.event.read_events` function opens either one or multiple event files given via file name or URL using the ``pathname_or_url`` attribute. :type pathname_or_url: str or StringIO.StringIO :param pathname_or_url: String containing a file name or a URL or a open file-like object. Wildcards are allowed for a file name. If this attribute is omitted, an example :class:`~obspy.core.event.Catalog` object will be returned. :type format: str :param format: Format of the file to read (e.g. ``"QUAKEML"``). See the `Supported Formats`_ section below for a list of supported formats. :rtype: :class:`~obspy.core.event.Catalog` :return: An ObsPy :class:`~obspy.core.event.Catalog` object. .. rubric:: _`Supported Formats` Additional ObsPy modules extend the functionality of the :func:`~obspy.core.event.read_events` function. The following table summarizes all known file formats currently supported by ObsPy. Please refer to the `Linked Function Call`_ of each module for any extra options available at the import stage. %s Next to the :func:`~obspy.core.event.read_events` function the :meth:`~obspy.core.event.Catalog.write` method of the returned :class:`~obspy.core.event.Catalog` object can be used to export the data to the file system. """ if pathname_or_url is None: # if no pathname or URL specified, return example catalog return _create_example_catalog() elif not isinstance(pathname_or_url, (str, native_str)): # not a string - we assume a file-like object try: # first try reading directly catalog = _read(pathname_or_url, format, **kwargs) except TypeError: # if this fails, create a temporary file which is read directly # from the file system pathname_or_url.seek(0) with NamedTemporaryFile() as fh: fh.write(pathname_or_url.read()) catalog = _read(fh.name, format, **kwargs) return catalog elif isinstance(pathname_or_url, bytes) and \ pathname_or_url.strip().startswith(b'<'): # XML string return _read(io.BytesIO(pathname_or_url), format, **kwargs) elif "://" in pathname_or_url[:10]: # URL # extract extension if any suffix = os.path.basename(pathname_or_url).partition('.')[2] or '.tmp' with NamedTemporaryFile(suffix=suffix) as fh: download_to_file(url=pathname_or_url, filename_or_buffer=fh) catalog = _read(fh.name, format, **kwargs) return catalog else: pathname = pathname_or_url # File name(s) pathnames = sorted(glob.glob(pathname)) if not pathnames: # try to give more specific information why the stream is empty if glob.has_magic(pathname) and not glob.glob(pathname): raise Exception("No file matching file pattern: %s" % pathname) elif not glob.has_magic(pathname) and not os.path.isfile(pathname): raise IOError(2, "No such file or directory", pathname) catalog = _read(pathnames[0], format, **kwargs) if len(pathnames) > 1: for filename in pathnames[1:]: catalog.extend(_read(filename, format, **kwargs).events) ResourceIdentifier.bind_resource_ids() return catalog
def test_evalresp(self): """ Tests evaluating instrument response information. """ client = Client() dt = UTCDateTime("2005-01-01") # plot as PNG file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='plot', filename=tempfile) with open(tempfile, 'rb') as fp: self.assertEqual(fp.read(4)[1:4], b'PNG') # plot-amp as PNG file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='plot-amp', filename=tempfile) with open(tempfile, 'rb') as fp: self.assertEqual(fp.read(4)[1:4], b'PNG') # plot-phase as PNG file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='plot-phase', filename=tempfile) with open(tempfile, 'rb') as fp: self.assertEqual(fp.read(4)[1:4], b'PNG') # fap as ASCII file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', filename=tempfile) with open(tempfile, 'rt') as fp: self.assertEqual(fp.readline(), '1.000000E-05 1.055934E+04 1.792007E+02\n') # cs as ASCII file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='cs', filename=tempfile) with open(tempfile, 'rt') as fp: self.assertEqual( fp.readline(), '1.000000E-05 -1.055831E+04 1.472963E+02\n') # fap & def as ASCII file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='def', filename=tempfile) with open(tempfile, 'rt') as fp: self.assertEqual(fp.readline(), '1.000000E-05 1.055934E+04 1.792007E+02\n') # fap & dis as ASCII file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='dis', filename=tempfile) with open(tempfile, 'rt') as fp: self.assertEqual(fp.readline(), '1.000000E-05 6.634627E-01 2.692007E+02\n') # fap & vel as ASCII file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='vel', filename=tempfile) with open(tempfile, 'rt') as fp: self.assertEqual(fp.readline(), '1.000000E-05 1.055934E+04 1.792007E+02\n') # fap & acc as ASCII file with NamedTemporaryFile() as tf: tempfile = tf.name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='acc', filename=tempfile) with open(tempfile, 'rt') as fp: self.assertEqual(fp.readline(), '1.000000E-05 1.680571E+08 8.920073E+01\n') # fap as NumPy ndarray data = client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap') np.testing.assert_array_equal( data[0], [1.00000000e-05, 1.05593400e+04, 1.79200700e+02]) # cs as NumPy ndarray data = client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='cs') np.testing.assert_array_equal( data[0], [1.00000000e-05, -1.05583100e+04, 1.472963e+02])
def test_write_ah1(self): """ Testing writing AH1 file format using _write_ah1() function. """ # AH v1 testfile = os.path.join(self.path, 'st.ah') stream_orig = _read_ah(testfile) with NamedTemporaryFile() as tf: tmpfile = tf.name + '.AH' # write testfile _write_ah1(stream_orig, tmpfile) # read again st = _read_ah1(tmpfile) self.assertEqual(len(st), 1) tr = st[0] ah = tr.stats.ah stats = tr.stats # stream header self.assertEqual(stats.network, '') self.assertEqual(stats.station, 'ALE') self.assertEqual(stats.location, '') self.assertEqual(stats.channel, 'VHZ') starttime = UTCDateTime(1994, 6, 9, 0, 40, 45) endtime = UTCDateTime(1994, 6, 12, 8, 55, 4, 724522) self.assertEqual(stats.starttime, starttime) self.assertEqual(stats.endtime, endtime) self.assertAlmostEqual(stats.sampling_rate, 0.100000, 6) self.assertAlmostEqual(stats.delta, 9.999990, 6) self.assertEqual(stats.npts, 28887) self.assertEqual(len(tr), 28887) self.assertEqual(stats.calib, 1.0) # station self.assertEqual(ah.version, '1.0') self.assertEqual(ah.station.code, 'ALE') self.assertEqual(ah.station.channel, 'VHZ') self.assertEqual(ah.station.type, 'Global S') self.assertEqual(ah.station.latitude, 82.50330352783203) self.assertEqual(ah.station.longitude, -62.349998474121094) self.assertEqual(ah.station.elevation, 60.0) self.assertEqual(ah.station.gain, 265302864.0) self.assertEqual(len(ah.station.poles), 13) self.assertEqual(len(ah.station.zeros), 6) # event self.assertEqual(ah.event.latitude, -13.872200012207031) self.assertEqual(ah.event.longitude, -67.51249694824219) self.assertEqual(ah.event.depth, 640000.0) origintime = UTCDateTime(1994, 6, 9, 0, 33, 16) self.assertEqual(ah.event.origin_time, origintime) self.assertEqual(ah.event.comment, 'null') # record self.assertEqual(ah.record.type, 1) self.assertEqual(ah.record.ndata, 28887) self.assertEqual(tr.data.dtype, np.float64) self.assertAlmostEqual(ah.record.delta, 9.999990, 6) self.assertEqual(ah.record.max_amplitude, 9.265750885009766) rstarttime = UTCDateTime(1994, 6, 9, 0, 40, 45) self.assertEqual(ah.record.start_time, rstarttime) comment = 'Comp azm=0.0,inc=-90.0; Disp (m);' self.assertEqual(ah.record.comment, comment) self.assertEqual(ah.record.log, 'null') # data np.testing.assert_array_almost_equal( tr.data[:4], np.array([-236., -242., -252., -262.])) np.testing.assert_array_almost_equal( tr.data[-4:], np.array([101., 106., 107., 104.]))
from obspy.core import UTCDateTime from obspy.core.util import NamedTemporaryFile import matplotlib.pyplot as plt import numpy as np import os # MW 7.1 Darfield earthquake, New Zealand t1 = UTCDateTime("2010-09-3T16:30:00.000") t2 = UTCDateTime("2010-09-3T17:00:00.000") # Fetch waveform from IRIS web service into a ObsPy stream object client = Client() st = client.getWaveform('NZ', 'BFZ', '10', 'HHZ', t1, t2) # Download and save instrument response file into a temporary file respf = NamedTemporaryFile().name client.saveResponse(respf, 'NZ', 'BFZ', '10', 'HHZ', t1, t2, format="RESP") # make a copy to keep our original data st_orig = st.copy() # define a filter band to prevent amplifying noise during the deconvolution fl1 = 0.005 fl2 = 0.006 fl3 = 30. fl4 = 35. # this can be the date of your raw data or any date for which the # SEED RESP-file is valid date = t1
def test_evalresp(self): """ Tests evaluating instrument response information. """ client = Client() dt = UTCDateTime("2005-01-01") # plot as PNG file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='plot', filename=tempfile) self.assertEqual(open(tempfile, 'rb').read(4)[1:4], 'PNG') os.remove(tempfile) # plot-amp as PNG file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='plot-amp', filename=tempfile) self.assertEqual(open(tempfile, 'rb').read(4)[1:4], 'PNG') os.remove(tempfile) # plot-phase as PNG file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='plot-phase', filename=tempfile) self.assertEqual(open(tempfile, 'rb').read(4)[1:4], 'PNG') os.remove(tempfile) # fap as ASCII file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', filename=tempfile) self.assertEqual( open(tempfile, 'rt').readline(), '1.000000E-05 1.202802E+04 1.792007E+02\n') os.remove(tempfile) # cs as ASCII file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='cs', filename=tempfile) self.assertEqual( open(tempfile, 'rt').readline(), '1.000000E-05 -1.202685E+04 1.677835E+02\n') os.remove(tempfile) # fap & def as ASCII file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='def', filename=tempfile) self.assertEqual( open(tempfile, 'rt').readline(), '1.000000E-05 1.202802E+04 1.792007E+02\n') os.remove(tempfile) # fap & dis as ASCII file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='dis', filename=tempfile) self.assertEqual( open(tempfile, 'rt').readline(), '1.000000E-05 7.557425E-01 2.692007E+02\n') os.remove(tempfile) # fap & vel as ASCII file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='vel', filename=tempfile) self.assertEqual( open(tempfile, 'rt').readline(), '1.000000E-05 1.202802E+04 1.792007E+02\n') os.remove(tempfile) # fap & acc as ASCII file tempfile = NamedTemporaryFile().name client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap', units='acc', filename=tempfile) self.assertEqual( open(tempfile, 'rt').readline(), '1.000000E-05 1.914318E+08 8.920073E+01\n') os.remove(tempfile) # fap as NumPy ndarray data = client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='fap') np.testing.assert_array_equal( data[0], [1.00000000e-05, 1.20280200e+04, 1.79200700e+02]) # cs as NumPy ndarray data = client.evalresp(network="IU", station="ANMO", location="00", channel="BHZ", time=dt, output='cs') np.testing.assert_array_equal( data[0], [1.00000000e-05, -1.20268500e+04, 1.67783500e+02])