def test_filter_trace(): st = testsyn.copy() pre_filt = [1/90., 1/60., 1/27.0, 1/22.5] # check length doesn't change after filtering tr = st[0].copy() proc.filter_trace(tr, pre_filt) assert len(tr.data) == len(st[0].data)
def process_adjoint(adjsrcs, interp_flag=False, interp_starttime=None, interp_delta=None, interp_npts=None, sum_over_comp_flag=False, weight_flag=False, weight_dict=None, filter_flag=False, pre_filt=None, taper_percentage=0.05, taper_type="hann", add_missing_comp_flag=False, rotate_flag=False, inventory=None, event=None): """ Process adjoint sources function, to fit user's needs. Provide: 1) zero padding the adjoint sources, and then interpolation 2) add multiple instrument together 3) rotate from (R, T) to (N, E) :param adjsrcs: adjoint sources list from the same station :type adjsrcs: list :param adj_starttime: starttime of adjoint sources :param adj_starttime: obspy.UTCDateTime :param raw_synthetic: raw synthetic from SPECFEM output, as reference :type raw_synthetic: obspy.Stream or obspy.Trace :param inventory: station inventory :type inventory: obspy.Inventory :param event: event information :type event: obspy.Event :param sum_over_comp_flag: sum over component flag :param weight_dict: weight dictionary """ if not isinstance(adjsrcs, list): raise ValueError("Input adjsrcs should be type of list of adjoint " "sources") # transfer AdjointSource type to stream for easy processing adj_stream, adj_meta = convert_adjs_to_stream(adjsrcs) # time reverse the array time_reverse_array(adj_stream) if interp_flag: interp_adj_stream(adj_stream, interp_starttime, interp_delta, interp_npts) # sum multiple instruments if sum_over_comp_flag: adj_stream, adj_meta = \ sum_adj_on_component(adj_stream, adj_meta, weight_flag=weight_flag, weight_dict=weight_dict) if filter_flag: # after filtering, taper should be applied to ensure the adjoint # source would be zero at two ends adj_stream.taper(max_percentage=taper_percentage, type=taper_type) # filter each trace for tr in adj_stream: filter_trace(tr, pre_filt) # after filtering, taper should be applied to ensure the adjoint # source would be zero at two ends adj_stream.taper(max_percentage=taper_percentage, type=taper_type) if rotate_flag or add_missing_comp_flag: add_missing_components(adj_stream, component_list=["Z", "R", "T"]) if rotate_flag: origin = event.preferred_origin() or event.origins[0] rotate_adj_stream(adj_stream, origin.latitude, origin.longitude, inventory) # convert the stream back to pyadjoint.AdjointSource final_adjsrcs = convert_stream_to_adjs(adj_stream, adj_meta) return final_adjsrcs
def postprocess_adjsrc(adjsrcs, interp_starttime, interp_delta, interp_npts, rotate_flag=False, inventory=None, event=None, sum_over_comp_flag=False, weight_flag=False, weight_dict=None, filter_flag=False, pre_filt=None): """ Postprocess adjoint sources to fit SPECFEM input(same as raw_synthetic) 1) zero padding the adjoint sources 2) interpolation 3) add multiple instrument together if there are 4) rotate from (R, T) to (N, E) :param adjsrcs: adjoint sources list from the same station :type adjsrcs: list :param adj_starttime: starttime of adjoint sources :param adj_starttime: obspy.UTCDateTime :param raw_synthetic: raw synthetic from SPECFEM output, as reference :type raw_synthetic: obspy.Stream or obspy.Trace :param inventory: station inventory :type inventory: obspy.Inventory :param event: event information :type event: obspy.Event :param sum_over_comp_flag: sum over component flag :param weight_dict: weight dictionary """ if not isinstance(adjsrcs, list): raise ValueError("Input adjsrcs should be type of list of adjoint " "sources") # transfer AdjointSource type to stream for easy processing adj_stream = Stream() for adj in adjsrcs: _tr = _convert_adj_to_trace(adj) adj_stream.append(_tr) # zero padding interp_endtime = interp_starttime + interp_delta * interp_npts zero_padding_stream(adj_stream, interp_starttime, interp_endtime) # interpolate adj_stream.interpolate(sampling_rate=1.0/interp_delta, starttime=interp_starttime, npts=interp_npts) # sum multiple instruments if sum_over_comp_flag: adj_stream = sum_adj_on_component(adj_stream, weight_flag, weight_dict) # add zero trace for missing components missinglist = ["Z", "R", "T"] tr_template = adj_stream[0] for tr in adj_stream: missinglist.remove(tr.stats.channel[-1]) for component in missinglist: zero_adj = tr_template.copy() zero_adj.data.fill(0.0) zero_adj.stats.channel = "%s%s" % (tr_template.stats.channel[0:2], component) adj_stream.append(zero_adj) if rotate_flag: rotate_adj(adj_stream, event, inventory) if filter_flag: # filter the adjoint source if pre_filt is None or len(pre_filt) != 4: raise ValueError("Input pre_filt should be a list or tuple with " "length of 4") if not check_array_order(pre_filt, order="ascending"): raise ValueError("Input pre_filt must a in ascending order. The " "unit is Hz") for tr in adj_stream: filter_trace(tr, pre_filt) # convert the stream to pyadjoint.AdjointSource final_adjsrcs = [] adj_src_type = adjsrcs[0].adj_src_type minp = adjsrcs[0].min_period maxp = adjsrcs[0].max_period for tr in adj_stream: final_adjsrcs.append(_convert_trace_to_adj(tr, adj_src_type, minp, maxp)) return final_adjsrcs
def process_adjoint(adjsrcs, interp_flag=False, interp_starttime=None, interp_delta=None, interp_npts=None, sum_over_comp_flag=False, weight_flag=False, weight_dict=None, filter_flag=False, pre_filt=None, taper_percentage=0.05, taper_type="hann", rotate_flag=False, inventory=None, event=None): """ Process adjoint sources function, to fit user's needs. Provide: 1) zero padding the adjoint sources, and then interpolation 2) add multiple instrument together 3) rotate from (R, T) to (N, E) :param adjsrcs: adjoint sources list from the same station :type adjsrcs: list :param adj_starttime: starttime of adjoint sources :param adj_starttime: obspy.UTCDateTime :param raw_synthetic: raw synthetic from SPECFEM output, as reference :type raw_synthetic: obspy.Stream or obspy.Trace :param inventory: station inventory :type inventory: obspy.Inventory :param event: event information :type event: obspy.Event :param sum_over_comp_flag: sum over component flag :param weight_dict: weight dictionary """ if not isinstance(adjsrcs, list): raise ValueError("Input adjsrcs should be type of list of adjoint " "sources") # transfer AdjointSource type to stream for easy processing adj_stream, adj_meta = convert_adjs_to_stream(adjsrcs) if interp_flag: interp_adj_stream(adj_stream, interp_starttime, interp_delta, interp_npts) # sum multiple instruments if sum_over_comp_flag: adj_stream = sum_adj_on_component(adj_stream, weight_flag, weight_dict) if filter_flag: # after filtering, taper should be applied to ensure the adjoint # source would be zero at two ends adj_stream.taper(max_percentage=taper_percentage, type=taper_type) # filter the adjoint source if pre_filt is None or len(pre_filt) != 4: raise ValueError("Input pre_filt should be a list or tuple with " "length of 4") if not check_array_order(pre_filt, order="ascending"): raise ValueError("Input pre_filt must a in ascending order. The " "unit is Hz") for tr in adj_stream: filter_trace(tr, pre_filt) # after filtering, taper should be applied to ensure the adjoint # source would be zero at two ends adj_stream.taper(max_percentage=taper_percentage, type=taper_type) if rotate_flag: rotate_adj_stream(adj_stream, event, inventory) # convert the stream back to pyadjoint.AdjointSource final_adjsrcs = convert_stream_to_adjs(adj_stream, adj_meta) return final_adjsrcs
def postprocess_adjsrc(adjsrcs, interp_starttime, interp_delta, interp_npts, rotate_flag=False, inventory=None, event=None, sum_over_comp_flag=False, weight_flag=False, weight_dict=None, filter_flag=False, pre_filt=None): """ Postprocess adjoint sources to fit SPECFEM input(same as raw_synthetic) 1) zero padding the adjoint sources 2) interpolation 3) add multiple instrument together if there are 4) rotate from (R, T) to (N, E) :param adjsrcs: adjoint sources list from the same station :type adjsrcs: list :param adj_starttime: starttime of adjoint sources :param adj_starttime: obspy.UTCDateTime :param raw_synthetic: raw synthetic from SPECFEM output, as reference :type raw_synthetic: obspy.Stream or obspy.Trace :param inventory: station inventory :type inventory: obspy.Inventory :param event: event information :type event: obspy.Event :param sum_over_comp_flag: sum over component flag :param weight_dict: weight dictionary """ if not isinstance(adjsrcs, list): raise ValueError("Input adjsrcs should be type of list of adjoint " "sources") # transfer AdjointSource type to stream for easy processing adj_stream = Stream() for adj in adjsrcs: _tr = _convert_adj_to_trace(adj) adj_stream.append(_tr) # zero padding interp_endtime = interp_starttime + interp_delta * interp_npts zero_padding_stream(adj_stream, interp_starttime, interp_endtime) # interpolate adj_stream.interpolate(sampling_rate=1.0 / interp_delta, starttime=interp_starttime, npts=interp_npts) # sum multiple instruments if sum_over_comp_flag: adj_stream = sum_adj_on_component(adj_stream, weight_flag, weight_dict) # add zero trace for missing components missinglist = ["Z", "R", "T"] tr_template = adj_stream[0] for tr in adj_stream: missinglist.remove(tr.stats.channel[-1]) for component in missinglist: zero_adj = tr_template.copy() zero_adj.data.fill(0.0) zero_adj.stats.channel = "%s%s" % (tr_template.stats.channel[0:2], component) adj_stream.append(zero_adj) if rotate_flag: rotate_adj(adj_stream, event, inventory) if filter_flag: # filter the adjoint source if pre_filt is None or len(pre_filt) != 4: raise ValueError("Input pre_filt should be a list or tuple with " "length of 4") if not check_array_order(pre_filt, order="ascending"): raise ValueError("Input pre_filt must a in ascending order. The " "unit is Hz") for tr in adj_stream: filter_trace(tr, pre_filt) # convert the stream to pyadjoint.AdjointSource final_adjsrcs = [] adj_src_type = adjsrcs[0].adj_src_type minp = adjsrcs[0].min_period maxp = adjsrcs[0].max_period for tr in adj_stream: final_adjsrcs.append( _convert_trace_to_adj(tr, adj_src_type, minp, maxp)) return final_adjsrcs