Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the merge command for v102.0 #251

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
115 changes: 65 additions & 50 deletions source/commands/merge.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ merge

.. code-block:: console

MERGE [Verbose] [Gap Zero|Interp] [Overlap Compare|Average] [filelist]
MERGE [Verbose] [Gap Zero|Interp] [Overlap Compare|Average]
[TOLerance_delta v] [filelist]

输入
----
Expand All @@ -20,85 +21,99 @@ VERBOSE
合并数据时在终端显示合并的细节

GAP ZERO|INTERP
如何处理数据间断
``ZERO`` 表示将数据间断处补零值;
设置出现数据间断时的处理方式
``ZERO`` 表示将数据间断处补零值(默认处理方式)
``INTERP`` 表示对数据间断处进行线性插值

OVERLAP COMPARE|AVERAGE
如何处理数据重叠
``COMPARE`` 表示对重叠的时间段内的数据进行比较,若不匹配则退出
设置出现数据重叠时的处理方式
``COMPARE`` 表示对重叠的时间段内的数据进行比较,若不完全相同则不合并
``AVERAGE`` 表示对重叠时间段内的数据进行平均

TOLERANCE_DELTA v
将要合并的前后文件的时间间隔(calc_delta)和头段变量\ ``delta``\ 可能不相同。
如果二者的差的绝对值大于了 TOLERANCE_DELTA,将按照出现数据间断或重叠进行处理,
否则当作是数值计算误差处理。
TOLERANCE_DELTA 的默认值是 1e-6

filelist
SAC 二进制数据文件列表
SAC 二进制文件列表

说明
----

该命令用于将一系列时间上相邻的数据文件首尾相连合并成一个文件。在合并数据时,
会先检查要合并的文件是否有相同的 ``kstnm``\ 、\ ``knetwk``\ 、\
``kcmpnm``\ 、\ ``delta``\ 。
该命令用于将一系列时间上相邻的 SAC 文件首尾相连合并成一个文件。
``merge`` 命令会尝试将已经读取的全部文件和 filelist 中的全部文件合并成一个 SAC 文件。
seisman marked this conversation as resolved.
Show resolved Hide resolved
若没有已读取的文件,则只合并 filelist 中的文件;若 filelist 为空,则只合并已读取的文件。
``merge`` 命令可以合并任意数目和任意顺序的数据文件。

在合并前,``merge`` 命令会先检查这些文件的头段变量
\ ``kstnm``\ 、\ ``knetwk``\ 、\ ``kcmpnm``\ 和 \ ``delta``\ 是否相同。
如果不完全相同,SAC 会报错。

除了检查头段变量,``merge`` 命令还会检查数据在时间上是否存在间断(GAP)、重叠(OVERLAP)等问题。
将要合并的、时间上相邻的前后两个文件之间是存在时间间隔的,
即前一个文件的最后一个采样点和后一个文件的第一个采样点之间存在时间间隔。
理想情况下,这个时间间隔应该和头段变量 \ ``delta``\ 相等。
然而,实际情况二者可能不想等。如果二者的差异不大于 TOLERANCE_DELTA 给定的值(或其默认值),
SAC 会认为二者没有差异,即便有也是数值计算造成的。
当 SAC 文件的采样很高,或者数据的总持续时间很长就会出现这样的情况。
如果二者差异大于了 TOLERANCE_DELTA 给定的值(或其默认值),
SAC 会认为数据存在间断(GAP)或重叠(OVERLAP),会按照GAP或OVERLAP两个选项进行处理。
Comment on lines +55 to +62
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我觉得你对 TOLERANCE_DELTA 的理解有误,计算出的 delta 和实际 delta 的差大于或小于设定的阈值,跟数据是否间断或者重叠应该是两回事。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你看看官方的例子,应该就是这个意思。@core-man 你也看看呢

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个我解决不了了,或者你觉得该怎么解决。我看他给的例子就是这个意思 @seisman

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK,过几天看。你可以继续其他命令。


在 SAC v101.6 中完全重写了该命令,因而该命令的功能和语法与之前的版本有所不同。
.. code-block:: console

在v101.6之前的版本中,\ ``merge`` 命令的用法与 :doc:`/commands/addf` 命令的
用法相似。该命令会将内存中的文件依次分别与 filelist 中的文件进行合并,且
内存中的文件的开始时刻必须早于 filelist 中的文件的开始时刻。因而在将多个数据
文件合并成一个文件时,只能先读取第一段数据,然后 ``merge`` 第二段数据,
再 ``merge`` 第三段数据,依次不断循环执行。
SAC> merge verbose *.SAC # 使用了 VERBOSE 选项,会显示相关细节
merge calculating delta
merge calculated delta: 4.000000000000000e-03 (assuming no-gaps)
delta in header 4.000000189989805e-03 (first file)
difference: 1.899898e-10 = abs( calc_delta - delta )
tolerance: 1.000000e-06
using calulcted delta
merging 24 files => 3600000 data points

在上面的例子中,
因为 calc_delta,即前文说的文件间的时间间隔和 \ ``delta``\ 的差的绝对值小于 TOLERANCE_DELTA,
因此 SAC 认为差异是数值计算误差。
相反,如果 TOLERANCE_DELTA 设置为 0,即只要 calc_delta 和 \ ``delta``\ 不完全相同
就会被当作是重叠或间断来处理:

旧版本的 ``merge`` 命令用起来相对复杂。需要多次执行 ``merge`` 命令,且
需要用户自己判断波形文件的先后顺序。
.. code-block:: console

v101.6之后的新版 ``merge`` 命令,会将内存中的全部数据文件以及 filelist 中的
全部文件合并成单个文件。若内存中无数据,则只合并 filelist 中的数据文件;
若 filelist 为空,则只合并内存中的数据文件。且新版的 ``merge`` 命令可以合并
任意数目和任意顺序的数据文件。
SAC> r *.SAC
SAC> merge verbose tol 0.0
merging 24 files => 3599999 data points
merge: Gap zero fill: [n: 899999 t: 3599.996171]
merge: Gap zero fill: [n: 1049999 t: 4199.996199]
.....

若要合并的数据段之间存在间断,可以通过补零或线性插值的方式弥补间断;若数据段之间
存在重叠,可对重叠的部分进行比较,判断重叠的区域内振幅是否匹配,或者直接进行振幅的平均。
在 SAC 的源代码中,calc_delta 等于所有文件间时间间隔的平均值。

示例
----

下面看一个数据合并的示例:
合并内存中的所有数据

.. code-block:: console

SAC> read file1 file2
SAC> merge file3 file4

在 v101.6 之前的版本中,本示例的运行结果是:file3 与 file1 合并成文件 file1,
file4 与 file2 合并成文件 file2,此时内存中有两个文件 file1 和 file2。
而在 v101.6 及其之后的版本中,这个例子的结果是,文件 file1、file2、file3、file4
合并成文件 file1,此时内存中只有一个文件 file1。这样的修改使得不同版本的语法
不兼容,但实际使用时新版的 ``merge`` 命令要更方便也更符合人的正常思维。

下面介绍几个新版本的 ``merge`` 命令的用法示例。

多个文件合并成单个文件的一种方法:

.. code-block:: console

SAC> r file1 # 读取一个文件
SAC> merge file2 file3 file4 # merge 其余文件
SAC> r file1 file2 file3 file4
SAC> merge
SAC> w over

另一种合并办法:
合并 ``merge`` 命令的文件列表内的文件

.. code-block:: console

SAC> r file1 file2 file3 file4
SAC> merge # 合并内存中的所有文件
SAC> w over # 合并后的文件写入到 file1 中
SAC> merge file1 file2 file3 file4
SAC> w over

再一种合并方法:
同时合并内存中已有的文件和 ``merge`` 命令的文件列表的文件

.. code-block:: console

# 内存中无数据
SAC> merge file1 file2 file3 file4 # 合并 filelist 中的全部文件
SAC> w over # 保存到 file1 中
SAC> r file1 file2
SAC> merge file3 file4
SAC> w over

头段变量改变
------------
Expand All @@ -108,4 +123,4 @@ npts、depmin、depmax、depmen、e
BUGS
----

- ``filelist`` 不支持通配符(v101.6a)
- 101.6a 版的 ``merge`` 命令的文件列表不支持通配符,但 102.0 版已修正。