def uvw2enz(st): if len(st) != 3: print('Stream does not contain 3 Traces') return st for trace in st: head = trace.stats channel = head.channel if channel == 'BHU': U = trace.data elif channel == 'BHV': V = trace.data elif channel == 'BHW': W = trace.data else: print('Trace.channel is not BHU, BHV, or BHW') return st d = np.radians(-30) aU = np.radians(135) aV = np.radians(15) aW = np.radians(255) A = np.array([[np.cos(d)*np.sin(aU),np.cos(d)*np.cos(aU),np.sin(d)], [np.cos(d)*np.sin(aV), np.cos(d)*np.cos(aV), np.sin(d)], [np.cos(d)*np.sin(aW), np.cos(d)*np.cos(aW), np.sin(d)]]) B = np.linalg.inv(A) E,N,Z = np.dot(B,(U,V,W)) head.channel = 'BHE'; trE = Trace(data=E, header=head) head.channel = 'BHN'; trN = Trace(data=N, header=head) head.channel = 'BHZ'; trZ = Trace(data=Z, header=head) stENZ = Stream(traces=[trE,trN,trZ]) return stENZ
def readgeonet(geonetfile): """ Read strong motion data from a GeoNet data file @param geonetfile: Path to a valid GeoNet data file. @return: List of ObsPy Trace objects, containing accelerometer data in m/s. """ f = open(geonetfile,'rt') tracelist = [] headerlist = [] try: hdrlines = readheaderlines(f) except: pass while len(hdrlines[-1]): hdrdict = readheader(hdrlines) numlines = int(np.ceil(hdrdict['npts']/10.0)) data = [] for i in range(0,numlines): line = f.readline() parts = line.strip().split() mdata = [float(p) for p in parts] data = data + mdata data = np.array(data) header = hdrdict.copy() stats = Stats(hdrdict) trace = Trace(data,header=stats) #apply the calibration and convert from mm/s^2 to m/s^2 trace.data = trace.data * trace.stats['calib'] * 0.001 #convert to m/s^2 tracelist.append(trace.copy()) headerlist.append(header.copy()) hdrlines = readheaderlines(f) f.close() return (tracelist,headerlist)
def test_geometric_mean(): trace1 = Trace(data=np.asarray([1, 2, 3]), header={'channel': 'H1'}) trace2 = Trace(data=np.asarray([4, 5, 6]), header={'channel': 'H2'}) trace3 = Trace(data=np.asarray([4, 5]), header={'channel': 'H2'}) trace4 = Trace(data=np.asarray([4, 5, 6]), header={'channel': 'z'}) valid_stream = Stream(traces=[trace1, trace2]) one_horizontal = Stream(traces=[trace1, trace4]) too_many_horizontals = Stream(traces=[trace1, trace2, trace3]) uneven = Stream(traces=[trace1, trace3]) # Test valid target = [np.sqrt(0.5*(1**2+4**2)), np.sqrt(0.5*(2**2+5**2)), np.sqrt(0.5*(3**2+6**2))] gm_data = calculate_geometric_mean(valid_stream, return_combined=True) np.testing.assert_array_equal(gm_data, target) gm_val = calculate_geometric_mean(valid_stream) np.testing.assert_array_equal(gm_val, np.max(target)) # Test invalid for invalid in [one_horizontal, too_many_horizontals, uneven]: failed = False try: gm_data = calculate_geometric_mean(invalid) except: failed = True assert(failed == True)
def test_rotd(): ddir = os.path.join('data', 'testdata', 'process') datadir = pkg_resources.resource_filename('gmprocess', ddir) # Create a stream and station summary, convert from m/s^2 to cm/s^2 (GAL) osc1_data = np.genfromtxt(datadir + '/ALCTENE.UW..sac.acc.final.txt') osc2_data = np.genfromtxt(datadir + '/ALCTENN.UW..sac.acc.final.txt') osc1_data = osc1_data.T[1] * 100 osc2_data = osc2_data.T[1] * 100 tr1 = Trace(data=osc1_data, header={'channel': 'H1', 'delta': 0.01, 'npts': 10400}) tr2 = Trace(data=osc2_data, header={'channel': 'H2', 'delta': 0.01, 'npts': 10400}) st = Stream([tr1, tr2]) target_pga50 = 4.12528265306 target_sa1050 = 10.7362857143 target_pgv50 = 6.239364 target_sa0350 = 10.1434159021 target_sa3050 = 1.12614169215 station = StationSummary.from_stream(st, ['rotd50'], ['pga', 'pgv', 'sa0.3', 'sa1.0', 'sa3.0']) pgms = station.pgms np.testing.assert_allclose(pgms['PGA']['ROTD50.0'], target_pga50, atol=0.1) np.testing.assert_allclose( pgms['SA(1.0)']['ROTD50.0'], target_sa1050, atol=0.1) np.testing.assert_allclose(pgms['PGV']['ROTD50.0'], target_pgv50, atol=0.1) np.testing.assert_allclose( pgms['SA(0.3)']['ROTD50.0'], target_sa0350, atol=0.1) np.testing.assert_allclose( pgms['SA(3.0)']['ROTD50.0'], target_sa3050, atol=0.1)
def rot2enz(st, comp=False): if len(st) != 3: print('Stream does not contain 3 Traces') return st for trace in st: head = trace.stats channel = head.channel if channel == 'BH1': one = trace.data elif channel == 'BH2': two = trace.data elif channel == 'BHZ': Z = trace.data elif channel == 'BHN': N = trace.data elif channel == 'BHE': E = trace.data else: print('Trace.channel is not BH1, BH2, or BHZ') return st if comp==False: N,E = rotate(one, two, -14) elif comp==True: N,E = rotate(one, two, 23) head.channel = 'BHE'; trE = Trace(data=E, header=head) head.channel = 'BHN'; trN = Trace(data=N, header=head) head.channel = 'BHZ'; trZ = Trace(data=Z, header=head) stENZ = Stream(traces=[trE,trN,trZ]) return stENZ
def stack(st, stats=None, kw_stack={}, kw_snr={}): """ Stack traces in stream. """ if st.count() == 0: logger.error('No traces!') return st elif st.count() == 1: return st # Find lap if kw_stack.get('sort', False): st.sort(keys=['endtime']) st.trim( starttime=st[0].stats.starttime, endtime=st[0].stats.endtime, pad=True, fill_value=0, ) sk = Trace() data = _data_stack(st, **kw_stack, **kw_snr) if data is None: return else: sk.data = data sk.stats = _hdr_stack(st, stats, **kw_stack, **kw_snr) key_snr = kw_stack.get('snr', 'user2') weight = kw_stack.get('weight', 'None').lower() if 'none' not in weight: sk.stats.sac[key_snr] = snr(sk, **kw_snr) return sk
def rand_stack(st, stats=None, kw_stack={}, kw_snr={}): nsub = kw_stack.get('nsub', 4) key_nsrc = kw_stack.get('key_nsrc', 'user0') ntr = st.count() if ntr < 2: return st sk = Trace() sk.stats = _hdr_stack(st, stats, **kw_stack, **kw_snr) if ntr <= nsub: for tr in st: yield tr else: ind = np.arange(ntr) np.random.shuffle(ind) for sub in np.array_split(ind, nsub): data = 0 for i in sub: data += st[i].data n = sub.size data /= n sk.stats.sac[key_nsrc] = n sk.data = data yield sk return
def autocorrelate2(filelst): """ Autocorrelation in frequency domain. The implementation of AC is from SCIPY. The autocorrelograms is normalized. :param filelst: :return: """ for file in filelst: print "AC: ", file tr = read(file)[0] x = tr.data stel = tr.stats.sac.stel stla = tr.stats.sac.stla stlo = tr.stats.sac.stlo try: # auto-correlation from SCIPY implemented in F domain, which is much faster than those in time domain ac = signal.fftconvolve(x, x[::-1], mode="full") ac = ac / max(abs(ac)) except: continue tr1 = Trace(data=ac) tr1.stats.network = tr.stats.network tr1.stats.station = tr.stats.station tr1.stats.location = tr.stats.location tr1.stats.delta = tr.stats.delta tr1.stats.sampling_rate = tr.stats.sampling_rate tr1.stats.channel = tr.stats.channel tr1.stats._format = "SAC" tr1.stats.sac = {u'stla': stla, u'stlo': stlo, u'stel': stel} tr1.stats.sac.user1 = tr.stats.sac.user1 tr1.stats.sac.user2 = tr.stats.sac.user2 tr1.stats.sac.kuser1 = tr.stats.sac.kuser1 tr1.stats.sac.kuser2 = tr.stats.sac.kuser2 # tr1.stats.sac.stla = tr.stats.sac.stla # tr1.stats.sac.stlo = tr.stats.sac.stlo # tr1.stats.sac.stel = tr.stats.sac.stel path, fn = filen2(file) fullfn = "SDI/ac/" + path + "/" + fn # print fullfn try: os.makedirs("SDI/ac/" + path) except: pass tr1.write(fullfn, format="SAC") pass
def readgeonet(geonetfile): """ Read strong motion data from a GeoNet data file @param geonetfile: Path to a valid GeoNet data file. @return: List of ObsPy Trace objects, containing accelerometer data in m/s. """ f = open(geonetfile, 'rt') tracelist = [] headerlist = [] try: hdrlines = readheaderlines(f) except: pass while len(hdrlines[-1]): hdrdict = readheader(hdrlines) numlines = int(np.ceil(hdrdict['npts'] / 10.0)) data = [] for i in range(0, numlines): line = f.readline() parts = line.strip().split() mdata = [float(p) for p in parts] data = data + mdata data = np.array(data) header = hdrdict.copy() stats = Stats(hdrdict) trace = Trace(data, header=stats) #apply the calibration and convert from mm/s^2 to m/s^2 trace.data = trace.data * trace.stats[ 'calib'] * 0.001 #convert to m/s^2 tracelist.append(trace.copy()) headerlist.append(header.copy()) hdrlines = readheaderlines(f) f.close() return (tracelist, headerlist)
def rot_cr(st): if len(st) != 3: print('Stream does not contain 3 Traces') return st for trace in st: head = trace.stats channel = head.channel if channel == 'LH1': one = trace.data elif channel == 'LH2': two = trace.data elif channel == 'LHZ': Z = trace.data else: print('Trace.channel is not BH1, BH2, or BHZ') return st E, N = rotate(two, one, 62) head.channel = 'LHE' trE = Trace(data=E, header=head) head.channel = 'LHN' trN = Trace(data=N, header=head) head.channel = 'LHZ' trZ = Trace(data=Z, header=head) stENZ = Stream(traces=[trE, trN, trZ]) return stENZ
def readiran(iranfile, doRotation=True): """ Read strong motion data from a Iran data file @param iranfile: Path to a valid Iran data file. @keyword doRotation: Apply back-azimuth rotation of L & T channels to NS and EW. @return: List of ObsPy Trace objects, containing accelerometer data in m/s. """ f = open(iranfile, 'rt') tracelist = [] headerlist = [] try: hdrlines = readheaderlines(f) except: pass while len(hdrlines[-1]): hdrdict = readheader(hdrlines) numlines = int(np.ceil(hdrdict['npts'] / 10.0)) data = [] for i in range(0, numlines): line = f.readline() parts = line.strip().split() mdata = [float(p) for p in parts] data = data + mdata data = np.array(data) header = hdrdict.copy() stats = Stats(hdrdict) trace = Trace(data, header=stats) #apply the calibration and convert from mm/s^2 to m/s^2 trace.data = trace.data * trace.stats[ 'calib'] * 0.98 #convert to m/s^2 from g/10 tracelist.append(trace.copy()) headerlist.append(header.copy()) endblock = f.readline() hdrlines = readheaderlines(f) f.close() #data from Iran may be rotated so that one channel is aligned in the direction between the earthquake #epicenter and the station. We want to rotate the data back so that we have what are presumably the #original NS and EW channels. We presume that the "L" channel will rotate back to become NS, and #"T" will become EW. #First, find the channel called L* if doRotation: channels = [h['channel'][0:1] for h in headerlist] lidx = channels.index('L') tidx = channels.index('T') ldata = tracelist[lidx].data tdata = tracelist[tidx].data backaz = headerlist[0]['rotation']['L'] ndata, edata = rotate.rotate_RT_NE(ldata, tdata, backaz) tracelist[lidx].data = ndata.copy() tracelist[lidx].stats[ 'channel'] = 'H1' #most probably NS, but we're being cautious tracelist[tidx].data = edata.copy() tracelist[tidx].stats[ 'channel'] = 'H2' #most probably EW, but we're being cautious return (tracelist, headerlist)
def readiran(iranfile,doRotation=True): """ Read strong motion data from a Iran data file @param iranfile: Path to a valid Iran data file. @keyword doRotation: Apply back-azimuth rotation of L & T channels to NS and EW. @return: List of ObsPy Trace objects, containing accelerometer data in m/s. """ f = open(iranfile,'rt') tracelist = [] headerlist = [] try: hdrlines = readheaderlines(f) except: pass while len(hdrlines[-1]): hdrdict = readheader(hdrlines) numlines = int(np.ceil(hdrdict['npts']/10.0)) data = [] for i in range(0,numlines): line = f.readline() parts = line.strip().split() mdata = [float(p) for p in parts] data = data + mdata data = np.array(data) header = hdrdict.copy() stats = Stats(hdrdict) trace = Trace(data,header=stats) #apply the calibration and convert from mm/s^2 to m/s^2 trace.data = trace.data * trace.stats['calib'] * 0.98 #convert to m/s^2 from g/10 tracelist.append(trace.copy()) headerlist.append(header.copy()) endblock = f.readline() hdrlines = readheaderlines(f) f.close() #data from Iran may be rotated so that one channel is aligned in the direction between the earthquake #epicenter and the station. We want to rotate the data back so that we have what are presumably the #original NS and EW channels. We presume that the "L" channel will rotate back to become NS, and #"T" will become EW. #First, find the channel called L* if doRotation: channels = [h['channel'][0:1] for h in headerlist] lidx = channels.index('L') tidx = channels.index('T') ldata = tracelist[lidx].data tdata = tracelist[tidx].data backaz = headerlist[0]['rotation']['L'] ndata,edata = rotate.rotate_RT_NE(ldata,tdata,backaz) tracelist[lidx].data = ndata.copy() tracelist[lidx].stats['channel'] = 'H1' #most probably NS, but we're being cautious tracelist[tidx].data = edata.copy() tracelist[tidx].stats['channel'] = 'H2' #most probably EW, but we're being cautious return (tracelist,headerlist)
def getCatData(date, opt): """ Download data from IRIS or Earthworm waveserver with padding and filter it. This is a specialized version getData() for catalog events, pulling a smaller amount of time around a known event. date: UTCDateTime of known catalog event opt: Options object describing station/run parameters Returns ObsPy stream objects, one for cutting and the other for triggering """ nets = opt.network.split(',') stas = opt.station.split(',') locs = opt.location.split(',') chas = opt.channel.split(',') if opt.server == "IRIS": client = Client("IRIS") else: client = EWClient(opt.server, opt.port) st = Stream() for n in range(len(stas)): try: stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n], date - opt.atrig, date + 3*opt.atrig) stmp = stmp.filter("bandpass", freqmin=opt.fmin, freqmax=opt.fmax, corners=2, zerophase=True) stmp = stmp.merge(method=1, fill_value='interpolate') except (obspy.fdsn.header.FDSNException): try: # try again stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n], date - opt.atrig, date + 3*opt.atrig) stmp = stmp.filter("bandpass", freqmin=opt.fmin, freqmax=opt.fmax, corners=2, zerophase=True) stmp = stmp.merge(method=1, fill_value='interpolate') except (obspy.fdsn.header.FDSNException): print('No data found for {0}.{1}'.format(stas[n],nets[n])) trtmp = Trace() trtmp.stats.sampling_rate = opt.samprate trtmp.stats.station = stas[n] stmp = Stream().extend([trtmp.copy()]) # Resample to ensure all traces are same length if stmp[0].stats.sampling_rate != opt.samprate: stmp = stmp.resample(opt.samprate) st.extend(stmp.copy()) st = st.trim(starttime=date-opt.atrig, endtime=date+3*opt.atrig, pad=True, fill_value=0) stC = st.copy() return st, stC
def test__set_metadata(): """edge_test.EdgeFactory_test.test__set_metadata() """ # Call _set_metadata with 2 traces, and make certain the stats get # set for both traces. trace1 = Trace() trace2 = Trace() stream = Stream(traces=[trace1, trace2]) EdgeFactory()._set_metadata(stream, 'BOU', 'H', 'variation', 'minute') assert_equals(stream[0].stats['channel'], 'H') assert_equals(stream[1].stats['channel'], 'H')
def autocorrelate(filelst): for file in filelst: print "AC: ", file tr = read(file)[0] x = tr.data stel = tr.stats.sac.stel stla = tr.stats.sac.stla stlo = tr.stats.sac.stlo try: # auto-correlation from SCIPY implemented in F domain, which is much faster than those in time domain ac = signal.fftconvolve(x, x[::-1], mode="full") ac = ac/max(abs(ac)) except: continue tr1 = Trace(data=ac) tr1.stats.network = tr.stats.network tr1.stats.station =tr.stats.station tr1.stats.location = tr.stats.location tr1.stats.delta = tr.stats.delta tr1.stats.sampling_rate = tr.stats.sampling_rate tr1.stats.channel = tr.stats.channel tr1.stats._format = "SAC" tr1.stats.sac = {u'stla': stla, u'stlo': stlo, u'stel': stel} tr1.stats.sac.user1 = tr.stats.sac.user1 tr1.stats.sac.user2 = tr.stats.sac.user2 tr1.stats.sac.kuser1 = tr.stats.sac.kuser1 tr1.stats.sac.kuser2 = tr.stats.sac.kuser2 # tr1.stats.sac.stla = tr.stats.sac.stla # tr1.stats.sac.stlo = tr.stats.sac.stlo # tr1.stats.sac.stel = tr.stats.sac.stel path, fn = filen(file) fullfn = "SDI/ac/"+path+"/"+fn # print fullfn try: os.makedirs("SDI/ac/"+path) except: pass tr1.write(fullfn, format="SAC") pass
def read_cwb(filename, **kwargs): """Read Taiwan Central Weather Bureau strong motion file. Args: filename (str): Path to possible CWB data file. kwargs (ref): Other arguments will be ignored. Returns: Stream: Obspy Stream containing three channels of acceleration data (cm/s**2). """ if not is_cwb(filename): raise ValueError('%s is not a valid CWB strong motion data file.') f = open(filename, 'rt') # according to the powers that defined the Network.Station.Channel.Location # "standard", Location is a two character field. Most data providers, # including CWB here, don't provide this. We'll flag it as "--". data = np.genfromtxt(filename, skip_header=HDR_ROWS, delimiter=[COLWIDTH] * NCOLS) # time, Z, NS, EW hdr = _get_header_info(f, data) f.close() hdr_z = hdr.copy() hdr_z['channel'] = get_channel_name(hdr['sampling_rate'], is_acceleration=True, is_vertical=True, is_north=False) hdr_z['standard']['horizontal_orientation'] = np.nan hdr_h1 = hdr.copy() hdr_h1['channel'] = get_channel_name(hdr['sampling_rate'], is_acceleration=True, is_vertical=False, is_north=True) hdr_h1['standard']['horizontal_orientation'] = np.nan hdr_h2 = hdr.copy() hdr_h2['channel'] = get_channel_name(hdr['sampling_rate'], is_acceleration=True, is_vertical=False, is_north=False) hdr_h2['standard']['horizontal_orientation'] = np.nan stats_z = Stats(hdr_z) stats_h1 = Stats(hdr_h1) stats_h2 = Stats(hdr_h2) trace_z = Trace(data=data[:, 1], header=stats_z) trace_h1 = Trace(data=data[:, 2], header=stats_h1) trace_h2 = Trace(data=data[:, 3], header=stats_h2) stream = Stream([trace_z, trace_h1, trace_h2]) return stream
def filter(self, stream, time_at_rec, la_s, lo_s, depth, Rayleigh=True): env_stream = Stream() dist, az, baz = gps2dist_azimuth(lat1=la_s, lon1=lo_s, lat2=self.prior['la_r'], lon2=self.prior['lo_r'], a=self.prior['radius'], f=0) if Rayleigh == True: phases = self.get_R_phases(time_at_rec) else: phases = self.get_L_phases(time_at_rec) for i, v in enumerate(stream.traces): npts = len(v.data) trace = stream.traces[i].copy() trace.detrend(type="demean") trace.interpolate( sampling_rate=10. / phases[i]['dt'] ) # No method specified, so : 'weighted_average_slopes' is used trace.filter('highpass', freq=phases[i]['fmin'], zerophase=True) trace.filter('lowpass', freq=phases[i]['fmax'], zerophase=True) trace.detrend() trace.detrend(type="demean") env = envelope(trace.data) zero_trace = Trace(np.zeros(npts), header={ "starttime": phases[i]['starttime'](dist, depth), 'delta': trace.meta.delta, "station": trace.meta.station, "network": trace.meta.network, "location": trace.meta.location, "channel": trace.meta.channel, "instaseis": trace.meta.instaseis }) env_trace = Trace(env, header={ "starttime": phases[i]['starttime'](dist, depth), 'delta': trace.meta.delta, "station": trace.meta.station, "network": trace.meta.network, "location": trace.meta.location, "channel": trace.meta.channel, "instaseis": trace.meta.instaseis }) env_stream.append(env_trace) return env_stream
def create_trace(sta, T1, T2): from obspy import Trace from numpy import zeros from numpy import empty, nan tr = Trace() tr.stats['station'] = sta.split('.')[0] tr.stats['channel'] = sta.split('.')[1] tr.stats['network'] = sta.split('.')[2] tr.stats['location'] = sta.split('.')[3] tr.stats['sampling_rate'] = 100 tr.stats['starttime'] = T1 #tr.data=zeros(int((T2-T1)*tr.stats['sampling_rate'])) tr.data = empty(int((T2 - T1) * tr.stats['sampling_rate'])) tr.data[:] = nan return tr
def test_pphase_picker(): # compare our results with a data file from E. Kalkan datapath = os.path.join("data", "testdata", "strong-motion.mat") datafile = pkg_resources.resource_filename("gmprocess", datapath) matlabfile = loadmat(datafile) x = np.squeeze(matlabfile["x"]) dt = matlabfile["dt"][0][0] hdr = { "delta": dt, "sampling_rate": 1 / dt, "npts": len(x), "starttime": UTCDateTime("1970-01-01"), "standard": { "units_type": "acc" }, } trace = Trace(data=x, header=hdr) stream = Stream(traces=[trace]) period = 0.01 damping = 0.6 nbins = 200 loc = pphase_pick(stream[0], period=period, damping=damping, nbins=nbins, peak_selection=True) assert loc == 26.035
def calculate_fas(stream, imcs, periods, smoothing, bandwidth): """ Calculate the fourier amplitude spectra. This process requires getting the fourier amplitude spectra, applying the geometric mean to the horizontal traces, smoothing and returning the smoothed value for each requested period. Args: stream (obspy.core.stream.Stream): streams of strong ground motion. Traces in stream must be in units of g. imcs (list): list of imcs. (Currently only the geometric mean is supported and this is ignored. In the future it will account for channels and rotated channels.) Returns: dictionary: Dictionary of fas for the geometric mean. Units are in cm/s. The dictionary is structured as: fas_dict = { <period> : <value,... } """ fas_dict = {} sampling_rate = None # check units and add channel pga for trace in stream: if trace.stats['units'] != 'g' and trace.stats['units'] != 'cm/s/s': raise PGMException('Invalid units for sa: %r. ' 'Units must be g (cm/s/s)' % trace.stats['units']) if 'Z' not in trace.stats['channel'].upper(): sampling_rate = trace.stats.sampling_rate if sampling_rate is None: raise PGMException('No horizontal channels') spec_stream = Stream() for trace in stream: nfft = len(trace.data) # the fft scales so the factor of 1/nfft is applied spectra = abs(np.fft.rfft(trace.data, n=nfft)) / nfft spec_trace = Trace(data=spectra, header=trace.stats) spec_stream.append(spec_trace) ## The imc is always geometric mean. However, the combined stream is ## required rather than the single maximum value gm_trace = calculate_geometric_mean(spec_stream, return_combined=True) freqs = np.fft.rfftfreq(nfft, 1 / trace.stats.sampling_rate) fas_frequencies = 1 / np.asarray(list(periods)) smoothed_values = np.empty_like(fas_frequencies) if smoothing.lower() == 'konno_ohmachi': konno_ohmachi_smooth(gm_trace.astype(np.double), freqs, fas_frequencies, smoothed_values, bandwidth) else: raise PGMException('Not a valid smoothing option: %r' % smoothing) for idx, freq in enumerate(fas_frequencies): fas_dict[1/freq] = smoothed_values[idx] return fas_dict
def test_exceptions(): datafiles, _ = read_data_dir( 'geonet', 'us1000778i', '20161113_110259_WTMC_20.V2A') datafile_v2 = datafiles[0] stream_v2 = read_geonet(datafile_v2)[0] stream1 = stream_v2.select(channel="HN1") try: StationSummary.from_stream(stream1, ['rotd50'], ['pga']) sucess = True except PGMException: sucess = False assert sucess == False stream2 = Stream( [stream_v2.select(channel="HN1")[0], Trace(data=np.asarray([]), header={"channel": "HN2"})]) try: StationSummary.from_stream(stream2, ['rotd50'], ['pga']) sucess = True except PGMException: sucess = False assert sucess == False for trace in stream_v2: stream1.append(trace) try: StationSummary.from_stream(stream1, ['rotd50'], ['pga']) sucess = True except PGMException: sucess = False assert sucess == False
def GetWaveData(self, staNo, chnNo, startTimeInt, endTimeInt): """ 读取redis中指定台站编号、通道编号、波形开始时间、波形结束时间的波形数据,返回Trace类。读取失败数据返回极大值 """ list_data = list() errorSecSum = 0 print("GetWaveData") for sec in range(startTimeInt, endTimeInt): # print ('sec:'+str(sec)) wave_key_name = self.channel_list[staNo][chnNo]['network'] + '.' + self.channel_list[staNo][chnNo][ 'station'] + '.' + \ self.channel_list[staNo][chnNo]['channel'] + '.' + self.channel_list[staNo][chnNo][ 'location'] + '.Data' res = self.r.hget(wave_key_name, sec) ddd = [ np.iinfo(np.int32).max for col in range(0, self.station_list[staNo]['sampling_rate']) ] if res is not None: fmt = '' for num in range(0, self.station_list[staNo]['sampling_rate']): fmt = fmt + 'i' # print (struct.unpack(fmt,res)) ddd = list(struct.unpack(fmt, res)) else: print('the ' + str(sec) + ' second, data error') errorSecSum = errorSecSum + 1 list_data = list_data + ddd print('Total ' + str(errorSecSum) + ' seconds data error') tr_data = np.array(list_data, ) tr_Stat = self.channel_list[staNo][chnNo] tr_Stat['sampling_rate'] = self.station_list[staNo]['sampling_rate'] tr_Stat['starttime'] = UTCDateTime(startTimeInt) tr_Stat['npts'] = len(tr_data) return Trace(tr_data, tr_Stat)
def test_exceptions(): ddir = os.path.join('data', 'testdata') datadir = pkg_resources.resource_filename('gmprocess', ddir) data_file = os.path.join(datadir, 'arias_data.json') with open(data_file, 'rt') as f: jdict = json.load(f) time = np.array(jdict['time']) # input output is m/s/s acc = np.array(jdict['acc']) / 100 delta = time[2] - time[1] sr = 1 / delta header = { 'delta': delta, 'sampling_rate': sr, 'npts': len(acc), 'units': 'm/s/s', 'channel': 'H1' } trace = Trace(data=acc, header=header) stream = Stream([trace]) try: StationSummary.from_stream(stream, ['gmrotd50'], ['arias']) sucess = True except: sucess = False assert sucess == False try: StationSummary.from_stream(stream, ['rotd50'], ['arias']) sucess = True except: sucess = False assert sucess == False
def test_exceptions(): homedir = os.path.dirname( os.path.abspath(__file__)) # where is this script? data_dir = os.path.join(homedir, '..', 'data', 'evolutionary_IM_examples.xlsx') df = pd.read_excel(data_dir) time = df.iloc[:, 0].values # input output is m/s/s acc = df.iloc[:, 1].values / 100 delta = time[2] - time[1] sr = 1 / delta header = { 'delta': delta, 'sampling_rate': sr, 'npts': len(acc), 'units': 'm/s/s', 'channel': 'H1' } trace = Trace(data=acc, header=header) stream = Stream([trace]) try: StationSummary.from_stream(stream, ['gmrotd50'], ['arias']) sucess = True except: sucess = False assert sucess == False try: StationSummary.from_stream(stream, ['rotd50'], ['arias']) sucess = True except: sucess = False assert sucess == False
def test_stream(): inventory = get_inventory() channels = ['HN1', 'HN2', 'HNZ'] data = np.random.rand(1000) traces = [] network = inventory.networks[0] station = network.stations[0] chlist = station.channels channelcodes = [ch.code for ch in chlist] for channel in channels: chidx = channelcodes.index(channel) channeldata = chlist[chidx] header = { 'sampling_rate': channeldata.sample_rate, 'npts': len(data), 'network': network.code, 'location': channeldata.location_code, 'station': station.code, 'channel': channel, 'starttime': UTCDateTime(2010, 1, 1, 0, 0, 0) } trace = Trace(data=data, header=header) traces.append(trace) invstream = StationStream(traces=traces, inventory=inventory) inventory2 = invstream.getInventory() inv2_channel1 = inventory2.networks[0].stations[0].channels[0] inv_channel1 = inventory2.networks[0].stations[0].channels[0] assert inv_channel1.code == inv2_channel1.code # test the streamparam functionality statsdict = {'name': 'Fred', 'age': 34} invstream.setStreamParam('stats', statsdict) assert invstream.getStreamParamKeys() == ['stats'] cmpdict = invstream.getStreamParam('stats') assert statsdict == cmpdict
def test_uneven_stream(): inventory = get_inventory() channels = ['HN1', 'HN2', 'HNZ'] data1 = np.random.rand(1000) data2 = np.random.rand(1001) data3 = np.random.rand(1002) data = [data1, data2, data3] traces = [] network = inventory.networks[0] station = network.stations[0] chlist = station.channels channelcodes = [ch.code for ch in chlist] for datat, channel in zip(data, channels): chidx = channelcodes.index(channel) channeldata = chlist[chidx] header = { 'sampling_rate': channeldata.sample_rate, 'npts': len(datat), 'network': network.code, 'location': channeldata.location_code, 'station': station.code, 'channel': channel, 'starttime': UTCDateTime(2010, 1, 1, 0, 0, 0) } trace = Trace(data=datat, header=header) traces.append(trace) invstream = StationStream(traces=traces, inventory=inventory) x = 1
def test_exceptions(): homedir = os.path.dirname( os.path.abspath(__file__)) # where is this script? datafile_v2 = os.path.join(homedir, '..', 'data', 'geonet', '20161113_110259_WTMC_20.V2A') stream_v2 = read_geonet(datafile_v2) stream1 = stream_v2.select(channel="HN1") try: StationSummary.from_stream(stream1, ['gmrotd50'], ['pga']) sucess = True except PGMException: sucess = False assert sucess == False for trace in stream_v2: stream1.append(trace) try: StationSummary.from_stream(stream1, ['gmrotd50'], ['pga']) sucess = True except PGMException: sucess = False assert sucess == False stream2 = Stream([ stream_v2.select(channel="HN1")[0], Trace(data=np.asarray([]), header={"channel": "HN2"}) ]) try: StationSummary.from_stream(stream2, ['gmrotd50'], ['pga']) sucess = True except PGMException: sucess = False assert sucess == False
def test_pphase_picker(): # compare our results with a data file from E. Kalkan datapath = os.path.join('data', 'testdata', 'strong-motion.mat') datafile = pkg_resources.resource_filename('gmprocess', datapath) matlabfile = loadmat(datafile) x = np.squeeze(matlabfile['x']) dt = matlabfile['dt'][0][0] hdr = { 'delta': dt, 'sampling_rate': 1 / dt, 'npts': len(x), 'starttime': UTCDateTime('1970-01-01'), 'standard': { 'units': 'acc' } } trace = Trace(data=x, header=hdr) stream = Stream(traces=[trace]) period = 0.01 damping = 0.6 nbins = 200 loc = pphase_pick(stream[0], period=period, damping=damping, nbins=nbins, peak_selection=True) assert loc == 26.035
def ascii_specfem2d_obspy(**kwargs): """ Reads seismic traces from text files """ from obspy.core.stream import Stream from obspy.core.trace import Trace filenames = glob(solver='specfem2d', **kwargs) t = _np.loadtxt(files[0])[:,0] nt = len(t) nr = len(filenames) d = Trace(data=np.zeros(nt, dtype='float32')) trace.stats.starttime = t[0] trace.stats.delta = _np.mean(_np.diff(t)) trace.stats.nt = len(t) # read data stream = Stream(t)*nr for filename in filenames: stream.data = _np.loadtxt(filename)[:, 1] return stream
def test_stream(): inventory = get_inventory() channels = ["HN1", "HN2", "HNZ"] data = np.random.rand(1000) traces = [] network = inventory.networks[0] station = network.stations[0] chlist = station.channels channelcodes = [ch.code for ch in chlist] for channel in channels: chidx = channelcodes.index(channel) channeldata = chlist[chidx] header = { "sampling_rate": channeldata.sample_rate, "npts": len(data), "network": network.code, "location": channeldata.location_code, "station": station.code, "channel": channel, "starttime": UTCDateTime(2010, 1, 1, 0, 0, 0), } trace = Trace(data=data, header=header) traces.append(trace) invstream = StationStream(traces=traces, inventory=inventory) inventory2 = invstream.getInventory() inv2_channel1 = inventory2.networks[0].stations[0].channels[0] inv_channel1 = inventory2.networks[0].stations[0].channels[0] assert inv_channel1.code == inv2_channel1.code # test the streamparam functionality statsdict = {"name": "Fred", "age": 34} invstream.setStreamParam("stats", statsdict) assert invstream.getStreamParamKeys() == ["stats"] cmpdict = invstream.getStreamParam("stats") assert statsdict == cmpdict
def sym_xc(xc, noeven=False): """ Symmetrize a cross-correlation. """ pair = f'{xc.stats.sac.kevnm.split()[0]}-{xc.stats.station}' if not _is_sym(xc): logger.debug(f'Asymmetric {pair}') end = min(abs(xc.stats.sac.b), xc.stats.sac.e) xc = sliced(xc, -end, end) if _even_npts(xc) and noeven: logger.error(f'Even npts to symmexcize {pair}') else: sym = Trace() sym.data = _data_sym(xc.data) sym.stats = _hd_sym(xc.stats, npts=sym.data.size) return sym
def test_uneven_stream(): inventory = get_inventory() channels = ["HN1", "HN2", "HNZ"] data1 = np.random.rand(1000) data2 = np.random.rand(1001) data3 = np.random.rand(1002) data = [data1, data2, data3] traces = [] network = inventory.networks[0] station = network.stations[0] chlist = station.channels channelcodes = [ch.code for ch in chlist] for datat, channel in zip(data, channels): chidx = channelcodes.index(channel) channeldata = chlist[chidx] header = { "sampling_rate": channeldata.sample_rate, "npts": len(datat), "network": network.code, "location": channeldata.location_code, "station": station.code, "channel": channel, "starttime": UTCDateTime(2010, 1, 1, 0, 0, 0), } trace = Trace(data=datat, header=header) traces.append(trace) invstream = StationStream(traces=traces, inventory=inventory) x = 1
def df2stream(df, header, network='NT', location='R0', radians=True, default_elevation=0): """ Build and return obspy :class:`Stream` from *header* information and the :class:`DataFrame` *df*. Use *dec_tenths_arcminute* (local magnetic declination in determining magnetic north and east or XYZ in units of tenths of arcminutes). If *radians*, angles in D are given in degrees and must be converted to radians. If the site elevation is not included in the header, use *default_elevation*. The *network* and *location* identifiers are used in forming the trace names in the resultant stream. """ glon = header['Geodetic Longitude'] if glon < 0: glon += 360 delta = (df.index[1] - df.index[0]).total_seconds() fs = 1 / delta d1 = df.index[0] d2 = df.index[-1] d1_obj = UTCDateTime('{:%Y-%m-%d %H:%H:%S}'.format(d1)) d2_obj = UTCDateTime('{:%Y-%m-%d %H:%H:%S}'.format(d2)) dec_tenths_arcminute = header.get( 'decbas', get_dec_tenths_arcminute(header, d1.to_pydatetime())) logger.info( 'using declination baseline = {:.1f} (tenths of arcminutes)'.format( dec_tenths_arcminute)) N = df.shape[0] stream_header = { 'geodetic_latitude': header['Geodetic Latitude'], 'geodetic_longitude': glon, 'station': header['IAGA CODE'], 'sampling_rate': fs, 'starttime': d1_obj, 'endtime': d2_obj, 'declination_base': dec_tenths_arcminute, 'npts': N } try: stream_header['elevation'] = header['Elevation'] except KeyError: stream_header['elevation'] = default_elevation logger.warning( 'elevation is unknown --- inserting {}'.format(default_elevation)) traces = [] for column in df.columns: channel = column[-1] header_i = stream_header.copy() header_i['channel'] = channel.upper() header_i['network'] = network header_i['location'] = location vals = df[column].values if channel == 'D' and radians: vals = NP.radians(vals) traces.append(Trace(data=vals, header=header_i)) return Stream(traces=traces)
def readknet(knetfilename): """ Read a KNet ASCII file, and return an ObsPy Trace object, plus a dictionary of header values. @param knetfilename: String path to valid KNet ASCII file, as described here: http://www.kyoshin.bosai.go.jp/kyoshin/man/knetform_en.html @return: ObsPy Trace object, and a dictionary of some of the header values found in the input file. """ data = [] hdrdict = {} f = open(knetfilename,'rt') dataOn = False headerlines = [] for line in f.readlines(): if line.startswith('Memo'): hdrdict = readheader(headerlines) dataOn = True continue if not dataOn: headerlines.append(line) continue if dataOn: parts = line.strip().split() mdata = [float(p) for p in parts] data = data + mdata f.close() #fill in the values usually expected in Stats as best we can hdrdict['npts'] = len(data) elapsed = float(hdrdict['npts'])/float(hdrdict['sampling_rate']) hdrdict['endtime'] = hdrdict['starttime'] + elapsed hdrdict['network'] = 'NIED' hdrdict['location'] = '' #The Stats constructor appears to modify the fields in the input dictionary - let's save #a copy header = hdrdict.copy() data = np.array(data) stats = Stats(hdrdict) trace = Trace(data,header=stats) #apply the calibration and convert to m/s^2 trace.data = trace.data * trace.stats['calib'] * 0.01 #convert to m/s^2 return (trace,header)
def readgeonet(geonetfile): """ Read strong motion data from a GeoNet data file @param geonetfile: Path to a valid GeoNet data file. @return: List of ObsPy Trace objects, containing accelerometer data in m/s. """ #notes on implementation: # originally I had written code to read each line of data manually, just # as I was reading the header lines. However, this became VERY slow for large # files. I discovered that numpy's genfromtxt function was much faster. However, # I could not get that function to work when I passed it a file object instead of a file name. # Consequently, the only way I could keep the genfromtxt() method and file pointer in sync was # to read and discard all of the lines of data that genfromtxt() parsed. While annoying, the combination # of these two seems to still be at least an order of magnitude faster than manually reading the file. f = open(geonetfile,'rt') tracelist = [] headerlist = [] totlines = 0 hdrlines = readheaderlines(f) while len(hdrlines[-1]): totlines += len(hdrlines) hdrdict = readheader(hdrlines) numlines = int(np.ceil(hdrdict['npts']/10.0)) data = np.genfromtxt(geonetfile,skip_header=totlines,max_rows=numlines) totlines += numlines #now we need to set the file position to where we just ended for i in range(0,numlines): f.readline() data = data.flatten() header = hdrdict.copy() stats = Stats(hdrdict) trace = Trace(data,header=stats) #apply the calibration and convert from mm/s^2 to m/s^2 trace.data = trace.data * trace.stats['calib'] * 0.001 #convert to m/s^2 tracelist.append(trace.copy()) headerlist.append(header.copy()) hdrlines = readheaderlines(f) f.close() return (tracelist,headerlist)
def readitaly(datafile): f = open(datafile,'rt') #header needs: station,channel,location,npts,starttime,sampling_rate,delta,calib,lat,lon,height,duration,endtime,maxacc,network data = [] hdrdict = {} for line in f.readlines(): if not len(line.strip()): continue if not line.find(':') > -1: data.append(float(line.strip())) continue key,value = line.split(':') key = key.strip() value = value.strip() if key not in list(HEADERS.keys()): continue hdrkey = HEADERS[key] if hdrkey == 'starttime': value = UTCDateTime(datetime.datetime.strptime(value,TIMEFMT)) elif hdrkey not in ['station','channel','location','network']: value = float(value) hdrdict[hdrkey] = value f.close() hdrdict['sampling_rate'] = 1/hdrdict['delta'] hdrdict['endtime'] = hdrdict['starttime'] + hdrdict['duration'] hdrdict['npts'] = int(hdrdict['npts']) hdrdict['calib'] = 1.0 hdrdict['units'] = 'acc' data = np.array(data) header = hdrdict.copy() stats = Stats(hdrdict) trace = Trace(data,header=stats) #apply the calibration and convert from mm/s^2 to m/s^2 trace.data = trace.data * trace.stats['calib'] * 0.01 #convert to m/s^2 return trace
def readturkey(turkeyfile): """ Read strong motion data from a Turkey data file @param geonetfile: Path to a valid Turkey data file. @return: List of ObsPy Trace objects, containing accelerometer data in m/s. """ f = open(turkeyfile,'rt') dataOn = False header = {} nschannel = [] ewchannel = [] udchannel = [] for line in f.readlines(): if line.strip().startswith('STATION ID'): parts = line.strip().split(':') header['station'] = parts[1].strip() continue if line.strip().startswith('STATION COORD'): parts = line.strip().split(':') cstr = parts[1].strip() parts = cstr.split('-') header['lat'] = float(parts[0][0:-1]) header['lon'] = float(parts[1][0:-1]) continue if line.strip().startswith('STATION ALT'): parts = line.strip().split(':') try: header['height'] = float(parts[1]) except: header['height'] = 0.0 continue if line.strip().startswith('RECORD TIME'): parts = line.strip().split(':') timestr = ':'.join(parts[1:]) timestr = timestr.strip().replace('(GMT)','').strip() dt = datetime.strptime(timestr[0:19],'%d/%m/%Y %H:%M:%S') dt = dt.replace(microsecond=int(timestr[20:])) header['starttime'] = UTCDateTime(dt) continue if line.strip().startswith('NUMBER OF DATA'): parts = line.strip().split(':') header['npts'] = int(parts[1]) continue if line.strip().startswith('SAMPLING INTERVAL'): parts = line.strip().split(':') header['delta'] = float(parts[1]) header['sampling_rate'] = 1.0/header['delta'] continue if line.strip().startswith('N-S'): dataOn = True continue if dataOn: parts = line.strip().split() nschannel.append(float(parts[0])) ewchannel.append(float(parts[1])) udchannel.append(float(parts[2])) f.close() nschannel = np.array(nschannel) ewchannel = np.array(ewchannel) udchannel = np.array(udchannel) header['network'] = 'TR' header['units'] = 'acc' nsheader = header.copy() nsheader['channel'] = 'NS' ewheader = header.copy() ewheader['channel'] = 'EW' udheader = header.copy() udheader['channel'] = 'UD' nsstats = Stats(nsheader) nstrace = Trace(nschannel,header=nsstats) ewstats = Stats(ewheader) ewtrace = Trace(ewchannel,header=ewstats) udstats = Stats(udheader) udtrace = Trace(udchannel,header=udstats) nstrace.data = nstrace.data * 0.01 #convert to m/s^2 ewtrace.data = ewtrace.data * 0.01 #convert to m/s^2 udtrace.data = udtrace.data * 0.01 #convert to m/s^2 tracelist = [nstrace,ewtrace,udtrace] hdrlist = [nsheader,ewheader,udheader] return (tracelist,hdrlist)
def _read_y(filename, headonly=False, **kwargs): # @UnusedVariable """ Reads a Nanometrics Y 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. :type filename: str :param filename: Nanometrics Y file to be read. :type headonly: bool, optional :param headonly: If set to True, read only the head. This is most useful for scanning available data in huge (temporary) data sets. :rtype: :class:`~obspy.core.stream.Stream` :return: A ObsPy Stream object. .. rubric:: Example >>> from obspy import read >>> st = read("/path/to/YAYT_BHZ_20021223.124800") >>> st # doctest: +ELLIPSIS <obspy.core.stream.Stream object at 0x...> >>> print(st) # doctest: +ELLIPSIS 1 Trace(s) in Stream: .AYT..BHZ | 2002-12-23T12:48:00.000100Z - ... | 100.0 Hz, 18000 samples """ # The first tag in a Y-file must be the TAG_Y_FILE (0) tag. This must be # followed by the following tags, in any order: # TAG_STATION_INFO (1) # TAG_STATION_LOCATION (2) # TAG_STATION_PARAMETERS (3) # TAG_STATION_DATABASE (4) # TAG_SERIES_INFO (5) # TAG_SERIES_DATABASE (6) # The following tag is optional: # TAG_STATION_RESPONSE (26) # The last tag in the file must be a TAG_DATA_INT32 (7) tag. This tag must # be followed by an array of LONG's. The number of entries in the array # must agree with what was described in the TAG_SERIES_INFO data. with open(filename, "rb") as fh: trace = Trace() trace.stats.y = AttribDict() count = -1 while True: endian, tag_type, next_tag, _next_same = __parse_tag(fh) if tag_type == 1: # TAG_STATION_INFO # UCHAR Update[8] # This field is only used internally for administrative # purposes. It should always be set to zeroes. # UCHAR Station[5] (BLANKPAD) # Station is the five letter SEED format station # identification. # UCHAR Location[2] (BLANKPAD) # Location Location is the two letter SEED format location # identification. # UCHAR Channel[3] (BLANKPAD) # Channel Channel is the three letter SEED format channel # identification. # UCHAR NetworkID[51] (ASCIIZ) # This is some descriptive text identifying the network. # UCHAR SiteName[61] (ASCIIZ) # SiteName is some text identifying the site. # UCHAR Comment[31] (ASCIIZ) # Comment is any comment for this station. # UCHAR SensorType[51] (ASCIIZ) # SensorType is some text describing the type of sensor used # at the station. # UCHAR DataFormat[7] (ASCIIZ) # DataFormat is some text describing the data format recorded # at the station. data = fh.read(next_tag) parts = _unpack_with_asciiz_and_decode(b"5s2s3s51z61z31z51z7z", data[8:]) trace.stats.station = parts[0] trace.stats.location = parts[1] trace.stats.channel = parts[2] # extra params = AttribDict() params.network_id = parts[3] params.side_name = parts[4] params.comment = parts[5] params.sensor_type = parts[6] params.data_format = parts[7] trace.stats.y.tag_station_info = params elif tag_type == 2: # TAG_STATION_LOCATION # UCHAR Update[8] # This field is only used internally for administrative # purposes. It should always be set to zeroes. # FLOAT Latitude # Latitude in degrees of the location of the station. The # latitude should be between -90 (South) and +90 (North). # FLOAT Longitude # Longitude in degrees of the location of the station. The # longitude should be between -180 (West) and +180 (East). # FLOAT Elevation # Elevation in meters above sea level of the station. # FLOAT Depth # Depth is the depth in meters of the sensor. # FLOAT Azimuth # Azimuth of the sensor in degrees clockwise. # FLOAT Dip # Dip is the dip of the sensor. 90 degrees is defined as # vertical right way up. data = fh.read(next_tag) parts = _unpack_with_asciiz_and_decode(endian + b"ffffff", data[8:]) params = AttribDict() params.latitude = parts[0] params.longitude = parts[1] params.elevation = parts[2] params.depth = parts[3] params.azimuth = parts[4] params.dip = parts[5] trace.stats.y.tag_station_location = params elif tag_type == 3: # TAG_STATION_PARAMETERS # UCHAR Update[16] # This field is only used internally for administrative # purposes. It should always be set to zeroes. # REALTIME StartValidTime # Time that the information in these records became valid. # REALTIME EndValidTime # Time that the information in these records became invalid. # FLOAT Sensitivity # Sensitivity of the sensor in nanometers per bit. # FLOAT SensFreq # Frequency at which the sensitivity was measured. # FLOAT SampleRate # This is the number of samples per second. This value can be # less than 1.0. (i.e. 0.1) # FLOAT MaxClkDrift # Maximum drift rate of the clock in seconds per sample. # UCHAR SensUnits[24] (ASCIIZ) # Some text indicating the units in which the sensitivity was # measured. # UCHAR CalibUnits[24] (ASCIIZ) # Some text indicating the units in which calibration input # was measured. # UCHAR ChanFlags[27] (BLANKPAD) # Text indicating the channel flags according to the SEED # definition. # UCHAR UpdateFlag # This flag must be “N” or “U” according to the SEED # definition. # UCHAR Filler[4] # Filler Pads out the record to satisfy the alignment # restrictions for reading data on a SPARC processor. data = fh.read(next_tag) parts = _unpack_with_asciiz_and_decode(endian + b"ddffff24z24z27sc4s", data[16:]) trace.stats.sampling_rate = parts[4] # extra params = AttribDict() params.start_valid_time = parts[0] params.end_valid_time = parts[1] params.sensitivity = parts[2] params.sens_freq = parts[3] params.sample_rate = parts[4] params.max_clk_drift = parts[5] params.sens_units = parts[6] params.calib_units = parts[7] params.chan_flags = parts[8] params.update_flag = parts[9] trace.stats.y.tag_station_parameters = params elif tag_type == 4: # TAG_STATION_DATABASE # UCHAR Update[8] # This field is only used internally for administrative # purposes. It should always be set to zeroes. # REALTIME LoadDate # Date the information was loaded into the database. # UCHAR Key[16] # Unique key that identifies this record in the database. data = fh.read(next_tag) parts = _unpack_with_asciiz_and_decode(endian + b"d16s", data[8:]) params = AttribDict() params.load_date = parts[0] params.key = parts[1] trace.stats.y.tag_station_database = params elif tag_type == 5: # TAG_SERIES_INFO # UCHAR Update[16] # This field is only used internally for administrative # purposes. It should always be set to zeroes. # REALTIME StartTime # This is start time of the data in this series. # REALTIME EndTime # This is end time of the data in this series. # ULONG NumSamples # This is the number of samples of data in this series. # LONG DCOffset # DCOffset is the DC offset of the data. # LONG MaxAmplitude # MaxAmplitude is the maximum amplitude of the data. # LONG MinAmplitude # MinAmplitude is the minimum amplitude of the data. # UCHAR Format[8] (ASCIIZ) # This is the format of the data. This should always be # “YFILE”. # UCHAR FormatVersion[8] (ASCIIZ) # FormatVersion is the version of the format of the data. # This should always be “5.0” data = fh.read(next_tag) parts = _unpack_with_asciiz_and_decode(endian + b"ddLlll8z8z", data[16:]) trace.stats.starttime = UTCDateTime(parts[0]) count = parts[2] # extra params = AttribDict() params.endtime = UTCDateTime(parts[1]) params.num_samples = parts[2] params.dc_offset = parts[3] params.max_amplitude = parts[4] params.min_amplitude = parts[5] params.format = parts[6] params.format_version = parts[7] trace.stats.y.tag_series_info = params elif tag_type == 6: # TAG_SERIES_DATABASE # UCHAR Update[8] # This field is only used internally for administrative # purposes. It should always be set to zeroes. # REALTIME LoadDate # Date the information was loaded into the database. # UCHAR Key[16] # Unique key that identifies this record in the database. data = fh.read(next_tag) parts = _unpack_with_asciiz_and_decode(endian + b"d16s", data[8:]) params = AttribDict() params.load_date = parts[0] params.key = parts[1] trace.stats.y.tag_series_database = params elif tag_type == 26: # TAG_STATION_RESPONSE # UCHAR Update[8] # This field is only used internally for administrative # purposes. It should always be set to zeroes. # UCHAR PathName[260] # PathName is the full name of the file which contains the # response information for this station. data = fh.read(next_tag) parts = _unpack_with_asciiz_and_decode(b"260s", data[8:]) params = AttribDict() params.path_name = parts[0] trace.stats.y.tag_station_response = params elif tag_type == 7: # TAG_DATA_INT32 trace.data = from_buffer(fh.read(np.dtype(np.int32).itemsize * count), dtype=np.int32) # break loop as TAG_DATA_INT32 should be the last tag in file break else: fh.seek(next_tag, 1) return Stream([trace])
def _single_corr_trace_to_obspy_trace(trace): """ Convert a correlation trace dictionary to an obspy trace. Convert a single correlation trace in an :class:`~obspy.core.trace.Trace` object. :type corr_trace: dictionary of type correlation trace :param corr_trace: input date to be converted :rtype: :class:`~obspy.core.trace.Trace` :return: **tr**: the obspy object containing the data """ tr = Trace(data=np.squeeze(trace['corr_trace'])) stats_keys = ['network', 'station', 'location', 'channel', 'npts', 'sampling_rate'] sac_keys = ['baz', 'az', 'stla', 'stlo', 'stel', 'evla', 'evlo', 'evel', 'dist'] # copy stats for key in stats_keys: try: tr.stats[key] = trace['stats'][key] except: print 'Error copying key: %s' % key raise # special keys tr.stats['starttime'] = UTCDateTime( convert_time([trace['stats']['starttime']])[0]) # test for presence of geo information flag = 0 for key in sac_keys: if not key in trace['stats']: flag += 1 if flag == 0: # geo information present tr.stats['sac'] = {} for key in sac_keys: tr.stats['sac'][key] = trace['stats'][key] # copy stats_tr1 if 'stats_tr1' in trace: tr.stats_tr1 = Stats() tr.stats_tr1['starttime'] = UTCDateTime( convert_time([trace['stats_tr1']['starttime']])[0]) for key in stats_keys: try: tr.stats_tr1[key] = trace['stats_tr1'][key] except: print 'Error copying key: %s' % key raise for key in sac_keys: try: tr.stats_tr1[key] = trace['stats_tr1'][key] except: pass # copy stats_tr2 if 'stats_tr2' in trace: tr.stats_tr2 = Stats() tr.stats_tr2['starttime'] = UTCDateTime( convert_time([trace['stats_tr2']['starttime']])[0]) for key in stats_keys: try: tr.stats_tr2[key] = trace['stats_tr2'][key] except: print 'Error copying key: %s' % key raise for key in sac_keys: try: tr.stats_tr2[key] = trace['stats_tr2'][key] except: pass return tr
def getData(tstart, tend, opt): """ Download data from files in a folder, from IRIS, or a Earthworm waveserver A note on SAC/miniSEED files: as this makes no assumptions about the naming scheme of your data files, please ensure that your headers contain the correct SCNL information! tstart: UTCDateTime of beginning of period of interest tend: UTCDateTime of end of period of interest opt: Options object describing station/run parameters Returns ObsPy stream objects, one for cutting and the other for triggering """ nets = opt.network.split(',') stas = opt.station.split(',') locs = opt.location.split(',') chas = opt.channel.split(',') st = Stream() if opt.server == 'SAC' or opt.server == 'miniSEED': # Generate list of files if opt.server == 'SAC': flist = list(itertools.chain.from_iterable(glob.iglob(os.path.join( root,'*.sac')) for root, dirs, files in os.walk(opt.sacdir)))+list( itertools.chain.from_iterable(glob.iglob(os.path.join( root,'*.SAC')) for root, dirs, files in os.walk(opt.sacdir))) elif opt.server == 'miniSEED': flist = list(itertools.chain.from_iterable(glob.iglob(os.path.join( root,'*.mseed')) for root, dirs, files in os.walk(opt.mseeddir)))+list( itertools.chain.from_iterable(glob.iglob(os.path.join( root,'*.MSEED')) for root, dirs, files in os.walk(opt.mseeddir))) # Determine which subset of files to load based on start and end times and # station name; we'll fully deal with stations below flist_sub = [] for f in flist: # Load header only stmp = obspy.read(f, headonly=True) # Check if station is contained in the stas list if stmp[0].stats.station in stas: # Check if contains either start or end time ststart = stmp[0].stats.starttime stend = stmp[0].stats.endtime if (ststart<=tstart and tstart<=stend) or (ststart<=tend and tend<=stend) or (tstart<=stend and ststart<=tend): flist_sub.append(f) # Fully load data from file stmp = Stream() for f in flist_sub: tmp = obspy.read(f, starttime=tstart, endtime=tend+opt.maxdt) if len(tmp) > 0: stmp = stmp.extend(tmp) # Filter and merge stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax, corners=2, zerophase=True) stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig) for m in range(len(stmp)): if stmp[m].stats.sampling_rate != opt.samprate: stmp[m] = stmp[m].resample(opt.samprate) stmp = stmp.merge(method=1, fill_value=0) # Only grab stations/channels that we want and in order netlist = [] stalist = [] chalist = [] loclist = [] for s in stmp: stalist.append(s.stats.station) chalist.append(s.stats.channel) netlist.append(s.stats.network) loclist.append(s.stats.location) # Find match of SCNL in header or fill empty for n in range(len(stas)): for m in range(len(stalist)): if (stas[n] in stalist[m] and chas[n] in chalist[m] and nets[n] in netlist[m] and locs[n] in loclist[m]): st = st.append(stmp[m]) if len(st) == n: print("Couldn't find "+stas[n]+'.'+chas[n]+'.'+nets[n]+'.'+locs[n]) trtmp = Trace() trtmp.stats.sampling_rate = opt.samprate trtmp.stats.station = stas[n] st = st.append(trtmp.copy()) else: if '.' not in opt.server: client = Client(opt.server) else: client = EWClient(opt.server, opt.port) for n in range(len(stas)): try: stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n], tstart, tend+opt.maxdt) stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax, corners=2, zerophase=True) stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig) for m in range(len(stmp)): if stmp[m].stats.sampling_rate != opt.samprate: stmp[m] = stmp[m].resample(opt.samprate) stmp = stmp.merge(method=1, fill_value=0) except (obspy.clients.fdsn.header.FDSNException): try: # try again stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n], tstart, tend+opt.maxdt) stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax, corners=2, zerophase=True) stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig) for m in range(len(stmp)): if stmp[m].stats.sampling_rate != opt.samprate: stmp[m] = stmp[m].resample(opt.samprate) stmp = stmp.merge(method=1, fill_value=0) except (obspy.clients.fdsn.header.FDSNException): print('No data found for {0}.{1}'.format(stas[n],nets[n])) trtmp = Trace() trtmp.stats.sampling_rate = opt.samprate trtmp.stats.station = stas[n] stmp = Stream().extend([trtmp.copy()]) # Last check for length; catches problem with empty waveserver if len(stmp) != 1: print('No data found for {0}.{1}'.format(stas[n],nets[n])) trtmp = Trace() trtmp.stats.sampling_rate = opt.samprate trtmp.stats.station = stas[n] stmp = Stream().extend([trtmp.copy()]) st.extend(stmp.copy()) # Edit 'start' time if using offset option if opt.maxdt: dts = np.fromstring(opt.offset, sep=',') for n, tr in enumerate(st): tr.stats.starttime = tr.stats.starttime-dts[n] st = st.trim(starttime=tstart, endtime=tend, pad=True, fill_value=0) stC = st.copy() return st, stC