Beispiel #1
0
def test_tfnoise_day_demo(tmp_path):
    daynoise = test_daynoise_demo()
    with pytest.raises(TypeError):
        assert TFNoise([])
    with pytest.raises(Exception):
        TFNoise(objnoise=daynoise)
    daynoise.average_daily_spectra()
    tfnoise_day = TFNoise(daynoise)
    tfnoise_day.transfer_func()
    d = tmp_path / "tmp"
    tfnoise_day.save(d)
    return tfnoise_day
def main():

    # Run Input Parser
    args = arguments.get_transfer_arguments()

    # Load Database
    db = stdb.io.load_db(fname=args.indb)

    # Construct station key loop
    allkeys = db.keys()
    sorted(allkeys)

    # Extract key subset
    if len(args.stkeys) > 0:
        stkeys = []
        for skey in args.stkeys:
            stkeys.extend([s for s in allkeys if skey in s])
    else:
        stkeys = db.keys()
        sorted(stkeys)

    # Loop over station keys
    for stkey in list(stkeys):

        # Extract station information from dictionary
        sta = db[stkey]

        if not args.skip_daily:
            # Path where spectra are located
            specpath = Path('SPECTRA') / stkey
            if not specpath.is_dir():
                raise (Exception("Path to " + str(specpath) +
                                 " doesn't exist - aborting"))

        if not args.skip_clean:
            # Path where average spectra will be saved
            avstpath = Path('AVG_STA') / stkey
            if not avstpath.is_dir():
                print("Path to " + str(avstpath) +
                      " doesn't exist - skipping cleaned station spectra")
                args.skip_clean = True

        if args.skip_daily and args.skip_clean:
            print("skipping both daily and clean spectra")
            continue

        # Path where transfer functions will be located
        tfpath = Path('TF_STA') / stkey
        if not tfpath.is_dir():
            print("Path to " + str(tfpath) + " doesn't exist - creating it")
            tfpath.mkdir(parents=True)

        # Path where plots will be saved
        if args.saveplot:
            plotpath = tfpath / 'PLOTS'
            if not plotpath.is_dir():
                plotpath.mkdir(parents=True)
        else:
            plotpath = False

        # Get catalogue search start time
        if args.startT is None:
            tstart = sta.startdate
        else:
            tstart = args.startT

        # Get catalogue search end time
        if args.endT is None:
            tend = sta.enddate
        else:
            tend = args.endT

        if tstart > sta.enddate or tend < sta.startdate:
            continue

        # Temporary print locations
        tlocs = sta.location
        if len(tlocs) == 0:
            tlocs = ['']
        for il in range(0, len(tlocs)):
            if len(tlocs[il]) == 0:
                tlocs[il] = "--"
        sta.location = tlocs

        # Update Display
        print(" ")
        print(" ")
        print("|===============================================|")
        print("|===============================================|")
        print("|                   {0:>8s}                    |".format(
            sta.station))
        print("|===============================================|")
        print("|===============================================|")
        print("|  Station: {0:>2s}.{1:5s}                            |".format(
            sta.network, sta.station))
        print("|      Channel: {0:2s}; Locations: {1:15s}  |".format(
            sta.channel, ",".join(tlocs)))
        print("|      Lon: {0:7.2f}; Lat: {1:6.2f}                |".format(
            sta.longitude, sta.latitude))
        print("|      Start time: {0:19s}          |".format(
            sta.startdate.strftime("%Y-%m-%d %H:%M:%S")))
        print("|      End time:   {0:19s}          |".format(
            sta.enddate.strftime("%Y-%m-%d %H:%M:%S")))
        print("|-----------------------------------------------|")

        # Filename for output transfer functions
        dstart = str(tstart.year).zfill(4) + '.' + str(
            tstart.julday).zfill(3) + '-'
        dend = str(tend.year).zfill(4) + '.' + str(tend.julday).zfill(3) + '.'
        fileavst = avstpath / (dstart + dend + 'avg_sta.pkl')

        # Find all files in directories
        p = specpath.glob('*spectra.pkl')
        spectra_files = [x for x in p if x.is_file()]
        if not args.skip_clean:
            p = avstpath.glob('*avg_sta.pkl')
            average_files = [x for x in p if x.is_file()]

        if not args.skip_daily:

            day_transfer_functions = []

            # Cycle through available files
            for filespec in spectra_files:

                year = filespec.name.split('.')[0]
                jday = filespec.name.split('.')[1]

                print()
                print("*********************************************" +
                      "***************")
                print("* Calculating transfer functions for key " + stkey +
                      " and day " + year + "." + jday)
                tstamp = year + '.' + jday + '.'
                filename = tfpath / (tstamp + 'transfunc.pkl')

                # Load file
                file = open(filespec, 'rb')
                daynoise = pickle.load(file)
                file.close()

                # Load spectra into TFNoise object
                daytransfer = TFNoise(daynoise)

                # Calculate the transfer functions
                daytransfer.transfer_func()

                # Store the frequency axis
                f = daytransfer.f

                # Append to list of transfer functions
                day_transfer_functions.append(daytransfer.transfunc)

                # Save daily transfer functions to file
                daytransfer.save(filename)

        if not args.skip_clean:

            # Cycle through available files
            for fileavst in average_files:

                name = fileavst.name.split('avg_sta')

                print()
                print("*********************************************" +
                      "***************")
                print("* Calculating transfer functions for key " + stkey +
                      " and range " + name[0])
                filename = tfpath / (name[0] + 'transfunc.pkl')

                # Load file
                file = open(fileavst, 'rb')
                stanoise = pickle.load(file)
                file.close()

                # Load spectra into TFNoise object - no Rotation object
                # for station averages
                rotation = Rotation(None, None, None)
                statransfer = TFNoise(stanoise)

                # Calculate the transfer functions
                statransfer.transfer_func()

                # Store the frequency axis
                f = statransfer.f

                # Extract the transfer functions
                sta_transfer_functions = statransfer.transfunc

                # Save average transfer functions to file
                statransfer.save(filename)

        if args.fig_TF:
            fname = stkey + '.' + 'transfer_functions'
            plot = plotting.fig_TF(f,
                                   day_transfer_functions,
                                   daynoise.tf_list,
                                   sta_transfer_functions,
                                   stanoise.tf_list,
                                   skey=stkey)

            if plotpath:
                plot.savefig(plotpath / (fname + '.' + args.form),
                             dpi=300,
                             bbox_inches='tight',
                             format=args.form)
            else:
                plot.show()
Beispiel #3
0
def test_tfnoise_sta_demo(tmp_path):
    stanoise = test_sta_average(tmp_path)
    tfnoise_sta = TFNoise(stanoise)
    tfnoise_sta.transfer_func()
    return tfnoise_sta
Beispiel #4
0
    def transfer_func(self):
        """compute daily transfer function
        """
        targetdt = 1. / self.sps
        oyear = self.otime.year
        omonth = self.otime.month
        oday = self.otime.day
        ohour = self.otime.hour
        omin = self.otime.minute
        osec = self.otime.second
        label = '%d_%s_%d_%d_%d_%d' % (oyear, monthdict[omonth], oday, ohour,
                                       omin, osec)
        self.eventdir = self.datadir + '/' + label
        self.outeventdir = self.outdir + '/' + label
        self.label = label
        chan_type = None
        # load SAC data
        for chtype in self.chan_rank:
            fname1 = self.eventdir + '/%s_%sH1.SAC' % (self.staid, chtype)
            fname2 = self.eventdir + '/%s_%sH2.SAC' % (self.staid, chtype)
            fnamez = self.eventdir + '/%s_%sHZ.SAC' % (self.staid, chtype)
            fnamep = self.eventdir + '/%s_%sDH.SAC' % (self.staid, chtype)
            if os.path.isfile(fname1) and os.path.isfile(fname1) and \
                os.path.isfile(fnamez) and os.path.isfile(fnamep):
                chan_type = chtype
                break
        if chan_type is None:
            return 0
        self.chan_type = chan_type
        fname1 = self.eventdir + '/%s_%sH1.SAC' % (self.staid, chan_type)
        fname2 = self.eventdir + '/%s_%sH2.SAC' % (self.staid, chan_type)
        fnamez = self.eventdir + '/%s_%sHZ.SAC' % (self.staid, chan_type)
        fnamep = self.eventdir + '/%s_%sDH.SAC' % (self.staid, chan_type)
        self.sth = obspy.read(fname1)
        self.sth += obspy.read(fname2)
        self.sth += obspy.read(fnamez)
        self.stp = obspy.read(fnamep)
        #

        if abs(self.sth[0].stats.delta - targetdt) > 1e-3 or abs(self.sth[1].stats.delta - targetdt) > 1e-3 or \
            abs(self.sth[2].stats.delta - targetdt) > 1e-3 or abs(self.stp[0].stats.delta - targetdt) > 1e-3:
            raise ValueError('!!! CHECK fs :' + self.staid)
        else:
            self.sth[0].stats.delta = targetdt
            self.sth[1].stats.delta = targetdt
            self.sth[2].stats.delta = targetdt
            self.stp[0].stats.delta = targetdt
        stime_event = self.sth[-1].stats.starttime
        etime_event = self.sth[-1].stats.endtime
        self.sth.trim(starttime=stime_event,
                      endtime=etime_event,
                      pad=True,
                      nearest_sample=True,
                      fill_value=0.)
        self.stp.trim(starttime=stime_event,
                      endtime=etime_event,
                      pad=True,
                      nearest_sample=True,
                      fill_value=0.)
        self.window = self.sth[-1].stats.npts / self.sps
        # trim data

        # load daily noise data
        daystr = '%d.%s.%d.%s' % (self.otime.year, monthdict[self.otime.month],
                                  self.otime.day, self.staid)
        dfname1 = self.daydir + '/ft_%s.%sH1.SAC' % (daystr, chan_type)
        dfname2 = self.daydir + '/ft_%s.%sH2.SAC' % (daystr, chan_type)
        dfnamez = self.daydir + '/ft_%s.%sHZ.SAC' % (daystr, chan_type)
        dfnamep = self.daydir + '/ft_%s.%sDH.SAC' % (daystr, chan_type)
        if not( os.path.isfile(dfname1) and os.path.isfile(dfname2) and \
                os.path.isfile(dfnamez) and os.path.isfile(dfnamep)):
            return 0
        tr1 = obspy.read(dfname1)[0]
        tr2 = obspy.read(dfname2)[0]
        trZ = obspy.read(dfnamez)[0]
        trP = obspy.read(dfnamep)[0]

        if abs(tr1.stats.delta - targetdt) > 1e-3 or abs(tr2.stats.delta - targetdt) > 1e-3 or \
                abs(trZ.stats.delta - targetdt) > 1e-3 or abs(trP.stats.delta - targetdt) > 1e-3:
            raise ValueError('!!! CHECK fs :' + self.staid)
        else:
            tr1.stats.delta = targetdt
            tr2.stats.delta = targetdt
            trP.stats.delta = targetdt
            trZ.stats.delta = targetdt

        # trim data
        slidind_wlength = self.window - int(
            self.overlap * self.window) * tr1.stats.delta
        stime_noise = tr1.stats.starttime
        newtime = np.floor((tr1.stats.endtime - stime_noise) /
                           slidind_wlength) * slidind_wlength
        tr1.trim(starttime=stime_noise, endtime=stime_noise + newtime)
        tr2.trim(starttime=stime_noise, endtime=stime_noise + newtime)
        trZ.trim(starttime=stime_noise, endtime=stime_noise + newtime)
        trP.trim(starttime=stime_noise, endtime=stime_noise + newtime)

        if np.all(trP.data == 0.) and not (np.all(tr1.data == 0.)
                                           or np.all(tr2.data == 0.)):
            self.daynoise = DayNoise(tr1=tr1,
                                     tr2=tr2,
                                     trZ=trZ,
                                     trP=obspy.Trace(),
                                     overlap=self.overlap,
                                     window=self.window)
            self.out_dtype = 'Z2-1'
        elif (np.all(tr1.data == 0.)
              or np.all(tr2.data == 0.)) and (not np.all(trP.data == 0.)):
            self.daynoise = DayNoise(tr1=obspy.Trace(),
                                     tr2=obspy.Trace(),
                                     trZ=trZ,
                                     trP=trP,
                                     overlap=self.overlap,
                                     window=self.window)
            self.out_dtype = 'ZP'
        elif (not (np.all(tr1.data == 0.) or np.all(tr2.data == 0.))) and (
                not np.all(trP.data == 0.)):
            self.daynoise = DayNoise(tr1=tr1,
                                     tr2=tr2,
                                     trZ=trZ,
                                     trP=trP,
                                     overlap=self.overlap,
                                     window=self.window)
            self.out_dtype = 'ZP-21'
        else:
            return 0
        # self.daynoise.QC_daily_spectra()
        # self.daynoise.average_daily_spectra()
        # self.tfnoise    = TFNoise(self.daynoise)
        # self.tfnoise.transfer_func()
        try:
            self.daynoise.QC_daily_spectra()
            self.daynoise.average_daily_spectra()
            self.tfnoise = TFNoise(self.daynoise)
            self.tfnoise.transfer_func()
        except:
            return -1
        return 1
Beispiel #5
0
class atacr_event_sta(object):
    def __init__(self,
                 inv,
                 datadir,
                 outdir,
                 noisedir,
                 otime,
                 overlap=0.3,
                 chan_rank=['L', 'H', 'B'],
                 sps=1.):
        network = inv.networks[0]
        station = network[0]
        channel = station[0]
        self.stdb_inv   = stdb.StDbElement(network = network.code, station = station.code, channel = channel.code[:2],\
            location = channel.location_code, latitude = station.latitude, longitude = station.longitude,\
                elevation = station.elevation, polarity=1., azcorr=0., startdate = station.start_date,\
                    enddate = station.end_date, restricted_status = station.restricted_status)
        self.datadir = datadir
        self.outdir = outdir
        self.noisedir = noisedir
        self.otime = otime
        self.overlap = overlap
        self.staid = network.code + '.' + station.code
        self.chan_rank = chan_rank
        self.stlo = station.longitude
        self.stla = station.latitude
        self.monthdir = self.noisedir + '/%04d.%s' % (
            self.otime.year, monthdict[self.otime.month])
        self.daydir = self.monthdir + '/%d.%s.%d' % (
            self.otime.year, monthdict[self.otime.month], self.otime.day)
        self.sps = sps
        return

    def transfer_func(self):
        """compute daily transfer function
        """
        targetdt = 1. / self.sps
        oyear = self.otime.year
        omonth = self.otime.month
        oday = self.otime.day
        ohour = self.otime.hour
        omin = self.otime.minute
        osec = self.otime.second
        label = '%d_%s_%d_%d_%d_%d' % (oyear, monthdict[omonth], oday, ohour,
                                       omin, osec)
        self.eventdir = self.datadir + '/' + label
        self.outeventdir = self.outdir + '/' + label
        self.label = label
        chan_type = None
        # load SAC data
        for chtype in self.chan_rank:
            fname1 = self.eventdir + '/%s_%sH1.SAC' % (self.staid, chtype)
            fname2 = self.eventdir + '/%s_%sH2.SAC' % (self.staid, chtype)
            fnamez = self.eventdir + '/%s_%sHZ.SAC' % (self.staid, chtype)
            fnamep = self.eventdir + '/%s_%sDH.SAC' % (self.staid, chtype)
            if os.path.isfile(fname1) and os.path.isfile(fname1) and \
                os.path.isfile(fnamez) and os.path.isfile(fnamep):
                chan_type = chtype
                break
        if chan_type is None:
            return 0
        self.chan_type = chan_type
        fname1 = self.eventdir + '/%s_%sH1.SAC' % (self.staid, chan_type)
        fname2 = self.eventdir + '/%s_%sH2.SAC' % (self.staid, chan_type)
        fnamez = self.eventdir + '/%s_%sHZ.SAC' % (self.staid, chan_type)
        fnamep = self.eventdir + '/%s_%sDH.SAC' % (self.staid, chan_type)
        self.sth = obspy.read(fname1)
        self.sth += obspy.read(fname2)
        self.sth += obspy.read(fnamez)
        self.stp = obspy.read(fnamep)
        #

        if abs(self.sth[0].stats.delta - targetdt) > 1e-3 or abs(self.sth[1].stats.delta - targetdt) > 1e-3 or \
            abs(self.sth[2].stats.delta - targetdt) > 1e-3 or abs(self.stp[0].stats.delta - targetdt) > 1e-3:
            raise ValueError('!!! CHECK fs :' + self.staid)
        else:
            self.sth[0].stats.delta = targetdt
            self.sth[1].stats.delta = targetdt
            self.sth[2].stats.delta = targetdt
            self.stp[0].stats.delta = targetdt
        stime_event = self.sth[-1].stats.starttime
        etime_event = self.sth[-1].stats.endtime
        self.sth.trim(starttime=stime_event,
                      endtime=etime_event,
                      pad=True,
                      nearest_sample=True,
                      fill_value=0.)
        self.stp.trim(starttime=stime_event,
                      endtime=etime_event,
                      pad=True,
                      nearest_sample=True,
                      fill_value=0.)
        self.window = self.sth[-1].stats.npts / self.sps
        # trim data

        # load daily noise data
        daystr = '%d.%s.%d.%s' % (self.otime.year, monthdict[self.otime.month],
                                  self.otime.day, self.staid)
        dfname1 = self.daydir + '/ft_%s.%sH1.SAC' % (daystr, chan_type)
        dfname2 = self.daydir + '/ft_%s.%sH2.SAC' % (daystr, chan_type)
        dfnamez = self.daydir + '/ft_%s.%sHZ.SAC' % (daystr, chan_type)
        dfnamep = self.daydir + '/ft_%s.%sDH.SAC' % (daystr, chan_type)
        if not( os.path.isfile(dfname1) and os.path.isfile(dfname2) and \
                os.path.isfile(dfnamez) and os.path.isfile(dfnamep)):
            return 0
        tr1 = obspy.read(dfname1)[0]
        tr2 = obspy.read(dfname2)[0]
        trZ = obspy.read(dfnamez)[0]
        trP = obspy.read(dfnamep)[0]

        if abs(tr1.stats.delta - targetdt) > 1e-3 or abs(tr2.stats.delta - targetdt) > 1e-3 or \
                abs(trZ.stats.delta - targetdt) > 1e-3 or abs(trP.stats.delta - targetdt) > 1e-3:
            raise ValueError('!!! CHECK fs :' + self.staid)
        else:
            tr1.stats.delta = targetdt
            tr2.stats.delta = targetdt
            trP.stats.delta = targetdt
            trZ.stats.delta = targetdt

        # trim data
        slidind_wlength = self.window - int(
            self.overlap * self.window) * tr1.stats.delta
        stime_noise = tr1.stats.starttime
        newtime = np.floor((tr1.stats.endtime - stime_noise) /
                           slidind_wlength) * slidind_wlength
        tr1.trim(starttime=stime_noise, endtime=stime_noise + newtime)
        tr2.trim(starttime=stime_noise, endtime=stime_noise + newtime)
        trZ.trim(starttime=stime_noise, endtime=stime_noise + newtime)
        trP.trim(starttime=stime_noise, endtime=stime_noise + newtime)

        if np.all(trP.data == 0.) and not (np.all(tr1.data == 0.)
                                           or np.all(tr2.data == 0.)):
            self.daynoise = DayNoise(tr1=tr1,
                                     tr2=tr2,
                                     trZ=trZ,
                                     trP=obspy.Trace(),
                                     overlap=self.overlap,
                                     window=self.window)
            self.out_dtype = 'Z2-1'
        elif (np.all(tr1.data == 0.)
              or np.all(tr2.data == 0.)) and (not np.all(trP.data == 0.)):
            self.daynoise = DayNoise(tr1=obspy.Trace(),
                                     tr2=obspy.Trace(),
                                     trZ=trZ,
                                     trP=trP,
                                     overlap=self.overlap,
                                     window=self.window)
            self.out_dtype = 'ZP'
        elif (not (np.all(tr1.data == 0.) or np.all(tr2.data == 0.))) and (
                not np.all(trP.data == 0.)):
            self.daynoise = DayNoise(tr1=tr1,
                                     tr2=tr2,
                                     trZ=trZ,
                                     trP=trP,
                                     overlap=self.overlap,
                                     window=self.window)
            self.out_dtype = 'ZP-21'
        else:
            return 0
        # self.daynoise.QC_daily_spectra()
        # self.daynoise.average_daily_spectra()
        # self.tfnoise    = TFNoise(self.daynoise)
        # self.tfnoise.transfer_func()
        try:
            self.daynoise.QC_daily_spectra()
            self.daynoise.average_daily_spectra()
            self.tfnoise = TFNoise(self.daynoise)
            self.tfnoise.transfer_func()
        except:
            return -1
        return 1

    def correct(self):
        """compute monthly transfer function
        """
        tmptime = self.sth[-1].stats.starttime
        tstamp  = str(tmptime.year).zfill(4)+'.' + \
            str(tmptime.julday).zfill(3)+'.'
        tstamp  = tstamp + str(tmptime.hour).zfill(2) + \
                    '.'+str(tmptime.minute).zfill(2)
        eventstream = EventStream( sta = self.stdb_inv, sth = self.sth, stp = self.stp,\
                    tstamp = tstamp, lat = self.stla, lon = self.stlo, time = tmptime,\
                    window = self.window, sampling_rate = 1., ncomp = 4)
        eventstream.correct_data(self.tfnoise)
        # save data
        if not os.path.isdir(self.outeventdir):
            os.makedirs(self.outeventdir)
        outTrZ = (self.sth.select(channel='??Z')[0]).copy()
        outTrZ.data = eventstream.correct[self.out_dtype].copy()
        outfnameZ = self.outeventdir + '/%s_%sHZ.SAC' % (self.staid,
                                                         self.chan_type)
        if os.path.isfile(outfnameZ):
            shutil.copyfile(src=outfnameZ, dst=outfnameZ + '_old')
            os.remove(outfnameZ)
        outTrZ.write(outfnameZ, format='SAC')
Beispiel #6
0
def test_tfnoise_day_demo():
    daynoise = test_day_average()
    tfnoise_day = TFNoise(daynoise)
    tfnoise_day.transfer_func()
    return tfnoise_day
Beispiel #7
0
 def transfer_func(self):
     """compute monthly transfer function
     """
     targetdt    = 1./self.sps
     stime       = obspy.UTCDateTime('%04d%02d01' %(self.year, self.month))
     monthdir    = self.monthdir
     if not os.path.isdir(monthdir):
         return False
     chan_type   = None
     Nday        = 0
     while( (stime.year == self.year) and (stime.month == self.month)):
         daydir  = monthdir+'/%d.%s.%d' %(self.year, monthdict[self.month], stime.day)
         if not os.path.isdir(daydir):
             stime   += 86400.
             continue 
         fpattern= daydir+'/ft_%d.%s.%d.%s' %(self.year, monthdict[self.month], stime.day, self.staid)
         if chan_type is None:
             for chtype in self.chan_rank:
                 fname1  = fpattern+'.%sH1.SAC' %chtype
                 fname2  = fpattern+'.%sH2.SAC' %chtype
                 fnamez  = fpattern+'.%sHZ.SAC' %chtype
                 fnamep  = fpattern+'.%sDH.SAC' %chtype
                 if os.path.isfile(fname1) and os.path.isfile(fname1) and \
                     os.path.isfile(fnamez) and os.path.isfile(fnamep):
                     chan_type   = chtype
                     break
         if chan_type is None:
             stime   += 86400.
             continue
         fname1  = fpattern+'.%sH1.SAC' %chan_type
         fname2  = fpattern+'.%sH2.SAC' %chan_type
         fnamez  = fpattern+'.%sHZ.SAC' %chan_type
         fnamep  = fpattern+'.%sDH.SAC' %chan_type
         if not (os.path.isfile(fname1) and os.path.isfile(fname1) and \
                 os.path.isfile(fnamez) and os.path.isfile(fnamep)):
             stime   += 86400.
             continue
         tr1     = obspy.read(fname1)[0]
         stimetr = tr1.stats.starttime
         tr2     = obspy.read(fname2)[0]
         trZ     = obspy.read(fnamez)[0]
         trP     = obspy.read(fnamep)[0]
         
         if abs(tr1.stats.delta - targetdt) > 1e-3 or abs(tr2.stats.delta - targetdt) > 1e-3 or \
             abs(trZ.stats.delta - targetdt) > 1e-3 or abs(trP.stats.delta - targetdt) > 1e-3:
             raise ValueError('!!! CHECK fs :'+ self.staid)
         else:
             tr1.stats.delta     = targetdt
             tr2.stats.delta     = targetdt
             trP.stats.delta     = targetdt
             trZ.stats.delta     = targetdt
         # # # if np.all(tr1.data == 0.) or np.all(tr2.data == 0.) or np.all(trZ.data == 0.) or np.all(trP.data == 0.):
         # # #     stime   += 86400.
         # # #     continue
         tr1.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
         tr2.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
         trZ.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
         trP.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
         
         # # # print (self.staid)
         if np.all(trP.data == 0.) and not (np.all(tr1.data == 0.) or np.all(tr2.data == 0.)):
             self.stanoise   += DayNoise(tr1=tr1, tr2=tr2, trZ=trZ, trP=obspy.Trace(), overlap=self.overlap, window = self.window)
             self.out_dtype  = 'Z2-1'
         elif (np.all(tr1.data == 0.) or np.all(tr2.data == 0.)) and (not np.all(trP.data == 0.)):
             self.stanoise   += DayNoise(tr1=obspy.Trace(), tr2=obspy.Trace(), trZ=trZ, trP=trP, overlap=self.overlap, window = self.window)
             self.out_dtype  = 'ZP'
         elif (not (np.all(tr1.data == 0.) or np.all(tr2.data == 0.))) and (not np.all(trP.data == 0.)):
             self.stanoise   += DayNoise(tr1=tr1, tr2=tr2, trZ=trZ, trP=trP, overlap=self.overlap, window = self.window)
             self.out_dtype  = 'ZP-21'
         else:
             stime   += 86400.
             continue
         stime   += 86400.
         Nday    += 1
     if Nday <= 1:
         return False
     self.stanoise.QC_sta_spectra()
     self.stanoise.average_sta_spectra()
     self.tfnoise= TFNoise(self.stanoise)
     self.tfnoise.transfer_func()
     return True
Beispiel #8
0
class atacr_monthly_sta(object):
    
    def __init__(self, inv, datadir, outdir, year, month, overlap = 0.5, window = 21000., chan_rank = ['L', 'H', 'B'], sps = 1.):
        network     = inv.networks[0]
        station     = network[0]
        channel     = station[0]
        self.stdb_inv   = stdb.StDbElement(network = network.code, station = station.code, channel = channel.code[:2],\
            location = channel.location_code, latitude = station.latitude, longitude = station.longitude,\
                elevation = station.elevation, polarity=1., azcorr=0., startdate = station.start_date,\
                    enddate = station.end_date, restricted_status = station.restricted_status)
        self.datadir    = datadir
        self.outdir     = outdir
        self.year       = year
        self.month      = month
        self.overlap    = overlap
        self.window     = window
        self.staid      = network.code+'.'+station.code
        self.chan_rank  = chan_rank
        self.stanoise   = StaNoise()
        self.stlo       = station.longitude
        self.stla       = station.latitude
        self.monthdir   = self.datadir + '/%04d.%s' %(self.year, monthdict[self.month])
        self.sps        = sps
        return
    
    def transfer_func(self):
        """compute monthly transfer function
        """
        targetdt    = 1./self.sps
        stime       = obspy.UTCDateTime('%04d%02d01' %(self.year, self.month))
        monthdir    = self.monthdir
        if not os.path.isdir(monthdir):
            return False
        chan_type   = None
        Nday        = 0
        while( (stime.year == self.year) and (stime.month == self.month)):
            daydir  = monthdir+'/%d.%s.%d' %(self.year, monthdict[self.month], stime.day)
            if not os.path.isdir(daydir):
                stime   += 86400.
                continue 
            fpattern= daydir+'/ft_%d.%s.%d.%s' %(self.year, monthdict[self.month], stime.day, self.staid)
            if chan_type is None:
                for chtype in self.chan_rank:
                    fname1  = fpattern+'.%sH1.SAC' %chtype
                    fname2  = fpattern+'.%sH2.SAC' %chtype
                    fnamez  = fpattern+'.%sHZ.SAC' %chtype
                    fnamep  = fpattern+'.%sDH.SAC' %chtype
                    if os.path.isfile(fname1) and os.path.isfile(fname1) and \
                        os.path.isfile(fnamez) and os.path.isfile(fnamep):
                        chan_type   = chtype
                        break
            if chan_type is None:
                stime   += 86400.
                continue
            fname1  = fpattern+'.%sH1.SAC' %chan_type
            fname2  = fpattern+'.%sH2.SAC' %chan_type
            fnamez  = fpattern+'.%sHZ.SAC' %chan_type
            fnamep  = fpattern+'.%sDH.SAC' %chan_type
            if not (os.path.isfile(fname1) and os.path.isfile(fname1) and \
                    os.path.isfile(fnamez) and os.path.isfile(fnamep)):
                stime   += 86400.
                continue
            tr1     = obspy.read(fname1)[0]
            stimetr = tr1.stats.starttime
            tr2     = obspy.read(fname2)[0]
            trZ     = obspy.read(fnamez)[0]
            trP     = obspy.read(fnamep)[0]
            
            if abs(tr1.stats.delta - targetdt) > 1e-3 or abs(tr2.stats.delta - targetdt) > 1e-3 or \
                abs(trZ.stats.delta - targetdt) > 1e-3 or abs(trP.stats.delta - targetdt) > 1e-3:
                raise ValueError('!!! CHECK fs :'+ self.staid)
            else:
                tr1.stats.delta     = targetdt
                tr2.stats.delta     = targetdt
                trP.stats.delta     = targetdt
                trZ.stats.delta     = targetdt
            # # # if np.all(tr1.data == 0.) or np.all(tr2.data == 0.) or np.all(trZ.data == 0.) or np.all(trP.data == 0.):
            # # #     stime   += 86400.
            # # #     continue
            tr1.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
            tr2.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
            trZ.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
            trP.trim(starttime = stimetr, endtime = stimetr + 8400.*10-1)
            
            # # # print (self.staid)
            if np.all(trP.data == 0.) and not (np.all(tr1.data == 0.) or np.all(tr2.data == 0.)):
                self.stanoise   += DayNoise(tr1=tr1, tr2=tr2, trZ=trZ, trP=obspy.Trace(), overlap=self.overlap, window = self.window)
                self.out_dtype  = 'Z2-1'
            elif (np.all(tr1.data == 0.) or np.all(tr2.data == 0.)) and (not np.all(trP.data == 0.)):
                self.stanoise   += DayNoise(tr1=obspy.Trace(), tr2=obspy.Trace(), trZ=trZ, trP=trP, overlap=self.overlap, window = self.window)
                self.out_dtype  = 'ZP'
            elif (not (np.all(tr1.data == 0.) or np.all(tr2.data == 0.))) and (not np.all(trP.data == 0.)):
                self.stanoise   += DayNoise(tr1=tr1, tr2=tr2, trZ=trZ, trP=trP, overlap=self.overlap, window = self.window)
                self.out_dtype  = 'ZP-21'
            else:
                stime   += 86400.
                continue
            stime   += 86400.
            Nday    += 1
        if Nday <= 1:
            return False
        self.stanoise.QC_sta_spectra()
        self.stanoise.average_sta_spectra()
        self.tfnoise= TFNoise(self.stanoise)
        self.tfnoise.transfer_func()
        return True
    
    def correct(self):
        """compute monthly transfer function
        """
        targetdt    = 1./self.sps
        stime       = obspy.UTCDateTime('%04d%02d01' %(self.year, self.month))
        monthdir    = self.monthdir
        omonthdir   = self.outdir + '/%04d.%s' %(self.year, monthdict[self.month])
        if not os.path.isdir(monthdir):
            return False
        chan_type   = None
        while( (stime.year == self.year) and (stime.month == self.month)):
            daydir      = monthdir+'/%d.%s.%d' %(self.year, monthdict[self.month], stime.day)
            fpattern    = daydir+'/ft_%d.%s.%d.%s' %(self.year, monthdict[self.month], stime.day, self.staid)
            odaydir     = omonthdir+'/%d.%s.%d' %(self.year, monthdict[self.month], stime.day)
            if not os.path.isdir(odaydir):
                os.makedirs(odaydir)
            if chan_type is None:
                for chtype in self.chan_rank:
                    fname1  = fpattern+'.%sH1.SAC' %chtype
                    fname2  = fpattern+'.%sH2.SAC' %chtype
                    fnamez  = fpattern+'.%sHZ.SAC' %chtype
                    fnamep  = fpattern+'.%sDH.SAC' %chtype
                    if os.path.isfile(fname1) and os.path.isfile(fname2) and \
                        os.path.isfile(fnamez) and os.path.isfile(fnamep):
                        chan_type   = chtype
                        break
            if chan_type is None:
                stime   += 86400.
                continue
            fname1  = fpattern+'.%sH1.SAC' %chan_type
            fname2  = fpattern+'.%sH2.SAC' %chan_type
            fnamez  = fpattern+'.%sHZ.SAC' %chan_type
            fnamep  = fpattern+'.%sDH.SAC' %chan_type
            if not (os.path.isfile(fname1) and os.path.isfile(fname2) and \
                    os.path.isfile(fnamez) and os.path.isfile(fnamep)):
                stime   += 86400.
                continue
            tr1     = obspy.read(fname1)[0]
            stimetr = tr1.stats.starttime
            tr2     = obspy.read(fname2)[0]
            trZ     = obspy.read(fnamez)[0]
            trP     = obspy.read(fnamep)[0]
            
            if (np.all(tr1.data == 0.) or np.all(tr2.data == 0.)) and np.all(trP.data == 0.):
                stime   += 86400.
                continue
            
            if abs(tr1.stats.delta - targetdt) > 1e-3 or abs(tr2.stats.delta - targetdt) > 1e-3 or \
                abs(trZ.stats.delta - targetdt) > 1e-3 or abs(trP.stats.delta - targetdt) > 1e-3:
                raise ValueError('!!! CHECK fs :'+ self.staid)
            else:
                tr1.stats.delta     = targetdt
                tr2.stats.delta     = targetdt
                trP.stats.delta     = targetdt
                trZ.stats.delta     = targetdt
            
            outfnameZ   = odaydir+'/ft_%d.%s.%d.%s.%sHZ.SAC' %(self.year, monthdict[self.month], stime.day, self.staid, chan_type)
            # sliding window raw data
            StreamZ = obspy.Stream()
            overlap = 0.99
            for tmptr in trZ.slide(window_length = self.window-1, step = int((self.window-1)*overlap)):
                # print (tmptr.stats.npts)
                StreamZ += tmptr.copy()
            Stream1 = obspy.Stream()
            for tmptr in tr1.slide(window_length = self.window-1, step = int((self.window-1)*overlap)):
                Stream1 += tmptr.copy()
            Stream2 = obspy.Stream()
            for tmptr in tr2.slide(window_length = self.window-1, step = int((self.window-1)*overlap)):
                Stream2 += tmptr.copy()
            StreamP = obspy.Stream()
            for tmptr in trP.slide(window_length = self.window-1, step = int((self.window-1)*overlap)):
                StreamP += tmptr.copy()
            # remove tilt and compliance
            outStreamZ  = obspy.Stream()
            Ntraces     = len(StreamZ)
            for itr in range(Ntraces):
                sth     = obspy.Stream()
                if not (np.all(Stream1[itr].data == 0.) or np.all(Stream1[itr].data == 0.)):
                    sth     += Stream1[itr]
                    sth     += Stream2[itr]
                sth     += StreamZ[itr]
                stp     = obspy.Stream()
                if not np.all(StreamP[itr].data == 0.):
                    stp     += StreamP[itr]
                tmptime = StreamZ[itr].stats.starttime
                tstamp  = str(tmptime.year).zfill(4)+'.' + \
                    str(tmptime.julday).zfill(3)+'.'
                tstamp  = tstamp + str(tmptime.hour).zfill(2) + \
                            '.'+str(tmptime.minute).zfill(2)
                if self.out_dtype == 'ZP':
                    ncomp   = 2
                elif self.out_dtype == 'Z2-1':
                    ncomp   = 3
                elif self.out_dtype  == 'ZP-21':
                    ncomp   = 4
                
                eventstream = EventStream( sta = self.stdb_inv, sth = sth, stp = stp,\
                    tstamp = tstamp, lat = self.stla, lon = self.stlo, time = tmptime,\
                    window = self.window,
                    sampling_rate = 1., ncomp = ncomp)
                eventstream.correct_data(self.tfnoise)
                tmptr       = StreamZ[itr].copy()
                tmptr.data  = eventstream.correct[self.out_dtype].copy()
                outStreamZ  += tmptr
                # outStreamZ.data = 
            # merge data
            outStreamZ.merge(method = 1, fill_value = 'interpolate', interpolation_samples=2)
            outTrZ  = outStreamZ[0]
            if os.path.isfile(outfnameZ):
                shutil.copyfile(src = outfnameZ, dst = outfnameZ+'_old')
                os.remove(outfnameZ)
            outTrZ.write(outfnameZ, format = 'SAC')
            stime   += 86400.