def get_restitution(self, tr, allowed_methods): if 'polezero' in allowed_methods: try: zeros, poles, constant = self._get_polezero(tr) zeros.append(0.0j) # for displacement return trace.PoleZeroResponse( poles, zeros, 1./constant ) except FileNotFound: pass if 'sampled' in allowed_methods: try: freqs, values = self._get_sampledresponse(tr) return trace.SampledResponse( freqs, 1.0/values ) except FileNotFound: pass if 'integration' in allowed_methods: try: cha = self.get_channel(tr) if cha is None: raise eventdata.NoRestitution('No gain information available') if cha.gain == 0.0: raise eventdata.NoRestitution('Gain is zero') return trace.IntegrationResponse(1./cha.gain) except FileNotFound, e: raise eventdata.NoRestitution(e)
def test_dump_load(self): r = trace.FrequencyResponse() r = trace.PoleZeroResponse([0j, 0j], [1j, 2j, 1 + 3j, 1 - 3j], 1.0) r.regularize() r2 = guts.load_string(r.dump()) assert cnumeq(r.poles, r2.poles, 1e-6) assert cnumeq(r.zeros, r2.zeros, 1e-6) assert numeq(r.constant, r2.constant) r = trace.SampledResponse([0., 1., 5., 10.], [0., 1., 1., 0.]) r.regularize() r2 = guts.load_string(r.dump()) assert numeq(r.frequencies, r2.frequencies, 1e-6) assert cnumeq(r.values, r2.values, 1e-6) r = trace.IntegrationResponse(2, 5.0) r2 = guts.load_string(r.dump()) assert numeq(r.n, r2.n) assert numeq(r.gain, r2.gain, 1e-6) r = trace.DifferentiationResponse(2, 5.0) r2 = guts.load_string(r.dump()) assert numeq(r.n, r2.n) assert numeq(r.gain, r2.gain, 1e-6) r = trace.AnalogFilterResponse(a=[1.0, 2.0, 3.0], b=[2.0, 3.0]) r2 = guts.load_string(r.dump()) assert numeq(r.a, r2.a, 1e-6) assert numeq(r.b, r2.b, 1e-6)
def testIntegrationDifferentiation(self): tlen = 100. dt = 0.1 n = int(tlen / dt) f = 0.5 tfade = tlen / 10. xdata = num.arange(n) * dt ydata = num.sin(xdata * 2. * num.pi * f) a = trace.Trace(channel='A', deltat=dt, ydata=ydata) b = a.transfer(tfade, (0.0, 0.1, 2., 3.), transfer_function=trace.IntegrationResponse()) b.set_codes(channel='B') c = a.transfer(tfade, (0.0, 0.1, 2., 3.), transfer_function=trace.DifferentiationResponse()) c.set_codes(channel='C') eps = 0.001 xdata = b.get_xdata() ydata = b.get_ydata() ydata_shouldbe = -num.cos(xdata * 2 * num.pi * f) / (2. * num.pi * f) assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \ 'integration failed' xdata = c.get_xdata() ydata = c.get_ydata() ydata_shouldbe = num.cos(xdata * 2 * num.pi * f) * (2. * num.pi * f) assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \ 'differentiation failed'
def testIntegrationDifferentiation(self): fmin = 0.1 fmax = 2.0 for tlen in [100., 1000., 10000]: for dt in [0.1, 0.05]: for f in [0.2, 0.5, 1.0]: n = int(tlen / dt) tfade = 2.0 / fmin xdata = num.arange(n) * dt ydata = num.sin(xdata * 2. * num.pi * f) a = trace.Trace(channel='A', deltat=dt, ydata=ydata) b = a.transfer( tfade, (fmin / 2., fmin, fmax, fmax * 2.), transfer_function=trace.IntegrationResponse()) b.set_codes(channel='B') c = a.transfer( tfade, (fmin / 2., fmin, fmax, fmax * 2.), transfer_function=trace.DifferentiationResponse()) c.set_codes(channel='C') eps = 0.005 xdata = b.get_xdata() ydata = b.get_ydata() ydata_shouldbe = -num.cos(xdata * 2 * num.pi * f) / ( 2. * num.pi * f) # if num.amax(num.abs(ydata-ydata_shouldbe)) > eps: # b_shouldbe = trace.Trace( # channel='B', location='integrated', # deltat=dt, ydata=ydata_shouldbe, tmin=xdata[0]) # trace.snuffle([b, b_shouldbe]) assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \ 'integration failed' xdata = c.get_xdata() ydata = c.get_ydata() ydata_shouldbe = num.cos( xdata * 2 * num.pi * f) * (2. * num.pi * f) # if num.amax(num.abs(ydata-ydata_shouldbe)) > eps: # c_shouldbe = trace.Trace( # channel='C', location='differentiated', # deltat=dt, ydata=ydata_shouldbe, tmin=xdata[0]) # trace.snuffle([c, c_shouldbe]) assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \ 'differentiation failed'
import numpy as num from pyrocko.guts import StringChoice, StringPattern, UnicodePattern, String,\ Unicode, Int, Float, List, Object, Timestamp, ValidationError, TBase from pyrocko.guts import load_xml # noqa from pyrocko import trace, model, util guts_prefix = 'pf' logger = logging.getLogger('pyrocko.fdsn.station') conversion = { ('M', 'M'): None, ('M/S', 'M'): trace.IntegrationResponse(1), ('M/S**2', 'M'): trace.IntegrationResponse(2), ('M', 'M/S'): trace.DifferentiationResponse(1), ('M/S', 'M/S'): None, ('M/S**2', 'M/S'): trace.IntegrationResponse(1), ('M', 'M/S**2'): trace.DifferentiationResponse(2), ('M/S', 'M/S**2'): trace.DifferentiationResponse(1), ('M/S**2', 'M/S**2'): None } class NoResponseInformation(Exception): pass class MultipleResponseInformation(Exception):
def get_restitution(self, tr, allowed_methods): if 'integration' in allowed_methods: trace.IntegrationResponse() else: raise Exception('only "integration" restitution method is allowed')
def evaluate(self, engine, source, targets, dataset=None, trs=None, extra_responses=[], debug=False): from ..waveform import target as base trs_processed = [] trs_orig = [] for itarget, target in enumerate(targets): if target.codes[-1] not in self.channels: continue store = engine.get_store(target.store_id) tmin = source.time + store.t(self.timing_tmin, source, target) tmax = source.time + store.t(self.timing_tmax, source, target) if self.fmin is not None and self.fmax is not None: freqlimits = [ self.fmin / 2., self.fmin, self.fmax, self.fmax * 2. ] tfade = 1. / self.fmin else: freqlimits = None tfade = 0.0 if dataset is not None: bazi = base.backazimuth_for_waveform(target.azimuth, target.codes) tr = dataset.get_waveform(target.codes, tinc_cache=1.0 / self.fmin, quantity=self.quantity, tmin=tmin, tmax=tmax, freqlimits=freqlimits, tfade=tfade, deltat=store.config.deltat, cache=True, backazimuth=bazi) else: tr = trs[itarget] tr.extend(tmin - tfade, tmax + tfade, fillmethod='repeat') tr = tr.transfer(freqlimits=freqlimits, tfade=tfade) trs_orig.append(tr) tr = tr.copy() responses = [] responses.extend(extra_responses) ndiff = \ WaveformQuantity.choices.index(self.quantity) - \ WaveformQuantity.choices.index(target.quantity) if ndiff > 0: responses.append(trace.DifferentiationResponse(ndiff)) if ndiff < 0: responses.append(trace.IntegrationResponse(-ndiff)) if self.response: responses.append(self.response) if self.named_response: responses.append(NamedResponse.map[self.named_response]) if responses: trans = trace.MultiplyResponse(responses) try: tr = tr.transfer(transfer_function=trans) except trace.TraceTooShort: raise FeatureMeasurementFailed('transfer: trace too short') if tmin is None or tmax is None: raise FeatureMeasurementFailed( 'timing determination failed (phase unavailable?)') tr.chop(tmin, tmax) tr.set_location(tr.location + '-' + self.name + '-proc') trs_processed.append(tr) markers = [] marker_candidates = [] if self.method in ['peak_component', 'peak_to_peak_component']: component_amp_maxs = [] for tr in trs_processed: y = tr.get_ydata() if self.method == 'peak_component': yabs = num.abs(y) i_at_amax = num.argmax(yabs) amax = yabs[i_at_amax] if debug: t_at_amax = tr.tmin + i_at_amax * tr.deltat mark = marker.Marker([tr.nslc_id], t_at_amax, t_at_amax, 0) marker_candidates.append(mark) component_amp_maxs.append(amax) else: i_at_amax = num.argmax(y) i_at_amin = num.argmin(y) amax = y[i_at_amax] amin = y[i_at_amin] if debug: t_at_amax = tr.tmin + i_at_amax * tr.deltat t_at_amin = tr.tmin + i_at_amin * tr.deltat ts = sorted([t_at_amax, t_at_amin]) mark = marker.Marker([tr.nslc_id], ts[0], ts[1], 0) marker_candidates.append(mark) component_amp_maxs.append(amax - amin) i_at_amax = num.argmax(component_amp_maxs) if debug: markers.append(marker_candidates[i_at_amax]) amp_max = component_amp_maxs[i_at_amax] elif self.method == 'peak_absolute_vector': trsum = None for tr in trs_processed: tr.set_ydata(tr.get_ydata()**2) if trsum is None: trsum = tr else: trsum.add(tr) trsum.set_ydata(num.sqrt(tr.get_ydata)) trsum.set_codes(channel='SUM') yabs = trsum.get_ydata() i_at_amax = num.argmax(yabs) amax = yabs[i_at_amax] t_at_amax = tr.tmin + i_at_amax * tr.deltat amp_max = amax if debug: markers.append( marker.Marker([trsum.nslc_id], t_at_amax, t_at_amax, 0)) trs_processed.append(trsum) elif self.method == 'spectral_average': component_amp_maxs = [] for tr in trs_processed: freqs, values = tr.spectrum() component_amp_maxs.append( num.mean( num.abs(values[num.logical_and(self.fmin <= freqs, freqs <= self.fmax)]))) amp_max = num.mean(component_amp_maxs) if debug: trs_out = [] for tr in trs_orig: tr_out = tr.copy() tr_out.set_location(tr_out.location + '-' + self.name) trs_out.append(tr_out) return amp_max, (trs_out + trs_processed, markers) return amp_max, None