def get_pyrocko_response(self, nslc, fake_input_units=None): responses = [] for stage in self.stage_list: responses.extend(stage.get_pyrocko_response(nslc)) if not self.stage_list and self.instrument_sensitivity: responses.append( trace.PoleZeroResponse( constant=self.instrument_sensitivity.value)) if fake_input_units is not None: if not self.instrument_sensitivity or \ self.instrument_sensitivity.input_units is None: raise NoResponseInformation('no input units given') input_units = self.instrument_sensitivity.input_units.name try: conresp = conversion[fake_input_units.upper(), input_units.upper()] except KeyError: raise NoResponseInformation( 'cannot convert between units: %s, %s' % (fake_input_units, input_units)) if conresp is not None: responses.append(conresp) return trace.MultiplyResponse(responses)
def get_pyrocko_response(self, nslc, fake_input_units=None): responses = [] for stage in self.stage_list: responses.extend(stage.get_pyrocko_response(nslc)) if not self.stage_list and self.instrument_sensitivity: responses.append( trace.PoleZeroResponse( constant=self.instrument_sensitivity.value)) if self.instrument_sensitivity: trial = trace.MultiplyResponse(responses) sval = self.instrument_sensitivity.value sfreq = self.instrument_sensitivity.frequency try: check_resp( trial, sval, sfreq, 0.1, prelude='Instrument sensitivity value inconsistent with ' 'sensitivity computed from complete response\n' ' channel: %s' % '.'.join(nslc)) except InconsistentResponseInformation as e: logger.warn(str(e)) if fake_input_units is not None: if not self.instrument_sensitivity or \ self.instrument_sensitivity.input_units is None: raise NoResponseInformation('no input units given') input_units = self.instrument_sensitivity.input_units.name try: conresp = conversion[fake_input_units.upper(), input_units.upper()] except KeyError: raise NoResponseInformation( 'cannot convert between units: %s, %s' % (fake_input_units, input_units)) if conresp is not None: responses.append(conresp) return trace.MultiplyResponse(responses)
def get_response(self, obj, quantity='displacement'): if (self.responses is None or len(self.responses) == 0) \ and (self.responses_stationxml is None or len(self.responses_stationxml) == 0): raise NotFound('No response information available.') quantity_to_unit = { 'displacement': 'M', 'velocity': 'M/S', 'acceleration': 'M/S**2' } if self.is_blacklisted(obj): raise NotFound('Response is blacklisted:', self.get_nslc(obj)) if not self.is_whitelisted(obj): raise NotFound('Response is not on whitelist:', self.get_nslc(obj)) net, sta, loc, cha = self.get_nslc(obj) tmin, tmax = self.get_tmin_tmax(obj) keys_x = [(net, sta, loc, cha), (net, sta, '', cha), ('', sta, '', cha)] keys = [] for k in keys_x: if k not in keys: keys.append(k) candidates = [] for k in keys: if k in self.responses: for x in self.responses[k]: if x.tmin < tmin and (x.tmax is None or tmax < x.tmax): if quantity == 'displacement': candidates.append(x.response) elif quantity == 'velocity': candidates.append( trace.MultiplyResponse([ x.response, trace.DifferentiationResponse() ])) elif quantity == 'acceleration': candidates.append( trace.MultiplyResponse([ x.response, trace.DifferentiationResponse(2) ])) else: assert False for sx in self.responses_stationxml: try: candidates.append( sx.get_pyrocko_response( (net, sta, loc, cha), timespan=(tmin, tmax), fake_input_units=quantity_to_unit[quantity])) except (fs.NoResponseInformation, fs.MultipleResponseInformation): pass if len(candidates) == 1: return candidates[0] elif len(candidates) == 0: raise NotFound('No response found:', (net, sta, loc, cha)) else: raise NotFound('Multiple responses found:', (net, sta, loc, cha))
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
def post_process(response, norths, easts, stf_spec, stations=False, show=True, savedir=None, save=True, quantity="velocity"): nnorth = norths.size neast = easts.size norths2, easts2 = coords_2d(norths, easts) by_i = defaultdict(list) traces = [] for source, target, tr in response.iter_results(): tr = tr.copy() if quantity == "velocity": trans = trace.DifferentiationResponse(1) if quantity == "acceleration": trans = trace.DifferentiationResponse(2) if quantity is not "displacement": trans = trace.MultiplyResponse([trans, stf_spec]) tr = tr.transfer(transfer_function=trans) #tr.highpass(4, 0.5) #tr.lowpass(4, 4.0) tr_resamp = tr.copy() # uncomment to active resampling to get a smooth image (slow): tr_resamp.resample(tr.deltat * 0.25) by_i[int(target.codes[1])].append(tr_resamp) traces.append(tr) values = num.zeros(nnorth * neast) from pyrocko import trace as trd # if stations is True: # trd.snuffle(traces) # if stations is True: # from pyrocko import io # io.save(traces, "traces_pgv.mseed") plot_trs = [] for i in range(norths2.size): trs = by_i[i] if trs: ysum = num.sqrt(sum(tr.ydata**2 for tr in trs)) ymax = num.max(ysum) values[i] = ymax if norths2[i] == easts2[i]: plot_trs.extend(trs) values = values.reshape((norths.size, easts.size)) if save is True: path = savedir + '/shakemap.pkl' f = open(path, 'wb') pickle.dump([values, easts, norths], f) f.close() return values