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.assertEqual(tr.stats.processing, ["downsample:integerDecimation:4"]) 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.assertEqual(tr.stats.processing, ["downsample:integerDecimation:10"]) # 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.assertAlmostEquals(0.0811378285461, fp, places=7) tr2.decimate(4, no_filter=True) np.testing.assert_array_equal(tr.data, tr2.data)
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.assertEqual(tr.stats.processing, ["downsample:integerDecimation:4"]) 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.assertEqual(tr.stats.processing, ["downsample:integerDecimation:10"]) # 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.assertAlmostEquals(0.0811378285461, fp, places=7) tr2.decimate(4, no_filter=True) np.testing.assert_array_equal(tr.data, tr2.data)
def getobs(mseed_filename, client, event, phases, frq4, windows, stas, stalocs, picks=None, delta_T={ 'P': 1., 'SH': 1., 'R': 10., 'L': 10. }, taper=None, adjtime=None): # Connect to arclink server #st = read('../mseed/mini.seed') org = event.preferred_origin() if org is None: org = event.origins[0] st = read(mseed_filename) stobs = {'params': {'filter': frq4, 'windows': windows}} syn = {} torg = org.time trngmx = 3600. invout = None # First do any requried time adjustments if not adjtime is None: for tr in st: if not tr.stats.station in adjtime.keys(): continue print 'Adjusting time for station %s by %g secs' % \ (tr.stats.station,adjtime[tr.stats.station]) tr.stats.starttime -= adjtime[tr.stats.station] for phase in phases: if not phase in stas.keys(): continue stobs[phase] = Stream() for sta in stas[phase]: # If this is a body wave phase find the pick - skip if none found if phase == 'P' or phase == 'SH': sta_pick = None # If no picks supplied then get them from events if picks is None: for pick in event.picks: if pick.phase_hint == phase[0:1] and \ pick.waveform_id.station_code == sta: sta_pick = pick break else: # Get them from picks - e.g. returned by get_isctimes if sta in picks.keys() and phase[0:1] in picks[sta]: sta_pick = Pick() sta_pick.time = picks[sta][phase[0:1]] if sta_pick is None: print 'No %s pick found for station %s - skipping' % ( phase, sta) continue # Set location code if prescribed, otherwise use '00' (preferred) if sta in stalocs.keys(): loc = stalocs[sta] else: loc = '00' # Select the channels for this station - skip if none found chans = st.select(station=sta, location=loc) if len(chans) == 0: # if nothing for loc='00', try also with '' loc = '' chans = st.select(station=sta, location=loc) if len(chans) == 0: print 'No channels found for %s' % sta continue try: inv = client.get_stations(network=chans[0].stats.network, station=sta, location=loc, starttime=torg, endtime=torg + 100., level='response') except Exception as e: warnings.warn(str(e)) print 'FDSNWS request failed for trace id %s - skipping' % sta continue try: coordinates = inv[0].get_coordinates(chans[0].id) except: print 'No coordinates found for station %s, channel %s' % \ (sta,chans[0].id) continue dist, azm, bazm = gps2dist_azimuth(org['latitude'], org['longitude'], coordinates['latitude'], coordinates['longitude']) gcarc = locations2degrees(org['latitude'], org['longitude'], coordinates['latitude'], coordinates['longitude']) if phase == 'R' or phase == 'P': # Rayleigh or P wave try: tr = st.select(station=sta, component='Z', location=loc)[0] except IndexError: print 'No vertical for %s:%s' % (sta, loc) continue try: inv = client.get_stations(network=tr.stats.network, station=sta, channel=tr.stats.channel, location=loc, starttime=torg, endtime=torg + 100., level='response') except Exception as e: warnings.warn(str(e)) print 'FDSNWS request failed for trace id %s - skipping' % tr.id continue tr = tr.copy() tr.stats.response = inv[0].get_response(tr.id, torg) tr.stats.coordinates = inv[0].get_coordinates(tr.id) tr.remove_response(pre_filt=frq4[phase], output='DISP') tr.stats.gcarc = gcarc tr.stats.azimuth = azm #t1 = minv[0].get_responeax(tr.stats.starttime,t+dist/rvmax) #t2 = min(tr.stats.endtime ,t+dist/rvmin) t1 = max(torg, tr.stats.starttime) t2 = min(torg + trngmx, tr.stats.endtime) tr.trim(starttime=t1, endtime=t2) decim = int(0.01 + delta_T[phase] / tr.stats.delta) ch = inv.select(station=sta, channel=tr.stats.channel)[0][0][0] print tr.id,' ',tr.stats.sampling_rate,' decimated by ',decim,\ 'sensitivity=',ch.response.instrument_sensitivity.value if tr.stats.starttime - torg < 0.: tr.trim(starttime=torg) tr.decimate(factor=decim, no_filter=True) tr.data *= 1.e6 # Convert to microns elif phase == 'L' or phase == 'SH': # Love or SH wave if len(chans.select(component='E')) != 0: try: tr1a = st.select(station=sta, component='E', location=loc)[0] tr2a = st.select(station=sta, component='N', location=loc)[0] except: print 'Station %s does not have 2 horizontal componets -skipping' % sta continue elif len(chans.select(component='1')) != 0: try: tr1a = st.select(station=sta, component='1', location=loc)[0] tr2a = st.select(station=sta, component='2', location=loc)[0] except: print 'Station %s does not have 2 horizontal componets -skipping' % sta continue tr1 = tr1a.copy() tr1.data = tr1a.data.copy() tr2 = tr2a.copy() tr2.data = tr2a.data.copy() ch1 = inv.select(station=sta, channel=tr1.stats.channel)[0][0][0] ch2 = inv.select(station=sta, channel=tr2.stats.channel)[0][0][0] tr1.stats.response = ch1.response tr1.remove_response(pre_filt=frq4[phase], output='DISP') tr2.stats.response = ch2.response tr2.remove_response(pre_filt=frq4[phase], output='DISP') strt = max(tr1.stats.starttime, tr2.stats.starttime) endt = min(tr1.stats.endtime, tr2.stats.endtime) tr1.trim(starttime=strt, endtime=endt) tr2.trim(starttime=strt, endtime=endt) # Rotate components first to ZNE vert, north, east = rotate2zne(tr1.data, ch1.azimuth, 0., tr2.data, ch2.azimuth, 0., np.zeros(tr1.stats.npts), 0., 0.) radial, transverse = rotate_ne_rt(north, east, bazm) tr = Trace(header=tr1.stats, data=transverse) tr2 = Trace(header=tr2.stats, data=radial) tr.stats.channel = tr.stats.channel[:-1] + 'T' # Change one of the invout channels to end in 'T' net = inv[-1] stn = net[0] chn = stn[0] chn.code = chn.code[:-1] + 'T' # tr.stats.gcarc = gcarc tr.stats.azimuth = azm decim = int(0.01 + delta_T[phase] / tr.stats.delta) print tr.id, ' ', tr.stats.sampling_rate, ' decimated by ', decim print '%s: sensitivity=%g, azimuth=%g, dip=%g' % ( ch1.code, ch1.response.instrument_sensitivity.value, ch1.azimuth, ch1.dip) print '%s: sensitivity=%g, azimuth=%g, dip=%g' % ( ch2.code, ch2.response.instrument_sensitivity.value, ch2.azimuth, ch2.dip) if tr.stats.starttime - torg < 0.: tr.trim(starttime=torg) tr2.trim(starttime=torg) tr.decimate(factor=decim, no_filter=True) tr2.decimate(factor=decim, no_filter=True) tr.radial = 1.e6 * tr2.data tr.stats.coordinates = coordinates tr.data *= 1.e6 # Convert to microns if phase == 'R' or phase == 'L': # Window according to group velocity window gwin = windows[phase] tbeg, tend = (dist * .001 / gwin[1], dist * .001 / gwin[0]) tr.trim(torg + tbeg, torg + tend) elif phase == 'P' or phase == 'SH': # Window by times before and after pick tbef, taft = windows[phase] tr.trim(sta_pick.time - tbef, sta_pick.time + taft) idx = int(0.5 + tbef / tr.stats.delta) avg = tr.data[:idx].mean() tr.data -= avg if not taper is None: itp = int(taper * tr.stats.npts) for i in range(tr.stats.npts - itp, tr.stats.npts): tr.data[i] *= 0.5 * (1. + mt.cos( mt.pi * (i - (tr.stats.npts - itp)) / float(itp))) tr.stats.pick = sta_pick stobs[phase].append(tr) # Appen station inventory to invout if invout is None: invout = inv else: invout += inv # Pickle to file return stobs, invout