def _data(): """returns a dict with fields 'mseed', 'mseed_ACC', 'mseed_VEL', 'mseed_DISP' (all Streams. The latter three after removing the response) 'inventory' (an inventory object) and two strings: 'mseed_path' and 'inventory_path'""" folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data') mseed_path = os.path.join(folder, 'trace_GE.APE.mseed') mseed = obspy_read(mseed_path) inv_path = os.path.join(folder, 'inventory_GE.APE.xml') s = StringIO() with open(inv_path) as _opn: s.write(_opn.read()) s.seek(0) inv_obj = read_inventory(s) ret = {'mseed': mseed, 'inventory': inv_obj, 'mseed_path': mseed_path, 'data_path': folder, 'inventory_path': inv_path} for inv_output in ['ACC', 'VEL', 'DISP']: mseed2 = remove_response(mseed, inv_obj, output=inv_output) ret['mseed_'+inv_output] = mseed2 return ret
def process(pro, seg, cha, sta, evt, dcen, station_inventory, amp_ratio_threshold, arrival_time_delay, savewindow_delta, taper_max_percentage, snr_window_length, remove_response_output, remove_response_water_level, bandpass_corners, bandpass_freq_max, bandpass_max_nyquist_ratio, multi_event_threshold1, multi_event_threshold1_duration, multi_event_threshold2, coda_window_length, coda_subwindow_length, coda_subwindow_overlap, coda_subwindow_amplitude_threshold, **kwargs): """ Processes a single segment. This function is supposed to perform calculation and set the attributes of the `pro` object (it does not need to return it). These attributes are set in the `models` module and the value types should match (meaning an attribute reflecting an integer database column should be set with integer values only). Exceptions are handled externally and should be consulted by looking at the log messages stored in the output database (whose address is given in the `config.yaml` file) :param pro: a dict-like object (whose keys can be accessed also as attributes, so `pro['whatever]=6 is the same as `pro.whatever=4`) which has to be populated with values resulting from processing the given segment. :param seg: the segment (i.e., time series data) originating the processing. Its actual data can be accessed via `loads(seg.data)` which returns a Stream object. Additional fields are accessible via attributes and their names can be inspected via `seg.keys()` FIXME: write detailed doc! parameters and arguments must not conflict with imported functions """ # convert to UTCDateTime for operations later: a_time = UTCDateTime(seg.arrival_time) + arrival_time_delay mseed = read(StringIO(seg.data)) if get_gaps(mseed): pro.has_gaps = True else: if len(mseed) != 1: raise ValueError("Mseed has more than one Trace") pro.has_gaps = False # work on the trace now. All functions will return Traces or scalars, which is better # so we can write them to database more easily mseed = mseed[0] ampratio = amp_ratio(mseed) pro.amplitude_ratio = ampratio if ampratio >= amp_ratio_threshold: pro.is_saturated = True else: pro.is_saturated = False mseed = bandpass(mseed, evt.magnitude, freq_max=bandpass_freq_max, max_nyquist_ratio=bandpass_max_nyquist_ratio, corners=bandpass_corners) inv_obj = station_inventory mseed_acc = remove_response(mseed, inv_obj, output='ACC', water_level=remove_response_water_level) mseed_vel = remove_response(mseed, inv_obj, output='VEL', water_level=remove_response_water_level) mseed_disp = remove_response(mseed, inv_obj, output='DISP', water_level=remove_response_water_level) mseed_wa = simulate_wa(mseed_disp) mseed_rem_resp = mseed_disp if remove_response_output == 'DISP' else \ (mseed_vel if remove_response_output == 'VEL' else mseed_acc) mseed_cum = cumsum(mseed_rem_resp) cum_times = cumtimes(mseed_cum, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95) t05, t10, t90, t95 = cum_times[0], cum_times[1], cum_times[-2], \ cum_times[-1] # mseed_acc_atime_95 = mseed_acc.slice(a_time, t95) # mseed_vel_atime_t95 = mseed_vel.slice(a_time, t95) # mseed_wa_atime_t95 = mseed_wa.slice(a_time, t95) t_PGA, PGA = maxabs(mseed_acc, a_time, t95) t_PGV, PGV = maxabs(mseed_vel, a_time, t95) t_PWA, PWA = maxabs(mseed_wa, a_time, t95) # instantiate the trace below cause it's used also later ... mseed_rem_resp_t05_t95 = mseed_rem_resp.slice(t05, t95) fft_rem_resp_s = fft(mseed_rem_resp_t05_t95, taper_max_percentage=taper_max_percentage) fft_rem_resp_n = fft(mseed_rem_resp, fixed_time=a_time, window_in_sec=t05-t95, # negative float (in seconds) taper_max_percentage=taper_max_percentage) # calculate the *real* start time snr_rem_resp_t05_t95 = snr(fft_rem_resp_s, fft_rem_resp_n, signals_form='fft', in_db=False) fft_rem_resp_s2 = fft(mseed_rem_resp, t10, t90-t10, taper_max_percentage=taper_max_percentage) fft_rem_resp_n2 = fft(mseed_rem_resp, a_time, t10-t90, taper_max_percentage=taper_max_percentage) snr_rem_resp_t10_t90 = snr(fft_rem_resp_s2, fft_rem_resp_n2, signals_form='fft', in_db=False) fft_rem_resp_s3 = fft(mseed_rem_resp, a_time, snr_window_length, taper_max_percentage=taper_max_percentage) fft_rem_resp_n3 = fft(mseed_rem_resp, a_time, -snr_window_length, taper_max_percentage=taper_max_percentage) snr_rem_resp_fixed_window = snr(fft_rem_resp_s3, fft_rem_resp_n3, signals_form='fft', in_db=False) gme = get_multievent # rename func just to avoid line below is not too wide double_evt = \ gme(mseed_cum, t05, t95, threshold_inside_tmin_tmax_percent=multi_event_threshold1, threshold_inside_tmin_tmax_sec=multi_event_threshold1_duration, threshold_after_tmax_percent=multi_event_threshold2) mseed_rem_resp_savewindow = mseed_rem_resp.slice(a_time-savewindow_delta, t95+savewindow_delta).\ taper(max_percentage=taper_max_percentage) wa_savewindow = mseed_wa.slice(a_time-savewindow_delta, t95+savewindow_delta).\ taper(max_percentage=taper_max_percentage) # deltafreq = dfreq(mseed_rem_resp_t05_t95) # write stuff now to instance: pro.mseed_rem_resp_savewindow = dumps(mseed_rem_resp_savewindow) pro.fft_rem_resp_t05_t95 = dumps(fft_rem_resp_s) pro.fft_rem_resp_until_atime = dumps(fft_rem_resp_n) pro.wood_anderson_savewindow = dumps(wa_savewindow) pro.cum_rem_resp = dumps(mseed_cum) pro.pga_atime_t95 = PGA pro.pgv_atime_t95 = PGV pro.pwa_atime_t95 = PWA pro.t_pga_atime_t95 = dtime(t_PGA) pro.t_pgv_atime_t95 = dtime(t_PGV) pro.t_pwa_atime_t95 = dtime(t_PWA) pro.cum_t05 = dtime(t05) pro.cum_t10 = dtime(t10) pro.cum_t25 = dtime(cum_times[2]) pro.cum_t50 = dtime(cum_times[3]) pro.cum_t75 = dtime(cum_times[4]) pro.cum_t90 = dtime(t90) pro.cum_t95 = dtime(t95) pro.snr_rem_resp_fixedwindow = snr_rem_resp_fixed_window pro.snr_rem_resp_t05_t95 = snr_rem_resp_t05_t95 pro.snr_rem_resp_t10_t90 = snr_rem_resp_t10_t90 # pro.amplitude_ratio = Column(Float) # pro.is_saturated = Column(Boolean) # pro.has_gaps = Column(Boolean) pro.double_event_result = double_evt[0] pro.secondary_event_time = dtime(double_evt[1]) # WITH JESSIE IMPLEMENT CODA ANALYSIS: # pro.coda_tmax = Column(DateTime) # pro.coda_length_sec = Column(Float) return pro