:author: 周茂
:date: 2024-06-21

.. index:: ! mgd77list
.. program:: mgd77list

mgd77list
=========

:官方文档: :doc:`gmt:supplements/mgd77/mgd77list`
:简介: 从 MGD77 文件中提取数据

**mgd77list** 读取 MGD77 文件并生成 ASCII 或二进制表数据。MGD77 文件包括测线信息，比如
ID，时间，位置，控制代码和地球物理观测，其中地球物理观测数据可能包括：重力，磁，水深等，
因此还可能包括对这些观测数据的改正，例如：Eotvos 改正和 diurnal 改正。MGD77+ NetCDF 文件
还可能包含其他用户自定义信息，见 :doc:`mgd77info` 的 **-C** 选项；若想添加自定义列，参考
:doc:`mgd77manage` 。用户可以提取包括上面信息以及下面信息的任意组合，其中包括 8 个计算量
（距离、航向、航向变化、速度、Carter 改正、Eotvos 改正以及重力和磁的全球参考场）和时间的
子部分（年、月、日、时、分、秒）以及 GEODAS id 以及权重（见 :option:`-W` ）等。通过指定沿轨的
累积时间或距离或者指定地理区域，可以选定特定的数据。提取出来的数据可以使用一定的逻辑判断
来进一步筛选。如果需要提取多个测线的信息，则多个测线之间由段信息分隔。

语法
----

**gmt mgd77list**
*GEODAS-ids*
:option:`-F`\ *columns*\ [,\ *logic*][:\ *bittests*]
[ :option:`-A`\ **c**\|\ **d**\|\ **f**\|\ **m**\|\ **t**\ *code*\ [**+f**] ]
[ :option:`-D`\ **A**\|\ **a**\ *startdate* ]
[ :option:`-D`\ **B**\|\ **b**\ *stopdate* ]
[ :option:`-E` ]
[ :option:`-G`\ **a**\ *startrec* ]
[ :option:`-G`\ **b**\ *stoprec* ]
[ :option:`-I`\ **a\|c\|m\|t** ]
[ :option:`-L`\ [*corrtable*] ]
[ :option:`-N`\ **d**\|\ **s**\ *unit* ]
[ :option:`-Q`\ **a**\|\ **c**\|\ **v**\ *min*/*max* ]
[ :option:`-R`\ *region* ]
[ :option:`-S`\ **a**\ *startdist* ]
[ :option:`-S`\ **b**\ *stopdist* ]
[ :option:`-T`\ [**m**\|\ **e**] ]
[ :option:`-V`\ [*level*] ]
[ :option:`-W`\ *weight* ]
[ :option:`-Z`\ **n**\|\ **p** ]
[ :option:`-bo`\ *binary* ]
[ :option:`-h`\ *headers* ]
[ :option:`-j`\ *flags* ]
[ :doc:`--PAR=value </conf/overview>` ]

输入数据
--------

.. include:: explain_ncid.rst_

必须选项
--------

.. option:: -F

**-F**\ *columns*\ [,\ *logic*][:\ *bittests*]
    指定输出列 *columns* ，*columns* 中的多列必须使用逗号分隔，列名为缩写，按给定
    的顺序输出。如果列名为大写字母，则表示该列输出中不能存在 NaN。除非经过设置，
    否则，输出的 ASCII 文件将使用 :term:`FORMAT_FLOAT_OUT` 指定的格式。所有的
    可用的列名的缩写如下表：

.. list-table:: 测量数据字段说明
   :widths: 15 85
   :header-rows: 1

   * - 列名
     - 含义
   * - **recno**
     - 计数器
   * - **dst**
     - 数字记录类型，通常为 3 或者 5（Y2K-compliant 测量）
   * - **id**
     - 测量 ID 字符串
   * - **ngdcid**
     - 8 字符的 NGDC（现在为 NCEI）测线 ID 字符串（通常是文件前缀）
   * - **time**
     - 时间，从绝对时间（默认）、相对时间以及小数年时间中选择。三种时间的参数设置分别为：

       - 绝对时间：:term:`FORMAT_DATE_OUT` 和 :term:`FORMAT_CLOCK_OUT`
       - 相对时间：:term:`FORMAT_FLOAT_OUT` 和 :term:`TIME_SYSTEM` 或者（:term:`TIME_EPOCH` 和 :term:`TIME_UNIT`）
       - 小数年时间：:term:`FORMAT_FLOAT_OUT`
   * - **lon**
     - 经度，格式由 :term:`FORMAT_GEO_OUT` 指定
   * - **lat**
     - 纬度，格式由 :term:`FORMAT_GEO_OUT` 指定
   * - **twt**
     - 双程传播时间，单位 s
   * - **depth**
     - 改正后的测深，单位为 m，正值，表示海面下深度
   * - **mtf1**
     - 传感器 1 的总磁场强度，单位 nTesla
   * - **mtf2**
     - 传感器 2 的总磁场强度，单位 nTesla
   * - **mag**
     - 残余磁异常，单位 nTesla
   * - **gobs**
     - 重力，单位 mgal
   * - **faa**
     - 自由空气重力异常，单位 mgal
   * - **ptc**
     - 位置类型代码：1 为固定位置，3 为内插位置，9 为未指定
   * - **bcc**
     - 测深改正代码：

       - 01-55 Matthews zone 改正
       - 59 Matthews 改正，但未指定 zone
       - 60 S，Kuwahara formula for T-S
       - 61 Wilson formula for T-S
       - 62 Del Grosso formula for T-S
       - 63 Carter’s tables，88 其他，在头部记录中
       - 99 未指定
   * - **btc**
     - 测深类型代码：1 观测值，3 内插值，9 未指定
   * - **msens**
     - 评估残余磁场的传感器：1 第一个或者 leading 传感器，2 第二个或 trailing 传感器，9 未指定
   * - **msd**
     - 磁传感器深度（或高度），单位 m，向下为正
   * - **diur**
     - 磁 diurnal 改正，单位 nTesla
   * - **eot**
     - Eotvos 改正，单位 mgal
   * - **sln**
     - Seismic Line Number 字符串
   * - **sspn**
     - Seismic Shot Point Number 字符串
   * - **nqc**
     - 导航质量代码：5 怀疑（测量机构），6 怀疑（NCEI），9 确定没问题
   * - **year**
     - 年
   * - **month**
     - 月
   * - **day**
     - 日
   * - **hour**
     - 时
   * - **min**
     - 分
   * - **sec**
     - 秒
   * - **dist**
     - 沿轨距离，计算方法见 **-j** ，单位见 :option:`-N` [km]
   * - **az**
     - 方位角，从北方向顺时针计算，单位 度
   * - **cc**
     - 航向变更，单位 度
   * - **vel**
     - 速度，单位见 :option:`-N` [m/s]
   * - **weight**
     - 该数据集权重，见 :option:`-W`
   * - **carter**
     - Carter 深度改正（必须有 **twt** 的前提下）
   * - **igrf**
     - 国际地磁参考场（总场），单位 nTesla
   * - **ngrav**
     - 国际重力参考场，即正常重力，单位 mgal：

       - 默认使用头部记录中的 Gravity Theoretical Formula Code 参数
       - 如果该参数未设置就使用 IGF80。也可以使用 **-Af** 指定
   * - **ceot**
     - | 从导航信息中计算 Eotvos 改正：
       | :math:`E = 7.5038 \cdot V \cdot \cos(lat) \cdot \sin(az) + 0.004154 \cdot V^2`


除上述列名外，下表中还列出了一些其他可识别的参数：

.. list-table:: 参数含义说明
   :widths: 20 80
   :header-rows: 1

   * - 参数
     - 含义
   * - **mgd77**
     - 输出所有的 27 个 MGD77 字段
   * - **mgd77t**
     - 输出所有的 26 个 MGD77T 字段
   * - **geo**
     - 输出 10 个字段，分别为 **time**、**lon**、**lat** 以及 7 个地球物理观测字段：**twt**、**depth**、**mtf1**、**mtf2**、**mag**、**gobs** 和 **faa**
   * - **dat**
     - 与 **mgd77t** 相同，但使用 plain table（纯文本表格）文件顺序
   * - **all**
     - 返回文件中所有数据列
   * - **allt**
     - 与 **mgd77t** 相同，但时间项输出为“日期-时间”格式


在这些集合后面使用 **+** 追加 **dist**，**azim**，**cc**，**vel**，和 **weight** 将可输出
对应信息。对上面提取的结果还可进行逻辑测试，其中 *logic* 由一个或多个逗号分隔的
*par*\ **OP**\ *value* 指令组成，其中 *par* 是上面列出的列名中的一个，**OP** 为逻辑运算
符（<，<=，=，!=，>=，>，\|），*value* 为常数。符点数进行数值比较，字符参数进行词法比较。
位比较（ \| ）中 *value* 中必须至少有一个位的结果是 1；且最少有一个逻辑通过测试测可以输出结果。
但如果使用大写列名，则必须所有的逻辑测试通过才可输出。

**注** ：(1) 指定对某列进行逻辑判断并不意味着该列被输出，输出必须经过指定。(2) 某些运算符
是特殊的 Unix 字符，建议在 :option:`-F` 整个参数外添加引号。(3) 逻辑测试仅适用于观测数据，派生
数据，例如距离和速度等，必须使用 :option:`-D` ，:option:`-Q` ，:option:`-S` 等选项。

对于 MGD77+ 文件，可以追加 :*bittests* ，即一个冒号，后面为一个或多个逗号分隔的 +-*col*
项。+ 表示所选位必须是 1（打开），- 表示必须为 0（关闭）。所有的位必须都通过测试。默认情况
下，具有特殊的 **MGD77_flags** 列的 MGD77+ 文件将使用这些标志，并且将与打开（ON）位相关的
观测设置为 NaN，即表示出现错误。``:`` 后面不添加任何信息将关闭此行为。需要注意的是，这些
记录标志和用于沿轨的系统改正不同，后者不能使用 :option:`-T` 选项。

可选选项
--------

.. option:: -A

**-A**\ **c**\|\ **d**\|\ **f**\|\ **m**\|\ **t**\ *code*\ [**+f**]
    默认情况下，改正后的测深（ **depth** ），残余磁异常（ **mag** ），自由空气重力异常（
    **faa** ），以及 Carter 深度改正（ **carter** ）如果被 :option:`-F` 选项选择的话，都会按原
    样输出；:option:`-A` 选项可改变该行为。对于上面的每种数据，都有 2-4 种方法来调整数据。通过
    **c**，**d** 和 **f** 或者 **m** 可分别选择上述对应的变量。也可以通过数字代码相加的
    和表示选择多种处理。例如，**-Ac**\ 3 将首先尝试使用 **-Ac**\ 1 表示的方法来估计 Carter
    改正，但如果深度为 NaN，将使用 **-Ac**\ 2 表示的方法。在所有的情况下，如果计算过程中
    存在 NaN，则会导致结果为 NaN。使用 **+f** 选项将会重新计算异常，即使文件中异常为 NaN。
    此外，用户可以使用 **-At** 为没有时间的测线通过距离和持续的时间来创建伪时间。
**-Ac**
    设置计算 **carter** 改正的方法。C(\ **twt**) Carter 改正的深度（同时依赖 **lon** 和
    **lat** ）；U(\ **twt**, *v*) 是未改正的深度（U = **twt** \* *v* / 2 ），其中的 *v*
    使用 MGD77 头部信息中的 "Assumed Sound Velocity" 参数，如果该速度为无效值，则假定为
    1500 m/s，也可以自己设定 *v* 并追加 m/s 作为单位；TU(\ **depth**, *v*) 是从未改正的
    深度计算的双程传播时间；TC(\ **depth**) 是通过 Carter 改正后得到的深度计算的双程传播
    时间。下面介绍可选择的选项：

    **-Ac1**\ [,\ *v*] 返回 U(\ **twt**, *v*) 和 **depth** 的差 [默认]

    **-Ac2**\ [,\ *v*] 返回 U(\ **twt**, *v*) 和 Carter (**twt**) 的差

    **-Ac4**\ [,\ *v*] 返回未改正的 **depth** 和 Carter (TU(**depth**)) 的差

    **-Ac8**\ [,\ *v*] 返回 U(TC(\ **depth**), *v*) 和 **depth** 的差

**-Ad**
    确定如何获取 **depth** 输出：

    **-Ad1** 返回储存在数据集中的 **depth** [默认]

    **-Ad2**\ [,\ *v*] 返回计算的未改正的深度 U(\ **twt**, *v*)

    **-Ad4** 返回计算的改正后的深度 C(\ **twt**)

**-Af**
    确定如何获取 **faa** 输出。如果计算中需要 **ngrav** （即International Gravity reference
    Field, IGF 或正常重力），则根据 MGD77 标题参数中的 “Theoretical Gravity Formula Code”
    计算重力异常，如果上述代码不存在或无效，默认设置为 4。可以在下面 4 个代码中选择来设置
    重力参考场：

    - 1 代表 Heiskanen 1924

    - 2 代表 IGF 1930, 采用海福特椭球

    - 3 代表 IGF 1967, 采用 GRS67 椭球

    - 4 代表 IGF 1980, 采用 GRS80 椭球

    可设置的选项如下:

    **-Af1**\ [,\ *field*] 返回储存在数据集中的 **faa** [默认]。可使用 :option:`-F` 选项输出 **ngrav**

    **-Af2**\ [,\ *field*] 返回 **gobs** 和 **ngrav** 的差

    **-Af4**\ [,\ *field*] 返回以下结果 **gobs** + **eot** - **ngrav**

    **-Af8**\ [,\ *field*] 返回以下结果 **gobs** + **pred_eot** - **ngrav**

**-Am**
    确定如果获取 **mag** 输出。文件中可能存在一个或者两个测量值（**mtf1** 和 **mtf2** ），**msens**
    可表明其中哪个传感器优先。可设置的选项如下：

    **-Am1** 返回储存在数据集中的 **mag** [默认]

    **-Am2** 返回 **mgfx** 和 **igrf** 的差，其中 **x** 由 **msens** 指定，可以为 1 或者 2，
    表示优先使用的传感器，如果未指定则默认为 1

    **-Am4** 返回 **mgfx** 和 **igrf** 的差，其中 **x** 由 **msens** 指定，可以为 1 或者 2，
    表示优先使用的传感器，如果未指定则默认为 2

    **-Amc**\ *offset* 使用由于测量位置和船位置不同（导航引起）导致的改正值。通过将总磁场
    重新差值到船所在的位置得到（可能存在一定的偏移 *offset* ）。由于插值以及导航质量差可能会
    导致出现重复点。GMT 已经采取一定措施处理这些情况，但不能保证全部处理干净。内插算法使用
    :term:`GMT_INTERPOLANT` 设置的算法。*offset* 的默认单位为 m，可以通过 **f**，**k**，**M**
    或 **u** 设置为英尺，km，英里，海里和 survery 英尺。

**-At**
    使用已知的测线观测时长来计算测线缺失的时间记录，该计算时间记录为伪时间记录

.. option:: -D

**-Da**\ *startdate*
    不列出开始日期 *startdata* 之前收集的数据，*startdata* 格式为 yyyy-mm-dd\ **T**\ [hh:mm:ss]。
    使用 **-DA** 可排除缺失时间记录的数据。[默认输出所有数据]
**-Db**\ *stopdate*
    不列出截止日期 *stopdata* 之后收集的数据，*stopdata* 格式为 yyyy-mm-dd\ **T**\ [hh:mm:ss]。
    使用 **-DB** 可排除缺失时间记录的数据。[默认输出所有数据]

.. option:: -E

**-E**
    精确匹配，仅输出指定的列 [默认输出至少一个匹配的列]

.. option:: -G

**-Ga**\ *startrec*
    不列出在 *startrec* 之前的记录 [默认为 0，即第一个记录]
**-Gb**\ *stoprec*
    不列出在 *stoprec* 之后的记录 [默认为最后一个记录]

.. option:: -I

**-I**\ **a\|c\|m\|t**
    忽略某些数据格式的文件。**a\|c\|m\|t** 分别表示忽略 MGD77 ASCII、MGD77+ NetCDF、
    MGD77T ASCII 、tab 分隔的普通文本文件。该选项可以重复使用以忽略多个格式

.. option:: -L

**-L**\ [*corrtable*]
    使用改正表 *corrtable* 中的值来做改正[默认使用 **$MGD77_HOME** 文件夹下的
    mgd77_corrections.txt 文件作为改正表]。改正表格式见 `改正表`_

.. option:: -N

**-Nd**\|\ **s**\ *unit*
    设置距离和速度的单位。
    **d** 表示距离，**s** 表示速度，然后可以分别指定距离和速度的单位。

    - **e** m 或 m/s，

    - **f** feet 或 feet/s

    - **k** km 或 kms/hr

    - **m** miles 或 miles/hr

    - **n** nautical miles 或 knots

    - **u** survey feet 或 survey feet/s).

    默认地，设置为 **-Ndk** **-Nse** （km 和 m/s）

.. option:: -Q

**-Qa**\ *min*/*max*
    指定可接受的方位角范围 *min*/*max* ，只输出该方位角范围内的记录 [0/360]。
**-Qc**\ *min*/*max*
    指定航向改变的范围 *min*/*max* ，只输出该范围内的记录 [-360/+360]。使用 **-QC**
    可在判断前先取绝对值。
**-Qv**\ *min*/*max*
    指定速度范围 *min*/*max* ，只输出该范围内的记录 [0/infinity]。

.. include:: explain_-R.rst_

.. option:: -S

**-Sa**\ *startdist*
    只列出测线累积距离大于 *startdist* 的数据，可追加单位。
**-Sb**\ *stopdist*
    只列出测线累积距离小于 *stopdist* 的数据，可追加单位。

.. option:: -T

**-T**\ [**m**\|\ **e**]
    关闭基于 MGD77+ 文件中的改正项的自动调整，用于抵消源机构使用 MGD77+ 导出数据创建 MGD77
    时使用的错误的单位等问题，普通 MGD77 文件不受该选项影响。**m** 表示只用于 MGD77 文件中
    存在的变量，**e** 表示只用于扩展的变量，默认两者都包括。**注** ：基于记录的 E77 标志
    （仅限于 MGD77+ 文件）不被视为系统误差改正。相反，这些位标志可以通过 :option:`-F` 选项中的
    冒号来控制。

.. option:: -W

**-W**\ *weight*
    为数据设置权重。权重的输出必须在 :option:`-F` 选项中设置。如果使用 :doc:`blockmean` ，
    :doc:`blockmedian` ，:doc:`blockmode` 模块进行加权平均处理数据，可使用该选项

.. option:: -Z

**-Z**\ **n**\|\ **p**
    为低于海平面的 **depth**，**carter** 和 **msd** 指定符号，**-Zn** 指定为负的测深，
    默认使用 **-Zp** 表示向下为正

.. include:: explain_-V.rst_

.. include:: explain_-bo.rst_

.. include:: explain_-h.rst_

.. include:: explain_distcalc.rst_

.. include:: explain_help.rst_

示例
----

从 :file:`01010047.mgd77` 文件中提取 distance，heading，gravity 以及 bathymetry，将数据
限定为 June 3 1971 20:45 以后，且累积观测距离小于 5000 km 的范围内 ::

    gmt mgd77list 01010047 -Da1971-06-03T20:45 -Sb5000 -Fdist,azim,faa,depth > myfile.txt

使用 :file:`Cruises.lis` 文件中列出的所有测线中的自由空气重力异常以便后续作为 :doc:`blockmean`
和 :doc:`surface` 模块的输入，数据必须在限定的区域内，且输出为二进制 ::

    gmt mgd77list `cat cruises.lis` -Flon,lat,faa -R-40/-30/25/35 -bo > allgrav.b

从 :file:`Cruises.lis` 中列出的测线数据中提取深度超过 9000 m 且未插值（ **btc** != 1 ）
的数据的位置 ::

    gmt mgd77list `cat cruises.lis` -F"depth,DEPTH>9000,BTC!=1" > really_deep.txt

从所有的 MGD77+ NetCDF 文件中提取 dist，faa，和 grav12_2 ，要求这些字段的值不能为 NaN，
测线文件的 ID 位于 :file:`Cruises.lis` ::

    gmt mgd77list `cat cruises.lis` -E -Ia -F"dist,faa,grav12_2,depth<3000" > \
        shallow_grav.txt

与上例使用相同的数据，但只提取 faa 的位标志为 BAD 的数据 ::

    gmt mgd77list `cat cruises.lis` -E -Ia -F"dist,faa,grav12_2:+faa" > bad_grav.txt

输出所有测线中的 lon，lat，mag 和 faa，根据最新的参考字段计算 mag 和 faa 的残余量 ::

    gmt mgd77list `cat cruises.lis` -Flon,lat,mag,faa -Af2,4 -Am2 > data.txt

重新计算的异常
--------------

当通过 :option:`-A` 选项显式地或通过 MGD77+ 文件中 E77 元数据隐式地指定重新计算异常时，GMT 只计算
原始异常中不为 NaN 的异常。这样的做的原因是，许多异常列包括手动编辑的修改，这些结果不能被重
新计算。

IGRF (International Geomagnetic Reference Field)
------------------------------------------------

IGRF 基于英国地质调查局的 Susan Macmilan 编写的 Fortran 程序，由 Algrave 大学的 Joaquim 通过
f2c 转换到 C 语言，最终 Paul Wessel 改成 GMT 风格。

IGF (International Gravity reference Field)
-------------------------------------------

这里给出代码中使用的计算正常重力的公式, GMT 在重力观测值中扣除该正常重力得到重力异常。
下述公式均为索米里安公式的在不同椭球下的近似公式，对于 WGS-84 椭球，其与 GRS80 椭球仅
存在微小差异，应采用第四个公式 ::

    (1) g = 978052.0 * [1 + 0.005285 * sin^2(lat) - 7e-6 * sin^2(2*lat) + 27e-6 * cos^2(lat) * cos^2(lon-18)]

    (2) g = 978049.0 * [1 + 0.0052884 * sin^2(lat) - 0.0000059 * sin^2(2*lat)]

    (3) g = 978031.846 * [1 + 0.0053024 * sin^2(lat) - 0.0000058 * sin^2(2*lat)]

    (4) g = 978032.67714 * [(1 + 0.00193185138639 * sin^2(lat)) / sqrt (1 - 0.00669437999013 * sin^2(lat))]

如果您发现上述公式存在问题，请向
`GMT 官方 <https://github.com/GenericMappingTools/gmt>`__ 报告。

改正表
------

改正表是一个 ASCII 文件，其中包含实施改正所需的系数和参数。文件头部可以存在以 ``#`` 为开头的
注释，改正记录的格式如下 ::

    cruiseID observation correction

其中 *cruiseID* 为测线 ID，NCEI 定义的前缀，*observation* 为 :option:`-F` 选项里列名表中的某个列名，
*correction* 由一项或者多项组成，所有的项在输出观测值前都被扣除，每项的格式为 ::

    factor[*[function]([scale](abbrev[-origin]))[^power]]

其中方括号中的值是可选的，除不同项之间，其他地方不允许有空格。*factor* 是基函数的幅值，可选的
*function* 可以是 sin，cos，或者 exp。可选的 *scale* 和 *origin* 用于对参数进行一定的转换。
*abbrev* 参数是上面列出的列名之一。如果 *origin* 为 **T** ，则将其替换为文件中第一个 *abbrev*
值（通常同于时间）。如果第一条记录为 NaN，则将 *origin* 设置为 0。在乘以幅度前，可也对整个表达
式设置一定的幂指数 *power* 。

下面是对测线 99999999 的虚构数据的改正示例，三行分别表示：对深度 **depth** 进行 Carter 改正，
对自由空气重力异常 **faa** 移除线性趋势，对磁异常 **mag** 进行依赖航向和纬度的改正，对重力
**gobs** 需要添加 10 mGal 的增量 ::

    99999999 depth 1.0*((carter))

    99999999 faa 14.1 1e-5*((time-T))

    99999999 mag 0.5*cos(0.5*(azim-19))^2 1.0*exp(-1e-3(lat))^1.5

    99999999 gobs -10

参考
----

MGD77 (Marine Geophysical Data Exchange Format) 格式见
`http://www.ngdc.noaa.gov/mgg/dat/geodas/docs/mgd77.txt. <http://www.ngdc.noaa.gov/mgg/dat/geodas/docs/mgd77.txt>`__

IGRF 见 `<https://www.ngdc.noaa.gov/IAGA/vmod/igrf.html>`__

相关模块
--------

:doc:`mgd77convert`,
:doc:`mgd77header`,
:doc:`mgd77magref`,
:doc:`mgd77manage`,
:doc:`mgd77path`,
:doc:`mgd77track`,
:doc:`mgd77sniffer`,
:doc:`mgd77track`
