Example #1
0
 def test_sacpaz_from_dataless(self):
     # The following dictionary is extracted from a datalessSEED
     # file
     pazdict = {
         "sensitivity": 2516580000.0,
         "digitizer_gain": 1677720.0,
         "seismometer_gain": 1500.0,
         "zeros": [0j, 0j],
         "gain": 59198800.0,
         "poles": [
             (-0.037010000000000001 + 0.037010000000000001j),
             (-0.037010000000000001 - 0.037010000000000001j),
             (-131 + 467.30000000000001j),
             (-131 - 467.30000000000001j),
             (-251.30000000000001 + 0j),
         ],
     }
     tr = Trace()
     # This file was extracted from the datalessSEED file using rdseed
     pazfile = os.path.join(os.path.dirname(__file__), "data", "SAC_PZs_NZ_HHZ_10")
     attach_paz(tr, pazfile, todisp=False)
     sacconstant = pazdict["digitizer_gain"] * pazdict["seismometer_gain"] * pazdict["gain"]
     np.testing.assert_almost_equal(tr.stats.paz["gain"] / 1e17, sacconstant / 1e17, decimal=6)
     # pole-zero files according to the SAC convention are in displacement
     self.assertEqual(len(tr.stats.paz["zeros"]), 3)
Example #2
0
 def test_sacpaz_from_dataless(self):
     # The following dictionary is extracted from a datalessSEED
     # file
     pazdict = {
         'sensitivity':
         2516580000.0,
         'digitizer_gain':
         1677720.0,
         'seismometer_gain':
         1500.0,
         'zeros': [0j, 0j],
         'gain':
         59198800.0,
         'poles': [(-0.037010000000000001 + 0.037010000000000001j),
                   (-0.037010000000000001 - 0.037010000000000001j),
                   (-131 + 467.30000000000001j),
                   (-131 - 467.30000000000001j), (-251.30000000000001 + 0j)]
     }
     tr = Trace()
     # This file was extracted from the datalessSEED file using rdseed
     pazfile = os.path.join(os.path.dirname(__file__), 'data',
                            'SAC_PZs_NZ_HHZ_10')
     attach_paz(tr, pazfile, todisp=False)
     sacconstant = pazdict['digitizer_gain'] * \
         pazdict['seismometer_gain'] * pazdict['gain']
     np.testing.assert_almost_equal(tr.stats.paz['gain'] / 1e17,
                                    sacconstant / 1e17,
                                    decimal=6)
     # pole-zero files according to the SAC convention are in displacement
     self.assertEqual(len(tr.stats.paz['zeros']), 3)
Example #3
0
 def test_attach_paz_diff_order(self):
     pazfile = os.path.join(os.path.dirname(__file__), "data", "NZCRLZ_HHZ10.pz")
     tr = Trace()
     attach_paz(tr, pazfile)
     np.testing.assert_array_almost_equal(tr.stats.paz["gain"], 7.4592e-2, decimal=6)
     self.assertEqual(len(tr.stats.paz["zeros"]), 5)
     self.assertEqual(len(tr.stats.paz["poles"]), 4)
Example #4
0
 def test_attach_paz_diff_order(self):
     pazfile = os.path.join(os.path.dirname(__file__),
                            'data', 'NZCRLZ_HHZ10.pz')
     tr = Trace()
     attach_paz(tr, pazfile)
     np.testing.assert_array_almost_equal(tr.stats.paz['gain'],
                                          7.4592e-2, decimal=6)
     self.assertEqual(len(tr.stats.paz['zeros']), 5)
     self.assertEqual(len(tr.stats.paz['poles']), 4)
Example #5
0
    def test_SacInstCorrection(self):
        # SAC recommends to taper the transfer function if a pure
        # deconvolution is done instead of simulating a different
        # instrument. This test checks the difference between the
        # result from removing the instrument response using SAC or
        # ObsPy. Visual inspection shows that the traces are pretty
        # much identical but differences remain (rms ~ 0.042). Haven't
        # found the cause for those, yet. One possible reason is the
        # floating point arithmetic of SAC vs. the double precision
        # arithmetic of Python. However differences still seem to be
        # too big for that.
        pzf = os.path.join(self.path, 'SAC_PZs_KARC_BHZ')
        sacf = os.path.join(self.path, 'KARC.LHZ.SAC.asc.gz')
        testsacf = os.path.join(self.path, 'KARC_corrected.sac.asc.gz')
        plow = 160.
        phigh = 4.
        fl1 = 1.0 / (plow + 0.0625 * plow)
        fl2 = 1.0 / plow
        fl3 = 1.0 / phigh
        fl4 = 1.0 / (phigh - 0.25 * phigh)
        #Uncomment the following to run the sac-commands
        #that created the testing file
        #if 1:
        #    import subprocess as sp
        #    p = sp.Popen('sac',shell=True,stdin=sp.PIPE)
        #    cd1 = p.stdin
        #    print >>cd1, "r %s"%sacf
        #    print >>cd1, "rmean"
        #    print >>cd1, "rtrend"
        #    print >>cd1, "taper type cosine width 0.03"
        #    print >>cd1, "transfer from polezero subtype %s to none \
        #    freqlimits %f %f %f %f" % (pzf, fl1, fl2, fl3, fl4)
        #    print >>cd1, "w over ./data/KARC_corrected.sac"
        #    print >>cd1, "quit"
        #    cd1.close()
        #    p.wait()

        stats = {'network': 'KA', 'delta': 0.99999988079072466,
                 'station': 'KARC', 'location': 'S1',
                 'starttime': UTCDateTime(2001, 2, 13, 0, 0, 0, 993700),
                 'calib': 1.00868e+09, 'channel': 'BHZ'}
        tr = Trace(np.loadtxt(sacf), stats)

        attach_paz(tr, pzf, tovel=False)
        tr.data = seisSim(tr.data, tr.stats.sampling_rate,
                          paz_remove=tr.stats.paz, remove_sensitivity=False,
                          pre_filt=(fl1, fl2, fl3, fl4))

        data = np.loadtxt(testsacf)

        # import matplotlib.pyplot as plt
        # plt.plot(tr.data)
        # plt.plot(data)
        # plt.show()
        rms = np.sqrt(np.sum((tr.data - data) ** 2) / \
                      np.sum(tr.data ** 2))
        self.assertTrue(rms < 0.0421)
Example #6
0
    def test_SacInstCorrection(self):
        # SAC recommends to taper the transfer function if a pure
        # deconvolution is done instead of simulating a different
        # instrument. This test checks the difference between the
        # result from removing the instrument response using SAC or
        # ObsPy. Visual inspection shows that the traces are pretty
        # much identical but differences remain (rms ~ 0.042). Haven't
        # found the cause for those, yet. One possible reason is the
        # floating point arithmetic of SAC vs. the double precision
        # arithmetic of Python. However differences still seem to be
        # too big for that.
        pzf = os.path.join(self.path, 'SAC_PZs_KARC_BHZ')
        sacf = os.path.join(self.path, 'KARC.LHZ.SAC.asc.gz')
        testsacf = os.path.join(self.path, 'KARC_corrected.sac.asc.gz')
        plow = 160.
        phigh = 4.
        fl1 = 1.0 / (plow + 0.0625 * plow)
        fl2 = 1.0 / plow
        fl3 = 1.0 / phigh
        fl4 = 1.0 / (phigh - 0.25 * phigh)
        #Uncomment the following to run the sac-commands
        #that created the testing file
        #if 1:
        #    import subprocess as sp
        #    p = sp.Popen('sac',shell=True,stdin=sp.PIPE)
        #    cd1 = p.stdin
        #    print >>cd1, "r %s"%sacf
        #    print >>cd1, "rmean"
        #    print >>cd1, "rtrend"
        #    print >>cd1, "taper type cosine width 0.03"
        #    print >>cd1, "transfer from polezero subtype %s to none \
        #    freqlimits %f %f %f %f" % (pzf, fl1, fl2, fl3, fl4)
        #    print >>cd1, "w over ./data/KARC_corrected.sac"
        #    print >>cd1, "quit"
        #    cd1.close()
        #    p.wait()

        stats = {'network': 'KA', 'delta': 0.99999988079072466,
                 'station': 'KARC', 'location': 'S1',
                 'starttime': UTCDateTime(2001, 2, 13, 0, 0, 0, 993700),
                 'calib': 1.00868e+09, 'channel': 'BHZ'}
        tr = Trace(np.loadtxt(sacf), stats)

        attach_paz(tr, pzf, tovel=False)
        tr.data = seisSim(tr.data, tr.stats.sampling_rate,
                          paz_remove=tr.stats.paz, remove_sensitivity=False,
                          pre_filt=(fl1, fl2, fl3, fl4))

        data = np.loadtxt(testsacf)

        # import matplotlib.pyplot as plt
        # plt.plot(tr.data)
        # plt.plot(data)
        # plt.show()
        rms = np.sqrt(np.sum((tr.data - data) ** 2) /
                      np.sum(tr.data ** 2))
        self.assertTrue(rms < 0.0421)
Example #7
0
def removeInstrument(st, args):

    if (args.sim == 'PZs'):

        # prefilters
        f = args.flim.split()
        f0 = eval(f[0])
        f1 = eval(f[1])
        f2 = eval(f[2])
        f3 = eval(f[3])
        toPurge = []  # station to purge if no Paz found

        for i in range(len(st)):

            # attach poles and zeros instrument
            if (args.dva == '1'):
                try:
                    attach_paz(st[i], st[i].stats.PZs_file, todisp=False)
                except:
                    print "No appropriate PZs file found for station " + st[
                        i].stats.station, st[i].stats.channel, st[
                            i].stats.network
                    toPurge.append(st[i].stats.station)
            else:
                try:
                    attach_paz(st[i], st[i].stats.PZs_file, tovel=True)
                except:
                    print "No appropriate PZs file found for station " + st[
                        i].stats.station, st[i].stats.channel, st[
                            i].stats.network
                    toPurge.append(st[i].stats.station)

        # remove stations if len(toPurge>0)
        if len(toPurge) > 0:
            st = purgeListStation(st, toPurge, 'r')
            print "Check if station/channel/network/location of the PZs files and the same string within loaded binary files "
            print "do correspond. It may occour for instance that the headers strings of the waveform files (e.g. sac, fseed) "
            print "do not agrees with the same strings of the PZs name files. For instance the name of the network. "
            print "If these strings do not correspond, modify the name of the PZs files or the header values of the waveforms"
            print "You may also choose to remove this station using the option --purge (see help for details)"

        # now do remove
        for i in range(len(st)):

            # remove instrument to displacement
            #          st[i].data=detrend(st[i].data)
            st[i].data = seisSim(st[i].data,st[i].stats.sampling_rate,paz_remove=st[i].stats.paz, \
                         taper=True, taper_fraction=0.050, pre_filt=(f0,f1,f2,f3)) #,water_level=60.0)

            # from meters to centimeters
            st[i].data = st[i].data * 100

    return st
Example #8
0
def removeInstrument(st,args):

    if(args.sim == 'PZs'):

       # prefilters
       f = args.flim.split()
       f0 = eval(f[0])
       f1 = eval(f[1])
       f2 = eval(f[2])
       f3 = eval(f[3])
       toPurge=  []   # station to purge if no Paz found

       for i in range(len(st)):
   
           # attach poles and zeros instrument
           if(args.dva=='1'):
              try:
                attach_paz(st[i], st[i].stats.PZs_file,todisp=False)
              except:
                print "No appropriate PZs file found for station " + st[i].stats.station,st[i].stats.channel,st[i].stats.network
                toPurge.append(st[i].stats.station)
           else:
              try:
                attach_paz(st[i], st[i].stats.PZs_file,tovel=True)
              except:
                print "No appropriate PZs file found for station " + st[i].stats.station,st[i].stats.channel,st[i].stats.network
                toPurge.append(st[i].stats.station)

                
       # remove stations if len(toPurge>0)
       if len(toPurge) > 0:
           st = purgeListStation(st,toPurge,'r')
           print "Check if station/channel/network/location of the PZs files and the same string within loaded binary files "
           print "do correspond. It may occour for instance that the headers strings of the waveform files (e.g. sac, fseed) "
           print "do not agrees with the same strings of the PZs name files. For instance the name of the network. "
           print "If these strings do not correspond, modify the name of the PZs files or the header values of the waveforms"
           print "You may also choose to remove this station using the option --purge (see help for details)"

       # now do remove
       for i in range(len(st)):

           # remove instrument to displacement
#          st[i].data=detrend(st[i].data)
           st[i].data = seisSim(st[i].data,st[i].stats.sampling_rate,paz_remove=st[i].stats.paz, \
                        taper=True, taper_fraction=0.050, pre_filt=(f0,f1,f2,f3)) #,water_level=60.0) 

           # from meters to centimeters
           st[i].data = st[i].data * 100
       
    
    return st
Example #9
0
 def test_sacpaz_from_resp(self):
     # The following two files were both extracted from a dataless
     # seed file using rdseed
     respfile = os.path.join(os.path.dirname(__file__),
                             'data', 'RESP.NZ.CRLZ.10.HHZ')
     sacpzfile = os.path.join(os.path.dirname(__file__),
                              'data', 'SAC_PZs_NZ_CRLZ_HHZ')
     # This is a rather lengthy test, in which the
     # poles, zeros and the gain of each instrument response file
     # are converted into the corresponding velocity frequency response
     # function which have to be sufficiently close. Possibly due to
     # different truncations in the RESP-formatted and SAC-formatted
     # response files the frequency response functions are not identical.
     tr1 = Trace()
     tr2 = Trace()
     attach_resp(tr1, respfile, torad=True, todisp=False)
     attach_paz(tr2, sacpzfile, torad=False, tovel=True)
     p1 = tr1.stats.paz.poles
     z1 = tr1.stats.paz.zeros
     g1 = tr1.stats.paz.gain
     t_samp = 0.01
     n = 32768
     fy = 1 / (t_samp * 2.0)
     # start at zero to get zero for offset/ DC of fft
     f = np.arange(0, fy + fy / n, fy / n)  # arange should includes fy
     w = f * 2 * np.pi
     s = 1j * w
     a1 = np.poly(p1)
     b1 = g1 * np.poly(z1)
     h1 = np.polyval(b1, s) / np.polyval(a1, s)
     h1 = np.conj(h1)
     h1[-1] = h1[-1].real + 0.0j
     p2 = tr2.stats.paz.poles
     z2 = tr2.stats.paz.zeros
     g2 = tr2.stats.paz.gain
     a2 = np.poly(p2)
     b2 = g2 * np.poly(z2)
     h2 = np.polyval(b2, s) / np.polyval(a2, s)
     h2 = np.conj(h2)
     h2[-1] = h2[-1].real + 0.0j
     amp1 = abs(h1)
     amp2 = abs(h2)
     phase1 = np.unwrap(np.arctan2(-h1.imag, h1.real))
     phase2 = np.unwrap(np.arctan2(-h2.imag, h2.real))
     np.testing.assert_almost_equal(phase1, phase2, decimal=4)
     rms = np.sqrt(np.sum((amp1 - amp2) ** 2) /
                   np.sum(amp2 ** 2))
     self.assertTrue(rms < 2.02e-06)
     self.assertTrue(tr1.stats.paz.t_shift, 0.4022344)
Example #10
0
 def test_attach_paz(self):
     fvelhz = io.StringIO("""ZEROS 3
     -5.032 0.0
     POLES 6
     -0.02365 0.02365
     -0.02365 -0.02365
     -39.3011 0.
     -7.74904 0.
     -53.5979 21.7494
     -53.5979 -21.7494
     CONSTANT 2.16e18""")
     tr = Trace()
     attach_paz(tr, fvelhz, torad=True, todisp=True)
     np.testing.assert_array_almost_equal(tr.stats.paz['zeros'][0],
                                          - 31.616988, decimal=6)
     self.assertEqual(len(tr.stats.paz['zeros']), 4)
def addPazStats(st, dir, sfiles): 

   # loop over sac files to find stations
   for i in range(len(st)):

          sta = st[i].stats['station']
          cha = st[i].stats['channel']
          net = st[i].stats['network']
          filename = 'SAC.PZs.' + net + '.' + sta + '.' + cha
          new = dir + os.sep + filename
          # here an empty file results into erroro
          # test if file is empty before
          try:
           if os.stat(new)[6] > 3:  
             # now test if Constant is there
             for line in open(new):
                 if "CONSTANT" in line:
                    attach_paz(st[i],new)
           else:
             print "Empty Paz file ",new
          except: 
             print "file ",new," not found"

   return st