时间变量

基本思路

SAC 的头段区有很多与时间相关的头段变量,包括 nzyearnzjdaynzhournzminnzsecnzmsecbeoaftn(n=0–9)。正确使用它们的前提是理解 SAC 中的时间概念。这一节将试着说清楚这个问题。

首先,SAC 处理的是地震波形数据,SAC 格式里保存的是时间序列数据。先不管其它的一些台站经纬度、事件经纬度信息,就数据而言,至少需要一系列数据值以及每个数据值所对应的时刻。

在本节接下来的内容中,将严格区分两个高中物理学过的概念:时刻和时间。简单地说,在时间轴上,时刻是一个点,时间是一个线段。

一个简单的例子如下:

2014-02-26T20:45:00.000     0.10
2014-02-26T20:45:01.000     0.25
2014-02-26T20:45:02.000     0.33
2014-02-26T20:45:03.000     0.21
2014-02-26T20:45:04.000     0.35
2014-02-26T20:45:05.000     0.55
2014-02-26T20:45:06.000     0.78
2014-02-26T20:45:07.000     0.66
2014-02-26T20:45:08.000     0.42
2014-02-26T20:45:09.000     0.34
2014-02-26T20:45:10.000     0.25

其中第二列是数据点,每个数据点所对应的时刻放在第一列,格式为“yyyy-mm-ddThh:mm:ss.xxx”。数据点是以 1 秒的等间隔进行采样的。

若把这堆时刻以及数据点直接写入文件中,将占据大量的磁盘空间,读写也很不方便。考虑将某一个时刻定义为参考时刻,并把其它所有的时刻都用相对于该参考时刻的秒数来表示,这样可以简化不少。

比如取“2014-02-26T20:45:00.000”为参考时刻,即

nzyear = 2014
nzjday = 57
nzhour = 20
nzmin  = 45
nzsec  = 00
nzmsec = 000

则上面的数据可以简化为

00.000     0.10
01.000     0.25
02.000     0.33
03.000     0.21
04.000     0.35
05.000     0.55
06.000     0.78
07.000     0.66
08.000     0.42
09.000     0.34
10.000     0.25

其中第二列是数据点,第一列是每个数据点对应的时刻相对于参考时刻的相对秒数,下面简称其为相对时间。

显然参考时刻的选取是任意的,若取“2014-02-26T20:45:05.000”为参考时刻,则上面的数据简化为

-05.000     0.10
-04.000     0.25
-03.000     0.33
-02.000     0.21
-01.000     0.35
 00.000     0.55
 01.000     0.78
 02.000     0.66
 03.000     0.42
 04.000     0.34
 05.000     0.25

一般来说,会选取一个比较特殊的时刻作为参考时刻,比如第一个数据点对应的时刻,或者地震波形数据中的发震时刻。

下面还是回到以“2014-02-26T20:45:00.000”为参考时刻简化得到的结果。因为数据是等间距的,相对时间这一列完全可以进一步简化,比如用“起始相对时间+采样间隔+数据点数”或者“起始相对时间+采样间隔+结束相对时间”就完全可以表征第一列的相对时间。

SAC 选择了另外一种简化模式,“起始相对时间+采样间隔+数据点数+结束相对时间”,即头段变量中的“b+delta+npts+e”,这其实是存在信息冗余的,这就造就了头段变量 e 的一些特殊性,后面会提到。

按照 SAC 的模式在对相对时间进行简化之后,整个数据可以表示为

nzyear = 2014
nzjday = 57
nzhour = 20
nzmin  = 45
nzsec  = 00
nzmsec = 000
b      = 0.0
e      = 10.0
delta  = 1.0
npts   = 11

0.10
0.25
0.33
0.21
0.35
0.55
0.78
0.66
0.42
0.34
0.25

似乎到这里就结束了。

地震学里的一个重要问题是拾取震相到时(时刻),所以还需要几个额外的头段变量来保存这些震相到时(时刻),不过显然不需要真的把“时刻”保存到这些头段变量中,不然上面的一大堆就真是废话了。SAC 将震相到时(时刻)相对于参考时刻的时间差(即相对时间)保存到头段变量 oaftn 中。

综上,SAC 中跟时间有关的概念有三个:

参考时刻

由头段变量 nzyearnzjdaynzhournzminnzsecnzmsec 决定

相对时间

即某个时刻相对于参考时刻的时间差(单位为秒),保存到头段变量 beoaftn(n=0–9)

绝对时刻

=参考时刻+相对时间

一些测试

下面以一个具体的数据为例,通过修改各种与时间相关的头段来试着去进一步理解 SAC 的时间概念。

生成样例数据

SAC> fg seis
SAC> lh iztype
    iztype = BEGIN TIME
SAC> ch iztype IUNKN
SAC> w seis

lh 是命令 listhdr 的简写,用于列出头段变量的值。chchnhdr 的简写,用于修改头段变量的值。

备注

这里额外多做了一个操作修改 iztype 的操作,这是由于这个数据稍稍有一点 bug。

iztype 指定了参考时刻的类型,其显示为 BEGIN TIME,实际上其枚举值是 IB,也就是说这个数据选取文件第一个数据点的时刻作为参考时刻,那么 b 的值应该为0。而实际上这个数据的 b 值并不为0,这其实是这个数据的一点小 bug。这也从另一个侧面说明 SAC 只有在修改与时间相关的头段变量时才可能会检查到这个错误/警告,所以这里先将其修正为 IUNKN

修改文件起始时间 b

SAC> r seis
SAC> lh kzdate kztime b delta npts e o a f

     kzdate = MAR 29 (088), 1981
     kztime = 10:38:14.000
          b = 9.459999e+00
      delta = 1.000000e-02
       npts = 1000
          e = 1.945000e+01
          o = -4.143000e+01
          a = 1.046400e+01
SAC> ch b 10
SAC> lh

     kzdate = MAR 29 (088), 1981
     kztime = 10:38:14.000
          b = 1.000000e+01
      delta = 1.000000e-02
       npts = 1000
          e = 1.999000e+01
          o = -4.143000e+01
          a = 1.046400e+01

修改 b 前后的变化仅在于 be 值的变化,而参考时刻以及其它相对时间并没有发生变化。

这意味着整段 SAC 数据中的任意一个数据点所对应的时刻都向后延迟了 0.54 秒!这样做很危险,因为 be 的绝对时刻被修改了,而其它头段如 oaftn 的绝对时刻却没有变。

使用的时候必须非常小心:

  • 如果 oaftn 都没有定义, 那么修改 b 值可以用于校正仪器的时间零飘1以及时区差异2。关于时区的校正,参考 时区校正 一节。

  • 如果 oaftn 已经被定义, 则修改 b 值会导致与震相相关的头段变量出现错误!3

修改文件结束时间 e

SAC> r ./seis
SAC> lh kzdate kztime b delta npts e o a f

     kzdate = MAR 29 (088), 1981
     kztime = 10:38:14.000
          b = 9.459999e+00
      delta = 1.000000e-02
       npts = 1000
          e = 1.945000e+01
          o = -4.143000e+01
          a = 1.046400e+01
SAC> ch e 0
SAC> lh

     kzdate = MAR 29 (088), 1981
     kztime = 10:38:14.000
          b = 9.459999e+00
      delta = 1.000000e-02
       npts = 1000
          e = 1.945000e+01
          o = -4.143000e+01
          a = 1.046400e+01

可以看到,修改前后所有变量均没有发生变化,即 e 的值是不可以随意改变的,根据上面的结果可知,e 的值是通过 bdeltanpts的值动态计算的。这也与上一节说到的头段变量冗余问题相符合。不要试图修改 deltanpts,这不科学!

修改 o、a、f、tn

这几个头段变量完全是由用户自定义的,因而任何的定义、修改、取消定义都不会对数据的正确性产生影响,因而这里不再测试。

修改参考时间

SAC> r ./seis
SAC> lh kzdate kztime b delta npts e o a f

     kzdate = MAR 29 (088), 1981
     kztime = 10:38:14.000
          b = 9.459999e+00
      delta = 1.000000e-02
       npts = 1000
          e = 1.945000e+01
          o = -4.143000e+01
          a = 1.046400e+01
SAC> ch nzsec 15
SAC> lh

     kzdate = MAR 29 (088), 1981
     kztime = 10:38:15.000
          b = 9.459999e+00
      delta = 1.000000e-02
       npts = 1000
          e = 1.945000e+01
          o = -4.143000e+01
          a = 1.046400e+01

试图修改参考时刻,整个 SAC 头段,除了参考时刻外其它时间变量都没有发生变化。根据“绝对时刻=参考时刻+相对时间”可知,这导致所有 SAC 数据点的绝对时刻发生了平移,这一点理论上可以用于校正零飘或者时区,但是由于 SAC 不支持智能判断时间(比如不知道1时80分实际上是2时20分),所以修改时区时需要获取参考时刻6个头段变量,加上时区的校正值,再写入到参考时刻6个变量中,相对较为繁琐,因而若要校正时区,建议直接修改头段变量中的 b 值。

修改发震时刻

数据处理中一个常见的需求是修改发震时刻,这可以通过修改头段变量 o 来实现,但是经常需要将参考时刻设置为发震时刻。上面的测试表明,直接修改参考时刻是很危险的,所以 SAC 的 ch 命令提供了 allt 选项来实现这一功能,在 事件信息 一节中会具体解释。

总结

将SAC中的时间变量分为三类:

  1. 参考时刻:即 nzyearnzjdaynzhournzminnzsecnzmsec

  2. 相对时间:即 oaftn

  3. 特殊的相对时间:即 b4

第二类时间变量可以随意修改,即震相拾取。

第一、三类时间变量的修改会导致数据绝对时刻发生改变。一般通过修改第三类时间变量来校正时间零漂和时区差异。在设置了发震时刻后,应使用 chnhdr 命令的 allt 选项修改第一、三类时间变量。

1

零飘,即仪器中的时刻与标准时刻不同。

2

时区差异可以理解成另一种零飘。

3

如果只定义了 o 值,或者 aftn 为理论震相到时而非计算机拾取或人工拾取的到时,修改 b 也是没有问题的。有些乱,不多说了。总之不要随便修改 b 的值。

4

由于 e 不可独立修改,所以不再考虑