SAC下的时间概念

如前所述(前文链接),SAC下的时间主要包括参考时间和相对时间,这二者构成了所有SAC数据点的绝对时间。参考时间由六个变量构成NZYEAR、NZJDAY、NZHOUR、 NZMIN、NZSEC、NZMSEC,相对时间包括b、e、f、o、a、tn(n=0~9)。

下面针对这些时间变量做一些测试:
选取了一个地震的三分量,列出其kzdate、kztime、b、e如下:

    kzdate = MAR 11 (070), 2011
    kztime = 05:46:23.019
         b = 5.380000e-04
         e = 4.499951e+03

1、直接修改文件起始时间b:ch b 10
  得到结果如下:
    kzdate = MAR 11 (070), 2011
    kztime = 05:46:23.019
         b = 1.000000e+01
         e = 4.509950e+03
文件的参考时间没有发生变化,b和e都向后推迟了10s,这意味着整段SAC数据任一点的绝对时间延迟了10s,因而可以通过修改b值来校正时间零飘以及时区差异引起的绝对时间的修改。

2、修改文件结束时间e:ch e 0
  得到结果如下:
    kzdate = MAR 11 (070), 2011
    kztime = 05:46:23.019
         b = 5.380000e-04
         e = 4.499951e+03
文件的参考时间以及e均没有发生变化,这意味着e的值不是可以任意改变的,而是根据b、delta及npts动态决定的,尝试修改delta,e值随之改变;尝试修改npts以达到类似“cut”的效果时,出现警告:
WARNING: NVHDR, NPTS, NWFID, NORID, and NEVID cannot be changed with CHNHDR

3、修改o、a、f、tn:
这些变量是用于标记时刻的变量,不是必须的,用户可以随意修改,不会对参考时间等产生任何的影响。

4、修改参考时间:
随便定义了几个o、a、f、t0的值,以验证修改参考时间对这些时间变量的影响,原始变量值如下:
    kzdate = MAR 11 (070), 2011
    kztime = 05:46:23.019
         b = 5.380000e-04
         e = 4.499951e+03
         o = 2.000000e+01
         a = 4.000000e+01
         f = 9.000000e+01
        t0 = 6.000000e+01
通过ch nzmin 50来修改参考时间,得到结果如下:
    kzdate = MAR 11 (070), 2011
    kztime = 05:50:23.019
         b = 5.380000e-04
         e = 4.499951e+03
         o = 2.000000e+01
         a = 4.000000e+01
         f = 9.000000e+01
        t0 = 6.000000e+01
整个SAC文件中除参考时间外其他时间都没有发生变化,这导致SAC数据点的绝对时间发生了平移,与第一条中直接修改b的情况类似。

5、更多的时候我们需要将参考时间修改为发震时刻,从第四条可以看出,直接修改参考时间的方案是不可行的。

当我们将参考时间提前10s的时候,为了保证其他时间变量所对应的绝对时间不发生变化,我们需要同时将各个相对时间加上10s(这样才能保证在某个参考时间下标记的震相到时等信息可以完全映射到另一个参考时间下的震相到时,这或许可以理解为时间坐标系下的坐标变换)。
因为修改参考时间,而使得每个相对时间都要一一修改,这工作量有点大。SAC自身提供了一个更为简单的选项帮助我们实现了这一功能,如manaul中所说:“你可以使用allt t选项改变这个参考时间和其他所有的相对时间,这个秒数t增加到每个给定的相对时间上,同样的秒数也从参考时间中减去,这样就使数据实际的GMT时间保持不变”。
还是上面那个例子,使用ch allt 10得到结果如下:
    kzdate = MAR 11 (070), 2011
    kztime = 05:46:13.019
         b = 1.000054e+01
         e = 4.509951e+03
         o = 3.000000e+01
         a = 5.000000e+01
         f = 1.000000e+02
        t0 = 7.000000e+01
相对时间都增加了10s,参考时间减少了10s。

6、为方便起见,你可以输入一个GMT时间而不是输入一个绝对时间。当输入GMT时间时,SAC首先将其变为相对时间再存储到头段变量中。已知某事件的发震时刻,想要将发震时刻作为参考时间,其他所有的相对时间都变成相对这个参考时间的秒数,可以使用
      ch o gmt 2011 070 05 50 23 019 
得到如下结果:
    kzdate = MAR 11 (070), 2011
    kztime = 05:46:23.019
         b = 5.380000e-04
         e = 4.499951e+03
         o = 2.400000e+02
         a = 4.000000e+01
         f = 9.000000e+01
        t0 = 6.000000e+01
发震时刻被转换为相对时间240存储在头段变量o中,为了修改参考时间为发震时刻,需要将所有相对时间减去240s,参考时间加上240s,命令为ch allt -240 iztype io,结果如下:
    kzdate = MAR 11 (070), 2011
    kztime = 05:50:23.019
         b = -2.399995e+02
         e = 4.259951e+03
         o = 0.000000e+00
         a = -2.000000e+02
         f = -1.500000e+02
        t0 = -1.800000e+02
由结果可以看出,这么做达到了我们想要的目的。

7、在SAC宏文件或者bash、perl脚本中批量修改发震时刻的方法,有基本的编程知识应该都不会太困难,关键是将o的值提取出来放入一个变量中,这个可以通过setbb做到,这个事情以后有时间再说。总结:
将SAC中的时间变量可以细分为三类:
第一类为参考时间,即NZYEAR、NZJDAY、NZHOUR、NZMIN、NZSEC、NZMSEC;
第二类为相对时间,即o、a、f、tn;
第三类为特殊的相对时间,即b、e。
在第三类中e是不能随意改变的,所以可以不考虑。单独修改这三类时间变量都不会影响其他时间变量,修改第二类时间不会造成整个数据的绝对时间的改变,修改 第一、三类时间变量时数据绝对时间会发生改变(该特性可用于校正时间零漂或时区不一致)。为了保证数据的绝对时间不发生改变,通常使用allt选项来实现。

SAC 101.4 源码在Ubuntu 10.04下的安装

1、解压源码安装包

tar zxvf sac-101.4.tar.gz
2、

./configure

3、

make

出现如下错误:

     checking for tgetent in -lcurses... no
     checking for tgetent in -lncurses... no
     configure: error: libtermcap, libcurses or libncurses are required!
     make[1]: *** [lib/libedit.a] 错误 1
     make[1]:正在离开目录 `/home/dongzhi/Document/sac-101.4/libedit'
     make: *** [all-recursive] 错误 1

解决办法:
利用apt-file查找libtermcap、libcurses、libncurses位于哪个软件包中。   

apt-file search libtermcap

给出结果为
        libncurses5-dev: /usr/lib/libtermcap.a
        libncurses5-dev: /usr/lib/libtermcap.so
安装libncurses5-dev:

sudo apt-get install libncurses5-dev

再次make,出现错误

        In file included from ../inc/gdm.h:14,
                    from ./msg/outmsg.c:14:
        ../inc/gd5.gui.h:66:27: error: X11/Intrinsic.h: 没有那个文件或目录

apt-file search X11/Intrinsic.h给出结果:
         libxt-dev: /usr/include/X11/Intrinsic.h
         tendra: /usr/lib/TenDRA/lib/include/x5/t.api/X11/Intrinsic.h
安装libxt-dev:

          sudo apt-get install libxt-dev

继续make,又出错!而且错误有点诡异。
考虑到前面configure和make到时候因为错误中断过,所以还是重新解压,configure,make再来一遍,
这次很顺利!
执行

sudo make install

就会将SAC安装到/usr/local/sac下。
然后就是作一些环境变量到设定,同前面的文章。
---------------------------------------------------------------------------
具体安装说明参考SAC源代码中Readme.buildsac

Ubuntu Tweak安装

Ubuntu Tweak是ubuntu下的一个系统配置和优化工具,主要面向新手级的普通用户,它可以设置很多并不能在系统首选项中设置的隐藏选项,以满足用户自定义 的乐趣。即使是新手,也可以方便地通过它来进行适合自己的系统调整。主要是针对Ubuntu,对于部分其他linux也支持,但功能并不完全可用。
官方网站:http://ubuntu-tweak.com/

通过添加源的方法进行安装:
1、添加密钥、加源

$ sudo add-apt-repository ppa:tualatrix/ppa
2、更新源

   $ sudo apt-get update

3、安装

    $ sudo apt-get install ubuntu-tweak

---------------------------------------------------------------------------
目前Ubuntu 11.10对应的Tweak版本为0.6 alpha测试版本,请谨慎安装。详情参见官方网站

在脚本中调用SAC

SAC是一个交互命令,需要人机联动,当只是使用SAC进行机械性的数据处理时,使用脚本进行批处理就显得很重要了。在SAC内部有宏文件可以使用,但是 宏文件不能方便的与外界程序进行交互。所以在脚本中调用SAC便显得格外重要,也经常使用。SAC新版本中加入了在脚本中如果调用SAC的介绍,原文位于 sac/aux/help/user_man/sac_script,相应的脚本位于sac/doc/examples中。

下面仅仅只是一些列举:
sh

#!/bin/sh

sac <<EOF
fg seismo
lh columns 2
quit
EOF

csh

  #!/bin/csh

  sac <<EOF
  fg seismo
  lh columns 2
  quit
  EOF

perl

  #!/usr/bin/env perl

  open(SAC, "| sac ") or die "Error opening sac";
  print SAC "fg seismo\n";
  print SAC "lh columns 2\n";
  print SAC "quit\n";
  close(SAC);

python

  #!/usr/bin/env python

  import subprocess

  p = subprocess.Popen(['sac'],
                       stdout = subprocess.PIPE, 
                       stdin  = subprocess.PIPE,
                       stderr = subprocess.STDOUT )

  out = p.communicate('''
  fg seismo
  lh columns 2
  quit
  ''')
  print out[0]

另外需要说的一点是在调用SAC时会出现SAC版本号等东西,这些文本会出现中终端中而引起很多的麻烦。一个方法是将 SAC_DISPLAY_COPYRIGHT设置为0,另一个办法是将SAC的输出重定向到垃圾箱/dev/null,这要求你需要知道SAC的输出信息 中哪些需要哪些不需要,请仔细考虑利弊而为之~
更多的例子参见上面给出的文档及脚本。学习一种脚本很重要~~

SAC Version 101.5 相对前一版本的变化

SAC Version 101.5于2011年11月发布。相对前一版本,修正了一些BUG并在功能上做了一些加强。目前在CentOS 5上还没有安装成功,目前没有其他系统,所以没有再尝试。问题不是很大,应该比较容易解决,只是最近没有时间和心思去折腾。

下面列举一些SAC中比较重要的更新:

1、BUG FIX

  • sacinit.sh做了修正。当初在安装时需要修改的三条语句已经修改正确
  • sgftops格式转换过程中出现的水平线被去除
  • Hypo和APK文件格式修正。与APK有关的一些命令都没有使用过,当初ZhangXin同学使用时发现了数据格式的bug,不过现在已经修改了,希望不会再有问题
  • apk目前可以正常使用。上一版本中APK无法正确的判定事件的起始和结束
  • 互相关做了修正
  • readalpha被readtable取代

2、ENHANCEMENT

  • 在manual中增加了文件sac_script,介绍了如何在各种bash、csh、perl、python中如何调用SAC,这个相当有用!!!!
  • aux/seismgram做了更新。。。这个其实是执行命令fg seismgram时读取的文件。。
  • 新增命令SACEIMG或SAVE:用于将绘图保存为多种格式,包括.ps.pdf.png.xpm.sgf
  • 新增了命令traveltime,用于标记理论到时,只可以使用iasp91和ak135,这样就可以在SAC内部标定到时,而不必借助于ttimes和外部脚本。不足之处在于无法自定义速度模型,这一点还是不如TauP,但是应该已经能够满足部分需求了。
  • 新增图像格式:.ps.pdf.png.xpm
  • libsacio库更新了
  • 在上一版本中datagen命令说需要的一些地震文件没有随软件包发布,这个版本中已经有了这些数据文件。位于aux/datagen,对于新手来说有这些真实数据练手还是比较重要的(想当初我就一个seismogram折腾来折腾去)

总的来说,这次的更新还是解决了不少问题了,也加入了一些让人眼前一亮的功能~

2012-12-18更新

-------------------------------------------

SAC 101.5 经测试在ubuntu 11.10上安装一切正常。

SAC不同格式间的转换

传统意义上的SAC数据都是二进制文件,在前面的“SAC文件格式”一文中也已经说过SAC的二进制格式,但是其实SAC还有ASCII格式,以及另外一种不能称为SAC文件的格式---只有两列数据的文件。

平时可能会遇到的几个问题及其对策(具体命令参见help):
1、SAC二进制sacfile转换成SAC的ASCII文件sacfile.ascii

SAC> r sacfile
SAC> w alpha sacfile.ascii
2、SAC的ASCII文件转换成SAC二进制文件:

SAC> r alpha sacfile.ascii
SAC> w sacfile

3、包含两列数据(分别代表自变量和因变量)的文件ascii转换成SAC二进制文件

SAC> readalpha content xy ascii
SAC> w sacfile
这样转换的好处在于,很多非地震数据(比如任意的xy数据)都可以用SAC来处理以实现相应的功能,这也就是在SAC在介绍中自称其为“一个用于处理连续信号尤其是时间序列数据的通用交互式程序”的原因。
4、将SAC二进制文件转换成自变量因变量两列数据
这个应该是没法用命令直接做到的,比较合适的做法是写一个C或FORTRAN调用读取SAC文件,然后以数组形式写入文件。

Fortran根据系统时间产生随机数

FORTRAN中用于产生随机数的子程序有random_seed和random_number,其中random_seed产生 seed,random_number根据seed的值产生随机数。当random_seed()的参数为空时,其会给出一个默认的seed值,这意味着 每次调用时产生的随机数都是相同的。(这也是有用的,这意味着你每次在执行程序的时候,会获得相同随机数序列,这些便于调试,但是有时候可能会需要每次生 成不同的随机数序列以满足程序的要求)。
下面的方法时利用系统时间产生随机数:

subroutine init_random_seed()
integer :: i,n,clock
integer,dimension(:),allocatable :: seed
call random_seed(size=n)
allocate(seed(n))
call system_clock(count=clock)
seed=clock+37*(/(i-1,i=1,n)/)
call random_seed(PUT=seed) 
deallocate(seed)
end subroutine
该子程序来源于GNU Fortran:
调用这个与系统时间有关的随机函数发生器:

program rand
call init_random_seed()
call random_number(x)
print *,x
end

[转]Linux文本中每行之后^M解决办法

本文转载自:http://www.kuqin.com/linux/20090725/64266.html

问:我在Windows中通过FTP传一个文本文件到Linux中,但是打开文本文件后每行最后都有^M的标志。由于很长,用编辑器去除太麻烦,有什么解决办法呢?

答:为了解决这个问题,Linux下专门有两个工具可以互换Windows格式和Linux格式,它们分别是dos2unix和unix2dos。比如用下面的命令就可以将文件名为“filename”文件从Windows格式转换为Linux文本格式。

正文:

在linux下,不可避免的会用VIM打开一些windows下编辑过的文本文件。我们会发现文件的每行结尾都会有一个^M符号,这是因为DOS下的编辑器和Linux编辑器对文件行末的回车符处理不一致,

对于回车符的定义:
windows:0D0A
unixlinux: 0A
MAC: 0D

比较快捷的去除这些符号的方法有这么几种:

(1)是用VI的命令:

   使用vi打开文本文件
   vi dos.txt
   命令模式下输入
   :set fileformat=unix
   :w

这个方法使用起来是有限制的,有些时候就算是fileformat是unix也会出现^M,所以这个方法并不一定有用,

可以在vi下使用:set fileformat?来检查fileformat

(2) VI下使用正则表达式替换?
  g/^M/s/^M//
   或者
  %s/^M//g

(3)使用sed 工具
   sed  's/^M//' filename > tmp_filename

(4)既然window下的回车符多了‘ ’,那么当然通过删除‘ ’ ,也可以实现:
   cat file | tr -d " "

(5)最后一个方法是本人最常用的方法,个人觉得最方便
   在终端下敲命令:
   $ dos2unix filename
   直接转换成unix格式,就OK了!~

Perl中的默认变量

  • $_ "老地方"变量,当未告知Perl使用哪个变量或数值时,Perl将自动使用该变量
  • $"  数组内插到双引号串中各个元素间自动添加分隔用的符号,默认值为空格
  • $#  arrayname 数组最后索引值
  • @_  在子程序中用于接收参数的的数组变量,仅在子程序执行期间有效,在标量上下文中表示参数个数
  • @ARGV 储存调用参数的数组
  • $0 脚本文件名
  • $! 储存解释用的系统错误信息
  • %ENV  用于存储环境变量信息的Hash