Exemplo n.º 1
0
def filter_trace(tr, pre_filt):
    """
    Perform a frequency domain taper mimicing the behavior during the
    response removal, without a actual response removal.

    :param tr: input trace
    :param pre_filt: frequency array(Hz) in ascending order, to define
        the four corners of filter, for example, [0.01, 0.1, 0.2, 0.5].
    :type pre_filt: Numpy.array or list
    :return: filtered trace
    """
    if type(tr) != obspy.Trace:
        raise ValueError("First Argument should be trace: %s" % type(tr))

    if not check_array_order(pre_filt):
        raise ValueError("Frequency band should be in ascending order: %s"
                         % pre_filt)

    data = tr.data.astype(np.float64)

    # smart calculation of nfft dodging large primes
    nfft = _npts2nfft(len(data))

    fy = 1.0 / (tr.stats.delta * 2.0)
    freqs = np.linspace(0, fy, nfft // 2 + 1)

    # Transform data to Frequency domain
    data = np.fft.rfft(data, n=nfft)
    data *= c_sac_taper(freqs, flimit=pre_filt)
    data[-1] = abs(data[-1]) + 0.0j
    # transform data back into the time domain
    data = np.fft.irfft(data)[0:len(data)]
    # assign processed data and store processing information
    tr.data = data
Exemplo n.º 2
0
def filter_trace(tr, pre_filt):
    """
    Perform a frequency domain taper mimicing the behavior during the
    response removal, without a actual response removal.

    :param tr: input trace
    :param pre_filt: frequency array(Hz) in ascending order, to define
        the four corners of filter, for example, [0.01, 0.1, 0.2, 0.5].
    :type pre_filt: Numpy.array or list
    :return: filtered trace
    """
    if not isinstance(tr, Trace):
        raise TypeError("First Argument should be trace: %s" % type(tr))

    if not check_array_order(pre_filt):
        raise ValueError("Frequency band should be in ascending order: %s" %
                         pre_filt)

    data = tr.data.astype(np.float64)

    # smart calculation of nfft dodging large primes
    nfft = _npts2nfft(len(data))

    fy = 1.0 / (tr.stats.delta * 2.0)
    freqs = np.linspace(0, fy, nfft // 2 + 1)

    # Transform data to Frequency domain
    data = np.fft.rfft(data, n=nfft)
    data *= c_sac_taper(freqs, flimit=pre_filt)
    data[-1] = abs(data[-1]) + 0.0j
    # transform data back into the time domain
    data = np.fft.irfft(data)[0:len(data)]
    # assign processed data and store processing information
    tr.data = data
Exemplo n.º 3
0
def filter_synt(tr, pre_filt):
    """
    Perform a frequency domain taper like during the response removal
    just without an actual response...

    :param tr:
    :param pre_filt:
    :return:
    """

    data = tr.data.astype(np.float64)

    # smart calculation of nfft dodging large primes
    nfft = _npts2nfft(len(data))

    fy = 1.0 / (tr.stats.delta * 2.0)
    freqs = np.linspace(0, fy, nfft // 2 + 1)

    # Transform data to Frequency domain
    data = np.fft.rfft(data, n=nfft)
    data *= c_sac_taper(freqs, flimit=pre_filt)
    data[-1] = abs(data[-1]) + 0.0j
    # transform data back into the time domain
    data = np.fft.irfft(data)[0 : len(data)]
    # assign processed data and store processing information
    tr.data = data
Exemplo n.º 4
0
    def process_function(st, inv):
        st.detrend("linear")
        st.detrend("demean")
        st.taper(max_percentage=0.05, type="hann")

        # Perform a frequency domain taper like during the response removal
        # just without an actual response...
        for tr in st:
            data = tr.data.astype(np.float64)

            # smart calculation of nfft dodging large primes
            from obspy.signal.util import _npts2nfft
            nfft = _npts2nfft(len(data))

            fy = 1.0 / (tr.stats.delta * 2.0)
            freqs = np.linspace(0, fy, nfft // 2 + 1)

            # Transform data to Frequency domain
            data = np.fft.rfft(data, n=nfft)
            data *= c_sac_taper(freqs, flimit=pre_filt)
            data[-1] = abs(data[-1]) + 0.0j
            # transform data back into the time domain
            data = np.fft.irfft(data)[0:len(data)]
            # assign processed data and store processing information
            tr.data = data

        st.detrend("linear")
        st.detrend("demean")
        st.taper(max_percentage=0.05, type="hann")

        st.interpolate(sampling_rate=sampling_rate,
                       starttime=starttime,
                       npts=npts)

        components = [tr.stats.channel[-1] for tr in st]
        if "N" in components and "E" in components:
            station_latitude = inv[0][0].latitude
            station_longitude = inv[0][0].longitude
            _, baz, _ = gps2DistAzimuth(station_latitude, station_longitude,
                                        event_latitude, event_longitude)

            st.rotate(method="NE->RT", back_azimuth=baz)

        # Convert to single precision to save space.
        for tr in st:
            tr.data = np.require(tr.data, dtype="float32")

        return st
    def process_function(st, inv):
        st.detrend("linear")
        st.detrend("demean")
        st.taper(max_percentage=0.05, type="hann")

        # Perform a frequency domain taper like during the response removal
        # just without an actual response...
        for tr in st:
            data = tr.data.astype(np.float64)

            # smart calculation of nfft dodging large primes
            from obspy.signal.util import _npts2nfft
            nfft = _npts2nfft(len(data))

            fy = 1.0 / (tr.stats.delta * 2.0)
            freqs = np.linspace(0, fy, nfft // 2 + 1)

            # Transform data to Frequency domain
            data = np.fft.rfft(data, n=nfft)
            data *= c_sac_taper(freqs, flimit=pre_filt)
            data[-1] = abs(data[-1]) + 0.0j
            # transform data back into the time domain
            data = np.fft.irfft(data)[0:len(data)]
            # assign processed data and store processing information
            tr.data = data

        st.detrend("linear")
        st.detrend("demean")
        st.taper(max_percentage=0.05, type="hann")

        st.interpolate(sampling_rate=sampling_rate, starttime=starttime,
                       npts=npts)

        components = [tr.stats.channel[-1] for tr in st]
        if "N" in components and "E" in components:
            station_latitude = inv[0][0].latitude
            station_longitude = inv[0][0].longitude
            _, baz, _ = gps2DistAzimuth(station_latitude, station_longitude,
                                        event_latitude, event_longitude)

            st.rotate(method="NE->RT", back_azimuth=baz)

        # Convert to single precision to save space.
        for tr in st:
            tr.data = np.require(tr.data, dtype="float32")

        return st
    def process_synthetics(self):

        lowpass_freq = 1 / 60.
        highpass_freq = 1 / 120.

        freqmin = highpass_freq
        freqmax = lowpass_freq

        f2 = highpass_freq
        f3 = lowpass_freq
        f1 = 0.8 * f2
        f4 = 1.2 * f3
        pre_filt = (f1, f2, f3, f4)

        self.tr.differentiate()

        # self.tr.data = convolve_stf(self.tr.data)

        self.tr.detrend("linear")
        self.tr.detrend("demean")
        self.tr.taper(max_percentage=0.05, type="hann")

        # Perform a frequency domain taper like during the response removal
        # just without an actual response...

        data = self.tr.data.astype(np.float64)
        orig_len = len(data)

        # smart calculation of nfft dodging large primes
        from obspy.signal.util import _npts2nfft
        from obspy.signal.invsim import c_sac_taper
        nfft = _npts2nfft(len(data))

        fy = 1.0 / (self.tr.stats.delta * 2.0)
        freqs = np.linspace(0, fy, nfft // 2 + 1)

        # Transform data to Frequency domain
        data = np.fft.rfft(data, n=nfft)
        data *= c_sac_taper(freqs, flimit=pre_filt)
        data[-1] = abs(data[-1]) + 0.0j
        # transform data back into the time domain
        data = np.fft.irfft(data)[0:orig_len]
        # assign processed data and store processing information
        self.tr.data = data
Exemplo n.º 7
0
def pre_filter(stream, pre_filt=(0.02, 0.05, 8.0, 10.0)):
    """
    Applies the same filter as remove_response without actually removing the
    response.
    """
    for tr in stream:
        data = tr.data.astype(np.float64)
        nfft = _npts2nfft(len(data))
        fy = 1.0 / (tr.stats.delta * 2.0)
        freqs = np.linspace(0, fy, nfft // 2 + 1)

        # Transform data to Frequency domain
        data = np.fft.rfft(data, n=nfft)
        data *= c_sac_taper(freqs, flimit=pre_filt)
        data[-1] = abs(data[-1]) + 0.0j
        # transform data back into the time domain
        data = np.fft.irfft(data)[0:tr.stats.npts]
        # assign processed data and store processing information
        tr.data = data
    return stream
Exemplo n.º 8
0
def pre_filter(stream, pre_filt=(0.02, 0.05, 8.0, 10.0)):
    """
    Applies the same filter as remove_response without actually removing the
    response.
    """
    for tr in stream:
        data = tr.data.astype(np.float64)
        nfft = _npts2nfft(len(data))
        fy = 1.0 / (tr.stats.delta * 2.0)
        freqs = np.linspace(0, fy, nfft // 2 + 1)

        # Transform data to Frequency domain
        data = np.fft.rfft(data, n=nfft)
        data *= c_sac_taper(freqs, flimit=pre_filt)
        data[-1] = abs(data[-1]) + 0.0j
        # transform data back into the time domain
        data = np.fft.irfft(data)[0:tr.stats.npts]
        # assign processed data and store processing information
        tr.data = data
    return stream
Exemplo n.º 9
0
def process_synt(datadir, station, event = None, stationxml_dir = None, period_band = None, npts=None,
                sampling_rate=None, output_dir=None, suffix=None):

    # ensemble the stream
    #station_list = generate_station_list(datadir)
    #for station in station_list:
    zdatafile = station[0] + "." + station[1] + ".MXZ.sem.sac"
    ndatafile = station[0] + "." + station[1] + ".MXN.sem.sac"
    edatafile = station[0] + "." + station[1] + ".MXE.sem.sac"
    zpath = os.path.join(datadir, zdatafile)
    npath = os.path.join(datadir, ndatafile)
    epath = os.path.join(datadir, edatafile)
    st = read(zpath)
    st2 = read(npath)
    st3 = read(epath)
    #print st
    #print st2
    st.append(st2[0])
    st.append(st3[0])

    #print "\nProcessing file: %s" %filename
    # interpolation value
    #npts = 3630
    #sampling_rate = 1.0  # Hz
    min_period = period_band[0]
    max_period = period_band[1]
    f2 = 1.0 / max_period
    f3 = 1.0 / min_period
    f1 = 0.8 * f2
    f4 = 1.2 * f3
    pre_filt = (f1, f2, f3, f4)

    # fetch event information
    event_name = get_event_name(event)
    short_event_name = adjust_event_name(event_name)

    origin = event.preferred_origin() or event.origins[0]
    event_latitude = origin.latitude
    event_longitude = origin.longitude
    event_time = origin.time
    event_depth = origin.depth
    starttime = event_time
    print "event_time:",event_time

    #output_path = os.path.join(output_dir, short_event_name)
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    nrecords = len(st)
    # processing
    for i, tr in enumerate(st):
        #get component name
        cmpname = tr.stats.channel
        #print tr.stats
        #tr.interpolate(sampling_rate=sampling_rate, starttime=starttime,
        #                npts=npts)
        #tr.decimate(4, strict_length=False,no_filter=True)
        print "Processing %d of total %d" %(i+1, nrecords)
        print "Detrend, Demean and Taper..."
        tr.detrend("linear")
        tr.detrend("demean")
        tr.taper(max_percentage=0.05, type="hann")
        #print "response show:"
        #print tr.stats.response


        # Perform a frequency domain taper like during the response removal
        # just without an actual response...
        #for tr in st:
        print "Filtering..."
        data = tr.data.astype(np.float64)

        # smart calculation of nfft dodging large primes
        from obspy.signal.util import _npts2nfft
        nfft = _npts2nfft(len(data))

        fy = 1.0 / (tr.stats.delta * 2.0)
        freqs = np.linspace(0, fy, nfft // 2 + 1)

        # Transform data to Frequency domain
        data = np.fft.rfft(data, n=nfft)
        data *= c_sac_taper(freqs, flimit=pre_filt)
        data[-1] = abs(data[-1]) + 0.0j
        # transform data back into the time domain
        data = np.fft.irfft(data)[0:len(data)]
        # assign processed data and store processing information
        tr.data = data

        print "Detrend, Demean and Taper again..."
        tr.detrend("linear")
        tr.detrend("demean")
        tr.taper(max_percentage=0.05, type="hann")
        print "Interpolate..."
        try:
            tr.interpolate(sampling_rate=sampling_rate, starttime=starttime,
                           npts=npts)
        except:
            print "Error"
            return

    # rotate
    station_latitude = st[0].stats.sac['stla']
    station_longitude = st[0].stats.sac['stlo']
    event_latitude = st[0].stats.sac['evla']
    event_longitude = st[0].stats.sac['evlo']
    #print station_latitude, station_longitude
    #print station_latitude, station_longitude
    _, baz, _ = gps2DistAzimuth(station_latitude, station_longitude,
                                    event_latitude, event_longitude)
    print st
    st.rotate(method="NE->RT", back_azimuth=baz)
    # write out
    print st
    for tr in st:
        comp = tr.stats.channel
        outfn = station[0] + "." + station[1] + "." + comp + ".sac"
        if suffix is not None and suffix != "":
            outfn = outfn + "." + suffix
        outpath = os.path.join(output_dir, outfn)
        print "file saved:", outpath
        tr.stats.sac['b'] = 0
        tr.stats.sac['iztype'] = 9
        tr.write(outpath, format="SAC")
Exemplo n.º 10
0
def correct_response(st, removeResp=False, removePAZ=False, simPAZ=False, pre_filt=None, cornFreq=0.0083):
    """
    Correct the seismometer response.
    
    Seismometer response is given in either a dictionary ``removeResp''
    or a dictionary ``removePAZ''. ``removeResp has precedence. The
    dictionaries have the following structure

    removeResp: dictionary with Response information to be removed
        has the following keys:
        respfile: (str) filename of evalresp response file.
        units: (str) Units to return response in. Can be either DIS, VEL or ACC
        start_stage: (int) integer stage numbers of start stage (<0 causes
            default evalresp bahaviour).
        stop_stage: (int) integer stage numbers of stop stage
    removePAZ: dictionary with poles and zeros to be removed has the following
        keys:
            poles: (list of complex numbers) location of poles
            zeros: (list of complex numbers) location of zeros
            gain: (float) gain
            sensitivity: (float) sensitivity
        It can easily be retrieved with obspy.arclink.client.Client.getPAZ

    if ``removeResp'' is given the response of each trace must be present in
    the respfile. If ``removePAZ'' is used the response is assumed to be the
    same for all traces in the stream.
    A filter specified in pre_filt can be applied in to avoid amplification of
    noise.
    The instrument to be simulated is either described in the dictionary simPAZ
    or if simPAZ is False by the corner frequency ``cornFreq''. Response
    correction is done in place and original data is overwritten.
    
    The input stream ``st'' should be demeaned and tapered.
    
    :type st: obspy.core.stream.Stream
    :param st: data stream to be corrected
    :type removeResp: dict
    :param removeResp: Response information to be removed
    :type removePAZ: dict
    :param removePAZ: Response information to be removed
    :type simPAZ: dict
    :param simPAZ: Response information to be simulated
    :type cornFreq: float
    :param cornFreq: corner frequency of instrument to be simulated
    :type pre_filt: list
    :param pre_filt: 4 corners of the filter
    """
    
    for tr in st:
        starttime = tr.stats['starttime']
        endtime = tr.stats['endtime']
        network = tr.stats['network']
        station = tr.stats['station']
        channel = tr.stats['channel']
        location = tr.stats['location']
        length = tr.stats['npts']
        sampling_rate = tr.stats['sampling_rate']
        np2l = nextpow2(2.*length)
        
        if not simPAZ:
            simPAZ = cornFreq2Paz(cornFreq, damp=0.70716)
        simresp, freqs = np.conj(pazToFreqResp(simPAZ['poles'], simPAZ['zeros'],
                          scale_fac=simPAZ['gain']*simPAZ['sensitivity'],
                          t_samp=1./sampling_rate,
                          nfft=np2l, freq=True)) #see Doc of pazToFreqResp for reason of conj()
        
        if removeResp:
            freqresp, freqs = evalresp(1./sampling_rate,np2l,removeResp['respfile'],
                                starttime, network=network, station=station,
                                channel=channel, locid=location,
                                start_stage=removeResp['start_stage'],
                                stop_stage=removeResp['stop_stage'],
                                units=removeResp['units'], freq=True)
        else:
            freqresp, freqs = np.conj(pazToFreqResp(removePAZ['poles'], removePAZ['zeros'],
                          scale_fac=removePAZ['gain']*removePAZ['sensitivity'],
                          t_samp=1./sampling_rate,
                          nfft=np2l, freq=True)) #see Doc of pazToFreqResp for reason of conj()
        
        ftr = np.fft.rfft(tr.data,n=np2l)
        ftr /= freqresp
        ftr[0] = 0.j  # correct the NaN in the DC component
        ftr *= simresp
        
        if pre_filt:
            ftr *= c_sac_taper(freqs, flimit=pre_filt)

        tr.data = np.fft.irfft(ftr)
        tr.trim(starttime,endtime)
    
    return   
Exemplo n.º 11
0
def correct_response(st,
                     removeResp=False,
                     removePAZ=False,
                     simPAZ=False,
                     pre_filt=None,
                     cornFreq=0.0083):
    """
    Correct the seismometer response.
    
    Seismometer response is given in either a dictionary ``removeResp''
    or a dictionary ``removePAZ''. ``removeResp has precedence. The
    dictionaries have the following structure

    removeResp: dictionary with Response information to be removed
        has the following keys:
        respfile: (str) filename of evalresp response file.
        units: (str) Units to return response in. Can be either DIS, VEL or ACC
        start_stage: (int) integer stage numbers of start stage (<0 causes
            default evalresp bahaviour).
        stop_stage: (int) integer stage numbers of stop stage
    removePAZ: dictionary with poles and zeros to be removed has the following
        keys:
            poles: (list of complex numbers) location of poles
            zeros: (list of complex numbers) location of zeros
            gain: (float) gain
            sensitivity: (float) sensitivity
        It can easily be retrieved with obspy.arclink.client.Client.getPAZ

    if ``removeResp'' is given the response of each trace must be present in
    the respfile. If ``removePAZ'' is used the response is assumed to be the
    same for all traces in the stream.
    A filter specified in pre_filt can be applied in to avoid amplification of
    noise.
    The instrument to be simulated is either described in the dictionary simPAZ
    or if simPAZ is False by the corner frequency ``cornFreq''. Response
    correction is done in place and original data is overwritten.
    
    The input stream ``st'' should be demeaned and tapered.
    
    :type st: obspy.core.stream.Stream
    :param st: data stream to be corrected
    :type removeResp: dict
    :param removeResp: Response information to be removed
    :type removePAZ: dict
    :param removePAZ: Response information to be removed
    :type simPAZ: dict
    :param simPAZ: Response information to be simulated
    :type cornFreq: float
    :param cornFreq: corner frequency of instrument to be simulated
    :type pre_filt: list
    :param pre_filt: 4 corners of the filter
    """

    for tr in st:
        starttime = tr.stats['starttime']
        endtime = tr.stats['endtime']
        network = tr.stats['network']
        station = tr.stats['station']
        channel = tr.stats['channel']
        location = tr.stats['location']
        length = tr.stats['npts']
        sampling_rate = tr.stats['sampling_rate']
        np2l = nextpow2(2. * length)

        if not simPAZ:
            simPAZ = cornFreq2Paz(cornFreq, damp=0.70716)
        simresp, freqs = np.conj(
            pazToFreqResp(
                simPAZ['poles'],
                simPAZ['zeros'],
                scale_fac=simPAZ['gain'] * simPAZ['sensitivity'],
                t_samp=1. / sampling_rate,
                nfft=np2l,
                freq=True))  #see Doc of pazToFreqResp for reason of conj()

        if removeResp:
            freqresp, freqs = evalresp(1. / sampling_rate,
                                       np2l,
                                       removeResp['respfile'],
                                       starttime,
                                       network=network,
                                       station=station,
                                       channel=channel,
                                       locid=location,
                                       start_stage=removeResp['start_stage'],
                                       stop_stage=removeResp['stop_stage'],
                                       units=removeResp['units'],
                                       freq=True)
        else:
            freqresp, freqs = np.conj(
                pazToFreqResp(
                    removePAZ['poles'],
                    removePAZ['zeros'],
                    scale_fac=removePAZ['gain'] * removePAZ['sensitivity'],
                    t_samp=1. / sampling_rate,
                    nfft=np2l,
                    freq=True))  #see Doc of pazToFreqResp for reason of conj()

        ftr = np.fft.rfft(tr.data, n=np2l)
        ftr /= freqresp
        ftr[0] = 0.j  # correct the NaN in the DC component
        ftr *= simresp

        if pre_filt:
            ftr *= c_sac_taper(freqs, flimit=pre_filt)

        tr.data = np.fft.irfft(ftr)
        tr.trim(starttime, endtime)

    return