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 create_trace(self, station_to_cut, mp=False): station_to_cut_segments = PH5toMSeed.get_nonrestricted_segments( [station_to_cut], self.restricted) obspy_stream = Stream() for stc in station_to_cut_segments: das = self.ph5.query_das_t(stc.das, stc.component, stc.starttime, stc.endtime, stc.sample_rate, stc.sample_rate_multiplier) if not das: return das = [x for x in das] Das_tf = next(iter(das or []), None) if Das_tf is None: return else: das_t_start = (float(Das_tf['time/epoch_l']) + float(Das_tf['time/micro_seconds_i']) / 1000000) if float(das_t_start) > float(stc.starttime): start_time = das_t_start else: start_time = stc.starttime nt = stc.notimecorrect if stc.sample_rate > 0: actual_sample_rate = float( stc.sample_rate) / float(stc.sample_rate_multiplier) else: actual_sample_rate = 0 if stc.sample_rate != 0: traces = self.ph5.cut(stc.das, start_time, stc.endtime, chan=stc.component, sample_rate=actual_sample_rate, apply_time_correction=nt, das_t=das) else: traces = self.ph5.textural_cut(stc.das, start_time, stc.endtime, chan=stc.component, das_t=das) if not isinstance(traces, list): return for trace in traces: if trace.nsamples == 0: continue try: obspy_trace = Trace(data=trace.data) except ValueError: continue if self.format == "SAC": Receiver_t = \ self.ph5.get_receiver_t_by_n_i(stc.receiver_n_i) azimuth = Receiver_t['orientation/azimuth/value_f'] dip = Receiver_t['orientation/dip/value_f'] obspy_trace.stats.sac = {'kstnm': stc.seed_station, 'kcmpnm': stc.seed_channel, 'knetwk': stc.net_code, 'stla': float(stc.latitude), 'stlo': float(stc.longitude), 'stel': float(stc.elev), 'cmpaz': float(azimuth), 'cmpinc': float(dip)} elif self.format == "GEOCSV": Receiver_t = \ self.ph5.get_receiver_t_by_n_i(stc.receiver_n_i) azimuth = Receiver_t['orientation/azimuth/value_f'] dip = Receiver_t['orientation/dip/value_f'] obspy_trace.stats.sensor_type = stc.sensor_type obspy_trace.stats.elevation = float(stc.elev) obspy_trace.stats.dip = float(dip) obspy_trace.stats.depth = 0 obspy_trace.stats.back_azimuth = azimuth obspy_trace.stats.experiment_id = stc.experiment_id obspy_trace.stats.component = stc.component obspy_trace.stats.response = self.get_response_obj(stc) obspy_trace.stats.array = stc.array_code elif self.format.upper() == "SEGY1" or \ self.format.upper() == "SEGY2": # These values are used to create the SEG-Y headers obspy_trace.stats.receiver_id = stc.station obspy_trace.stats.ttype = trace.ttype obspy_trace.stats.byteorder = trace.byteorder obspy_trace.stats.elevation = float(stc.elev) obspy_trace.stats.component = stc.component obspy_trace.stats.response = self.get_response_obj(stc) obspy_trace.stats.array = stc.array_code obspy_trace.stats.das = stc.das obspy_trace.stats.shot_id = stc.shot_id obspy_trace.stats.shot_lat = stc.shot_lat obspy_trace.stats.shot_lng = stc.shot_lng obspy_trace.stats.shot_elevation = stc.shot_elevation obspy_trace.stats.sampling_rate = actual_sample_rate obspy_trace.stats.location = stc.location obspy_trace.stats.station = stc.seed_station obspy_trace.stats.coordinates = AttribDict() obspy_trace.stats.coordinates.latitude = stc.latitude obspy_trace.stats.coordinates.longitude = stc.longitude obspy_trace.stats.channel = stc.seed_channel obspy_trace.stats.network = stc.net_code obspy_trace.stats.starttime = trace.start_time.getFdsnTime() if self.decimation: obspy_trace.decimate(int(self.decimation)) obspy_stream.append(obspy_trace) if len(obspy_stream.traces) < 1: return return obspy_stream
def main(): usage = 'usage: %prog [options] sac_file(s)' parser = OptionParser(usage=usage) parser.add_option('-m', '--maxfreq', dest='maxfreq', action='store', type='float', default=None, help='Maximum frequency (hz) to calculate the ' 'S-transform. If not specified, Nyquist ' 'frequence is used') parser.add_option('-d', '--downsample', dest='downsample', action='store_true', default=False, help='Downsample data if the Nyquist is higher than ' 'the max frequency') parser.add_option('-r', '--reffiled', dest='reffield', action='store', default=None, help='Reference (zero) field for plotting and/or ' 'cutting traces') parser.add_option('-s', '--startcut', dest='startcut', action='store', type='float', default=None, help='Cut start time (in sec) respect to ' 'reference field') parser.add_option('-e', '--endcut', dest='endcut', action='store', type='float', default=None, help='Cut end time (in sec) respect to reference field') parser.add_option('-f', '--factor', dest='decimation_factor', action='store', type='int', default=1, help='Factor for decimating the S-transform graph. ' '(Useful to speed-up plotting)') parser.add_option('-a', '--ascii', dest='ascii', action='store_true', default=False, help='Data file is in ascii format (two columns, ' 'time/amplitude)') (options, args) = parser.parse_args() if len(args) < 1: parser.print_usage(file=sys.stderr) sys.stderr.write("\tUse '-h' for help\n\n") sys.exit(1) for sacfile in args: print(sacfile) if options.ascii: data = np.loadtxt(sacfile) time = data[:, 0] amplitude = data[:, 1] tr = Trace(amplitude) tr.stats.delta = time[1] - time[0] else: try: tr, = read(sacfile, format='SAC') except Exception as message: print(message) next # Calculate nyquist and do downsampling, if required stats = tr.stats delta = stats.delta fny = 1. / (2*delta) if options.maxfreq: if fny > options.maxfreq: if options.downsample: newdelta = fny/options.maxfreq * delta dsample = int(np.floor(newdelta/delta)) delta = delta * dsample fny = 1./(2*delta) tr.decimate(factor=dsample) else: fny = options.maxfreq # Cut data, if required if options.startcut: if not options.reffield: sys.stderr.write('Error: you must specify a reference field ' '(option -r)\n') sys.exit(1) if not options.endcut: sys.stderr.write('Error: you must specify a end cut time ' '(option -e)\n') sys.exit(1) tstart = stats.starttime + stats.sac[options.reffield] -\ stats.sac.b + options.startcut tend = tstart + options.endcut print(tstart, tend, stats.sac.b, stats.sac.a) tr.trim(tstart, tend) #stats.sac[options.reffield] = stats.sac.b - options.startcut #stats.sac.b = 0 data = tr.data # remove mean data -= data.mean() # normalize trace norm = np.max((data.max(), -data.min())) data /= norm df = 1/(delta*len(data)) # frequency step low = 0 # lowest frequency for the S-Transform nfreq = int(np.ceil(fny/df)) # number of discrete frequencies # Stockwell file name basename = os.path.basename(sacfile) stock_file_name = basename + '.stock.npy' # If we have a transform saved to disk, we don't recalculate it try: stock = np.load(stock_file_name) print('File %s loaded' % stock_file_name) except Exception: #Stockwell transform stock = st.st(data, low, nfreq) stock = np.flipud(stock) #Save transform to disk if save_stockwell: np.save(stock_file_name, stock) #if stockwell_stack == None: # stockwell_stack = stock #else: # stockwell_stack += stock reftime = 0 if options.reffield: try: reftime = stats.sac[options.reffield] - stats.sac.b except Exception as message: sys.stderr.write(message) plot_stockwell(data, delta, reftime, stock, df, sacfile, options.decimation_factor)
def create_trace(self, station_to_cut, mp=False): station_to_cut_segments = PH5toMSeed.get_nonrestricted_segments( [station_to_cut], self.restricted) obspy_stream = Stream() for stc in station_to_cut_segments: new_endtime = stc.endtime + (1 / float(stc.sample_rate)) self.ph5.read_das_t(stc.das, stc.starttime, stc.endtime, reread=False) if stc.das not in self.ph5.Das_t: return Das_t = ph5api.filter_das_t(self.ph5.Das_t[stc.das]['rows'], stc.component) Das_t = [x for x in Das_t] Das_tf = next(iter(Das_t or []), None) if Das_tf is None: return else: das_t_start = (float(Das_tf['time/epoch_l']) + float(Das_tf['time/micro_seconds_i']) / 1000000) if float(das_t_start) > float(stc.starttime): start_time = das_t_start else: start_time = stc.starttime nt = stc.notimecorrect actual_sample_rate = float( stc.sample_rate) / float(stc.sample_rate_multiplier) traces = self.ph5.cut(stc.das, start_time, new_endtime, chan=stc.component, sample_rate=actual_sample_rate, apply_time_correction=nt, das_t=Das_t) if not isinstance(traces, list): return for trace in traces: if trace.nsamples == 0: continue # if start time is before requested start time move up 1 sample # and delete first sample of data if trace.start_time.epoch() < stc.starttime: trace.start_time = trace.start_time + \ (1 / float(stc.sample_rate)) trace.data = trace.data[1:] try: obspy_trace = Trace(data=trace.data) except ValueError: continue if self.format == "SAC": Receiver_t = \ self.ph5.get_receiver_t_by_n_i(stc.receiver_n_i) azimuth = Receiver_t['orientation/azimuth/value_f'] dip = Receiver_t['orientation/dip/value_f'] obspy_trace.stats.sac = {'kstnm': stc.seed_station, 'kcmpnm': stc.seed_channel, 'knetwk': stc.net_code, 'stla': float(stc.latitude), 'stlo': float(stc.longitude), 'stel': float(stc.elev), 'cmpaz': float(azimuth), 'cmpinc': float(dip)} elif self.format == "GEOCSV": Receiver_t = \ self.ph5.get_receiver_t_by_n_i(stc.receiver_n_i) azimuth = Receiver_t['orientation/azimuth/value_f'] dip = Receiver_t['orientation/dip/value_f'] obspy_trace.stats.sensor_type = stc.sensor_type obspy_trace.stats.elevation = float(stc.elev) obspy_trace.stats.dip = float(dip) obspy_trace.stats.depth = 0 obspy_trace.stats.back_azimuth = azimuth obspy_trace.stats.experiment_id = stc.experiment_id obspy_trace.stats.array = stc.array_code obspy_trace.stats.component = stc.component obspy_trace.stats.response = self.get_response_obj(stc) obspy_trace.stats.sampling_rate = actual_sample_rate obspy_trace.stats.location = stc.location obspy_trace.stats.station = stc.seed_station obspy_trace.stats.coordinates = AttribDict() obspy_trace.stats.coordinates.latitude = stc.latitude obspy_trace.stats.coordinates.longitude = stc.longitude obspy_trace.stats.channel = stc.seed_channel obspy_trace.stats.network = stc.net_code obspy_trace.stats.starttime = trace.start_time.getFdsnTime() if self.decimation: obspy_trace.decimate(int(self.decimation)) obspy_stream.append(obspy_trace) self.ph5.Das_t = {} if len(obspy_stream.traces) < 1: return return obspy_stream