batch
- 官方文档:
- 简介:
自动化批处理作业处理
batch 模块可以使用单个主脚本生成 GMT 处理作业,并针对所有作业重复执行, 同时利用特定作业变量进行一些变化。该模块简化(并隐藏)了通常需要设置完整处理序列的大部分步骤。 用户可以专注于编写主处理脚本,并让作业的并行执行自动完成。 我们可以通过可选的 preflight 脚本设置所需数据集并进行一次性计算。 完成后,我们可以通过 postflight 脚本可选地汇总数据输出并生成摘要图或类似操作。
备注
该模块适用于对脚本语言循环等用法不熟悉的用户,更熟练的用户可自行使用脚本语言代替本模块以实现更高自由度。
语法
gmt batch mainscript -Nprefix -Tnjobs|min/max/inc[+n]|timefile[+pwidth][+sfirst][+w[str]|W] [ -D ] [ -Ftemplate ] [ -Iincludefile ] [ -M[job] ] [ -Q[s] ] [ -Sbpreflight ] [ -Sfpostflight ] [ -V[level] ] [ -W[dir] ] [ -Z ] [ -fflags ] [ -x[[-]n] ] [ --PAR=value ]
注意:选项标志和相关参数之间不允许有任何空格。
必选选项
- mainscript
独立的 GMT 现代模式处理脚本的名称,用于执行参数相关的计算。 脚本可以访问作业变量,如作业编号和下面定义的其他变量, 并且可以使用 Bourne shell (.sh)、Bourne again shell (.bash)、 C shell (.csh) 或 DOS batch (.bat) 编写。脚本语言由文件扩展名推断, 并且我们使用相同语言构建隐藏的批处理脚本。可以访问的参数将在下文讨论。
- -Nprefix
决定批处理文件产品的前缀以及执行后可找到中间作业产品的最终子目录。
- -Tnjobs|min/max/inc[+n]|timefile[+pwidth][+sfirst][+w[str]|W]
指定要生成的作业数量,创建从 min 到 max 以 inc 为间隔的一列数据集, 或提供包含参数集的文件,每行对应一个作业。列中的值将作为命名变量 BATCH_COL0, BATCH_COL1 等可用于 mainscript, 任何尾随文本可通过 BATCH_TEXT 访问。记录数量等于作业数量。 注意,如果只给出 njobs,则仅可使用 BATCH_JOB,因为没有数据文件。 有关数组创建的详细信息,请参见 生成一维数组。还提供几个修饰符: - +n 指示 inc 为所需作业数而非增量。 - +p 可设置作业编号格式的宽度,例如 name_000010.grd 宽度为 6。默认情况下自动设置宽度,但如果通过 +s 在多台计算机间分割作业,则必须保证所有帧名称宽度一致。 - +s 从 first 而非 0 开始编号输出作业。注意:所有作业仍包含,修饰符仅影响输出编号。 - +w 将尾随文本拆分为单词,通过变量 BATCH_WORD0、BATCH_WORD1 等访问。默认以制表符或空格分隔,可附加 str 指定其他分隔符。仅使用制表符可使用 +W。
可选选项
- -D
如果主脚本没有生成使用前缀 BATCH_NAME 的产品, 或者主脚本将直接处理这些产品文件位置,请选择此选项。
- -Ftemplate
不使用 BATCH_NAME 前缀的单一流水号构建产品文件名, 而是使用 C格式 template 根据 timefile 数据列创建唯一名称。限制如下: (1) 如果 timefile 有尾随文本, 可用单个 %s 在模板最后格式化;如果无 %s,则尾随文本不会使用。 (2) 前 N 个格式语句用于转换 timefile 的前 N 列;不能跳过列或指定列顺序 (可用 -iflags 重排输入顺序)。 (3) 可使用最多五个数值语句(前提 timefile 有足够列)。 例如 -Fmy_data_%05.2lf_%07.0lf_%s 使用 timefile 的前两列和尾随文本生成唯一前缀。 注意:GMT 数据集内部使用双精度变量,即使列为整数也应使用浮点格式。 若格式语句和尾随文本包含空格或制表符,将自动替换为下划线。
- -Iincludefile
将 includefile 的内容插入 batch_init.sh 脚本, 供所有批处理脚本访问。通常用于添加主脚本和可选 -S 脚本可依赖的常量变量。
- -M[job]
不生成和启动完整处理序列,仅选择一个主作业 [0] 测试。 主作业将在 workdir 中运行,其产品会生成。任何 preflight 脚本会在主作业前运行, 但 postflight 脚本不会执行(但会创建)。
- -Q[s]
调试:保留所有创建的文件和目录以供检查。或附加 s 仅生成批处理脚本但不执行。 唯一例外是可选 preflight 脚本(-Sb),始终执行, 因为可能产生构建主批处理脚本所需的数据。
- -Sbpreflight
可选 GMT 现代模式 preflight 脚本(与 mainscript 同语言), 可下载或复制数据文件,或创建 mainscript 所需的文件(如 timefile)。 总是在主批处理序列之前执行。
- -Sfpostflight
可选 postflight 脚本(与 mainscript 同语言),可在所有作业完成后执行最终处理, 如汇总产品、生成报告或图示。注意:postflight 脚本不必为 GMT 脚本。
- -V[level] (more …)
设置 verbose 等级 [w]
- -W[dir]
默认情况下,所有临时文件和作业产品创建在 -N 设置的 prefix 子目录中。 可通过 dir 覆盖路径。若未提供路径,将在系统临时目录中创建名为 prefix 的工作目录。 工作目录的好处是避免 DropBox 或 TimeMachine 的无限同步,或主目录空间不足问题。 产品文件仍放置在 prefix 目录中。除非 -Q 指定调试,否则工作目录在完成后会被删除。
- -f[i|o]colinfo (more …)
指定输入或输出列的数据类型
- -x[[-]n]
限制分发作业时使用的核心数量。默认尝试使用所有可用核心。 附加 n 表示仅使用 n 核心(若 n 太大则截断为最大核心数)。 负数 n 表示选择 (所有 - n) 核心(至少 1 核)。并行处理不依赖 OpenMP; 前一个作业完成后启动下一个。注意:batch 会保留一个核心,因此实际用于作业的核心为 n-1。
- -^ 或 -
显示简短的帮助信息,包括模块简介和基本语法信息(Windows下只能使用 -)
- -+ 或 +
显示帮助信息,包括模块简介、基本语法以及模块特有选项的说明
- -? 或无参数
显示完整的帮助信息,包括模块简介、基本语法以及所有选项的说明
- --PAR=value
临时修改GMT参数的值,可重复多次使用。参数列表见 配置参数
生成一维数组
下面将展示如何使用 gmtmath 生成一维数组(其中大部分操作也可通过 linux 中的 seq 命令方便地实现)
不使用任何子选项
以 0.1 为步长,生成 3.1 到 4.2 等等间隔序列
gmt math -o0 -T3.1/4.2/0.1 T =
3.1
3.2
...
4.2
+a 选项
该选项不对生成的数列进行运算操作,而是将该数列以列的形式追加到输出表数据,类似 linux 中的 paste 命令。
+b 选项
以 3 和 20 分别为起点和终点,创建一个 2 的整数幂的列表,将生成 的整数幂以 1 为步长取值 -T3/20/1+b
gmt math -o0 -T3/20/1+b T =
4
8
16
+l 选项
以 7 和 135 分别为起点和终点,先创建一个 10 的整数幂的列表,当 inc 为 1 时,输出该列表;当 inc 为 2 时,同时输出该列表中每个元素的 1,2,5 倍值(不包括超出原始数据范围的部分); 当 inc 为 3 时,同时输出 该列表中每个元素的 1,2,…,9 倍值(同样不包括超出原始数据范围的部分)。 -T7/135/2+l 将会生成如下数列
gmt math -o0 -T7/135/2+l T =
10
20
50
100
inc 为负整数时,将实现如下效果
gmt math -o0 -T1e-4/1e4/-2+l T =
0.0001
0.01
1
100
10000
+i 选项
该选项将以 1 作为默认步长,第三个数字做为每步长中的数字个数 length。假设需要在 1 分钟内每 24 秒生成一帧
gmt math -o0 -T0/60/24+i T =
0
0.0416666666667
0.0833333333333
0.125
0.166666666667
...
60
+n 选项
生成固定长度的数列。以 3.44 和 7.82 为 起点和终点,生成长度为 5 的等间隔序列
gmt math -o0 -T3.44/7.82/5+n T =
3.44
4.535
5.63
6.725
7.82
-T 后直接加文件或逗号分隔的数列
-T 后可以直接加文件,文件中即为要生成的列表;另外,可以直接使用逗号分隔, 将列表附加到 -T 选项后,如下为 Fibonacci 数列前 6 项
gmt math -o0 -T0,1,1,2,3,5 T =
0
1
1
2
3
5
注 : 如果数列只包含一个值,必须在其后加逗号以表明仍是一个数列
+u 选项
如果文件或者逗号分隔的数列中有重复数字或未排序,可以使用 +u 选项去重并排序。
+t 选项
生成绝对时间序列。在 inc 后分别添加 y ,o ,d ,h , m 和 s 表示时间步长的单位为年,月,日,时,分,秒。在其后附加 +t 选项, 可以进一步强调生成时间序列,也可以不加
gmt math -o0 -T2020-03-01T/2020-03-07T/1d T =
2020-03-01T00:00:00
2020-03-02T00:00:00
2020-03-03T00:00:00
2020-03-04T00:00:00
2020-03-05T00:00:00
2020-03-06T00:00:00
2020-03-07T00:00:00
生成距离序列
如果输入文件中包含两列以上的数据,可以使用前两列计算距离,并生成等距序列。 在 inc 后分别添加 d,m,s,e,f,M,n 和 u 表示距离步长的单位为度,分,秒,米,英尺,公里,英里,海里,英尺。如果 为笛卡尔坐标,使用 c 作为距离步长单位。
+e 选项
如果只给定 inc 而从数据中获取最大值和最小值,则 (max - min)/inc 可能 不是整数,GMT 讲会自动对 inc 进行一定的调整。如果不想调整 inc ,则可以 使用 +e 选项,GMT 会固定最小值,适当调整最大值。
参数
多个参数会自动分配,可用于 mainscript 和可选 preflight/postflight 脚本。 参数分为常量和随作业编号变化的变量。常量对所有脚本可用:BATCH_PREFIX: 批处理作业通用前缀(由 -N 设置);BATCH_NJOBS:作业总数(由 -T 给出或推断)。 若使用 -I,其中列出的静态参数也可用于所有脚本。此外,mainscript 可访问随作业编号变化的参数: BATCH_JOB:当前作业编号(整数,例如 136), BATCH_ITEM: 根据宽度格式化的作业编号字符串(例如 000136),BATCH_NAME: 当前作业唯一前缀(即 prefix_BATCH_ITEM)。若提供 timefile, 则 BATCH_COL0、BATCH_COL1 等变量分别对应列。 尾随文本可通过 BATCH_TEXT 访问,若启用 +w 分词, 则还可通过 BATCH_WORD0、 BATCH_WORD1 等访问。注意: 处理脚本生成的产品应使用 BATCH_NAME 作为前缀, 以便自动移动到起始目录(除非使用 -D)。使用 -F 可基于 -T 输入参数生成更灵活的产品名称。
数据文件
批处理脚本可访问 batch 启动时存在的起始目录中的任何文件, 以及 mainscript 或通过 -S 设置的可选脚本生成的新文件。 无需指定路径。其他文件可能需要完整路径,除非其目录已包含在 DIR_DATA 设置中。
自定义 gmt.conf 文件
如果在运行 batch 前主脚本所在目录有 gmt.conf 文件, 则该文件将被所有创建和执行的脚本共享,除非脚本在启动现代模式时使用 -C 覆盖。 修改 GMT 默认值的推荐方式是通过 gmtset 在输入脚本中调用。 注意:每个脚本独立运行(现代模式),因此通过 preflight 创建 gmt.conf 文件无法被其他脚本使用。
构建主脚本
如果调用间没有变化,批处理序列没有意义。为了实现变化, mainscript 需要访问不同的数据集、 数据子集,或作业参数不同,或以上组合。策略如下:
通过 -T 提供的 timefile 列出特定数据文件, mainscript 使用 BATCH_TEXT 或 BATCH_WORD? 访问特定作业文件名。
对于 3D 网格(或 2D 网格堆叠),沿垂直于切片的轴(时间或深度)插值, 可使用 grdinterpolate 获取临时切片网格进行处理。
可使用 gmtmath 或 grdmath 动态生成数据, 或每个作业稍作不同处理(使用 timefile 参数)。
利用 timefile 传递任何所需参数。
技术细节
batch 模块会创建多个隐藏脚本:
batch_init 初始化变量并包含可选 includefile 内容。
batch_preflight (可选,来自 -Sb) 准备所需数据文件。
batch_postflight (可选,来自 -Sf) 在所有作业完成后处理文件。
batch_job 接受作业编号并处理数据。
batch_cleanup 结束时删除临时文件。
每个作业有单独的 batch_params_###### 脚本,用于提供作业特定变量。
preflight 和 postflight 可访问 batch_init 信息, batch_job 还可访问作业特定参数文件。
使用 -Q 可仅生成这些脚本以供检查。
注意:mainscript 会为每个作业复制以上所需文件,多个作业可同时在所有可用核心上运行。 多线程 GMT 模块将限制为单核心调用。 每个作业都会确保创建唯一文件,以便 batch 判断作业完成并启动下一个。
Shell 脚本局限
由于无法控制 shell(如 bash 或 csh)在两个进程间管道的实现(通常涉及子 shell), 建议避免在主脚本中使用 GMT 模块间管道(例如 gmt blockmean … | gmt surface …)。 批处理同时运行多个实例时,子 shell 可能导致 GMT 历史文件损坏,出现错误信息。 建议将管道拆分为使用临时文件的两步。 非 GMT 模块与 GMT 模块间的管道不受影响(如 echo … | gmt convert …)。
使用该模块建议
编写批处理作业相对简单,但需以变量为思路。先编写单个 mainscript,确定哪些随作业编号变化, 创建变量。如果只需作业编号,可直接使用自动生成变量。 否则,需制作 -T 文件,每行对应一个作业,列包含所需值。 固定变量可通过 -I 指向 includefile 赋值。测试脚本时, 使用 -Q -M 确保主作业结果正确,调整变量和选项,最终移除 -Q。建议初期使用小批次作业快速验证。
示例
提取几内亚湾的 2x2 弧分分辨率地球 DEM 子集,并计算高斯滤波高通网格, 滤波宽度从 10 到 200 km,步长 10 km。所有网格完成后,计算标准差。示例操作:
cat << EOF > pre.sh
gmt begin
gmt math -o0 -T10/200/10 T = widths.txt
gmt grdcut -R-10/20/-10/20 @earth_relief_02m -Gdata.grd
gmt end
EOF
cat << 'EOF' > main.sh
gmt begin
gmt grdfilter data.grd -Fg${BATCH_COL0}+h -G${BATCH_NAME}.grd -D2
gmt end
EOF
cat << 'EOF' > post.sh
gmt begin ${BATCH_PREFIX} pdf
gmt grdmath ${BATCH_PREFIX}_*.grd -S STD = ${BATCH_PREFIX}_std.grd
gmt grdimage ${BATCH_PREFIX}_std.grd -B -B+t"STD of Gaussians residuals" -Chot
gmt coast -Wthin,white
gmt end show
EOF
gmt batch main.sh -Sbpre.sh -Sfpost.sh -Twidths.txt -Nfilter -V -Z
当然,变量的使用语法会根据脚本语言而有所不同。在这里, 我们实际上是动态生成 pre.sh、main.sh 和 post.sh 脚本, 因此需要对任何变量进行转义(因为它们以美元符号开头,需要按原样书写)。 通过将 EOF 用引号包围,重定向不会替换变量,而是将其保留为原文文本。 执行结束后,我们会得到 20 个网格文件(例如 filter_07.grd), 以及通过堆叠所有单独脚本并计算标准差生成的 filter_std.grd 文件。 完成这些操作所需的信息对用户是隐藏的;实际执行的批处理脚本是基于用户提供的 main.sh 脚本生成的, 而 batch 提供了额外的机制。batch 模块会自动管理所有作业的并行执行循环, 使用所有可用核心,并在前一个作业完成后启动新的作业。
另一个示例,我们获取所有欧洲国家的列表,并为每个国家制作一个简单的海岸线图, 将国家名称放在标题中,将两字符 ISO 代码放在左上角, 然后在 postflight 中将所有单独的 PDF 合并为一个 PDF 文件,并删除单独的文件。 在这里,我们将 EOF 标签用引号包围,以防止未转义的变量被解释:
cat << EOF > pre.sh
gmt begin
gmt coast -E=EU+l > countries.txt
gmt end
EOF
cat << 'EOF' > main.sh
gmt begin ${BATCH_NAME} pdf
gmt coast -R${BATCH_WORD0}+r2 -JQ10c -Glightgray -Slightblue -B -B+t"${BATCH_WORD1}" -E${BATCH_WORD0}+gred+p0.5p
echo ${BATCH_WORD0} | gmt text -F+f16p+jTL+cTL -Gwhite -W1p
gmt end
EOF
cat << 'EOF' > post.sh
gmt psconvert -TF -F${BATCH_PREFIX} ${BATCH_PREFIX}_*.pdf
rm -f ${BATCH_PREFIX}_*.pdf
EOF
gmt batch main.sh -Sbpre.sh -Sfpost.sh -Tcountries.txt+w"\t" -Ncountries -V -W -Z
macOS 问题
默认同时打开的文件数在 macOS 上相对较小,执行大量作业时可能出现 “Too many open files” 错误。可参考 链接 解决。