From 9d5e3f8d5f120569a11a71388c670c950c0f20e0 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 14:24:15 +0100 Subject: [PATCH 01/20] Initial addition of gsfml supplement Trying to see if GSFML can be a supplement of GMT. --- src/gsfml/CK1995n.h | 231 +++++++++ src/gsfml/CK1995r.h | 231 +++++++++ src/gsfml/CMakeLists.txt | 35 ++ src/gsfml/Chron_Normal.h | 231 +++++++++ src/gsfml/Chron_Normal2.h | 231 +++++++++ src/gsfml/Chron_Reverse.h | 231 +++++++++ src/gsfml/Chron_Reverse2.h | 231 +++++++++ src/gsfml/GST2004n.h | 231 +++++++++ src/gsfml/GST2004r.h | 231 +++++++++ src/gsfml/GST2012n.h | 231 +++++++++ src/gsfml/GST2012r.h | 231 +++++++++ src/gsfml/Geek2007n.h | 231 +++++++++ src/gsfml/Geek2007r.h | 231 +++++++++ src/gsfml/README.gsfml | 53 ++ src/gsfml/fz_analysis.h | 106 ++++ src/gsfml/fz_funcs.sh | 118 +++++ src/gsfml/fzanalyzer.c | 981 ++++++++++++++++++++++++++++++++++++ src/gsfml/fzblender.c | 635 +++++++++++++++++++++++ src/gsfml/fzinformer | 186 +++++++ src/gsfml/fzmapper | 240 +++++++++ src/gsfml/fzmodeler | 179 +++++++ src/gsfml/fzprofiler | 269 ++++++++++ src/gsfml/gsfml_config.h.in | 22 + src/gsfml/gsfml_glue.c | 60 +++ src/gsfml/mlconverter.c | 369 ++++++++++++++ 25 files changed, 6025 insertions(+) create mode 100644 src/gsfml/CK1995n.h create mode 100644 src/gsfml/CK1995r.h create mode 100644 src/gsfml/CMakeLists.txt create mode 100644 src/gsfml/Chron_Normal.h create mode 100644 src/gsfml/Chron_Normal2.h create mode 100644 src/gsfml/Chron_Reverse.h create mode 100644 src/gsfml/Chron_Reverse2.h create mode 100644 src/gsfml/GST2004n.h create mode 100644 src/gsfml/GST2004r.h create mode 100644 src/gsfml/GST2012n.h create mode 100644 src/gsfml/GST2012r.h create mode 100644 src/gsfml/Geek2007n.h create mode 100644 src/gsfml/Geek2007r.h create mode 100644 src/gsfml/README.gsfml create mode 100644 src/gsfml/fz_analysis.h create mode 100644 src/gsfml/fz_funcs.sh create mode 100644 src/gsfml/fzanalyzer.c create mode 100644 src/gsfml/fzblender.c create mode 100755 src/gsfml/fzinformer create mode 100755 src/gsfml/fzmapper create mode 100755 src/gsfml/fzmodeler create mode 100755 src/gsfml/fzprofiler create mode 100644 src/gsfml/gsfml_config.h.in create mode 100644 src/gsfml/gsfml_glue.c create mode 100644 src/gsfml/mlconverter.c diff --git a/src/gsfml/CK1995n.h b/src/gsfml/CK1995n.h new file mode 100644 index 00000000000..b676949c35c --- /dev/null +++ b/src/gsfml/CK1995n.h @@ -0,0 +1,231 @@ +{ 0, 0.78 }, +{ 0.99, 1.07 }, +{ -1.0, -1.0 }, +{ 1.77, 1.95 }, +{ 2.14, 2.15 }, +{ 2.581, 3.04 }, +{ 3.11, 3.22 }, +{ 3.33, 3.58 }, +{ 4.18, 4.29 }, +{ 4.48, 4.62 }, +{ 4.8, 4.89 }, +{ 4.98, 5.23 }, +{ 5.894, 6.137 }, +{ 6.269, 6.567 }, +{ 6.935, 7.091 }, +{ 7.135, 7.17 }, +{ 7.341, 7.375 }, +{ 7.432, 7.562 }, +{ 7.65, 8.072 }, +{ 8.225, 8.257 }, +{ -1.0, -1.0 }, +{ 8.699, 9.025 }, +{ -1.0, -1.0 }, +{ 9.23, 9.308 }, +{ 9.58, 9.642 }, +{ 9.74, 9.88 }, +{ 9.92, 10.949 }, +{ 11.052, 11.099 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ 11.476, 11.531 }, +{ -1.0, -1.0 }, +{ 11.935, 12.078 }, +{ 12.184, 12.401 }, +{ 12.678, 12.708 }, +{ 12.775, 12.819 }, +{ 12.991, 13.139 }, +{ 13.302, 13.51 }, +{ 13.703, 14.076 }, +{ 14.178, 14.612 }, +{ 14.8, 14.888 }, +{ 15.034, 15.155 }, +{ 16.014, 16.293 }, +{ 16.327, 16.488 }, +{ 16.556, 16.726 }, +{ 17.277, 17.615 }, +{ -1.0, -1.0 }, +{ 18.281, 18.781 }, +{ 19.048, 20.131 }, +{ 20.518, 20.725 }, +{ 20.996, 21.32 }, +{ 21.768, 21.859 }, +{ 22.151, 22.248 }, +{ 22.459, 22.493 }, +{ 22.588, 22.75 }, +{ 22.804, 23.069 }, +{ 23.353, 23.535 }, +{ 23.677, 23.8 }, +{ 23.999, 24.118 }, +{ 24.73, 24.781 }, +{ 24.835, 25.183 }, +{ 25.496, 25.648 }, +{ -1.0, -1.0 }, +{ 25.823, 25.951 }, +{ 25.992, 26.554 }, +{ 27.027, 27.972 }, +{ 28.283, 28.512 }, +{ 28.578, 28.745 }, +{ 29.401, 29.662 }, +{ 29.765, 30.098 }, +{ 30.479, 30.939 }, +{ 33.058, 33.545 }, +{ 34.655, 34.94 }, +{ 35.343, 35.526 }, +{ 35.685, 36.341 }, +{ 36.618, 37.473 }, +{ 37.604, 37.848 }, +{ 37.92, 38.113 }, +{ 38.426, 39.552 }, +{ 39.631, 40.13 }, +{ 41.257, 41.521 }, +{ 42.536, 43.789 }, +{ 46.264, 47.906 }, +{ 49.037, 49.714 }, +{ 50.778, 50.946 }, +{ 51.047, 51.743 }, +{ 52.364, 52.663 }, +{ 52.757, 52.801 }, +{ 52.903, 53.347 }, +{ 55.904, 56.391 }, +{ 57.554, 57.911 }, +{ 60.92, 61.276 }, +{ 62.499, 63.634 }, +{ 63.976, 64.745 }, +{ 65.578, 67.61 }, +{ 67.735, 68.737 }, +{ 71.071, 71.338 }, +{ 71.587, 73.004 }, +{ 73.291, 73.374 }, +{ 73.619, 79.075 }, +{ 83, 118 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -999.0, -999.0} diff --git a/src/gsfml/CK1995r.h b/src/gsfml/CK1995r.h new file mode 100644 index 00000000000..7319f198712 --- /dev/null +++ b/src/gsfml/CK1995r.h @@ -0,0 +1,231 @@ +{ 0.78, 0.99 }, +{ 1.07, -1.0 }, +{ -1.0, 1.77 }, +{ 1.95, 2.14 }, +{ 2.15, 2.581 }, +{ 3.04, 3.11 }, +{ 3.22, 3.33 }, +{ 3.58, 4.18 }, +{ 4.29, 4.48 }, +{ 4.62, 4.8 }, +{ 4.89, 4.98 }, +{ 5.23, 5.894 }, +{ 6.137, 6.269 }, +{ 6.567, 6.935 }, +{ 7.091, 7.135 }, +{ 7.17, 7.341 }, +{ 7.375, 7.432 }, +{ 7.562, 7.65 }, +{ 8.072, 8.225 }, +{ 8.257, -1.0 }, +{ -1.0, 8.699 }, +{ 9.025, -1.0 }, +{ -1.0, 9.23 }, +{ 9.308, 9.58 }, +{ 9.642, 9.74 }, +{ 9.88, 9.92 }, +{ 10.949, 11.052 }, +{ 11.099, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, 11.476 }, +{ 11.531, -1.0 }, +{ -1.0, 11.935 }, +{ 12.078, 12.184 }, +{ 12.401, 12.678 }, +{ 12.708, 12.775 }, +{ 12.819, 12.991 }, +{ 13.139, 13.302 }, +{ 13.51, 13.703 }, +{ 14.076, 14.178 }, +{ 14.612, 14.8 }, +{ 14.888, 15.034 }, +{ 15.155, 16.014 }, +{ 16.293, 16.327 }, +{ 16.488, 16.556 }, +{ 16.726, 17.277 }, +{ 17.615, -1.0 }, +{ -1.0, 18.281 }, +{ 18.781, 19.048 }, +{ 20.131, 20.518 }, +{ 20.725, 20.996 }, +{ 21.32, 21.768 }, +{ 21.859, 22.151 }, +{ 22.248, 22.459 }, +{ 22.493, 22.588 }, +{ 22.75, 22.804 }, +{ 23.069, 23.353 }, +{ 23.535, 23.677 }, +{ 23.8, 23.999 }, +{ 24.118, 24.73 }, +{ 24.781, 24.835 }, +{ 25.183, 25.496 }, +{ 25.648, -1.0 }, +{ -1.0, 25.823 }, +{ 25.951, 25.992 }, +{ 26.554, 27.027 }, +{ 27.972, 28.283 }, +{ 28.512, 28.578 }, +{ 28.745, 29.401 }, +{ 29.662, 29.765 }, +{ 30.098, 30.479 }, +{ 30.939, 33.058 }, +{ 33.545, 34.655 }, +{ 34.94, 35.343 }, +{ 35.526, 35.685 }, +{ 36.341, 36.618 }, +{ 37.473, 37.604 }, +{ 37.848, 37.92 }, +{ 38.113, 38.426 }, +{ 39.552, 39.631 }, +{ 40.13, 41.257 }, +{ 41.521, 42.536 }, +{ 43.789, 46.264 }, +{ 47.906, 49.037 }, +{ 49.714, 50.778 }, +{ 50.946, 51.047 }, +{ 51.743, 52.364 }, +{ 52.663, 52.757 }, +{ 52.801, 52.903 }, +{ 53.347, 55.904 }, +{ 56.391, 57.554 }, +{ 57.911, 60.92 }, +{ 61.276, 62.499 }, +{ 63.634, 63.976 }, +{ 64.745, 65.578 }, +{ 67.61, 67.735 }, +{ 68.737, 71.071 }, +{ 71.338, 71.587 }, +{ 73.004, 73.291 }, +{ 73.374, 73.619 }, +{ 79.075, 83 }, +{ 118, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -999.0, -999.0} diff --git a/src/gsfml/CMakeLists.txt b/src/gsfml/CMakeLists.txt new file mode 100644 index 00000000000..906410b943a --- /dev/null +++ b/src/gsfml/CMakeLists.txt @@ -0,0 +1,35 @@ +# +# Copyright (c) 1991-2023 by the GMT Team (https://www.generic-mapping-tools.org/team.html) +# See LICENSE.TXT file for copying and redistribution conditions. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; version 3 or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# Contact info: www.generic-mapping-tools.org +#------------------------------------------------------------------------------- +# +# CMake settings for supplemental package: +# +# SUPPL_NAME: name of the supplemental package +# SUPPL_HEADERS: header files. Will be installed if BUILD_DEVELOPER is TRUE +# SUPPL_PROGS_SRCS: list of C source codes for supplemental modules +# SUPPL_LIB_SRCS: list of C source codes for supplemental library +# SUPPL_EXAMPLE_FILES: README and other example files +# SUPPL_EXAMPLE_PROGS: Example scripts +# + +set (SUPPL_NAME gsfml) +set (SUPPL_HEADERS CK1995n.h Chron_Normal.h Chron_Reverse.h GST2004n.h GST2012n.h Geek2007n.h + CK1995r.h Chron_Normal2.h Chron_Reverse2.h GST2004r.h GST2012r.h Geek2007r.h) + fz_analysis.h) +AUX_SOURCE_DIRECTORY (longopt SUPPL_LONG_OPT_H) +set (SUPPL_PROGS_SRCS fzanalyzer.c fzblender.c mlconverter.c) +set (SUPPL_EXAMPLE_FILES README.gsfml) + +set (SUPPL_EXAMPLE_PROGS fz_funcs.sh fzinformer fzmapper fzmodeler fzprofiler) diff --git a/src/gsfml/Chron_Normal.h b/src/gsfml/Chron_Normal.h new file mode 100644 index 00000000000..7d229d8d48d --- /dev/null +++ b/src/gsfml/Chron_Normal.h @@ -0,0 +1,231 @@ +"C1n", +"C1r.1n", +"C1r.2r-1n", +"C2n", +"C2r.1n", +"C2An.1n", +"C2An.2n", +"C2An.3n", +"C3n.1n", +"C3n.2n", +"C3n.3n", +"C3n.4n", +"C3An.1n", +"C3An.2n", +"C3Bn", +"C3Br.1n", +"C3Br.2n", +"C4n.1n", +"C4n.2n", +"C4r.1n", +"C4r.2r-1n", +"C4An", +"C4Ar.1r-1n", +"C4Ar.1n", +"C4Ar.2n", +"C5n.1n", +"C5n.2n", +"C5r.1n", +"C5r.2r-1n", +"C5r.2r-2n", +"C5r.2n", +"C5r.3r-1n", +"C5An.1n", +"C5An.2n", +"C5Ar.1n", +"C5Ar.2n", +"C5AAn", +"C5ABn", +"C5ACn", +"C5ADn", +"C5Bn.1n", +"C5Bn.2n", +"C5Cn.1n", +"C5Cn.2n", +"C5Cn.3n", +"C5Dn", +"C5Dr-1n", +"C5En", +"C6n", +"C6An.1n", +"C6An.2n", +"C6AAn", +"C6AAr.1n", +"C6AAr.2n", +"C6Bn.1n", +"C6Bn.2n", +"C6Cn.1n", +"C6Cn.2n", +"C6Cn.3n", +"C7n.1n", +"C7n.2n", +"C7An", +"C7Ar-1n", +"C8n.1n", +"C8n.2n", +"C9n", +"C10n.1n", +"C10n.2n", +"C11n.1n", +"C11n.2n", +"C12n", +"C13n", +"C15n", +"C16n.1n", +"C16n.2n", +"C17n.1n", +"C17n.2n", +"C17n.3n", +"C18n.1n", +"C18n.2n", +"C19n", +"C20n", +"C21n", +"C22n", +"C23n.1n", +"C23n.2n", +"C24n.1n", +"C24n.2n", +"C24n.3n", +"C25n", +"C26n", +"C27n", +"C28n", +"C29n", +"C30n", +"C31n", +"C32n.1n", +"C32n.2n", +"C32r.1n", +"C33n", +"C34n", +"M1n", +"M2n", +"M4n", +"M6n", +"M7n", +"M8n", +"M9n", +"M10n", +"M10Nn.1n", +"M10Nn.2n", +"M10Nn.3n", +"M11n", +"M11r.1n", +"M11An.1n", +"M11An.2n", +"M12n", +"M12r.1n", +"M12An", +"M13n", +"M14n", +"M15n", +"M16n", +"M17n", +"M18n", +"M19n.1n", +"M19n", +"M20n.1n", +"M20n.2n", +"M21n", +"M22n.1n", +"M22n.2n", +"M22n.3n", +"M22An", +"M23n.1n", +"M23n.2n", +"M24n.1n", +"M24n.2n", +"M24An", +"M24Bn", +"M25n", +"M25An.1n", +"M25An.2n", +"M25An.3n", +"M26n.1n", +"M26n.2n", +"M26n.3n", +"M26n.4n", +"M27n", +"M28n", +"M28An", +"M28Bn", +"M28Cn", +"M28Dn", +"M29n.1n", +"M29n.2n", +"M29An", +"M30n", +"M30An", +"M31n.1n", +"M31n.2n", +"M31n", +"M32n.1n", +"M32n.2n", +"M32n", +"M33n", +"M33An", +"M33Bn", +"M33Cn.1n", +"M33Cn", +"M34n.1n", +"M34n.2n", +"M34n.3n", +"M34An", +"M34Bn.1n", +"M34Bn", +"M35n", +"M36n.1n", +"M36An", +"M36Bn", +"M36Cn", +"M37n.1n", +"M37n", +"M38n.1n", +"M38n.2n", +"M38n.3n", +"M38n.4n", +"M38n", +"M39n.1n", +"M39n.2n", +"M39n.3n", +"M39n.4n", +"M39n.5n", +"M39n.6n", +"M39n.7n", +"M39n", +"M40n.1n", +"M40n.2n", +"M40n.3n", +"M40n", +"M41n.1n", +"M41n.2n", +"M41n.3n", +"M41n", +"M42n.1n", +"M42n.2n", +"M42n.3n", +"M42n.4n", +"M42n.5n", +"M42n.6n", +"M42n.7n", +"M42n.8n", +"M42n.9n", +"M42n.10n", +"M42n", +"M43n.1n", +"M43n.2n", +"M43n.3n", +"M43n.4n", +"M43n", +"M44n.1n", +"M44n.2n", +"M44n.3n", +"M44n.4n", +"M44n.5n", +"M44n.6n", +"M44n.7n", +"M44n.8r", +"M44n", +"M45n", +NULL diff --git a/src/gsfml/Chron_Normal2.h b/src/gsfml/Chron_Normal2.h new file mode 100644 index 00000000000..ed0a43bce6f --- /dev/null +++ b/src/gsfml/Chron_Normal2.h @@ -0,0 +1,231 @@ +"C1N", +"C1R1N", +"C1R2R-1N", +"C2N", +"C2R1N", +"C2AN1N", +"C2AN2N", +"C2AN3N", +"C3N1N", +"C3N2N", +"C3N3N", +"C3N4N", +"C3AN1N", +"C3AN2N", +"C3BN", +"C3BR1N", +"C3BR2N", +"C4N1N", +"C4N2N", +"C4R1N", +"C4R2R-1N", +"C4AN", +"C4AR1R-1N", +"C4AR1N", +"C4AR2N", +"C5N1N", +"C5N2N", +"C5R1N", +"C5R2R-1N", +"C5R2R-2N", +"C5R2N", +"C5R3R-1N", +"C5AN1N", +"C5AN2N", +"C5AR1N", +"C5AR2N", +"C5AAN", +"C5ABN", +"C5ACN", +"C5ADN", +"C5BN1N", +"C5BN2N", +"C5CN1N", +"C5CN2N", +"C5CN3N", +"C5DN", +"C5DR-1N", +"C5EN", +"C6N", +"C6AN1N", +"C6AN2N", +"C6AAN", +"C6AAR1N", +"C6AAR2N", +"C6BN1N", +"C6BN2N", +"C6CN1N", +"C6CN2N", +"C6CN3N", +"C7N1N", +"C7N2N", +"C7AN", +"C7AR-1N", +"C8N1N", +"C8N2N", +"C9N", +"C10N1N", +"C10N2N", +"C11N1N", +"C11N2N", +"C12N", +"C13N", +"C15N", +"C16N1N", +"C16N2N", +"C17N1N", +"C17N2N", +"C17N3N", +"C18N1N", +"C18N2N", +"C19N", +"C20N", +"C21N", +"C22N", +"C23N1N", +"C23N2N", +"C24N1N", +"C24N2N", +"C24N3N", +"C25N", +"C26N", +"C27N", +"C28N", +"C29N", +"C30N", +"C31N", +"C32N1N", +"C32N2N", +"C32R1N", +"C33N", +"C34N", +"M1N", +"M2N", +"M4N", +"M6N", +"M7N", +"M8N", +"M9N", +"M10N", +"M10NN1N", +"M10NN2N", +"M10NN3N", +"M11N", +"M11R1N", +"M11AN1N", +"M11AN2N", +"M12N", +"M12R1N", +"M12AN", +"M13N", +"M14N", +"M15N", +"M16N", +"M17N", +"M18N", +"M19N1N", +"M19N", +"M20N1N", +"M20N2N", +"M21N", +"M22N1N", +"M22N2N", +"M22N3N", +"M22AN", +"M23N1N", +"M23N2N", +"M24N1N", +"M24N2N", +"M24AN", +"M24BN", +"M25N", +"M25AN1N", +"M25AN2N", +"M25AN3N", +"M26N1N", +"M26N2N", +"M26N3N", +"M26N4N", +"M27N", +"M28N", +"M28AN", +"M28BN", +"M28CN", +"M28DN", +"M29N1N", +"M29N2N", +"M29AN", +"M30N", +"M30AN", +"M31N1N", +"M31N2N", +"M31N", +"M32N1N", +"M32N2N", +"M32N", +"M33N", +"M33AN", +"M33BN", +"M33CN1N", +"M33CN", +"M34N1N", +"M34N2N", +"M34N3N", +"M34AN", +"M34BN1N", +"M34BN", +"M35N", +"M36N1N", +"M36AN", +"M36BN", +"M36CN", +"M37N1N", +"M37N", +"M38N1N", +"M38N2N", +"M38N3N", +"M38N4N", +"M38N", +"M39N1N", +"M39N2N", +"M39N3N", +"M39N4N", +"M39N5N", +"M39N6N", +"M39N7N", +"M39N", +"M40N1N", +"M40N2N", +"M40N3N", +"M40N", +"M41N1N", +"M41N2N", +"M41N3N", +"M41N", +"M42N1N", +"M42N2N", +"M42N3N", +"M42N4N", +"M42N5N", +"M42N6N", +"M42N7N", +"M42N8N", +"M42N9N", +"M42N10N", +"M42N", +"M43N1N", +"M43N2N", +"M43N3N", +"M43N4N", +"M43N", +"M44N1N", +"M44N2N", +"M44N3N", +"M44N4N", +"M44N5N", +"M44N6N", +"M44N7N", +"M44N8R", +"M44N", +"M45N", +NULL diff --git a/src/gsfml/Chron_Reverse.h b/src/gsfml/Chron_Reverse.h new file mode 100644 index 00000000000..98046ec1e7e --- /dev/null +++ b/src/gsfml/Chron_Reverse.h @@ -0,0 +1,231 @@ +"C1r.1r", +"C1r.2r", +"C1r.2r", +"C2r.1r", +"C2r.2r", +"C2An.1r", +"C2An.2r", +"C2Ar", +"C3n.1r", +"C3n.2r", +"C3n.3r", +"C3r", +"C3An.1r", +"C3Ar", +"C3Br.1r", +"C3Br.2r", +"C3Br.3r", +"C4n.1r", +"C4r.1r", +"C4r.2r", +"C4r.2r", +"C4Ar.1r", +"C4Ar.1r", +"C4Ar.2r", +"C4Ar.3r", +"C5n.1r", +"C5r.1r", +"C5r.2r", +"C5r.2r", +"C5r.2r", +"C5r.3r", +"C5r.3r", +"C5An.1r", +"C5Ar.1r", +"C5Ar.2r", +"C5Ar.3r", +"C5AAr", +"C5ABr", +"C5ACr", +"C5ADr", +"C5Bn.1r", +"C5Br", +"C5Cn.1r", +"C5Cn.2r", +"C5Cr", +"C5Dr", +"C5Dr", +"C5Er", +"C6r", +"C6An.1r", +"C6Ar", +"C6AAr.1r", +"C6AAr.2r", +"C6AAr.3r", +"C6Bn.1r", +"C6Br", +"C6Cn.1r", +"C6Cn.2r", +"C6Cr", +"C7n.1r", +"C7r", +"C7Ar*", +"C7Ar*", +"C8n.1r", +"C8r", +"C9r", +"C10n.1r", +"C10r", +"C11n.1r", +"C11r", +"C12r", +"C13r", +"C15r", +"C16n.1r", +"C16r", +"C17n.1r", +"C17n.2r", +"C17r", +"C18n.1r", +"C18r", +"C19r", +"C20r", +"C21r", +"C22r", +"C23n.1r", +"C23r", +"C24n.1r", +"C24n.2r", +"C24r", +"C25r", +"C26r", +"C27r", +"C28r", +"C29r", +"C30r", +"C31r", +"C32n.1r", +"C32r.1r", +"C32r.2r", +"C33r", +"M0r", +"M1r", +"M3r", +"M5r", +"M6r", +"M7r", +"M8r", +"M9r", +"M10r", +"M10Nn.1r", +"M10Nn.2r", +"M10Nr", +"M11r.1r", +"M11r.2r", +"M11An.1r", +"M11Ar", +"M12r.1r", +"M12r.2r", +"M12Ar", +"M13r", +"M14r", +"M15r", +"M16r", +"M17r", +"M18r", +"M19n.1r", +"M19r", +"M20n.1r", +"M20r", +"M21r", +"M22n.1r", +"M22n.2r", +"M22r", +"M22Ar", +"M23n.1r", +"M23r", +"M24n.1r", +"M24r", +"M24Ar", +"M24Br", +"M25r", +"M25An.1r", +"M25An.2r", +"M25Ar", +"M26n.1r", +"M26n.2r", +"M26n.3r", +"M26r", +"M27r", +"M28r", +"M28Ar", +"M28Br", +"M28Cr", +"M28Dr", +"M29n.1r", +"M29r", +"M29Ar", +"M30r", +"M30Ar", +"M31n.1r", +"M31n.2r", +"M31r", +"M32n.1r", +"M32n.2r", +"M32r", +"M33r", +"M33Ar", +"M33Br", +"M33Cn.1r", +"M33Cr", +"M34n.1r", +"M34n.2r", +"M34n.3r", +"M34Ar", +"M34Bn.1r", +"M34Br", +"M35r", +"M36n.1r", +"M36Ar", +"M36Br", +"M36Cr", +"M37n.1r", +"M37r", +"M38n.1r", +"M38n.2r", +"M38n.3r", +"M38n.4r", +"M38r", +"M39n.1r", +"M39n.2r", +"M39n.3r", +"M39n.4r", +"M39n.5r", +"M39n.6r", +"M39n.7r", +"M39r", +"M40n.1r", +"M40n.2r", +"M40n.3r", +"M40r", +"M41n.1r", +"M41n.2r", +"M41n.3r", +"M41r", +"M42n.1r", +"M42n.2r", +"M42n.3r", +"M42n.4r", +"M42n.5r", +"M42n.6r", +"M42n.7r", +"M42n.8r", +"M42n.9r", +"M42n.10r", +"M42r", +"M43n.1r", +"M43n.2r", +"M43n.3r", +"M43n.4r", +"M43r", +"M44n.1r", +"M44n.2r", +"M44n.3r", +"M44n.4r", +"M44n.5r", +"M44n.6r", +"M44n.7r", +"M44n.8r", +"M44r", +"M45r", +NULL diff --git a/src/gsfml/Chron_Reverse2.h b/src/gsfml/Chron_Reverse2.h new file mode 100644 index 00000000000..fc936dea9cd --- /dev/null +++ b/src/gsfml/Chron_Reverse2.h @@ -0,0 +1,231 @@ +"C1R1R", +"C1R2R", +"C1R2R", +"C2R1R", +"C2R2R", +"C2AN1R", +"C2AN2R", +"C2AR", +"C3N1R", +"C3N2R", +"C3N3R", +"C3R", +"C3AN1R", +"C3AR", +"C3BR1R", +"C3BR2R", +"C3BR3R", +"C4N1R", +"C4R1R", +"C4R2R", +"C4R2R", +"C4AR1R", +"C4AR1R", +"C4AR2R", +"C4AR3R", +"C5N1R", +"C5R1R", +"C5R2R", +"C5R2R", +"C5R2R", +"C5R3R", +"C5R3R", +"C5AN1R", +"C5AR1R", +"C5AR2R", +"C5AR3R", +"C5AAR", +"C5ABR", +"C5ACR", +"C5ADR", +"C5BN1R", +"C5BR", +"C5CN1R", +"C5CN2R", +"C5CR", +"C5DR", +"C5DR", +"C5ER", +"C6R", +"C6AN1R", +"C6AR", +"C6AAR1R", +"C6AAR2R", +"C6AAR3R", +"C6BN1R", +"C6BR", +"C6CN1R", +"C6CN2R", +"C6CR", +"C7N1R", +"C7R", +"C7AR*", +"C7AR*", +"C8N1R", +"C8R", +"C9R", +"C10N1R", +"C10R", +"C11N1R", +"C11R", +"C12R", +"C13R", +"C15R", +"C16N1R", +"C16R", +"C17N1R", +"C17N2R", +"C17R", +"C18N1R", +"C18R", +"C19R", +"C20R", +"C21R", +"C22R", +"C23N1R", +"C23R", +"C24N1R", +"C24N2R", +"C24R", +"C25R", +"C26R", +"C27R", +"C28R", +"C29R", +"C30R", +"C31R", +"C32N1R", +"C32R1R", +"C32R2R", +"C33R", +"M0R", +"M1R", +"M3R", +"M5R", +"M6R", +"M7R", +"M8R", +"M9R", +"M10R", +"M10NN1R", +"M10NN2R", +"M10NR", +"M11R1R", +"M11R2R", +"M11AN1R", +"M11AR", +"M12R1R", +"M12R2R", +"M12AR", +"M13R", +"M14R", +"M15R", +"M16R", +"M17R", +"M18R", +"M19N1R", +"M19R", +"M20N1R", +"M20R", +"M21R", +"M22N1R", +"M22N2R", +"M22R", +"M22AR", +"M23N1R", +"M23R", +"M24N1R", +"M24R", +"M24AR", +"M24BR", +"M25R", +"M25AN1R", +"M25AN2R", +"M25AR", +"M26N1R", +"M26N2R", +"M26N3R", +"M26R", +"M27R", +"M28R", +"M28AR", +"M28BR", +"M28CR", +"M28DR", +"M29N1R", +"M29R", +"M29AR", +"M30R", +"M30AR", +"M31N1R", +"M31N2R", +"M31R", +"M32N1R", +"M32N2R", +"M32R", +"M33R", +"M33AR", +"M33BR", +"M33CN1R", +"M33CR", +"M34N1R", +"M34N2R", +"M34N3R", +"M34AR", +"M34BN1R", +"M34BR", +"M35R", +"M36N1R", +"M36AR", +"M36BR", +"M36CR", +"M37N1R", +"M37R", +"M38N1R", +"M38N2R", +"M38N3R", +"M38N4R", +"M38R", +"M39N1R", +"M39N2R", +"M39N3R", +"M39N4R", +"M39N5R", +"M39N6R", +"M39N7R", +"M39R", +"M40N1R", +"M40N2R", +"M40N3R", +"M40R", +"M41N1R", +"M41N2R", +"M41N3R", +"M41R", +"M42N1R", +"M42N2R", +"M42N3R", +"M42N4R", +"M42N5R", +"M42N6R", +"M42N7R", +"M42N8R", +"M42N9R", +"M42N10R", +"M42R", +"M43N1R", +"M43N2R", +"M43N3R", +"M43N4R", +"M43R", +"M44N1R", +"M44N2R", +"M44N3R", +"M44N4R", +"M44N5R", +"M44N6R", +"M44N7R", +"M44N8R", +"M44R", +"M45R", +NULL diff --git a/src/gsfml/GST2004n.h b/src/gsfml/GST2004n.h new file mode 100644 index 00000000000..ce9a3f986bf --- /dev/null +++ b/src/gsfml/GST2004n.h @@ -0,0 +1,231 @@ +{ 0, 0.781 }, +{ 0.988, 1.072 }, +{ 1.072, 1.173 }, +{ 1.778, 1.945 }, +{ 2.128, 2.148 }, +{ 2.518, 3.032 }, +{ 3.116, 3.207 }, +{ 3.33, 3.596 }, +{ 4.187, 4.3 }, +{ 4.493, 4.631 }, +{ 4.799, 4.896 }, +{ 4.997, 5.235 }, +{ 6.033, 6.252 }, +{ 6.436, 6.733 }, +{ 7.14, 7.212 }, +{ 7.212, 7.251 }, +{ 7.454, 7.489 }, +{ 7.528, 7.642 }, +{ 7.695, 8.108 }, +{ 8.254, 8.3 }, +{ 8.661, 8.699 }, +{ 8.769, 9.098 }, +{ -1.0, -1.0 }, +{ 9.312, 9.409 }, +{ 9.656, 9.717 }, +{ 9.779, 9.934 }, +{ 9.987, 11.04 }, +{ 11.118, 11.154 }, +{ 11.267, 11.298 }, +{ -1.0, 11.504 }, +{ 11.554, 11.614 }, +{ -1.0, -1.0 }, +{ 12.014, 12.116 }, +{ 12.207, 12.415 }, +{ 12.73, 12.765 }, +{ 12.82, 12.878 }, +{ 13.015, 13.183 }, +{ 13.369, 13.605 }, +{ 13.734, 14.095 }, +{ 14.194, 14.581 }, +{ 14.784, 14.877 }, +{ 15.032, 15.16 }, +{ 15.974, 16.268 }, +{ 16.303, 16.472 }, +{ 16.543, 16.721 }, +{ 17.235, 17.533 }, +{ -1.0, -1.0 }, +{ 18.056, 18.524 }, +{ 18.748, 19.722 }, +{ 20.04, 20.213 }, +{ 20.439, 20.709 }, +{ 21.083, 21.159 }, +{ 21.403, 21.483 }, +{ 21.659, 21.688 }, +{ 21.767, 21.936 }, +{ 21.992, 22.268 }, +{ 22.564, 22.754 }, +{ 22.902, 23.03 }, +{ 23.249, 23.375 }, +{ 24.044, 24.102 }, +{ 24.163, 24.556 }, +{ 24.915, 25.091 }, +{ -1.0, -1.0 }, +{ 25.295, 25.444 }, +{ 25.492, 26.154 }, +{ 26.714, 27.826 }, +{ 28.186, 28.45 }, +{ 28.525, 28.715 }, +{ 29.451, 29.74 }, +{ 29.853, 30.217 }, +{ 30.627, 31.116 }, +{ 33.266, 33.738 }, +{ 34.782, 35.043 }, +{ 35.404, 35.567 }, +{ 35.707, 36.276 }, +{ 36.512, 37.235 }, +{ 37.345, 37.549 }, +{ 37.61, 37.771 }, +{ 38.032, 38.975 }, +{ 39.041, 39.464 }, +{ 40.439, 40.671 }, +{ 41.59, 42.774 }, +{ 45.346, 47.235 }, +{ 48.599, 49.427 }, +{ 50.73, 50.932 }, +{ 51.057, 51.901 }, +{ 52.648, 53.004 }, +{ 53.116, 53.167 }, +{ 53.286, 53.808 }, +{ 56.665, 57.18 }, +{ 58.379, 58.737 }, +{ 61.65, 61.983 }, +{ 63.104, 64.128 }, +{ 64.432, 65.118 }, +{ 65.861, 67.696 }, +{ 67.809, 68.732 }, +{ 70.961, 71.225 }, +{ 71.474, 72.929 }, +{ 73.231, 73.318 }, +{ 73.557, 79.543 }, +{ 84, 125 }, +{ 125, 127.61 }, +{ 127.61, 128.11 }, +{ 129.76, 130.8 }, +{ 131.19, 131.41 }, +{ 131.56, 131.85 }, +{ 132.2, 132.52 }, +{ 132.83, 133.14 }, +{ 133.5, 133.87 }, +{ 134.3, 134.62 }, +{ 134.67, 134.98 }, +{ 135, 135.28 }, +{ 135.69, 136.44 }, +{ 136.68, 136.71 }, +{ 136.9, 137.39 }, +{ 137.44, 137.51 }, +{ 137.6, 137.82 }, +{ 138.56, 138.63 }, +{ 138.78, 139.03 }, +{ 139.12, 139.29 }, +{ 139.53, 139.77 }, +{ 140.36, 140.66 }, +{ 141.05, 142.06 }, +{ 142.55, 142.84 }, +{ 144.04, 144.57 }, +{ 144.88, 144.99 }, +{ 145.06, 145.95 }, +{ 146.16, 146.47 }, +{ 146.52, 147.16 }, +{ 147.77, 148.54 }, +{ 148.92, 150.05 }, +{ 150.08, 150.12 }, +{ 150.16, 150.21 }, +{ 150.73, 150.84 }, +{ 151.01, 151.34 }, +{ 151.62, 151.64 }, +{ 152.26, 152.5 }, +{ 152.96, 152.98 }, +{ 153.18, 153.31 }, +{ 153.58, 153.93 }, +{ 154.08, 154.37 }, +{ 154.55, 154.67 }, +{ 154.73, 154.81 }, +{ 154.86, 154.97 }, +{ 155.05, 155.13 }, +{ 155.18, 155.24 }, +{ 155.3, 155.35 }, +{ 155.39, 155.54 }, +{ 155.71, 155.85 }, +{ 156.01, 156.29 }, +{ 156.44, 156.53 }, +{ 156.76, 156.81 }, +{ 156.89, 156.99 }, +{ 157.08, 157.16 }, +{ 157.26, 157.41 }, +{ 157.44, 157.51 }, +{ 157.73, 157.78 }, +{ 157.84, 157.96 }, +{ 158.12, 158.21 }, +{ 158.24, 158.39 }, +{ 158.47, 158.5 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -999.0, -999.0} diff --git a/src/gsfml/GST2004r.h b/src/gsfml/GST2004r.h new file mode 100644 index 00000000000..dcbee2c7efc --- /dev/null +++ b/src/gsfml/GST2004r.h @@ -0,0 +1,231 @@ +{ 0.781, 0.988 }, +{ 1.072, 1.072 }, +{ 1.173, 1.778 }, +{ 1.945, 2.128 }, +{ 2.148, 2.518 }, +{ 3.032, 3.116 }, +{ 3.207, 3.33 }, +{ 3.596, 4.187 }, +{ 4.3, 4.493 }, +{ 4.631, 4.799 }, +{ 4.896, 4.997 }, +{ 5.235, 6.033 }, +{ 6.252, 6.436 }, +{ 6.733, 7.14 }, +{ 7.212, 7.212 }, +{ 7.251, 7.454 }, +{ 7.489, 7.528 }, +{ 7.642, 7.695 }, +{ 8.108, 8.254 }, +{ 8.3, 8.661 }, +{ 8.699, 8.769 }, +{ 9.098, -1.0 }, +{ -1.0, 9.312 }, +{ 9.409, 9.656 }, +{ 9.717, 9.779 }, +{ 9.934, 9.987 }, +{ 11.04, 11.118 }, +{ 11.154, 11.267 }, +{ 11.298, -1.0 }, +{ 11.504, 11.554 }, +{ 11.614, -1.0 }, +{ -1.0, 12.014 }, +{ 12.116, 12.207 }, +{ 12.415, 12.73 }, +{ 12.765, 12.82 }, +{ 12.878, 13.015 }, +{ 13.183, 13.369 }, +{ 13.605, 13.734 }, +{ 14.095, 14.194 }, +{ 14.581, 14.784 }, +{ 14.877, 15.032 }, +{ 15.16, 15.974 }, +{ 16.268, 16.303 }, +{ 16.472, 16.543 }, +{ 16.721, 17.235 }, +{ 17.533, -1.0 }, +{ -1.0, 18.056 }, +{ 18.524, 18.748 }, +{ 19.722, 20.04 }, +{ 20.213, 20.439 }, +{ 20.709, 21.083 }, +{ 21.159, 21.403 }, +{ 21.483, 21.659 }, +{ 21.688, 21.767 }, +{ 21.936, 21.992 }, +{ 22.268, 22.564 }, +{ 22.754, 22.902 }, +{ 23.03, 23.249 }, +{ 23.375, 24.044 }, +{ 24.102, 24.163 }, +{ 24.556, 24.915 }, +{ 25.091, -1.0 }, +{ -1.0, 25.295 }, +{ 25.444, 25.492 }, +{ 26.154, 26.714 }, +{ 27.826, 28.186 }, +{ 28.45, 28.525 }, +{ 28.715, 29.451 }, +{ 29.74, 29.853 }, +{ 30.217, 30.627 }, +{ 31.116, 33.266 }, +{ 33.738, 34.782 }, +{ 35.043, 35.404 }, +{ 35.567, 35.707 }, +{ 36.276, 36.512 }, +{ 37.235, 37.345 }, +{ 37.549, 37.61 }, +{ 37.771, 38.032 }, +{ 38.975, 39.041 }, +{ 39.464, 40.439 }, +{ 40.671, 41.59 }, +{ 42.774, 45.346 }, +{ 47.235, 48.599 }, +{ 49.427, 50.73 }, +{ 50.932, 51.057 }, +{ 51.901, 52.648 }, +{ 53.004, 53.116 }, +{ 53.167, 53.286 }, +{ 53.808, 56.665 }, +{ 57.18, 58.379 }, +{ 58.737, 61.65 }, +{ 61.983, 63.104 }, +{ 64.128, 64.432 }, +{ 65.118, 65.861 }, +{ 67.696, 67.809 }, +{ 68.732, 70.961 }, +{ 71.225, 71.474 }, +{ 72.929, 73.231 }, +{ 73.318, 73.557 }, +{ 79.543, 84 }, +{ 124.61, 125 }, +{ 127.61, 127.61 }, +{ 128.11, 129.76 }, +{ 130.8, 131.19 }, +{ 131.41, 131.56 }, +{ 131.85, 132.2 }, +{ 132.52, 132.83 }, +{ 133.14, 133.5 }, +{ 133.87, 134.3 }, +{ 134.62, 134.67 }, +{ 134.98, 135 }, +{ 135.28, 135.69 }, +{ 136.44, 136.68 }, +{ 136.71, 136.9 }, +{ 137.39, 137.44 }, +{ 137.51, 137.6 }, +{ 137.82, 138.56 }, +{ 138.63, 138.78 }, +{ 139.03, 139.12 }, +{ 139.29, 139.53 }, +{ 139.77, 140.36 }, +{ 140.66, 141.05 }, +{ 142.06, 142.55 }, +{ 142.84, 144.04 }, +{ 144.57, 144.88 }, +{ 144.99, 145.06 }, +{ 145.95, 146.16 }, +{ 146.47, 146.52 }, +{ 147.16, 147.77 }, +{ 148.54, 148.92 }, +{ 150.05, 150.08 }, +{ 150.12, 150.16 }, +{ 150.21, 150.73 }, +{ 150.84, 151.01 }, +{ 151.34, 151.62 }, +{ 151.64, 152.26 }, +{ 152.5, 152.96 }, +{ 152.98, 153.18 }, +{ 153.31, 153.58 }, +{ 153.93, 154.08 }, +{ 154.37, 154.55 }, +{ 154.67, 154.73 }, +{ 154.81, 154.86 }, +{ 154.97, 155.05 }, +{ 155.13, 155.18 }, +{ 155.24, 155.3 }, +{ 155.35, 155.39 }, +{ 155.54, 155.71 }, +{ 155.85, 156.01 }, +{ 156.29, 156.44 }, +{ 156.53, 156.76 }, +{ 156.81, 156.89 }, +{ 156.99, 157.08 }, +{ 157.16, 157.26 }, +{ 157.41, 157.44 }, +{ 157.51, 157.73 }, +{ 157.78, 157.84 }, +{ 157.96, 158.12 }, +{ 158.21, 158.24 }, +{ 158.39, 158.47 }, +{ 158.5, 158.54 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -999.0, -999.0} diff --git a/src/gsfml/GST2012n.h b/src/gsfml/GST2012n.h new file mode 100644 index 00000000000..5caa52dfdd4 --- /dev/null +++ b/src/gsfml/GST2012n.h @@ -0,0 +1,231 @@ +{ 0, 0.781 }, +{ 0.988, 1.072 }, +{ 1.173, 1.185 }, +{ 1.778, 1.945 }, +{ 2.128, 2.148 }, +{ 2.581, 3.032 }, +{ 3.116, 3.207 }, +{ 3.33, 3.596 }, +{ 4.187, 4.3 }, +{ 4.493, 4.631 }, +{ 4.799, 4.896 }, +{ 4.997, 5.235 }, +{ 6.033, 6.252 }, +{ 6.436, 6.733 }, +{ 7.14, 7.212 }, +{ 7.251, 7.285 }, +{ 7.454, 7.489 }, +{ 7.528, 7.642 }, +{ 7.695, 8.108 }, +{ 8.254, 8.3 }, +{ -1.0, -1.0 }, +{ 8.771, 9.105 }, +{ -1.0, -1.0 }, +{ 9.311, 9.426 }, +{ 9.647, 9.721 }, +{ 9.786, 9.937 }, +{ 9.984, 11.056 }, +{ 11.146, 11.188 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ 11.592, 11.657 }, +{ -1.0, -1.0 }, +{ 12.049, 12.174 }, +{ 12.272, 12.474 }, +{ 12.735, 12.77 }, +{ 12.829, 12.887 }, +{ 13.032, 13.183 }, +{ 13.363, 13.608 }, +{ 13.739, 14.07 }, +{ 14.163, 14.609 }, +{ 14.775, 14.87 }, +{ 15.032, 15.16 }, +{ 15.974, 16.268 }, +{ 16.303, 16.472 }, +{ 16.543, 16.721 }, +{ 17.235, 17.533 }, +{ 17.717, 17.74 }, +{ 18.056, 18.524 }, +{ 18.748, 19.722 }, +{ 20.04, 20.213 }, +{ 20.439, 20.709 }, +{ 21.083, 21.159 }, +{ 21.403, 21.483 }, +{ 21.659, 21.688 }, +{ 21.767, 21.936 }, +{ 21.992, 22.268 }, +{ 22.564, 22.754 }, +{ 22.902, 23.03 }, +{ 23.233, 23.295 }, +{ 23.962, 24 }, +{ 24.109, 24.474 }, +{ 24.761, 24.984 }, +{ -1.0, -1.0 }, +{ 25.099, 25.264 }, +{ 25.304, 25.987 }, +{ 26.42, 27.439 }, +{ 27.859, 28.087 }, +{ 28.141, 28.278 }, +{ 29.183, 29.477 }, +{ 29.527, 29.97 }, +{ 30.591, 31.034 }, +{ 33.157, 33.705 }, +{ 34.999, 35.294 }, +{ 35.706, 35.892 }, +{ 36.051, 36.7 }, +{ 36.969, 37.753 }, +{ 37.872, 38.093 }, +{ 38.159, 38.333 }, +{ 38.615, 39.627 }, +{ 39.698, 40.145 }, +{ 41.154, 41.39 }, +{ 42.301, 43.432 }, +{ 45.724, 47.349 }, +{ 48.566, 49.344 }, +{ 50.628, 50.835 }, +{ 50.961, 51.833 }, +{ 52.62, 53.074 }, +{ 53.199, 53.274 }, +{ 53.416, 53.983 }, +{ 57.101, 57.656 }, +{ 58.959, 59.237 }, +{ 62.221, 62.517 }, +{ 63.494, 64.667 }, +{ 64.958, 65.688 }, +{ 66.398, 68.196 }, +{ 68.369, 69.269 }, +{ 71.449, 71.689 }, +{ 71.939, 73.649 }, +{ 73.949, 74.049 }, +{ 74.309, 79.9 }, +{ 83.64, 125.93 }, +{ 126.3, 128.32 }, +{ 128.66, 129.11 }, +{ 130.6, 131.43 }, +{ 131.74, 131.92 }, +{ 132.04, 132.27 }, +{ 132.55, 132.8 }, +{ 133.05, 133.3 }, +{ 133.58, 133.88 }, +{ 134.22, 134.48 }, +{ 134.51, 134.76 }, +{ 134.78, 135 }, +{ 135.32, 135.92 }, +{ 136.11, 136.13 }, +{ 136.29, 136.69 }, +{ 136.74, 136.8 }, +{ 136.87, 137.06 }, +{ 137.73, 137.8 }, +{ 137.94, 138.17 }, +{ 138.25, 138.42 }, +{ 138.66, 138.91 }, +{ 139.59, 139.94 }, +{ 140.42, 141.64 }, +{ 142.22, 142.57 }, +{ 144, 144.64 }, +{ 145.01, 145.14 }, +{ 145.19, 146.28 }, +{ 146.54, 146.9 }, +{ 146.96, 147.72 }, +{ 148.44, 149.35 }, +{ 149.8, 151.12 }, +{ 151.17, 151.21 }, +{ 151.25, 151.32 }, +{ 151.92, 152.06 }, +{ 152.25, 152.64 }, +{ 152.93, 152.96 }, +{ 153.62, 153.87 }, +{ 154.35, 154.38 }, +{ 154.59, 154.73 }, +{ 155.01, 155.38 }, +{ 155.54, 155.85 }, +{ 156.04, 156.16 }, +{ 156.22, 156.29 }, +{ 156.39, 156.42 }, +{ 156.56, 156.69 }, +{ 156.75, 156.78 }, +{ 156.84, 156.94 }, +{ 157.04, 157.06 }, +{ 157.25, 157.4 }, +{ 157.57, 157.87 }, +{ 158.02, 158.12 }, +{ 158.36, 158.41 }, +{ 158.5, 158.6 }, +{ 158.69, 158.78 }, +{ 158.89, 159.04 }, +{ 159.07, 159.14 }, +{ 159.38, 159.43 }, +{ 159.49, 159.62 }, +{ 159.78, 159.88 }, +{ 159.91, 160.07 }, +{ 160.15, 160.18 }, +{ 160.22, 160.26 }, +{ 160.32, 160.34 }, +{ 160.37, 160.47 }, +{ 160.52, 160.55 }, +{ 160.63, 160.93 }, +{ 161.06, 161.14 }, +{ 161.21, 161.28 }, +{ 161.39, 161.43 }, +{ 161.49, 161.61 }, +{ 161.81, 161.89 }, +{ 161.96, 162.01 }, +{ 162.04, 162.06 }, +{ 162.12, 162.15 }, +{ 162.28, 162.37 }, +{ 162.43, 162.46 }, +{ 162.49, 162.55 }, +{ 162.7, 162.8 }, +{ 162.86, 162.9 }, +{ 162.92, 162.95 }, +{ 163.1, 163.16 }, +{ 163.29, 163.53 }, +{ 163.65, 163.76 }, +{ 163.85, 163.98 }, +{ 164.03, 164.18 }, +{ 164.22, 164.3 }, +{ 164.41, 164.63 }, +{ 164.69, 164.85 }, +{ 164.91, 165.08 }, +{ 165.2, 165.34 }, +{ 165.4, 165.53 }, +{ 165.65, 165.8 }, +{ 165.96, 166.08 }, +{ 166.21, 166.3 }, +{ 166.4, 166.47 }, +{ 166.51, 166.61 }, +{ 166.68, 166.72 }, +{ 166.89, 166.96 }, +{ 167.05, 167.11 }, +{ 167.33, 167.36 }, +{ 167.43, 167.51 }, +{ 167.69, 167.75 }, +{ 167.85, 167.91 }, +{ 168.01, 168.03 }, +{ 168.14, 168.24 }, +{ 168.34, 168.36 }, +{ 168.4, 168.45 }, +{ 168.49, 168.51 }, +{ 168.53, 168.57 }, +{ 168.59, 168.61 }, +{ 168.63, 168.65 }, +{ 168.68, 168.7 }, +{ 168.74, 168.8 }, +{ 168.92, 168.95 }, +{ 169.12, 169.14 }, +{ 169.23, 169.25 }, +{ 169.38, 169.47 }, +{ 169.55, 169.6 }, +{ 169.64, 169.68 }, +{ 169.74, 169.81 }, +{ 169.89, 169.93 }, +{ 169.97, 170 }, +{ 170.05, 170.08 }, +{ 170.21, 170.23 }, +{ 170.28, 170.3 }, +{ 170.37, 170.38 }, +{ 170.45, 170.45 }, +{ 170.49, 170.55 }, +{ 170.57, 170.61 }, +{ 170.64, 170.67 }, +{ -999.0, -999.0} diff --git a/src/gsfml/GST2012r.h b/src/gsfml/GST2012r.h new file mode 100644 index 00000000000..f4ea953fd07 --- /dev/null +++ b/src/gsfml/GST2012r.h @@ -0,0 +1,231 @@ +{ 0.781, 0.988 }, +{ 1.072, 1.173 }, +{ 1.185, 1.778 }, +{ 1.945, 2.128 }, +{ 2.148, 2.581 }, +{ 3.032, 3.116 }, +{ 3.207, 3.33 }, +{ 3.596, 4.187 }, +{ 4.3, 4.493 }, +{ 4.631, 4.799 }, +{ 4.896, 4.997 }, +{ 5.235, 6.033 }, +{ 6.252, 6.436 }, +{ 6.733, 7.14 }, +{ 7.212, 7.251 }, +{ 7.285, 7.454 }, +{ 7.489, 7.528 }, +{ 7.642, 7.695 }, +{ 8.108, 8.254 }, +{ 8.3, 8.771 }, +{ -1.0, -1.0 }, +{ 9.105, 9.311 }, +{ -1.0, -1.0 }, +{ 9.426, 9.647 }, +{ 9.721, 9.786 }, +{ 9.937, 9.984 }, +{ 11.056, 11.146 }, +{ 11.188, 11.592 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ 11.657, -1.0 }, +{ -1.0, 12.049 }, +{ 12.174, 12.272 }, +{ 12.474, 12.735 }, +{ 12.77, 12.829 }, +{ 12.887, 13.032 }, +{ 13.183, 13.363 }, +{ 13.608, 13.739 }, +{ 14.07, 14.163 }, +{ 14.609, 14.775 }, +{ 14.87, 15.032 }, +{ 15.16, 15.974 }, +{ 16.268, 16.303 }, +{ 16.472, 16.543 }, +{ 16.721, 17.235 }, +{ 17.533, 17.717 }, +{ 17.74, 18.056 }, +{ 18.524, 18.748 }, +{ 19.722, 20.04 }, +{ 20.213, 20.439 }, +{ 20.709, 21.083 }, +{ 21.159, 21.403 }, +{ 21.483, 21.659 }, +{ 21.688, 21.767 }, +{ 21.936, 21.992 }, +{ 22.268, 22.564 }, +{ 22.754, 22.902 }, +{ 23.03, 23.233 }, +{ 23.295, 23.962 }, +{ 24, 24.109 }, +{ 24.474, 24.761 }, +{ 24.984, -1.0 }, +{ -1.0, 25.099 }, +{ 25.264, 25.304 }, +{ 25.987, 26.42 }, +{ 27.439, 27.859 }, +{ 28.087, 28.141 }, +{ 28.278, 29.183 }, +{ 29.477, 29.527 }, +{ 29.97, 30.591 }, +{ 31.034, 33.157 }, +{ 33.705, 34.999 }, +{ 35.294, 35.706 }, +{ 35.892, 36.051 }, +{ 36.7, 36.969 }, +{ 37.753, 37.872 }, +{ 38.093, 38.159 }, +{ 38.333, 38.615 }, +{ 39.627, 39.698 }, +{ 40.145, 41.154 }, +{ 41.39, 42.301 }, +{ 43.432, 45.724 }, +{ 47.349, 48.566 }, +{ 49.344, 50.628 }, +{ 50.835, 50.961 }, +{ 51.833, 52.62 }, +{ 53.074, 53.199 }, +{ 53.274, 53.416 }, +{ 53.983, 57.101 }, +{ 57.656, 58.959 }, +{ 59.237, 62.221 }, +{ 62.517, 63.494 }, +{ 64.667, 64.958 }, +{ 65.688, 66.398 }, +{ 68.196, 68.369 }, +{ 69.269, 71.449 }, +{ 71.689, 71.939 }, +{ 73.649, 73.949 }, +{ 74.049, 74.309 }, +{ 79.9, 83.64 }, +{ 125.93, 126.3 }, +{ 128.32, 128.66 }, +{ 129.11, 130.6 }, +{ 131.43, 131.74 }, +{ 131.92, 132.04 }, +{ 132.27, 132.55 }, +{ 132.8, 133.05 }, +{ 133.3, 133.58 }, +{ 133.88, 134.22 }, +{ 134.48, 134.51 }, +{ 134.76, 134.78 }, +{ 135, 135.32 }, +{ 135.92, 136.11 }, +{ 136.13, 136.29 }, +{ 136.69, 136.74 }, +{ 136.8, 136.87 }, +{ 137.06, 137.73 }, +{ 137.8, 137.94 }, +{ 138.17, 138.25 }, +{ 138.42, 138.66 }, +{ 138.91, 139.59 }, +{ 139.94, 140.42 }, +{ 141.64, 142.22 }, +{ 142.57, 144 }, +{ 144.64, 145.01 }, +{ 145.14, 145.19 }, +{ 146.28, 146.54 }, +{ 146.9, 146.96 }, +{ 147.72, 148.44 }, +{ 149.35, 149.8 }, +{ 151.12, 151.17 }, +{ 151.21, 151.25 }, +{ 151.32, 151.92 }, +{ 152.06, 152.25 }, +{ 152.64, 152.93 }, +{ 152.96, 153.62 }, +{ 153.87, 154.35 }, +{ 154.38, 154.59 }, +{ 154.73, 155.01 }, +{ 155.38, 155.54 }, +{ 155.85, 156.04 }, +{ 156.16, 156.22 }, +{ 156.29, 156.39 }, +{ 156.42, 156.56 }, +{ 156.69, 156.75 }, +{ 156.78, 156.84 }, +{ 156.94, 157.04 }, +{ 157.06, 157.25 }, +{ 157.4, 157.57 }, +{ 157.87, 158.02 }, +{ 158.12, 158.36 }, +{ 158.41, 158.5 }, +{ 158.6, 158.69 }, +{ 158.78, 158.89 }, +{ 159.04, 159.07 }, +{ 159.14, 159.38 }, +{ 159.43, 159.49 }, +{ 159.62, 159.78 }, +{ 159.88, 159.91 }, +{ 160.07, 160.15 }, +{ 160.18, 160.22 }, +{ 160.26, 160.32 }, +{ 160.34, 160.37 }, +{ 160.47, 160.52 }, +{ 160.55, 160.63 }, +{ 160.93, 161.06 }, +{ 161.14, 161.21 }, +{ 161.28, 161.39 }, +{ 161.43, 161.49 }, +{ 161.61, 161.81 }, +{ 161.89, 161.96 }, +{ 162.01, 162.04 }, +{ 162.06, 162.12 }, +{ 162.15, 162.28 }, +{ 162.37, 162.43 }, +{ 162.46, 162.49 }, +{ 162.55, 162.7 }, +{ 162.8, 162.86 }, +{ 162.9, 162.92 }, +{ 162.95, 163.1 }, +{ 163.16, 163.29 }, +{ 163.53, 163.65 }, +{ 163.76, 163.85 }, +{ 163.98, 164.03 }, +{ 164.18, 164.22 }, +{ 164.3, 164.41 }, +{ 164.63, 164.69 }, +{ 164.85, 164.91 }, +{ 165.08, 165.2 }, +{ 165.34, 165.4 }, +{ 165.53, 165.65 }, +{ 165.8, 165.96 }, +{ 166.08, 166.21 }, +{ 166.3, 166.4 }, +{ 166.47, 166.51 }, +{ 166.61, 166.68 }, +{ 166.72, 166.89 }, +{ 166.96, 167.05 }, +{ 167.11, 167.33 }, +{ 167.36, 167.43 }, +{ 167.51, 167.69 }, +{ 167.75, 167.85 }, +{ 167.91, 168.01 }, +{ 168.03, 168.14 }, +{ 168.24, 168.34 }, +{ 168.36, 168.4 }, +{ 168.45, 168.49 }, +{ 168.51, 168.53 }, +{ 168.57, 168.59 }, +{ 168.61, 168.63 }, +{ 168.65, 168.68 }, +{ 168.7, 168.74 }, +{ 168.8, 168.92 }, +{ 168.95, 169.12 }, +{ 169.14, 169.23 }, +{ 169.25, 169.38 }, +{ 169.47, 169.55 }, +{ 169.6, 169.64 }, +{ 169.68, 169.74 }, +{ 169.81, 169.89 }, +{ 169.93, 169.97 }, +{ 170, 170.05 }, +{ 170.08, 170.21 }, +{ 170.23, 170.28 }, +{ 170.3, 170.37 }, +{ 170.38, 170.45 }, +{ 170.45, 170.49 }, +{ 170.55, 170.57 }, +{ 170.61, 170.64 }, +{ 170.67, -1.0 }, +{ -999.0, -999.0} diff --git a/src/gsfml/Geek2007n.h b/src/gsfml/Geek2007n.h new file mode 100644 index 00000000000..ce8237d1d12 --- /dev/null +++ b/src/gsfml/Geek2007n.h @@ -0,0 +1,231 @@ +{ 0, 0.78 }, +{ 0.99, 1.07 }, +{ 1.201, 1.211 }, +{ 1.77, 1.95 }, +{ 2.14, 2.15 }, +{ 2.581, 3.04 }, +{ 3.11, 3.22 }, +{ 3.33, 3.58 }, +{ 4.18, 4.29 }, +{ 4.48, 4.62 }, +{ 4.8, 4.89 }, +{ 4.98, 5.23 }, +{ 5.894, 6.137 }, +{ 6.269, 6.567 }, +{ 6.935, 7.091 }, +{ 7.135, 7.17 }, +{ 7.341, 7.375 }, +{ 7.432, 7.562 }, +{ 7.65, 8.072 }, +{ 8.225, 8.257 }, +{ 8.606, 8.664 }, +{ 8.699, 9.025 }, +{ 9.097, 9.117 }, +{ 9.23, 9.308 }, +{ 9.58, 9.642 }, +{ 9.74, 9.88 }, +{ 9.92, 10.949 }, +{ 11.052, 11.099 }, +{ 11.167, 11.193 }, +{ 11.352, 11.363 }, +{ 11.476, 11.531 }, +{ 11.555, 11.584 }, +{ 11.935, 12.078 }, +{ 12.184, 12.401 }, +{ 12.678, 12.708 }, +{ 12.775, 12.819 }, +{ 12.991, 13.139 }, +{ 13.302, 13.51 }, +{ 13.703, 14.076 }, +{ 14.178, 14.612 }, +{ 14.8, 14.888 }, +{ 15.034, 15.155 }, +{ 16.014, 16.293 }, +{ 16.327, 16.488 }, +{ 16.556, 16.726 }, +{ 17.277, 17.615 }, +{ 17.793, 17.854 }, +{ 18.281, 18.781 }, +{ 19.048, 20.131 }, +{ 20.518, 20.725 }, +{ 20.996, 21.32 }, +{ 21.768, 21.859 }, +{ 22.151, 22.248 }, +{ 22.459, 22.493 }, +{ 22.588, 22.75 }, +{ 22.804, 23.069 }, +{ 23.353, 23.535 }, +{ 23.677, 23.8 }, +{ 23.999, 24.118 }, +{ 24.73, 24.781 }, +{ 24.835, 25.183 }, +{ 25.496, 25.648 }, +{ 25.678, 25.705 }, +{ 25.823, 25.951 }, +{ 25.992, 26.554 }, +{ 27.027, 27.972 }, +{ 28.283, 28.512 }, +{ 28.578, 28.745 }, +{ 29.401, 29.662 }, +{ 29.765, 30.098 }, +{ 30.479, 30.939 }, +{ 33.058, 33.545 }, +{ 34.655, 34.94 }, +{ 35.343, 35.526 }, +{ 35.685, 36.341 }, +{ 36.618, 37.473 }, +{ 37.604, 37.848 }, +{ 37.92, 38.113 }, +{ 38.426, 39.552 }, +{ 39.631, 40.13 }, +{ 41.257, 41.521 }, +{ 42.536, 43.789 }, +{ 46.264, 47.906 }, +{ 49.037, 49.714 }, +{ 50.778, 50.946 }, +{ 51.047, 51.743 }, +{ 52.364, 52.663 }, +{ 52.757, 52.801 }, +{ 52.903, 53.347 }, +{ 55.904, 56.391 }, +{ 57.554, 57.911 }, +{ 60.92, 61.276 }, +{ 62.499, 63.634 }, +{ 63.976, 64.745 }, +{ 65.578, 67.61 }, +{ 67.735, 68.737 }, +{ 71.071, 71.338 }, +{ 71.587, 73.004 }, +{ 73.291, 73.374 }, +{ 73.619, 79.075 }, +{ 83, 120.6 }, +{ 121, 123.19 }, +{ 123.55, 124.05 }, +{ 125.67, 126.57 }, +{ 126.91, 127.11 }, +{ 127.23, 127.49 }, +{ 127.79, 128.07 }, +{ 128.34, 128.62 }, +{ 128.93, 129.25 }, +{ 129.63, 129.91 }, +{ 129.95, 130.22 }, +{ 130.24, 130.49 }, +{ 130.84, 131.5 }, +{ 131.71, 131.73 }, +{ 131.91, 132.35 }, +{ 132.4, 132.47 }, +{ 132.55, 132.76 }, +{ 133.51, 133.58 }, +{ 133.73, 133.99 }, +{ 134.08, 134.27 }, +{ 134.53, 134.81 }, +{ 135.57, 135.96 }, +{ 136.49, 137.85 }, +{ 138.5, 138.89 }, +{ 140.51, 141.22 }, +{ 141.63, 141.78 }, +{ 141.88, 143.07 }, +{ 143.36, 143.77 }, +{ 143.84, 144.7 }, +{ 145.52, 146.56 }, +{ 147.06, 148.57 }, +{ 148.62, 148.67 }, +{ 148.72, 148.79 }, +{ 149.49, 149.72 }, +{ 150.04, 150.69 }, +{ 150.91, 150.93 }, +{ 151.4, 151.72 }, +{ 151.98, 152 }, +{ 152.15, 152.24 }, +{ 152.43, 153.13 }, +{ 153.43, 154 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ 154.31, 155.32 }, +{ 155.55, 155.8 }, +{ 156.05, 156.19 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ 156.51, 157.27 }, +{ 157.53, 157.582 }, +{ 157.653, 157.785 }, +{ 157.957, 158.063 }, +{ 158.096, 158.262 }, +{ 158.35, 158.379 }, +{ 158.424, 158.471 }, +{ 158.528, 158.553 }, +{ 158.584, 158.689 }, +{ 158.745, 158.776 }, +{ 158.866, 159.182 }, +{ 159.324, 159.408 }, +{ 159.482, 159.555 }, +{ 159.676, 159.717 }, +{ 159.773, 159.903 }, +{ 160.121, 160.206 }, +{ 160.282, 160.33 }, +{ 160.361, 160.385 }, +{ 160.444, 160.479 }, +{ 160.617, 160.714 }, +{ 160.78, 160.809 }, +{ 160.844, 160.914 }, +{ 161.069, 161.18 }, +{ 161.24, 161.286 }, +{ 161.309, 161.34 }, +{ 161.491, 161.566 }, +{ 161.698, 161.957 }, +{ 162.08, 162.199 }, +{ 162.302, 162.442 }, +{ 162.494, 162.65 }, +{ 162.693, 162.777 }, +{ 162.896, 163.131 }, +{ 163.204, 163.37 }, +{ 163.44, 163.625 }, +{ 163.745, 163.896 }, +{ 163.966, 164.1 }, +{ 164.236, 164.391 }, +{ 164.571, 164.7 }, +{ 164.833, 164.934 }, +{ 165.042, 165.113 }, +{ 165.161, 165.264 }, +{ 165.343, 165.384 }, +{ 165.572, 165.642 }, +{ 165.736, 165.805 }, +{ 166.043, 166.076 }, +{ 166.149, 166.234 }, +{ 166.429, 166.497 }, +{ 166.606, 166.669 }, +{ 166.776, 166.804 }, +{ 166.919, 167.028 }, +{ 167.138, 167.16 }, +{ 167.205, 167.257 }, +{ 167.298, 167.323 }, +{ 167.341, 167.382 }, +{ 167.406, 167.432 }, +{ 167.447, 167.476 }, +{ 167.502, 167.525 }, +{ 167.569, 167.639 }, +{ 167.768, 167.792 }, +{ 167.983, 168.008 }, +{ 168.105, 168.121 }, +{ 168.259, 168.363 }, +{ 168.448, 168.503 }, +{ 168.551, 168.585 }, +{ 168.656, 168.729 }, +{ 168.813, 168.864 }, +{ 168.908, 168.934 }, +{ 168.986, 169.023 }, +{ 169.166, 169.184 }, +{ 169.242, 169.26 }, +{ 169.337, 169.349 }, +{ 169.421, 169.431 }, +{ 169.474, 169.531 }, +{ 169.558, 169.6 }, +{ 169.638, 169.662 }, +{ -999.0, -999.0} diff --git a/src/gsfml/Geek2007r.h b/src/gsfml/Geek2007r.h new file mode 100644 index 00000000000..709e7b1976c --- /dev/null +++ b/src/gsfml/Geek2007r.h @@ -0,0 +1,231 @@ +{ 0.78, 0.99 }, +{ 1.07, 1.201 }, +{ 1.211, 1.77 }, +{ 1.95, 2.14 }, +{ 2.15, 2.581 }, +{ 3.04, 3.11 }, +{ 3.22, 3.33 }, +{ 3.58, 4.18 }, +{ 4.29, 4.48 }, +{ 4.62, 4.8 }, +{ 4.89, 4.98 }, +{ 5.23, 5.894 }, +{ 6.137, 6.269 }, +{ 6.567, 6.935 }, +{ 7.091, 7.135 }, +{ 7.17, 7.341 }, +{ 7.375, 7.432 }, +{ 7.562, 7.65 }, +{ 8.072, 8.225 }, +{ 8.257, 8.606 }, +{ 8.664, 8.699 }, +{ 9.025, 9.097 }, +{ 9.117, 9.23 }, +{ 9.308, 9.58 }, +{ 9.642, 9.74 }, +{ 9.88, 9.92 }, +{ 10.949, 11.052 }, +{ 11.099, 11.167 }, +{ 11.193, 11.352 }, +{ 11.363, 11.476 }, +{ 11.531, 11.555 }, +{ 11.584, 11.935 }, +{ 12.078, 12.184 }, +{ 12.401, 12.678 }, +{ 12.708, 12.775 }, +{ 12.819, 12.991 }, +{ 13.139, 13.302 }, +{ 13.51, 13.703 }, +{ 14.076, 14.178 }, +{ 14.612, 14.8 }, +{ 14.888, 15.034 }, +{ 15.155, 16.014 }, +{ 16.293, 16.327 }, +{ 16.488, 16.556 }, +{ 16.726, 17.277 }, +{ 17.615, 17.793 }, +{ 17.854, 18.281 }, +{ 18.781, 19.048 }, +{ 20.131, 20.518 }, +{ 20.725, 20.996 }, +{ 21.32, 21.768 }, +{ 21.859, 22.151 }, +{ 22.248, 22.459 }, +{ 22.493, 22.588 }, +{ 22.75, 22.804 }, +{ 23.069, 23.353 }, +{ 23.535, 23.677 }, +{ 23.8, 23.999 }, +{ 24.118, 24.73 }, +{ 24.781, 24.835 }, +{ 25.183, 25.496 }, +{ 25.648, 25.678 }, +{ 25.705, 25.823 }, +{ 25.951, 25.992 }, +{ 26.554, 27.027 }, +{ 27.972, 28.283 }, +{ 28.512, 28.578 }, +{ 28.745, 29.401 }, +{ 29.662, 29.765 }, +{ 30.098, 30.479 }, +{ 30.939, 33.058 }, +{ 33.545, 34.655 }, +{ 34.94, 35.343 }, +{ 35.526, 35.685 }, +{ 36.341, 36.618 }, +{ 37.473, 37.604 }, +{ 37.848, 37.92 }, +{ 38.113, 38.426 }, +{ 39.552, 39.631 }, +{ 40.13, 41.257 }, +{ 41.521, 42.536 }, +{ 43.789, 46.264 }, +{ 47.906, 49.037 }, +{ 49.714, 50.778 }, +{ 50.946, 51.047 }, +{ 51.743, 52.364 }, +{ 52.663, 52.757 }, +{ 52.801, 52.903 }, +{ 53.347, 55.904 }, +{ 56.391, 57.554 }, +{ 57.911, 60.92 }, +{ 61.276, 62.499 }, +{ 63.634, 63.976 }, +{ 64.745, 65.578 }, +{ 67.61, 67.735 }, +{ 68.737, 71.071 }, +{ 71.338, 71.587 }, +{ 73.004, 73.291 }, +{ 73.374, 73.619 }, +{ 79.075, 83 }, +{ 120.6, 121 }, +{ 123.19, 123.55 }, +{ 124.05, 125.67 }, +{ 126.57, 126.91 }, +{ 127.11, 127.23 }, +{ 127.49, 127.79 }, +{ 128.07, 128.34 }, +{ 128.62, 128.93 }, +{ 129.25, 129.63 }, +{ 129.91, 129.95 }, +{ 130.22, 130.24 }, +{ 130.49, 130.84 }, +{ 131.5, 131.71 }, +{ 131.73, 131.91 }, +{ 132.35, 132.4 }, +{ 132.47, 132.55 }, +{ 132.76, 133.51 }, +{ 133.58, 133.73 }, +{ 133.99, 134.08 }, +{ 134.27, 134.53 }, +{ 134.81, 135.57 }, +{ 135.96, 136.49 }, +{ 137.85, 138.5 }, +{ 138.89, 140.51 }, +{ 141.22, 141.63 }, +{ 141.78, 141.88 }, +{ 143.07, 143.36 }, +{ 143.77, 143.84 }, +{ 144.7, 145.52 }, +{ 146.56, 147.06 }, +{ 148.57, 148.62 }, +{ 148.67, 148.72 }, +{ 148.79, 149.49 }, +{ 149.72, 150.04 }, +{ 150.69, 150.91 }, +{ 150.93, 151.4 }, +{ 151.72, 151.98 }, +{ 152, 152.15 }, +{ 152.24, 152.43 }, +{ 153.13, 153.43 }, +{ 154, 154.31 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ 155.32, 155.55 }, +{ 155.8, 156.05 }, +{ 156.19, 156.51 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ -1.0, -1.0 }, +{ 157.27, 157.53 }, +{ 157.582, 157.653 }, +{ 157.785, 157.957 }, +{ 158.063, 158.096 }, +{ 158.262, 158.35 }, +{ 158.379, 158.424 }, +{ 158.471, 158.528 }, +{ 158.553, 158.584 }, +{ 158.689, 158.745 }, +{ 158.776, 158.866 }, +{ 159.182, 159.324 }, +{ 159.408, 159.482 }, +{ 159.555, 159.676 }, +{ 159.717, 159.773 }, +{ 159.903, 160.121 }, +{ 160.206, 160.282 }, +{ 160.33, 160.361 }, +{ 160.385, 160.444 }, +{ 160.479, 160.617 }, +{ 160.714, 160.78 }, +{ 160.809, 160.844 }, +{ 160.914, 161.069 }, +{ 161.18, 161.24 }, +{ 161.286, 161.309 }, +{ 161.34, 161.491 }, +{ 161.566, 161.698 }, +{ 161.957, 162.08 }, +{ 162.199, 162.302 }, +{ 162.442, 162.494 }, +{ 162.65, 162.693 }, +{ 162.777, 162.896 }, +{ 163.131, 163.204 }, +{ 163.37, 163.44 }, +{ 163.625, 163.745 }, +{ 163.896, 163.966 }, +{ 164.1, 164.236 }, +{ 164.391, 164.571 }, +{ 164.7, 164.833 }, +{ 164.934, 165.042 }, +{ 165.113, 165.161 }, +{ 165.264, 165.343 }, +{ 165.384, 165.572 }, +{ 165.642, 165.736 }, +{ 165.805, 166.043 }, +{ 166.076, 166.149 }, +{ 166.234, 166.429 }, +{ 166.497, 166.606 }, +{ 166.669, 166.776 }, +{ 166.804, 166.919 }, +{ 167.028, 167.138 }, +{ 167.16, 167.205 }, +{ 167.257, 167.298 }, +{ 167.323, 167.341 }, +{ 167.382, 167.406 }, +{ 167.432, 167.447 }, +{ 167.476, 167.502 }, +{ 167.525, 167.569 }, +{ 167.639, 167.768 }, +{ 167.792, 167.983 }, +{ 168.008, 168.105 }, +{ 168.121, 168.259 }, +{ 168.363, 168.448 }, +{ 168.503, 168.551 }, +{ 168.585, 168.656 }, +{ 168.729, 168.813 }, +{ 168.864, 168.908 }, +{ 168.934, 168.986 }, +{ 169.023, 169.166 }, +{ 169.184, 169.242 }, +{ 169.26, 169.337 }, +{ 169.349, 169.421 }, +{ 169.431, 169.474 }, +{ 169.531, 169.558 }, +{ 169.6, 169.638 }, +{ -1.0, -1.0 }, +{ -999.0, -999.0} diff --git a/src/gsfml/README.gsfml b/src/gsfml/README.gsfml new file mode 100644 index 00000000000..205eff4ac24 --- /dev/null +++ b/src/gsfml/README.gsfml @@ -0,0 +1,53 @@ +GSFML Supplemental Package +Distributed under the GNU Lesser Public License; see file +LICENSE.TXT in main GMT directory. + +------------------------------------------------------ +Author: Paul Wessel (pwessel@hawaii.edu) + SOEST, University of Hawaii +Date: December 1, 2023 +Version: 6 (for GMT 6 release). +------------------------------------------------------ + +This directory contains: + +README.gsfml : This document +fzanalyzer.c : fzanalyser C program code +fzblender.c : fzblender C program code +mlconverter.c : mlconverter C program code +fz_analysis.h : Include file for these programs +CK1995n.h : Cande & Kent 1995 normal chron ages +Chron_Normal.h : Normal Chron identifiers +Chron_Reverse.h : Referse Chron identifiers +GST2004n.h : Gradstein et al 2004 normal chron ages +GST2012n.h : Gradstein et al 2012 normal chron ages +Geek2007n.h : Gee and Kent 2007 normal chron ages +CK1995r.h : Cande & Kent 1995 reverse chron ages +Chron_Normal2.h : Normal Chron identifiers without periods or dashes +Chron_Reverse2.h : Referse Chron identifiers without periods or dashes +GST2004r.h : Gradstein et al 2004 reverse chron ages +GST2012r.h : Gradstein et al 2012 reverse chron ages +Geek2007r.h : Gee and Kent 2007 reverse chron ages + + +This package contains 3 programs and 4 bash scripts that may be useful +to people who work with seafloor fabric and magnetic lineations. +The seven programs are + + fzanalyser - Analysis of fracture zones using crossing profiles + fzblender - Optimal refinement of fracture zone traces + mlconverter - Convert chron strings to ages using a magnetic time scale + fzinformer - Plot along-FZ statistical information + fzmapper - Make Mercator map of FZ traces and cross-profiles + fzmodeler - Make and optionally plot a synthetic FZ model profile + fzprofiler - Plot one or all FZ cross-profiles + fz_funcs.sh - Sub-functions for the 4 scripts + +REFERENCES: + +-> The hotspotting technique: + +Wessel, P., K. J. Matthews, R. D. Müller, A. Mazzoni, J. M. Whittaker, + R. Myhill, and M. T. Chandler, 2015, Semiautomatic fracture zone tracking, + Geochemistry, Geophysics, Geosystems, 10.1002/2015GC005853, + http://dx.doi.org/10.1002/2015gc005853. diff --git a/src/gsfml/fz_analysis.h b/src/gsfml/fz_analysis.h new file mode 100644 index 00000000000..13d48226ab1 --- /dev/null +++ b/src/gsfml/fz_analysis.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015-2023 by P. Wessel + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: http://www.soest.hawaii.edu/PT/GSFML + *-------------------------------------------------------------------- + * + * Named indices for output table for fzanalyzer trace analysis. + * + * Author: Paul Wessel + * Date: 01-DEC-2023 (requires GMT >= 6) + */ + +#ifndef _FZ_ANALYSIS_H +#define _FZ_ANALYSIS_H + +#include "gsfml_config.h" + +#define DEF_D_WIDTH 25.0 /* Default width of central corridor */ +#define DEF_L_MIN 0.0 /* Minimum compression for search */ +#define DEF_L_MAX 1.0 /* Maximum compression for search */ +#define DEF_L_INC 0.05 /* Increment for compression search */ +#define DEF_M_MIN 0.0 /* Minimum asymmetry for search */ +#define DEF_M_MAX 1.0 /* Maximum asymmetry for search */ +#define DEF_M_INC 0.05 /* Increment for asymmetry search */ +#define DEF_W_MIN 1.0 /* Minimum width for search */ +#define DEF_W_MAX 50.0 /* Maximum width for search */ +#define DEF_W_INC 1.0 /* Increment for width search */ + +#define N_FZ_ANALYSIS_COLS 61 /* Number of output columns for final result */ + +#define POS_XR 0 /* Longitude of raw digitizing */ +#define POS_YR 1 /* Latitude of raw digitizing */ +#define POS_DR 2 /* Distance at point along raw digitized trace */ +#define POS_AR 3 /* Azimuth at point along raw digitized trace */ +#define POS_ZR 4 /* Data value at point of raw digitizing */ +#define POS_TL 5 /* Crustal age estimate at left side of FZ (negative distances) */ +#define POS_TR 6 /* Crustal age estimate at right side of FZ (positive distances) */ +#define POS_SD 7 /* Offset of data minimum (in km) from raw line origin */ +#define POS_ST 8 /* Offset of trough model minimum (in km) from raw line origin */ +#define POS_SB 9 /* Offset of blend model minimum (in km) from raw line origin */ +#define POS_SE 10 /* Offset of blend model maximum slope (in km) from raw line origin */ +#define POS_BL 11 /* Best asymmetry value [0-1] */ +#define POS_OR 12 /* Orientation of model profile (-1 =>old on negative dist side, +1 => old on positive dist side) */ +#define POS_WD 13 /* Width of data trough */ +#define POS_WT 14 /* Width of model trough (trough) */ +#define POS_WB 15 /* Width of model trough (blend) */ +#define POS_AD 16 /* Peak-to-trough amplitude from data */ +#define POS_AT 17 /* Peak-to-trough amplitude from model (trough) */ +#define POS_AB 18 /* Peak-to-trough amplitude from model (blend) */ +#define POS_UT 19 /* Flank relative amplitude from model (trough) */ +#define POS_UB 20 /* Flank relative amplitude from model (blend) */ +#define POS_VT 21 /* Variance reduction (%) from model (trough) */ +#define POS_VB 22 /* Variance reduction (%) from model (blend) */ +#define POS_FT 23 /* F-statistic for model (trough) */ +#define POS_FB 24 /* F-statistic for model (blend) */ +#define POS_XDL 25 /* Longitude of data minimum left bounds */ +#define POS_XD0 26 /* Longitude of data minimum (trough) */ +#define POS_XDR 27 /* Longitude of data minimum right bounds */ +#define POS_YDL 28 /* Latitude of data minimum left bounds */ +#define POS_YD0 29 /* Latitude of data minimum (trough) */ +#define POS_YDR 30 /* Latitude of data minimum right bounds */ +#define POS_ZDL 31 /* Data value of data minimum left bounds */ +#define POS_ZD0 32 /* Data value of data minimum (trough) */ +#define POS_ZDR 33 /* Data value of data minimum right bounds */ +#define POS_XTL 34 /* Longitude of model minimum (trough) left bounds */ +#define POS_XT0 35 /* Longitude of model minimum (trough) */ +#define POS_XTR 36 /* Longitude of model minimum (trough) right bounds */ +#define POS_YTL 37 /* Latitude of model minimum (trough) left bounds */ +#define POS_YT0 38 /* Latitude of model minimum (trough) */ +#define POS_YTR 39 /* Latitude of model minimum (trough) right bounds */ +#define POS_ZTL 40 /* Model value at (trough) left bounds */ +#define POS_ZT0 41 /* Model value at minimum (trough) */ +#define POS_ZTR 42 /* Model value at (trough) right bounds */ +#define POS_XBL 43 /* Longitude of model minimum (blend) left bounds */ +#define POS_XB0 44 /* Longitude of model minimum (blend) */ +#define POS_XBR 45 /* Longitude of model minimum (blend) right bounds */ +#define POS_YBL 46 /* Latitude of model minimum (blend) left bounds */ +#define POS_YB0 47 /* Latitude of model minimum (blend) */ +#define POS_YBR 48 /* Latitude of model minimum (blend) right bounds */ +#define POS_ZBL 49 /* Model value at (blend) left bounds */ +#define POS_ZB0 50 /* Model value at minimum (blend) */ +#define POS_ZBR 51 /* Model value at (blend) right bounds */ +#define POS_XEL 52 /* Longitude of model max slope (blend) left bounds */ +#define POS_XE0 53 /* Longitude of model max slope (blend) */ +#define POS_XER 54 /* Longitude of model max slope (blend) right bounds */ +#define POS_YEL 55 /* Latitude of model max slope (blend) left bounds */ +#define POS_YE0 56 /* Latitude of model max slope (blend) */ +#define POS_YER 57 /* Latitude of model max slope (blend) right bounds */ +#define POS_ZEL 58 /* Model value at max slope (blend) left bounds */ +#define POS_ZE0 59 /* Model value at max slope (blend) */ +#define POS_ZER 60 /* Model value at max slope (blend) right bounds */ + +#define FZ_PAC 0 /* Array index for "Pacific" (isostatic edge dipole) model */ +#define FZ_ATL 1 /* Array index for "Atlantic" (isostatic symmetric trough) model */ +#define FZ_EMP 2 /* Array index for empirical model */ +#endif /* _FZ_ANALYSIS_H */ diff --git a/src/gsfml/fz_funcs.sh b/src/gsfml/fz_funcs.sh new file mode 100644 index 00000000000..615909a610a --- /dev/null +++ b/src/gsfml/fz_funcs.sh @@ -0,0 +1,118 @@ +#!/bin/bash +#-------------------------------------------------------------------- +# Copyright (c) 2015-2023 by P. Wessel +# See LICENSE.TXT file for copying and redistribution conditions. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; version 3 or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# Contact info: http://www.soest.hawaii.edu/PT/GSFML +#-------------------------------------------------------------------- +# Functions used by GSFML scripts +# These do not require GMT; they do basic stuff with Unix tools only +# +# Author: Paul Wessel +# Date: 01-DEC-2023 +# Mode: GMT classic mode +#-------------------------------------------------------------------- + +function fz_get_version +{ # Just echoes the current GSFML version + echo "2.0 [2023]" +} + +function fz_cleanup() { + rm -f *$$* + exit $1 +} + +function fz_get_dim +{ # Expects a dimension with trailing unit, e,g, 15c, and returns inches. Note we skip the first 2 chars which are option flag, e.g. -W[c|i] + echo $1 | awk '{if (substr($1,length($1),1) == "c") {print substr($1,3,length($1)-3)/2.54} else if (substr($1,length($1),1) == "i") {print substr($1,3,length($1)-3)} else {print substr($1,3)}}' +} + +function fz_get_arg +{ # Expects a arg. Note we skip the first 2 chars which are option flag, e.g. -W + echo $1 | awk '{print substr($1,3)}' +} + +function fz_get_item +{ # Expects a two-char name as arg2 (e.g., az or VB) and pulls out value from header record arg1 + # Must make sure arg1 is passed as one item (i.e., in double quotes) + echo $1 | tr ' ' '\n' | awk '{ if (substr($1,1,2) == "'$2'") print substr($1,4)}' +} + +function fz_col_id +{ # Returns the column number 0-60 given the tag + case $1 in + XR ) col=0 ;; + YR ) col=1 ;; + DR ) col=2 ;; + AR ) col=3 ;; + ZR ) col=4 ;; + TL ) col=5 ;; + TR ) col=6 ;; + SD ) col=7 ;; + ST ) col=8 ;; + SB ) col=9 ;; + SE ) col=10 ;; + BL ) col=11 ;; + OR ) col=12 ;; + WD ) col=13 ;; + WT ) col=14 ;; + WB ) col=15 ;; + AD ) col=16 ;; + AT ) col=17 ;; + AB ) col=18 ;; + UT ) col=19 ;; + UB ) col=20 ;; + VT ) col=21 ;; + VB ) col=22 ;; + FT ) col=23 ;; + FB ) col=24 ;; + XDL ) col=25 ;; + XD0 ) col=26 ;; + XDR ) col=27 ;; + YDL ) col=28 ;; + YD0 ) col=29 ;; + YDR ) col=30 ;; + ZDL ) col=31 ;; + ZD0 ) col=32 ;; + ZDR ) col=33 ;; + XTL ) col=34 ;; + XT0 ) col=35 ;; + XTR ) col=36 ;; + YTL ) col=37 ;; + YT0 ) col=38 ;; + YTR ) col=39 ;; + ZTL ) col=40 ;; + ZT0 ) col=41 ;; + ZTR ) col=42 ;; + XBL ) col=43 ;; + XB0 ) col=44 ;; + XBR ) col=45 ;; + YBL ) col=46 ;; + YB0 ) col=47 ;; + YBR ) col=48 ;; + ZBL ) col=49 ;; + ZB0 ) col=50 ;; + ZBR ) col=51 ;; + XEL ) col=52 ;; + XE0 ) col=53 ;; + XER ) col=54 ;; + YEL ) col=55 ;; + YE0 ) col=56 ;; + YER ) col=57 ;; + ZEL ) col=58 ;; + ZE0 ) col=59 ;; + ZER ) col=60 ;; + * ) echo "Bad tag in fz_col"; col=0 ;; + esac + echo $col +} diff --git a/src/gsfml/fzanalyzer.c b/src/gsfml/fzanalyzer.c new file mode 100644 index 00000000000..98cfef4589f --- /dev/null +++ b/src/gsfml/fzanalyzer.c @@ -0,0 +1,981 @@ +/* + * Copyright (c) 2015-2023 by P. Wessel + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: http://www.soest.hawaii.edu/PT/GSFML + *-------------------------------------------------------------------- + * + * fzanalyzer analyses a series of profiles across fracture zones + * + * Author: Paul Wessel + * Date: 01-DEC-2023 (Requires GMT >= 6) + */ + +#define THIS_MODULE_NAME "fzanalyzer" +#define THIS_MODULE_LIB "gsfml" +#define THIS_MODULE_PURPOSE "Analysis of fracture zones using crossing profiles" +#define THIS_MODULE_LIB_PURPOSE "GMT supplemental modules for GSFML" +#define THIS_MODULE_KEYS "DO" +#define THIS_MODULE_NEEDS "" +#define THIS_MODULE_OPTIONS "-Vb:hios>" + +#include "gmt_dev.h" +#include "fz_analysis.h" + +#define DEF_FZ_GAP 5.0 /* Half-width of FZ gap centered on d0 where we ignore ages in fitting a + b(d-d0) + c*H(d-d0) */ + +#define FZ_G0 0 +#define FZ_G1 1 +#define FZ_G2 2 + +#define N_REQUIRED_COLS 7 + +struct FZMODELER_CTRL { + struct In { + bool active; + char *file; + } In; + struct A { /* -A// */ + bool active; + double min, max, inc; + } A; + struct C { /* -C// */ + bool active; + double min, max, inc; + } C; + struct D { /* -Dcorr_width */ + bool active; + double corr_width; + } D; + struct F { /* -F */ + bool active; + char *file; + } F; + struct I { /* -I[/] */ + bool active; + int64_t fz; + int profile; + } I; + struct S { /* -S */ + bool active; + int mode; /* 0 = bash/sh, 1 = csh/tcsh syntax */ + } S; + struct T { /* -T */ + bool active; + char *prefix; + } T; + struct W { /* -W// */ + bool active; + double min, max, inc; + } W; +}; + +#define N_SHAPES 3 /* Number of shapes to blend (G0, G1, and G2) */ + +/* Named indices for the results array for one profile */ + +#define BEST_MODEL_B 0 /* Entry for the asymmetry parameter m [0,1] */ +#define BEST_WAY_B 1 /* Entry for the normal or reversed profile model (-1 means negative distance side is the old side in Pacific FZ model) */ +#define BEST_FZLOC_B 2 /* Entry for the distance of the FZ crossing */ +#define BEST_WIDTH_B 3 /* Entry for the best model FZ width w */ +#define BEST_FLANK_B 4 /* Entry for the best model flank relative amplitude (> 0) */ +#define BEST_AMPLT_B 5 /* Entry for the best model peak-to-trough amplitude (> 0) */ +#define BEST_VARMD_B 6 /* Entry for the best model variance reduction [0-100%] */ +#define BEST_INTER_B 7 /* Entry for the best model intercept */ +#define BEST_SLOPE_B 8 /* Entry for the best model linear slope */ +#define BEST_FSTAT_B 9 /* Entry for the best model F statistic */ +#define BEST_FZLOC_T 10 /* As BEST_FZLOC_B but for asymmetry = 0 */ +#define BEST_WIDTH_T 11 /* As BEST_WIDTH_B but for asymmetry = 0 */ +#define BEST_FLANK_T 12 /* As BEST_FLANK_B but for asymmetry = 0 */ +#define BEST_AMPLT_T 13 /* As BEST_AMPLT_B but for asymmetry = 0 */ +#define BEST_VARMD_T 14 /* As BEST_VARMD_B but for asymmetry = 0 */ +#define BEST_INTER_T 15 /* As BEST_INTER_B but for asymmetry = 0 */ +#define BEST_SLOPE_T 16 /* As BEST_SLOPE_B but for asymmetry = 0 */ +#define BEST_FSTAT_T 17 /* As BEST_FSTAT_B but for asymmetry = 0 */ +#define BEST_WIDTH_D 18 /* Entry for best data FZ width */ +#define BEST_AMPLT_D 19 /* Entry for best data peak/trough amplitude */ +#define BEST_XD_1 20 /* Entry for the raw data 1-sigma left side point longitude */ +#define BEST_XD_M 21 /* Entry for the raw data longitude at FZ crossing */ +#define BEST_XD_2 22 /* Entry for the raw data 1-sigma right side point longitude */ +#define BEST_YD_1 23 /* Entry for the raw data 1-sigma left side point latitude */ +#define BEST_YD_M 24 /* Entry for the raw data latitude at FZ crossing */ +#define BEST_YD_2 25 /* Entry for the raw data 1-sigma right side point latitude */ +#define BEST_ZD_1 26 /* Entry for the raw data 1-sigma left side point data value */ +#define BEST_ZD_M 27 /* Entry for the raw data data value at FZ crossing **/ +#define BEST_ZD_2 28 /* Entry for the raw data 1-sigma right side point data value */ +#define BEST_XT_1 29 /* Entry for the blend model 1-sigma left side point longitude */ +#define BEST_XT_M 30 /* Entry for the blend model longitude at FZ crossing */ +#define BEST_XT_2 31 /* Entry for the blend model 1-sigma right side point longitude */ +#define BEST_YT_1 32 /* Entry for the blend model 1-sigma left side point latitude */ +#define BEST_YT_M 33 /* Entry for the blend model latitude at FZ crossing */ +#define BEST_YT_2 34 /* Entry for the blend model 1-sigma right side point latitude */ +#define BEST_ZT_1 35 /* Entry for the blend model 1-sigma left side point data value */ +#define BEST_ZT_M 36 /* Entry for the blend model data value at FZ crossing **/ +#define BEST_ZT_2 37 /* Entry for the blend model 1-sigma right side point data value */ +#define BEST_XB_1 38 /* Entry for the blend model 1-sigma left side point longitude */ +#define BEST_XB_M 39 /* Entry for the blend model longitude at FZ crossing */ +#define BEST_XB_2 40 /* Entry for the blend model 1-sigma right side point longitude */ +#define BEST_YB_1 41 /* Entry for the blend model 1-sigma left side point latitude */ +#define BEST_YB_M 42 /* Entry for the blend model latitude at FZ crossing */ +#define BEST_YB_2 43 /* Entry for the blend model 1-sigma right side point latitude */ +#define BEST_ZB_1 44 /* Entry for the blend model 1-sigma left side point data value */ +#define BEST_ZB_M 45 /* Entry for the blend model data value at FZ crossing **/ +#define BEST_ZB_2 46 /* Entry for the blend model 1-sigma right side point data value */ +#define BEST_XE_1 47 /* Entry for the blend model [maximum slope] 1-sigma left side point longitude */ +#define BEST_XE_M 48 /* Entry for the blend model [maximum slope] longitude at FZ crossing */ +#define BEST_XE_2 49 /* Entry for the blend model [maximum slope] 1-sigma right side point longitude */ +#define BEST_YE_1 50 /* Entry for the blend model [maximum slope] 1-sigma left side point latitude */ +#define BEST_YE_M 51 /* Entry for the blend model [maximum slope] latitude at FZ crossing */ +#define BEST_YE_2 52 /* Entry for the blend model [maximum slope] 1-sigma right side point latitude */ +#define BEST_ZE_1 53 /* Entry for the blend model [maximum slope] 1-sigma left side point data value */ +#define BEST_ZE_M 54 /* Entry for the blend model [maximum slope] data value at FZ crossing **/ +#define BEST_ZE_2 55 /* Entry for the blend model [maximum slope] 1-sigma right side point data value */ +#define N_RESULTS 56 /* Big enough to hold all the BEST_* values */ + +/* Named indices for cross-section traces */ + +#define N_CROSS_COLS 9 /* Number of output columns (below) for cross profiles */ +#define XPOS_X 0 /* Longitudes along cross profile */ +#define XPOS_Y 1 /* Latitudes along cross profile */ +#define XPOS_D 2 /* Distances along cross profile */ +#define XPOS_A 3 /* Azimuths along cross profile */ +#define XPOS_Z 4 /* Data values along cross profile */ +#define XPOS_C 5 /* Crustal ages (C) along cross profile */ +#define XPOS_S 6 /* Distances to nearest FZ along cross profile */ +#define XPOS_T 7 /* Best-fitting Trough model (incl. trend) along cross profile */ +#define XPOS_B 8 /* Best-fitting Blend model (incl. trend) along cross profile */ + +#include "fz_analysis.h" + +#define LOC_DATA 0 /* Array id for location of minimum data value (the data trough) */ +#define LOC_TROUGH 1 /* Array id for location of fZ for m = 0 (the model trough for Atlantic signal) */ +#define LOC_BLEND_T 2 /* Array id for location of trough in fZ for best m (the model FZ location for optimal blend signal) */ +#define LOC_BLEND_E 3 /* Array id for location of max slope in fZ for best m (the model FZ location for optimal blend signal) */ + +typedef void (*PFV) (double *d, int nd, double d0, double width, int way, double *vgg); + +/* The synthetic FZ model is a blend of three Gaussian functions G0, G1, and G2: + model = A * [ a * G1 + (1 - a) * (c * G2 - G0)] + m + qx + The (G0 + c * G2) is the symmetric part (c controls amount of compression [0-1]) and + G1 is the asymmetric part. The amount of asymmetry in the model is given + by the asymmetry parameter a (0-1). We also model a linear trend m + qx. +*/ + +GMT_LOCAL void FZ_gaussian0 (double *d, int nd, double d0, double width, int i, double *vgg) +{ /* G0: Fake VGG signal over a trough [The "Atlantic" signal]. Here, + * d0 is position of FZ (the trough) and width is the Gaussian width. + * The signal is normalized to give unit amplitude. + * way is not used here since the signal is symmetric, so we call it i instead + * so we can used it for something else and shut up compiler warnings. + */ + double i_s, z, f; + f = M_SQRT2; + i_s = f / width; /* s = w/f; here we use 1/s to avoid division below */ + for (i = 0; i < nd; i++) { + z = (d[i] - d0) * i_s; /* Normalized distance */ + vgg[i] = exp (-z * z); + } +} + +GMT_LOCAL void FZ_gaussian1 (double *d, int nd, double d0, double width, int way, double *vgg) +{ /* G1: Fake VGG signal over an isostatic edge [The "Pacific" signal]. Here, + * d0 is position of FZ (steepest VGG gradient) and width is the peak-to-trough distance. + * The signal is normalized to give unit peak-to-trough amplitude. + * way is -1 or +1 and signals which side is young (we reflect the profile left/right) + * way == +1 means the left side of the profile (negative d values) is the old side. + */ + int i; + double i_s, z, f, i_A; + f = M_SQRT2; + i_s = f / width; /* s = w/f; here we use 1/s to avoid division below */ + i_A = 1.0 / (M_SQRT2 * exp (-0.5)); /* Amplitude scaling; again inverted to avoid division in loop */ + for (i = 0; i < nd; i++) { + z = (d[i] - d0) * i_s; /* Normalized distance */ + if (way == -1) z = -z; /* Since we reflect signal about the d0 axis */ + vgg[i] = z * exp (-z * z) * i_A; + } +} + +GMT_LOCAL void FZ_gaussian2 (double *d, int nd, double d0, double width, int i, double *vgg) +{ /* G2: Fake VGG signal over an FZ in compression (which raises bulges). Here, + * d0 is position of FZ (the trough) and width is the Gaussian width. + * The signal is normalized to give unit peak-to-trough amplitude. + * way is not used here since the signal is symmetric, so we call it i instead + * so we can used it for something else and shut up compiler warnings. + */ + double i_s, z, f, i_A; + f = M_SQRT2; + i_s = f / width; /* s = w/f; here we use 1/s to avoid division below */ + i_A = M_E; /* Amplitude scaling; again inverted to avoid division in loop */ + for (i = 0; i < nd; i++) { + z = (d[i] - d0) * i_s; /* Normalized distance */ + z *= z; /* z Squared */ + vgg[i] = z * exp (-z) * i_A; + } +} + +GMT_LOCAL void FZ_blendmodel (double *G0, double *G1, double *G2, double *combo, int n, double a, double c, double A) +{ /* Blend the two models using a (0-1), and c (>=0), normalize, then scale to given amplitude A */ + int i; + double one_minus_a, min = DBL_MAX, max = -DBL_MAX, scale; + one_minus_a = 1.0 - a; + for (i = 0; i < n; i++) { + combo[i] = a * G1[i] + one_minus_a * (c * G2[i] - G0[i]); /* a blend */ + if (combo[i] < min) min = combo[i]; + if (combo[i] > max) max = combo[i]; + } + scale = A / (max - min); + for (i = 0; i < n; i++) combo[i] *= scale; +} + +GMT_LOCAL int FZ_solution (struct GMT_CTRL *GMT, double *dist, double *data, double d0, double *model, int n, double *par) +{ /* LS solution for par[0] + par[1]*(dist-d0) + par[2] * model, ignoring NaNs */ + int i, m; + double d, N[9]; + + gmt_M_memset (N, 9, double); /* The 3x3 normal equation matrix */ + gmt_M_memset (par, 3, double); /* The 3x1 solution vector */ + for (i = m = 0; i < n; i++) { /* Build up N */ + if (gmt_M_is_dnan (data[i])) continue; /* Skip data points that are NaN */ + d = dist[i] - d0; + N[1] += d; + N[2] += model[i]; + N[4] += d * d; + N[5] += d * model[i]; + N[8] += model[i] * model[i]; + par[0] += data[i]; + par[1] += d * data[i]; + par[2] += data[i] * model[i]; + m++; + } + /* Finalize N for this 3x3 problem */ + N[0] = (double)m; N[3] = N[1]; N[6] = N[2]; N[7] = N[5]; + return (gmt_gaussjordan (GMT, N, 3U, par)); /* Return solution via par */ +} + +GMT_LOCAL double FZ_get_variance (double *z, int n) +{ /* Compute sum of squares, skipping NaNs */ + int i; + double var = 0.0; + for (i = 0; i < n; i++) if (!gmt_M_is_dnan (z[i])) var += z[i] * z[i]; + return (var); +} + +GMT_LOCAL void FZ_residuals (double *dist, double *data, double d0, double *model, double *residual, int n, double par[]) +{ /* Return residuals after removing best-fitting FZ shape */ + int i; + for (i = 0; i < n; i++) residual[i] = data[i] - (par[0] + par[1] * (dist[i] - d0) + par[2] * model[i]); +} + +GMT_LOCAL void FZ_trend (double *x, double *y, int n, double *intercept, double *slope, int remove) +{ /* Fits a LS line, but ignore points with NaNs in y[] */ + double sum_x, sum_xx, sum_y, sum_xy, xx, dx = 0.0; + int i, m, equidistant = 0; + + sum_x = sum_xx = sum_y = sum_xy = 0.0; + if (x == NULL) { /* If there are no x-values we assume dx is passed via intercept */ + equidistant = 1; + dx = *intercept; + } + for (i = m = 0; i < n; i++) { + if (gmt_M_is_dnan (y[i])) continue; + xx = (equidistant) ? dx*i : x[i]; + sum_x += xx; + sum_xx += xx*xx; + sum_y += y[i]; + sum_xy += xx*y[i]; + m++; + } + + *intercept = (sum_y*sum_xx - sum_x*sum_xy) / (m*sum_xx - sum_x*sum_x); + *slope = (m*sum_xy - sum_x*sum_y) / (m*sum_xx - sum_x*sum_x); + + if (remove) { + for (i = 0; i < n; i++) { + xx = (equidistant) ? dx*i : x[i]; + y[i] -= (*intercept + (*slope) * xx); + } + } +} + +GMT_LOCAL int FZ_fit_model (struct GMT_CTRL *GMT, double *d, double *vgg, int n, double corridor, double *width, int n_widths, double *asym, int n_asym, double *comp, int n_comp, double *results, PFV *FZshape) +{ + /* d = distance along crossing profile in km, with d = 0 the nominal FZ location given by digitized line. + * vgg = observed (resampled) VGG along crossing profile, possibly with NaNs at end. + * n = number of points in the profile (including any NaNs) + * corridor = half-width of the central corridor in which we try to adjust the FZ location + * widths = array with signal widths to try + * asym = array with asymmetry parameters to try + * comp = array with compression parameters to try + * results = array with parameters determined below + * + * Take observed VGG cross-profile, detrend it, and then try to fit + * a theoretical profile by shifting FZ position horizontally and + * adjusting the width of the signal. We do this for a blend of two models, and + * keep track of the best blend overall. In the end we return which + * model that fit best, its variance reduction (in %), and the parameters. */ + + int col0, w, m, ic, row, way, n_sing = 0, n_fits = 0, got_trough; + double *d_vgg = NULL, *res = NULL, *predicted_vgg = NULL, *vgg_comp[N_SHAPES] = {NULL, NULL, NULL}; + double min_var_b, min_var_t, var_model, intercept, slope, var_data, F, par[3]; + + /* The algorithms used below anticipate that vgg may have NaNs and thus skip those */ + + /* First find a LS trend and remove it from vgg */ + + d_vgg = gmt_M_memory (GMT, NULL, n, double); + res = gmt_M_memory (GMT, NULL, n, double); + for (m = 0; m < N_SHAPES; m++) vgg_comp[m] = gmt_M_memory (GMT, NULL, n, double); + predicted_vgg = gmt_M_memory (GMT, NULL, n, double); + gmt_M_memcpy (d_vgg, vgg, n, double); /* Make copy of vgg */ + FZ_trend (d, d_vgg, n, &intercept, &slope, 1); /* Find and remove linear trend just for data variance calculation */ + /* So trend = d * slope + intercept; the shift of FZ location does not change this calculation (i.e. d is original d) */ + + var_data = FZ_get_variance (d_vgg, n); /* Compute sum of squares for the detrended data */ + min_var_b = min_var_t = DBL_MAX; + got_trough = (gmt_M_is_zero (asym[0])); + for (way = -1; way < 2; way += 2) { /* Must use normal and reversed model since we dont know which side is young (-1 means old is to the left or negative d) */ + for (col0 = 0; col0 < n; col0++) { /* Search for a better fit to FZ location within +- corr km of digitized location */ + if (fabs (d[col0]) > corridor) continue; /* Outside central corridor where we allow relocation of FZ position */ + for (w = 0; w < n_widths; w++) { /* Search for best shape width from 20 to 100 km */ + for (m = 0; m < N_SHAPES; m++) FZshape[m] (d, n, d[col0], width[w], way, vgg_comp[m]); + for (ic = 0; ic < n_comp; ic++) { /* Search for best compression factor */ + for (row = 0; row < n_asym; row++) { /* Search for optimal asymmetry parameter asym */ + n_fits++; + FZ_blendmodel (vgg_comp[FZ_G0], vgg_comp[FZ_G1], vgg_comp[FZ_G2], predicted_vgg, n, asym[row], comp[ic], 1.0); /* a blend, with unit amplitude */ + if (FZ_solution (GMT, d, vgg, d[col0], predicted_vgg, n, par)) { /* LS solution for trend + scaled shape */ + n_sing++; + continue; /* Return 1 if singular */ + } + if (par[2] < 0.0) continue; /* Do not consider negative amplitudes since we have way to handle reversals */ + FZ_residuals (d, vgg, d[col0], predicted_vgg, res, n, par); /* Return residuals after removing best-fitting FZ shape */ + var_model = FZ_get_variance (res, n); /* Compute sum of squares */ + if (var_model < min_var_b) { /* A better fit was obtained, update parameters */ + min_var_b = var_model; + results[BEST_MODEL_B] = asym[row]; + results[BEST_WAY_B] = (double)way; + results[BEST_FZLOC_B] = d[col0]; + results[BEST_WIDTH_B] = width[w]; + results[BEST_FLANK_B] = comp[ic]; + results[BEST_INTER_B] = par[0]; + results[BEST_SLOPE_B] = par[1]; + results[BEST_AMPLT_B] = par[2]; + } + if (got_trough && row == 0 && var_model < min_var_t) { /* Keep separate tabs of best trough (t = 0) model */ + min_var_t = var_model; + results[BEST_FZLOC_T] = d[col0]; + results[BEST_WIDTH_T] = width[w]; + results[BEST_FLANK_T] = comp[ic]; + results[BEST_INTER_T] = par[0]; + results[BEST_SLOPE_T] = par[1]; + results[BEST_AMPLT_T] = par[2]; + } + } + } + } + } + } + F = ((var_data - min_var_b) / 4) / (min_var_b / (n - 4)); /* Compute F for best model, assuming nu = 5-1 = 4 */ + results[BEST_VARMD_B] = 100.0 * (var_data - min_var_b) / var_data; /* Variance reduction in % */ + results[BEST_FSTAT_B] = F; + if (got_trough) { /* Same results for a pure through model */ + F = ((var_data - min_var_t) / 3) / (min_var_t / (n - 3)); /* Compute F for best trough model, assuming nu = 4-1 = 3 */ + results[BEST_VARMD_T] = 100.0 * (var_data - min_var_t) / var_data; /* Variance reduction in % */ + results[BEST_FSTAT_T] = F; + } + else { /* Never requested a pure through model */ + for (w = BEST_FZLOC_T; w <= BEST_FSTAT_T; w++) results[w] = GMT->session.d_NaN; + } + gmt_M_free (GMT, d_vgg); + gmt_M_free (GMT, res); + gmt_M_free (GMT, predicted_vgg); + for (m = 0; m < N_SHAPES; m++) gmt_M_free (GMT, vgg_comp[m]); + return ((int)irint (100.0 * n_sing / n_fits)); /* Return percentage of singular solutions as a measure of trouble */ +} + +GMT_LOCAL void FZ_get_envelope (struct GMT_CTRL *GMT, double *pd, double *px, double *py, double *pz, int np, double *best_loc, int k, double *results) +{ /* Find the lon/lat of the points +/- 1-sigma from the FZ-crossing */ + int il, ir; + double sigma3, pe[3], threshold; + + /* First do data estimates. Here, pz[k] is the trough */ + threshold = 0.5 * pz[k]; /* Find where pz is first >= threshold on either side of k */ + for (il = k - 1; il >= 0 && pz[il] < threshold; il--); + results[BEST_XD_1] = (il == -1) ? GMT->session.d_NaN : px[il]; + results[BEST_YD_1] = (il == -1) ? GMT->session.d_NaN : py[il]; + results[BEST_ZD_1] = (il == -1) ? GMT->session.d_NaN : pz[il]; + results[BEST_XD_M] = px[k]; + results[BEST_YD_M] = py[k]; + results[BEST_ZD_M] = pz[k]; + for (ir = k + 1; ir < np && pz[ir] < threshold; ir++); + results[BEST_XD_2] = (ir == np) ? GMT->session.d_NaN : px[ir]; + results[BEST_YD_2] = (ir == np) ? GMT->session.d_NaN : py[ir]; + results[BEST_ZD_2] = (ir == np) ? GMT->session.d_NaN : pz[ir]; + results[BEST_WIDTH_D] = (il == -1 || ir == np) ? GMT->session.d_NaN : pd[ir] - pd[il]; + results[BEST_AMPLT_D] = 2.0 * (0.5 * (results[BEST_ZD_2] + results[BEST_ZD_1]) - results[BEST_ZD_M]); /* Twice since we used 0.5 as threshold */ + /* Then do trough model estimates */ + sigma3 = results[BEST_WIDTH_T]/2.0; /* Treat FZ width a fullwidth = 6sigma */ + pe[0] = best_loc[LOC_TROUGH] - sigma3; pe[1] = best_loc[LOC_TROUGH]; pe[2] = best_loc[LOC_TROUGH] + sigma3; + gmt_intpol (GMT, pd, px, NULL, np, 3, pe, &results[BEST_XT_1], 0.0, 1); /* Returns three longitudes starting at BEST_XT_1 location */ + gmt_intpol (GMT, pd, py, NULL, np, 3, pe, &results[BEST_YT_1], 0.0, 1); /* Returns three latitudes starting at BEST_YT_1 location */ + gmt_intpol (GMT, pd, pz, NULL, np, 3, pe, &results[BEST_ZT_1], 0.0, 1); /* Returns three data values starting at BEST_ZT_1 location */ + /* Then do blend model (at trough) estimates */ + sigma3 = results[BEST_WIDTH_B]/2.0; /* Treat FZ width a fullwidth = 6sigma */ + pe[0] = best_loc[LOC_BLEND_T] - sigma3; pe[1] = best_loc[LOC_BLEND_T]; pe[2] = best_loc[LOC_BLEND_T] + sigma3; + gmt_intpol (GMT, pd, px, NULL, np, 3, pe, &results[BEST_XB_1], 0.0, 1); /* Returns three longitudes starting at BEST_XB_1 location */ + gmt_intpol (GMT, pd, py, NULL, np, 3, pe, &results[BEST_YB_1], 0.0, 1); /* Returns three latitudes starting at BEST_YB_1 location */ + gmt_intpol (GMT, pd, pz, NULL, np, 3, pe, &results[BEST_ZB_1], 0.0, 1); /* Returns three data values starting at BEST_ZB_1 location */ + /* Last do blend model estimates for maximum slope location */ + sigma3 = results[BEST_WIDTH_B]/2.0; /* Treat FZ width a fullwidth = 6sigma */ + pe[0] = best_loc[LOC_BLEND_E] - sigma3; pe[1] = best_loc[LOC_BLEND_E]; pe[2] = best_loc[LOC_BLEND_E] + sigma3; + gmt_intpol (GMT, pd, px, NULL, np, 3, pe, &results[BEST_XE_1], 0.0, 1); /* Returns three longitudes starting at BEST_XE_1 location */ + gmt_intpol (GMT, pd, py, NULL, np, 3, pe, &results[BEST_YE_1], 0.0, 1); /* Returns three latitudes starting at BEST_YE_1 location */ + gmt_intpol (GMT, pd, pz, NULL, np, 3, pe, &results[BEST_ZE_1], 0.0, 1); /* Returns three data values starting at BEST_ZE_1 location */ +} + +GMT_LOCAL int FZ_trough_location (struct GMT_CTRL *GMT, double *dist, double *vgg_obs, double *vgg_blend, int np, double corr_width, double locations[]) +{ /* Return minimum locations of observed and best-blend profiles */ + int i, o_min = -1, b_min = -1; + double vo_min = DBL_MAX, vb_min = DBL_MAX; + for (i = 0; i < np; i++) { + if (fabs(dist[i]) > corr_width) continue; + if (!gmt_M_is_dnan (vgg_obs[i]) && vgg_obs[i] < vo_min) { + vo_min = vgg_obs[i]; + o_min = i; + } + if (!gmt_M_is_dnan (vgg_blend[i]) && vgg_blend[i] < vb_min) { + vb_min = vgg_blend[i]; + b_min = i; + } + } + /* Return the location, or NaN if everything is NaN */ + locations[LOC_DATA] = (o_min == -1) ? GMT->session.d_NaN : dist[o_min]; + locations[LOC_BLEND_T] = (b_min == -1) ? GMT->session.d_NaN : dist[b_min]; + return (o_min); +} + +GMT_LOCAL void FZ_get_ages (struct GMT_CTRL *GMT, double *dist, double *age, int np, double d0, double A[]) +{ /* Return the age on left and right side of FZ. FZ is a distance d0 */ + /* LS solution for par[0] + par[1]*(dist-d0) + par[2] * H(dist-d0), ignoring NaNs and points within DEF_FZ_GAP km of origin d0. + * We skip this gap since ages often spline from one side to the other and we seek to avoid fitting this ramp */ + int i, m; + double d, H, N[9], par[3]; + + gmt_M_memset (N, 9, double); /* The 3x3 normal equation matrix */ + gmt_M_memset (par, 3, double); /* The 3x1 solution vector */ + for (i = m = 0; i < np; i++) { /* Build up N */ + if (gmt_M_is_dnan (age[i])) continue; /* Skip data points that are NaN */ + d = dist[i] - d0; /* Distance relative to origin d0 */ + if (fabs (d) < DEF_FZ_GAP) continue; /* Skip data points within DEF_FZ_GAP km of origin */ + H = (d > 0.0) ? 1.0 : 0.0; /* Heaviside step function (d cannot be 0.0 as per test above) */ + N[1] += d; + N[2] += H; + N[4] += d * d; + N[5] += d * H; + N[8] += H * H; + par[0] += age[i]; + par[1] += d * age[i]; + par[2] += age[i] * H; + m++; + } + if (m < 3) { /* Nothing to do, return NaNs */ + A[0] = A[1] = GMT->session.d_NaN; + return; + } + /* Finalize N for this 3x3 problem */ + N[0] = (double)m; N[3] = N[1]; N[6] = N[2]; N[7] = N[5]; + (void) gmt_gaussjordan (GMT, N, 3U, par); + /* In evaluating model for d = 0 the slope does not contribute */ + A[0] = par[0]; /* Age just left of FZ */ + A[1] = A[0] + par[2]; /* Age just right of FZ */ +} + +static void *New_Ctrl (struct GMT_CTRL *GMT) { /* Allocate and initialize a new control structure */ + struct FZMODELER_CTRL *C; + + C = gmt_M_memory (GMT, NULL, 1, struct FZMODELER_CTRL); + + /* Initialize values whose defaults are not 0/false/NULL */ + C->D.corr_width = DEF_D_WIDTH; /* Only use center corridor */ + C->I.profile = -1; /* Use all profiles from current FZ */ + C->C.min = DEF_L_MIN; /* Min compression */ + C->C.max = DEF_L_MAX; /* Max compression */ + C->C.inc = DEF_L_INC; /* Sampling interval for FZ compression */ + C->A.min = DEF_M_MIN; /* Min asymmetry = Atlantic signal */ + C->A.max = DEF_M_MAX; /* Max asymmetry = Pacific signal */ + C->A.inc = DEF_M_INC; /* Sampling interval for FZ blend */ + C->T.prefix = strdup ("fztrack"); /* Default file prefix */ + C->W.min = DEF_W_MIN; /* Narrowest FZ shape width to fit */ + C->W.max = DEF_W_MAX; /* Widest FZ shape width to fit */ + C->W.inc = DEF_W_INC; /* Sampling interval for FZ shape width */ + return (C); +} + +static void Free_Ctrl (struct GMT_CTRL *GMT, struct FZMODELER_CTRL *C) { /* Deallocate control structure */ + if (!C) return; + if (C->In.file) free (C->In.file); + if (C->F.file) free (C->F.file); + if (C->T.prefix) free (C->T.prefix); + gmt_M_free (GMT, C); +} + +static int usage (struct GMTAPI_CTRL *API, int level) { + const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_NAME, THIS_MODULE_PURPOSE); + if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); + GMT_Usage (API, 0, "usage: %s -F [-C//] " + "[-A//] [-D] [-I[/]] " + "-S[c]] [-T] [%s] [-W//] " + "%s] [%s] [%s]", name, GMT_V_OPT, GMT_colon_OPT, GMT_b_OPT, GMT_i_OPT); + + if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS); + + GMT_Message (API, GMT_TIME_NONE, " REQUIRED ARGUMENTS:\n"); + GMT_Usage (API, 1, "\n"); + GMT_Usage (API, -2, " is a multi-segment file with (lon,lat,dist,az,data,nn,age) in the first " + "7 columns. It is obtained via grdtrack -C based on the original track lines."); + GMT_Usage (API, 1, "\n-F"); + GMT_Usage (API, -2, " is the file with resampled track lines from grdtrack -D."); + + GMT_Message (API, GMT_TIME_NONE, "\n OPTIONAL ARGUMENTS:\n"); + + GMT_Usage (API, 1, "\n-A//"); + GMT_Usage (API, -2, "Specify how FZ blend modeling between symmetric and asymmetric parts is to be done:"); + GMT_Usage (API, 3, "%s : Minimum asymmetry value [%g].", GMT_LINE_BULLET, DEF_M_MIN); + GMT_Usage (API, 3, "%s : Maximum asymmetry value [%g].", GMT_LINE_BULLET, DEF_M_MAX); + GMT_Usage (API, 3, "%s : Increment used for blend search [%g].", GMT_LINE_BULLET, DEF_M_INC); + GMT_Usage (API, -2, "To only use a single asymmetry value, only give the argument."); + GMT_Usage (API, 1, "\n-C//]"); + GMT_Usage (API, -2, "Specify how FZ compression modeling is to be done:"); + GMT_Usage (API, 3, "%s : Minimum compression value [%g].", GMT_LINE_BULLET, DEF_L_MIN); + GMT_Usage (API, 3, "%s : Maximum compression value [%g].", GMT_LINE_BULLET, DEF_L_MAX); + GMT_Usage (API, 3, "%s : Increment used for compression search [%g].", GMT_LINE_BULLET, DEF_L_INC); + GMT_Usage (API, -2, "To only use a single compression value, only give the argument."); + GMT_Usage (API, 1, "\n-D"); + GMT_Usage (API, -2, "Sets width (in km) of central cross-profile wherein FZ shifts may be sought [%g].", DEF_D_WIDTH); + GMT_Usage (API, 1, "\n-I[/]"); + GMT_Usage (API, -2, "Specify a particular id (first FZ is 0) to analyze " + "[Default analyzes the cross-profiles of all FZs]. " + "Optionally, append the id of a particular profile in that FZ."); + GMT_Usage (API, 1, "\n-S[c]"); + GMT_Usage (API, -2, "Write out a parameter file with settings needed for Bourne scripts. " + "Append c to use csh/tcsh syntax instead."); + GMT_Usage (API, 1, "\n-T"); + GMT_Usage (API, -2, "Set file prefix for all output files [fztrack]."); + GMT_Option (API, "V"); + GMT_Usage (API, 1, "\n-W//"); + GMT_Usage (API, -2, "Specify parameters that control how FZ width is determined:"); + GMT_Usage (API, 3, "%s : Minimum FZ signal width (in km) for nonlinear width search [%g].", GMT_LINE_BULLET, DEF_W_MIN); + GMT_Usage (API, 3, "%s : Maximum FZ signal width (in km) for nonlinear width search [%g].", GMT_LINE_BULLET, DEF_W_MAX); + GMT_Usage (API, 3, "%s : Increment (in km) used for width search [%g].", GMT_LINE_BULLET, DEF_W_INC); + GMT_Option (API, ":,b7i,."); + + return (GMT_MODULE_USAGE); +} + +static int parse (struct GMTAPI_CTRL *API, struct FZMODELER_CTRL *Ctrl, struct GMT_OPTION *options) { + + /* This parses the options provided to grdsample and sets parameters in CTRL. + * Any GMT common options will override values set previously by other commands. + * It also replaces any file names specified as input or output with the data ID + * returned when registering these sources/destinations with the API. + */ + + int j, n_files = 0, n_errors = 0; + struct GMT_OPTION *opt = NULL; + struct GMT_CTRL *GMT = API->GMT; + char ta[GMT_LEN64], tb[GMT_LEN64], tc[GMT_LEN64]; + + for (opt = options; opt; opt = opt->next) { + switch (opt->option) { + + case '<': /* Skip input files */ + Ctrl->In.active = true; + if (n_files == 0) Ctrl->In.file = strdup (opt->arg); + n_files++; + break; + + /* Processes program-specific parameters */ + + case 'A': + n_errors += gmt_M_repeated_module_option (API, Ctrl->D.active); + j = sscanf (opt->arg, "%[^/]/%[^/]/%s", ta, tb, tc); + Ctrl->A.min = atof (ta); + Ctrl->A.max = atof (tb); + Ctrl->A.inc = atof (tc); + if (j == 1) { /* Only gave a specific asymmetry value */ + Ctrl->A.max = Ctrl->A.min; + Ctrl->A.inc = 1.0; + } + break; + case 'C': + n_errors += gmt_M_repeated_module_option (API, Ctrl->C.active); + j = sscanf (opt->arg, "%[^/]/%[^/]/%s", ta, tb, tc); + Ctrl->C.min = atof (ta); + Ctrl->C.max = atof (tb); + Ctrl->C.inc = atof (tc); + if (j == 1) { /* Only gave a specific compression value */ + Ctrl->C.max = Ctrl->C.min; + Ctrl->C.inc = 1.0; + } + break; + case 'D': + n_errors += gmt_M_repeated_module_option (API, Ctrl->D.active); + Ctrl->D.corr_width = atof (opt->arg); + break; + case 'F': + n_errors += gmt_M_repeated_module_option (API, Ctrl->F.active); + Ctrl->F.file = strdup (opt->arg); + break; + case 'I': /* Just pick a single profile for analysis */ + n_errors += gmt_M_repeated_module_option (API, Ctrl->I.active); + j = sscanf (opt->arg, "%[^/]/%s", ta, tb); + if (j == 2) { /* Got both FZ and profile numbers */ + Ctrl->I.fz = atoi (ta); + Ctrl->I.profile = atoi (tb); + } + else + Ctrl->I.fz = atoi (opt->arg); + break; + case 'S': + n_errors += gmt_M_repeated_module_option (API, Ctrl->S.active); + if (opt->arg[0] == 'c') Ctrl->S.mode = 1; + break; + case 'T': + n_errors += gmt_M_repeated_module_option (API, Ctrl->T.active); + free (Ctrl->T.prefix); + Ctrl->T.prefix = strdup (opt->arg); + break; + case 'W': + n_errors += gmt_M_repeated_module_option (API, Ctrl->W.active); + sscanf (opt->arg, "%[^/]/%[^/]/%s", ta, tb, tc); + Ctrl->W.min = atof (ta); + Ctrl->W.max = atof (tb); + Ctrl->W.inc = atof (tc); + break; + + default: /* Report bad options */ + n_errors += gmt_default_error (GMT, opt->option); + break; + } + } + + if (GMT->common.b.active[GMT_IN] && GMT->common.b.ncol[GMT_IN] == 0) GMT->common.b.ncol[GMT_IN] = 7; + n_errors += gmt_M_check_condition (GMT, !Ctrl->In.active, "GMT SYNTAX ERROR: No input file specified\n"); + n_errors += gmt_M_check_condition (GMT, n_files > 1, "GMT SYNTAX ERROR: Only specify one input file\n"); + n_errors += gmt_M_check_condition (GMT, Ctrl->C.active && Ctrl->C.min < 0.0, "GMT SYNTAX ERROR -C: Values must be >= 0 (typically in 0-1 range)\n"); + n_errors += gmt_M_check_condition (GMT, Ctrl->A.active && (Ctrl->A.min < 0.0 || Ctrl->A.max > 1.0), "GMT SYNTAX ERROR -A: Values must be 0 <= m <= 1.\n"); + n_errors += gmt_M_check_condition (GMT, !Ctrl->F.file, "GMT SYNTAX ERROR -F: Must specify input trace file.\n"); + n_errors += gmt_M_check_condition (GMT, Ctrl->D.corr_width <= 0.0, "GMT SYNTAX ERROR -D: Corridor width must be positive.\n"); + n_errors += gmt_M_check_condition (GMT, GMT->common.b.active[GMT_IN] && GMT->current.setting.io_header[GMT_IN], "GMT SYNTAX ERROR. Binary input data cannot have header -h.\n"); + n_errors += gmt_M_check_condition (GMT, GMT->common.b.active[GMT_IN] && GMT->common.b.ncol[GMT_IN] < 7, "GMT SYNTAX ERROR. Binary input data (-bi) must have at least 7 columns.\n"); + + return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR); +} + +#define bailout(code) {gmt_M_free_options (mode); return (code);} +#define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); bailout (code);} + +EXTERN_MSC int GMT_fzanalyzer (void *V_API, int mode, void *args) { + int error = 0, k, start, stop, left, right; + int n_sing, way, m; + uint64_t n_FZ_widths, n_FZ_asym, n_FZ_comp, np_cross, n_half_cross, ii; + uint64_t fz, ku, row, col, xseg; + + char buffer[BUFSIZ], run_cmd[BUFSIZ], add[BUFSIZ], *cmd = NULL, *file = NULL; + + double fz_inc, corridor_half_width, cross_length, threshold, results[N_RESULTS], best_loc[4]; + double *FZ_width = NULL, *FZ_asym = NULL, *FZ_comp = NULL, ages[2], *comp[N_SHAPES]; + + PFV FZshape[N_SHAPES] = {NULL, NULL, NULL}; + + struct GMT_OPTION *options = NULL; + struct FZMODELER_CTRL *Ctrl = NULL; + struct GMT_DATASET *Fin = NULL, *Xin = NULL; + struct GMT_DATATABLE *F = NULL, *X = NULL; + struct GMT_DATASEGMENT *S = NULL; + struct GMT_CTRL *GMT = NULL, *GMT_cpy = NULL; + struct GMTAPI_CTRL *API = gmt_get_api_ptr (V_API); /* Cast from void to GMTAPI_CTRL pointer */ + + /*----------------------- Standard module initialization and parsing ----------------------*/ + + if (API == NULL) return (GMT_NOT_A_SESSION); + if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */ + options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */ + + if (!options || options->option == GMT_OPT_USAGE) bailout (usage (API, GMT_USAGE)); /* Return the usage message */ + if (options->option == GMT_OPT_SYNOPSIS) bailout (usage (API, GMT_SYNOPSIS)); /* Return the synopsis */ + + /* Parse the program-specific arguments */ + + GMT = gmt_begin_module (API, THIS_MODULE_LIB, THIS_MODULE_NAME, &GMT_cpy); /* Save current state */ + if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error); + Ctrl = New_Ctrl (GMT); /* Allocate and initialize a new control structure */ + if ((error = parse (API, Ctrl, options))) Return (error); + + /*---------------------------- This is the fzanalyzer main code ----------------------------*/ + + /* We know which columns are geographical */ + GMT->current.io.col_type[GMT_IN][GMT_X] = GMT->current.io.col_type[GMT_OUT][GMT_X] = GMT_IS_LON; + GMT->current.io.col_type[GMT_IN][GMT_Y] = GMT->current.io.col_type[GMT_OUT][GMT_Y] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XDL] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YDL] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XD0] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YD0] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XDR] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YDR] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XTL] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YTL] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XT0] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YT0] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XTR] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YTR] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XBL] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YBL] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XB0] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YB0] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XBR] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YBR] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XEL] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YEL] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XE0] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YE0] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][POS_XER] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][POS_YER] = GMT_IS_LAT; + + /* Assign pointer array to the three basic shapes */ + FZshape[FZ_G0] = FZ_gaussian0; FZshape[FZ_G1] = FZ_gaussian1; FZshape[FZ_G2] = FZ_gaussian2; + + /* Read in the resampled FZ track lines */ + + if (GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN, GMT_ADD_DEFAULT, 0, options) != GMT_NOERROR) { /* Establishes data input */ + Return (API->error); + } + if ((error = GMT_Begin_IO (API, GMT_IS_DATASET, GMT_IN, GMT_HEADER_ON))) Return (error); /* Enables data input and sets access mode */ + if ((Fin = GMT_Read_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, GMT_READ_NORMAL, NULL, Ctrl->F.file, NULL)) == NULL) Return ((error = GMT_DATA_READ_ERROR)); + F = Fin->table[0]; /* Since there is only one table */ + if (F->segment[0]->n_columns < N_REQUIRED_COLS) { /* Trouble */ + GMT_Message (API, GMT_TIME_NONE, "GMT SYNTAX ERROR: FZ file %s does not have the %d required columns\n", Ctrl->F.file, N_REQUIRED_COLS); + Return (EXIT_FAILURE); + } + /* Read in the cross-profiles */ + + if ((Xin = GMT_Read_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, GMT_READ_NORMAL, NULL, Ctrl->In.file, NULL)) == NULL) Return ((error = GMT_DATA_READ_ERROR)); + X = Xin->table[0]; /* Since there is only one table */ + if (X->segment[0]->n_columns < N_REQUIRED_COLS) { /* Trouble */ + GMT_Message (API, GMT_TIME_NONE, "GMT SYNTAX ERROR: Cross-profile file %s does not have the %d required columns\n", Ctrl->In.file, N_REQUIRED_COLS); + Return (EXIT_FAILURE); + } + + if ((error = GMT_End_IO (API, GMT_IN, 0))) Return (error); /* Disables further data input */ + + /* Set up the array of trial FZ widths based on -W parameters */ + n_FZ_widths = gmt_M_get_n (GMT, Ctrl->W.min, Ctrl->W.max, Ctrl->W.inc, 0); + FZ_width = gmt_M_memory (GMT, NULL, n_FZ_widths, double); + for (col = 0; col < n_FZ_widths; col++) FZ_width[col] = gmt_M_col_to_x (GMT, col, Ctrl->W.min, Ctrl->W.max, Ctrl->W.inc, 0.0, n_FZ_widths); + + /* Set up array of asymmetry values (or 1) based on -A */ + n_FZ_asym = gmt_M_get_n (GMT, Ctrl->A.min, Ctrl->A.max, Ctrl->A.inc, 0); + FZ_asym = gmt_M_memory (GMT, NULL, n_FZ_asym, double); + for (col = 0; col < n_FZ_asym; col++) FZ_asym[col] = gmt_M_col_to_x (GMT, col, Ctrl->A.min, Ctrl->A.max, Ctrl->A.inc, 0.0, n_FZ_asym); + + /* Set up array of compression values (or 1) based on -C */ + n_FZ_comp = gmt_M_get_n (GMT, Ctrl->C.min, Ctrl->C.max, Ctrl->C.inc, 0); + FZ_comp = gmt_M_memory (GMT, NULL, n_FZ_comp, double); + for (col = 0; col < n_FZ_comp; col++) FZ_comp[col] = gmt_M_col_to_x (GMT, col, Ctrl->C.min, Ctrl->C.max, Ctrl->C.inc, 0.0, n_FZ_comp); + + /* Get resampling step size and zone width in degrees */ + + np_cross = X->segment[0]->n_rows; /* Since all cross-profiles have the same length */ + corridor_half_width = 0.5 * Ctrl->D.corr_width; /* Only search for trough within this zone */ + ages[0] = ages[1] = GMT->session.d_NaN; /* So we can report NaN if there are no ages */ + + for (m = 0; m < N_SHAPES; m++) comp[m] = gmt_M_memory (GMT, NULL, np_cross, double); /* Will hold normalized G0, G1, and G2 model predictions */ + + cmd = GMT_Create_Cmd (API,options); + sprintf (run_cmd, "# %s %s", GMT->init.module_name, cmd); /* Build command line argument string */ + gmt_M_free (GMT, cmd); + + if (GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_OUT, GMT_ADD_DEFAULT, 0, options) != GMT_NOERROR) { /* Establishes data output */ + Return (API->error); + } + if ((error = GMT_Begin_IO (API, GMT_IS_DATASET, GMT_OUT, GMT_HEADER_ON))) Return (error); /* Enables data output and sets access mode */ + + GMT->current.setting.io_header[GMT_OUT] = true; /* To ensure writing of headers */ + + /* Extend the dataset of cross profiles to hold more columns */ + gmt_adjust_dataset (GMT, Xin, N_CROSS_COLS); /* Same table length as X, but with N_CROSS_COLS columns */ + for (ku = 0; ku < X->n_headers; ku++) free (X->header[ku]); + if (X->n_headers) gmt_M_free (GMT, X->header); + X->n_headers = 3; + X->header = gmt_M_memory (GMT, NULL, X->n_headers, char *); + X->header[0] = strdup ("# Equidistant cross-profiles normal to each FZ trace"); + X->header[1] = strdup (run_cmd); + strcpy (buffer, "# lon\t\tlat\tdist\taz\tdata\tage\tdist2fz\tTmodel\tBmodel"); + X->header[2] = strdup (buffer); + + /* To hold the results per FZ trace. Same number of points as the resampled trace in FZ */ + gmt_adjust_dataset (GMT, Fin, N_FZ_ANALYSIS_COLS); /* Same table length as F, but with N_FZ_ANALYSIS_COLS columns */ + for (ku = 0; ku < F->n_headers; ku++) free (F->header[ku]); + if (F->n_headers) gmt_M_free (GMT, F->header); + F->n_headers = 3; + F->header = gmt_M_memory (GMT, NULL, F->n_headers, char *); + F->header[0] = strdup ("# Analyzed FZ traces"); + F->header[1] = strdup (run_cmd); + F->header[2] = strdup ("# XR\t\tYR\tDR\tAR\tZR\tTL\tTR\tSD\tST\tSB\tSE\tBL\tOR\tWD\tWT\tWB\tAD\tAT\tAB\tUT\tUB\tVT\tVB\tFT\tFB\t" \ + "XDL\tXD0\tXDR\tYDL\tYD0\tYDR\tZDL\tZD0\tZDR\tXTL\tXT0\tXTR\tYTL\tYT0\tYTR\tZTL\tZT0\tZTR\tXBL\tXB0\tXBR\tYBL\t" \ + "YB0\tYBR\tZBL\tZB0\tZBR\tXEL\tXE0\tXER\tYEL\tYE0\tYER\tZEL\tZE0\tZER"); + + n_half_cross = (np_cross - 1) / 2; /* Number of points in a cross-profile on either side of the FZ (center point) */ + threshold = -0.1 * (X->segment[0]->data[XPOS_D][1] - X->segment[0]->data[XPOS_D][0]); /* 10% threshold lets us skip through tiny negative FZ dist steps due to round-off */ + cross_length = X->segment[0]->data[XPOS_D][np_cross-1] - X->segment[0]->data[XPOS_D][0]; /* Length of a cross-profile */ + + for (fz = xseg = 0; fz < F->n_segments; fz++) { /* For each FZ segment */ + + if (Ctrl->I.active && fz != (uint64_t)Ctrl->I.fz) { /* Skip this FZ */ + struct GMT_DATASEGMENT_HIDDEN *SH = gmt_get_DS_hidden (F->segment[fz]); + SH->mode = GMT_WRITE_SKIP; /* Ignore on output */ + xseg += F->segment[fz]->n_rows; /* Must wind past all the cross-profiles for the skipped FZ */ + continue; + } + + for (row = 0; row < F->segment[fz]->n_rows; row++, xseg++) { /* Process all the cross-profiles for this FZ */ + S = X->segment[xseg]; /* Current cross-profile */ + if (Ctrl->I.active && Ctrl->I.profile >= 0 && row != (uint64_t)Ctrl->I.profile) { /* Skip this profile */ + continue; + } + GMT_Report (API, GMT_MSG_NORMAL, "Process FZ cross-profile %s\r", S->label); + + /* Must determine if parts of the crossection is closer to a neighbor FZ; we then truncate the data. */ + start = stop = -1; + for (ku = 0, left = n_half_cross - 1, right = n_half_cross + 1; ku < n_half_cross; ku++, right++, left--) { /* March outwards from the center point which should have the smallest pn */ + if (start == -1 && !gmt_M_is_dnan (S->data[XPOS_S][left]) && (fz_inc = S->data[XPOS_S][left] - S->data[XPOS_S][left+1]) < threshold) start = left + 1; + if (stop == -1 && !gmt_M_is_dnan (S->data[XPOS_S][right]) && (fz_inc = S->data[XPOS_S][right] - S->data[XPOS_S][right-1]) < threshold) stop = right - 1; + } + /* If neighbor FZs are too close (distances start to decrease) we find the last point with an + * monotonic increase in FZ distance on either side. If there is no neighbor then start and/or + * stop will remain at -1. */ + if (start == -1) start = 0; + if (stop == -1) stop = np_cross - 1; + /* Now set the sampled grid profile to NaN if too close to a neighbor FZ */ + for (k = 0; k < start; k++) S->data[XPOS_Z][k] = GMT->session.d_NaN; + for (k = np_cross-1; k > stop; k--) S->data[XPOS_Z][k] = GMT->session.d_NaN; + /* It is now possible that the beginning and end of the cross profile will have NaNs */ + + /* Find best fit shift, width, and amplitude plus various quality factors */ + + gmt_M_memset (results, N_RESULTS, double); + n_sing = FZ_fit_model (GMT, S->data[XPOS_D], S->data[XPOS_Z], np_cross, corridor_half_width, FZ_width, n_FZ_widths, FZ_asym, n_FZ_asym, FZ_comp, n_FZ_comp, results, FZshape); + if (n_sing) GMT_Report (API, GMT_MSG_NORMAL, "Warning: Cross profile %s generated %ld %% singular solutions\n", S->label, n_sing); + + /* Evaluate the best model predictions */ + FZshape[FZ_G0] (S->data[XPOS_D], np_cross, results[BEST_FZLOC_T], results[BEST_WIDTH_T], 0, comp[FZ_G0]); /* Just need G0 & G2 for building trough model (asymmetry = 0) */ + FZshape[FZ_G2] (S->data[XPOS_D], np_cross, results[BEST_FZLOC_T], results[BEST_WIDTH_T], 0, comp[FZ_G2]); + FZ_blendmodel (comp[FZ_G0], comp[FZ_G1], comp[FZ_G2], S->data[XPOS_T], np_cross, 0.0, results[BEST_FLANK_T], results[BEST_AMPLT_T]); /* Best trough model (T) without the linear trend */ + way = irint (results[BEST_WAY_B]); /* Old side on negative distance (-1) or positive distances (+1) */ + for (m = 0; m < N_SHAPES; m++) FZshape[m] (S->data[XPOS_D], np_cross, results[BEST_FZLOC_B], results[BEST_WIDTH_B], way, comp[m]); /* Evaluate all three shapes given blend parameters */ + FZ_blendmodel (comp[FZ_G0], comp[FZ_G1], comp[FZ_G2], S->data[XPOS_B], np_cross, results[BEST_MODEL_B], results[BEST_FLANK_B], results[BEST_AMPLT_B]); /* Best blend (B) without the linear trend */ + m = FZ_trough_location (GMT, S->data[XPOS_D], S->data[XPOS_Z], S->data[XPOS_B], np_cross, corridor_half_width, best_loc); /* Determine the LOC_DATA and LOC_BLEND_T estimates of FZ location */ + best_loc[LOC_TROUGH] = results[BEST_FZLOC_T]; /* The 2nd best FZ location estimate is from the trough model */ + best_loc[LOC_BLEND_E] = results[BEST_FZLOC_B]; /* The 3rd best FZ location estimate is from the blend model */ + + /* Determine the +/- 1-sigma corridor around the best FZ trace */ + FZ_get_envelope (GMT, S->data[XPOS_D], S->data[XPOS_X], S->data[XPOS_Y], S->data[XPOS_Z], np_cross, best_loc, m, results); + /* Determine ages on left (d < 0) and right (d > 0) sides (if -A) */ + FZ_get_ages (GMT, S->data[XPOS_D], S->data[XPOS_C], np_cross, 0.0, ages); + + /* Copy the results for this cross-profile analysis to the output data set */ + F->segment[fz]->data[POS_TL][row] = ages[0]; /* Crustal age to left of FZ */ + F->segment[fz]->data[POS_TR][row] = ages[1]; /* Crustal age to right of FZ */ + F->segment[fz]->data[POS_SD][row] = S->data[XPOS_D][m]; /* Offset of data trough from digitized FZ location [0] */ + F->segment[fz]->data[POS_ST][row] = results[BEST_FZLOC_T]; /* Offset of model (trough) location from digitized FZ location */ + F->segment[fz]->data[POS_SB][row] = best_loc[LOC_BLEND_T]; /* Offset of model trough (blend) location from digitized FZ location */ + F->segment[fz]->data[POS_SE][row] = results[BEST_FZLOC_B]; /* Offset of model (blend) location from digitized FZ location */ + F->segment[fz]->data[POS_BL][row] = results[BEST_MODEL_B]; /* Best blend value at FZ location */ + F->segment[fz]->data[POS_OR][row] = results[BEST_WAY_B]; + F->segment[fz]->data[POS_WD][row] = results[BEST_WIDTH_D]; /* Best data width at FZ location */ + F->segment[fz]->data[POS_WT][row] = results[BEST_WIDTH_T]; /* Best trough model width at FZ location */ + F->segment[fz]->data[POS_WB][row] = results[BEST_WIDTH_B]; /* Best blend model width at FZ location */ + F->segment[fz]->data[POS_AD][row] = results[BEST_AMPLT_D]; /* Best data amplitude at FZ location */ + F->segment[fz]->data[POS_AT][row] = results[BEST_AMPLT_T]; /* Best trough amplitude at FZ location */ + F->segment[fz]->data[POS_AB][row] = results[BEST_AMPLT_B]; /* Best blend amplitude at FZ location */ + F->segment[fz]->data[POS_UT][row] = results[BEST_FLANK_T]; /* Best trough amplitude at FZ location */ + F->segment[fz]->data[POS_UB][row] = results[BEST_FLANK_B]; /* Best blend amplitude at FZ location */ + F->segment[fz]->data[POS_VT][row] = results[BEST_VARMD_T]; /* Best trough variance reduction at FZ location */ + F->segment[fz]->data[POS_VB][row] = results[BEST_VARMD_B]; /* Best blend variance reduction at FZ location */ + F->segment[fz]->data[POS_FT][row] = results[BEST_FSTAT_T]; /* Best trough F statistic at FZ location */ + F->segment[fz]->data[POS_FB][row] = results[BEST_FSTAT_B]; /* Best blend F statistic at FZ location */ + for (ii = BEST_XD_1, k = POS_XDL; ii <= BEST_ZE_2; ii++, k++) F->segment[fz]->data[k][row] = results[ii]; /* All 9 xyz triplets */ + + /* Update crosstrack profiles with linear trends */ + for (ii = 0; ii < np_cross; ii++) { /* Compute the best model fits as trend + scaled prediction shape. Note the trend requires BEST_FZLOC_B/T */ + S->data[XPOS_T][ii] += (results[BEST_INTER_T] + results[BEST_SLOPE_T] * (S->data[XPOS_D][ii] - results[BEST_FZLOC_T])); + S->data[XPOS_B][ii] += (results[BEST_INTER_B] + results[BEST_SLOPE_B] * (S->data[XPOS_D][ii] - results[BEST_FZLOC_B])); + } + sprintf (add, " mb=%03.2f rv=%+2d OB=%+05.1f WB=%02g UB=%04.2f AB=%05.1f VB=%2.2d FB=%05.1f OT=%+05.1f WT=%02g UT=%04.2f AT=%05.1f VT=%2.2d FT=%05.1f OD=%+05.1f WD=%02g OE=%+05.1f", + results[BEST_MODEL_B], way, best_loc[LOC_BLEND_T], results[BEST_WIDTH_B], results[BEST_FLANK_B], results[BEST_AMPLT_B], + (int)irint(results[BEST_VARMD_B]), results[BEST_FSTAT_B], best_loc[LOC_TROUGH], results[BEST_WIDTH_T], results[BEST_FLANK_T], + results[BEST_AMPLT_T], (int)irint(results[BEST_VARMD_T]), results[BEST_FSTAT_T], best_loc[LOC_DATA], + results[BEST_WIDTH_D], best_loc[LOC_BLEND_E]); + strcpy (buffer, S->header); + free (S->header); + gmt_chop (buffer); + strcat (buffer, add); + S->header = strdup (buffer); + } + } + GMT_Report (API, GMT_MSG_NORMAL, "Process FZ cross-profile %s\n", S->label); + + /* Save crosstrack profiles and models to file */ + sprintf (buffer, "%s_cross.txt", Ctrl->T.prefix); + file = strdup (buffer); + if (GMT_Write_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, 0, NULL, file, Xin) != GMT_NOERROR) Return ((error = GMT_DATA_WRITE_ERROR)); + GMT_Destroy_Data (API, &Xin); + free (file); + + /* Store FZ trace analysis */ + sprintf (buffer, "%s_analysis.txt", Ctrl->T.prefix); + file = strdup (buffer); + if (GMT_Write_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, 0, NULL, file, Fin) != GMT_NOERROR) Return ((error = GMT_DATA_WRITE_ERROR)); + GMT_Destroy_Data (API, &Fin); + free (file); + + if (Ctrl->S.active) { /* Store parameters */ + FILE *fp = NULL; + char *assign = NULL, *equal = NULL, *shell[2] = {"sh/bash", "[t]cshell"}; + sprintf (buffer, "%s_par.txt", Ctrl->T.prefix); + file = strdup (buffer); + if ((fp = fopen (file, "w")) == NULL) { + GMT_Report (API, GMT_MSG_NORMAL, "Syntax error: Unable to create file %s\n", file); + Return (EXIT_FAILURE); + } + GMT_Report (API, GMT_MSG_NORMAL, "Write modeling parameters script to File %s\n", file); + assign = (Ctrl->S.mode) ? strdup ("set ") : strdup (""); + equal = (Ctrl->S.mode) ? strdup (" = ") : strdup ("="); + fprintf (fp, "%s\n", run_cmd); + fprintf (fp, "# Parameters that may be used by %s scripts\n", shell[Ctrl->S.mode]); + fprintf (fp, "%sCORR_WIDTH%s%g\n", assign, equal, Ctrl->D.corr_width); + fprintf (fp, "%sCROSS_LENGTH%s%g\n", assign, equal, cross_length); + fprintf (fp, "%sL_MIN%s%g\n", assign, equal, Ctrl->C.min); + fprintf (fp, "%sL_MAX%s%g\n", assign, equal, Ctrl->C.max); + fprintf (fp, "%sL_INC%s%g\n", assign, equal, Ctrl->C.inc); + fprintf (fp, "%sM_MIN%s%g\n", assign, equal, Ctrl->A.min); + fprintf (fp, "%sM_MAX%s%g\n", assign, equal, Ctrl->A.max); + fprintf (fp, "%sM_INC%s%g\n", assign, equal, Ctrl->A.inc); + fprintf (fp, "%sW_MIN%s%g\n", assign, equal, Ctrl->W.min); + fprintf (fp, "%sW_MAX%s%g\n", assign, equal, Ctrl->W.max); + fprintf (fp, "%sW_INC%s%g\n", assign, equal, Ctrl->W.inc); + fprintf (fp, "%sTAG%s%s\n", assign, equal, Ctrl->T.prefix); + fclose (fp); + free (equal); + free (file); + free (assign); + } + + if ((error = GMT_End_IO (API, GMT_OUT, 0))) Return (error); /* Disables further data output */ + + /* Close files and free misc. memory */ + + for (m = 0; m < N_SHAPES; m++) gmt_M_free (GMT, comp[m]); + gmt_M_free (GMT, FZ_width); + gmt_M_free (GMT, FZ_asym); + gmt_M_free (GMT, FZ_comp); + + Return (GMT_NOERROR); +} diff --git a/src/gsfml/fzblender.c b/src/gsfml/fzblender.c new file mode 100644 index 00000000000..80e39e29f0d --- /dev/null +++ b/src/gsfml/fzblender.c @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2015-2023 by P. Wessel + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: http://www.soest.hawaii.edu/PT/GSFML + *-------------------------------------------------------------------- + * + * fzblender reads a FZ analysis file and produces a smooth, blended trace. + * + * Author: Paul Wessel + * Date: 01-DEC-2023 (Requires GMT >= 6) + */ + +#define THIS_MODULE_NAME "fzblender" +#define THIS_MODULE_LIB "gsfml" +#define THIS_MODULE_PURPOSE "Produce a smooth blended FZ trace" +#define THIS_MODULE_LIB_PURPOSE "GMT supplemental modules for GSFML" +#define THIS_MODULE_KEYS "DO" +#define THIS_MODULE_NEEDS "" +#define THIS_MODULE_OPTIONS "-Vh>" + +#include "gmt_dev.h" +#include "fz_analysis.h" + +#define DEF_Q_MIN 0.0 /* Minimum quality index */ +#define DEF_Q_MAX 4.0 /* Maximum quality index */ +#define DEF_Z_AMP_CUT 25.0 /* Amplitude cutoff for VGG */ +#define DEF_Z_VAR_CUT 50.0 /* Variance reduction cutoff */ +#define DEF_Z_F_CUT 50.0 /* F statistic cutoff */ +#define DEF_Z_W_CUT 15.0 /* Width cutoff */ + +#define N_BLENDS 5 /* Total number of traces available for blending */ +#define B_MODEL 0 +#define D_MODEL 1 +#define E_MODEL 2 +#define T_MODEL 3 +#define U_MODEL 4 + +#define N_LONG_COL 13 /* Number of input columns with longitudes */ +#define N_BLEND_COLS 10 /* Number of output columns */ +#define OUT_LON0 0 +#define OUT_LAT0 1 +#define OUT_DIST 2 +#define OUT_SHFT 3 +#define OUT_WDTH 4 +#define OUT_QWHT 5 +#define OUT_LONL 6 +#define OUT_LATL 7 +#define OUT_LONR 8 +#define OUT_LATR 9 + +struct FZBLENDER_CTRL { + struct In { + bool active; + char *file; + } In; + struct I { /* -I */ + bool active; + int profile; + } I; + struct D { /* -D */ + bool active; + char *file; + } D; + struct E { /* -E[] sEcondary filter */ + bool active; + char *args; /* Full filter args for filter1d */ + } E; + struct F { /* -F[] Primary filter */ + bool active; + char *args; /* Full filter args for filter1d */ + } F; + struct Q { /* -Q/ */ + bool active; + double min, max; + } Q; + struct S { /* -S[b][d][t][u][] */ + bool active; + int mode[N_BLENDS]; + int n_blend; + double weight[N_BLENDS]; + } S; + struct T { /* -T */ + bool active; + char *prefix; + char *file; + } T; + struct Z { /* -Z//] */ + bool active; + double amp_cut, var_cut, f_cut, w_cut; + } Z; +}; + +EXTERN_MSC int gmtlib_detrend (struct GMT_CTRL *GMT, double *x, double *y, uint64_t n, double increment, double *intercept, double *slope, int mode); +EXTERN_MSC int gmtlib_append_ogr_item (struct GMT_CTRL *GMT, char *name, unsigned int type, struct GMT_OGR *S); +EXTERN_MSC void gmtlib_write_ogr_header (FILE *fp, struct GMT_OGR *G); + +static void *New_Ctrl (struct GMT_CTRL *GMT) { /* Allocate and initialize a new control structure */ + struct FZBLENDER_CTRL *C; + + C = gmt_M_memory (GMT, NULL, 1, struct FZBLENDER_CTRL); + + /* Initialize values whose defaults are not 0/NULL */ + C->I.profile = -1; /* Default is to use all profiles */ + C->Q.min = DEF_Q_MIN; /* Min blend = Atlantic signal */ + C->Q.max = DEF_Q_MAX; /* Max blend = Pacitif signal */ + C->S.weight[B_MODEL] = C->S.weight[D_MODEL] = C->S.weight[E_MODEL] = C->S.weight[T_MODEL] = C->S.weight[U_MODEL] = 1.0; + C->T.prefix = strdup ("fztrack"); /* Default file prefix */ + C->Z.amp_cut = DEF_Z_AMP_CUT; /* Minimum significant amplitude */ + C->Z.var_cut = DEF_Z_VAR_CUT; /* Minimum significant variance reduction */ + C->Z.f_cut = DEF_Z_F_CUT; /* Minimum significant F value */ + C->Z.w_cut = DEF_Z_W_CUT; /* Minimum significant width */ + return (C); +} + +static void Free_Ctrl (struct GMT_CTRL *GMT, struct FZBLENDER_CTRL *C) { /* Deallocate control structure */ + if (!C) return; + if (C->In.file) free (C->In.file); + if (C->D.file) free (C->D.file); + if (C->E.args) free (C->E.args); + if (C->F.args) free (C->F.args); + if (C->T.prefix) free (C->T.prefix); + if (C->T.file) free (C->T.file); + gmt_M_free (GMT, C); +} + +static int usage (struct GMTAPI_CTRL *API, int level) { + const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_NAME, THIS_MODULE_PURPOSE); + if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); + GMT_Usage (API, 0, "usage: %s [-F] [-D] [-E] [-I] " + "[-Q/] [-Sbdetu[]] [-T] [%s] [-Z]\n\n", GMT_V_OPT); + + if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS); + + GMT_Message (API, GMT_TIME_NONE, " OPTIONAL ARGUMENTS:\n"); + + GMT_Usage (API, 1, "\n-D Save filtered data to _filtered_{P|S}.txt. [Delete filtered files]."); + GMT_Usage (API, 1, "\n-E"); + GMT_Usage (API, -2, "Sets sEcondary filter. See -F for filter selections. [No secondary filtering]."); + GMT_Usage (API, 1, "\n-F"); + GMT_Usage (API, -2, "Sets primary filter. Choose from convolution and non-convolution filters " + "and append full filter (6-sigma width) in km."); + GMT_Usage (API, -2, "Convolution filters:"); + GMT_Usage (API, 3, "b: Boxcar : Weights are equal."); + GMT_Usage (API, 3, "c: Cosine arch : Weights given by cosine arch."); + GMT_Usage (API, 3, "g: Gaussian : Weights given by Gaussian function."); + GMT_Usage (API, 3, "f: Custom : Weights given in one-column file ."); + GMT_Usage (API, -2, "Non-convolution filters:"); + GMT_Usage (API, 3, "m: Median : Return the median value."); + GMT_Usage (API, 3, "p: Maximum likelihood probability (mode) estimator : Return the mode:"); + GMT_Usage (API, 4, "+l Return the lowest mode if multiple modes are found [return average mode]."); + GMT_Usage (API, 4, "+u Return the uppermost mode if multiple modes are found [return average mode]."); + GMT_Usage (API, 3, "l: Lower : Return minimum of all points."); + GMT_Usage (API, 3, "L: Lower+ : Return minimum of all positive points."); + GMT_Usage (API, 3, "u: Upper : Return maximum of all points.n"); + GMT_Usage (API, 3, "U: Upper- : Return maximum of all negative points."); + GMT_Usage (API, -2, "Upper case type B, C, G, M, P, F will use robust filter versions, " + "i.e., replace outliers (2.5 L1 scale (MAD) of median) with median during filtering."); + GMT_Usage (API, 1, "\n-I"); + GMT_Usage (API, -2, "Specify a particular id (first FZ is 0) to model " + "[Default models all FZ traces]."); + GMT_Usage (API, 1, "\n-Q/"); + GMT_Usage (API, -2, "Specifies how FZ blend modeling is to be done:"); + GMT_Usage (API, 3, "%s : Minimum blend value [%g].", GMT_LINE_BULLET, DEF_Q_MIN); + GMT_Usage (API, 3, "%s : Maximum blend value [%g].", GMT_LINE_BULLET, DEF_Q_MAX); + GMT_Usage (API, -2, "Points whose quality index is below is given zero weight, " + "while points whose quality index is above is given unity weight."); + GMT_Usage (API, 1, "\n-Sbdetu[]"); + GMT_Usage (API, -2, "Select the FZ estimates to blend by appending the desired code; " + "Repeatable; optionally, append a custom weight [1]:"); + GMT_Usage (API, 3, "b: Selects the optional trough/edge blend minimum."); + GMT_Usage (API, 3, "d: Selects the empirical data minimum."); + GMT_Usage (API, 3, "e: Selects the maximum slope blend model location."); + GMT_Usage (API, 3, "t: Selects the optional trough model mimimum."); + GMT_Usage (API, 3, "u: Selects the user's digitized original locations."); + GMT_Usage (API, 1, "\n--T"); + GMT_Usage (API, -2, "Set file prefix for all input/output files [fztrack]. " + "Note: no files are give on the command line."); + GMT_Option (API, "V"); + GMT_Usage (API, 1, "\n-Z"); + GMT_Usage (API, -2, "Specify four threshold values used to determine quality of fit:"); + GMT_Usage (API, 3, "%s is the minimum amplitude value [%g].", GMT_LINE_BULLET, DEF_Z_AMP_CUT); + GMT_Usage (API, 3, "%s is the minimum variance reduction value (in %%).", GMT_LINE_BULLET, DEF_Z_VAR_CUT); + GMT_Usage (API, 3, "%s is the minimum F value [%g].", GMT_LINE_BULLET, DEF_Z_F_CUT); + GMT_Usage (API, 3, "%s is the typical FZ width (in km) [%g].", GMT_LINE_BULLET, DEF_Z_AMP_CUT); + GMT_Option (API, "."); + + return (GMT_MODULE_USAGE); +} + +static int parse (struct GMTAPI_CTRL *API, struct FZBLENDER_CTRL *Ctrl, struct GMT_OPTION *options) { + + /* This parses the options provided to grdsample and sets parameters in CTRL. + * Any GMT common options will override values set previously by other commands. + * It also replaces any file names specified as input or output with the data ID + * returned when registering these sources/destinations with the API. + */ + + int j, n_files = 0, n_errors = 0; + char *choice = "bdetu"; + char ta[GMT_LEN64], tb[GMT_LEN64], tc[GMT_LEN64], td[GMT_LEN64]; + struct GMT_OPTION *opt = NULL; + struct GMT_CTRL *GMT = API->GMT; + + for (opt = options; opt; opt = opt->next) { + switch (opt->option) { + + case '<': /* Skip input files */ + n_files++; + break; + + /* Processes program-specific parameters */ + + case 'D': /* Save intermediate filtered results */ + n_errors += gmt_M_repeated_module_option (API, Ctrl->D.active); + break; + case 'E': + n_errors += gmt_M_repeated_module_option (API, Ctrl->E.active); + Ctrl->E.args = strdup (opt->arg); + break; + case 'F': + n_errors += gmt_M_repeated_module_option (API, Ctrl->F.active); + Ctrl->F.args = strdup (opt->arg); + break; + case 'I': /* Just pick a single profile for analysis */ + n_errors += gmt_M_repeated_module_option (API, Ctrl->I.active); + Ctrl->I.profile = atoi (opt->arg); + break; + case 'Q': + n_errors += gmt_M_repeated_module_option (API, Ctrl->Q.active); + j = sscanf (opt->arg, "%[^/]/%s", ta, tb); + Ctrl->Q.min = atof (ta); + Ctrl->Q.max = atof (tb); + break; + case 'S': + n_errors += gmt_M_repeated_module_option (API, Ctrl->S.active); + switch (opt->arg[0]) { + case 'b': j = B_MODEL; break; + case 'd': j = D_MODEL; break; + case 'e': j = E_MODEL; break; + case 't': j = T_MODEL; break; + case 'u': j = U_MODEL; break; + default: + GMT_Message (API, GMT_TIME_NONE, "Error -S: Not a valid model type [%c].\n", (int)opt->arg[0]); + n_errors++; + j = -1; + break; + } + if (j != -1) { + if (Ctrl->S.mode[j]) GMT_Message (API, GMT_TIME_NONE, "Option -S%c already selected once!\n", choice[j]); + Ctrl->S.mode[j] = 1; + if (opt->arg[1]) Ctrl->S.weight[j] = atof (&opt->arg[1]); + } + break; + case 'T': + n_errors += gmt_M_repeated_module_option (API, Ctrl->T.active); + free (Ctrl->T.prefix); + Ctrl->T.prefix = strdup (opt->arg); + break; + case 'Z': + n_errors += gmt_M_repeated_module_option (API, Ctrl->Z.active); + sscanf (opt->arg, "%[^/]/%[^/]/%[^/]/%s", ta, tb, tc, td); + Ctrl->Z.amp_cut = atof (ta); + Ctrl->Z.var_cut = atof (tb); + Ctrl->Z.f_cut = atof (tc); + Ctrl->Z.w_cut = atof (td); + + default: /* Report bad options */ + n_errors += gmt_default_error (GMT, opt->option); + break; + } + } + for (j = 0; j < N_BLENDS; j++) if (Ctrl->S.mode[j]) Ctrl->S.n_blend++; + + n_errors += gmt_M_check_condition (GMT, n_files > 0, "GMT SYNTAX ERROR: No input files should be given on command line (see -T).\n"); + n_errors += gmt_M_check_condition (GMT, Ctrl->Q.active && (Ctrl->Q.min < 0.0 || Ctrl->Q.max > 4.0), "GMT SYNTAX ERROR -Q: Values must be 0 <= w <= 4.\n"); + n_errors += gmt_M_check_condition (GMT, Ctrl->E.active && !Ctrl->E.args, "GMT SYNTAX ERROR -E: No secondary along-track filter selected.\n"); + n_errors += gmt_M_check_condition (GMT, Ctrl->E.active && !Ctrl->F.active, "GMT SYNTAX ERROR -E: Cannot have secondary without primary filter.\n"); + n_errors += gmt_M_check_condition (GMT, !Ctrl->S.active || Ctrl->S.n_blend == 0, "GMT SYNTAX ERROR -S: No traces have been selected for blending.\n"); + + return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR); +} + +GMT_LOCAL void FZ_fit_quality (struct GMT_CTRL *GMT, struct GMT_DATASEGMENT *S, int r, double a, double v, double f, double w, double *Q) +{ /* Return Q[B_MODEL]=Q[E_MODEL] for blend, Q[T_MODEL] for trough model, Q[E_MODEL] and Q[FZ_EMP] for empirical trough model for this segment's row r */ + if (S->data[POS_AB][r] > a && S->data[POS_VB][r] > v && S->data[POS_FB][r] > f) + Q[B_MODEL] = 4.0; + else if (S->data[POS_AB][r] > a && S->data[POS_VB][r] > v) + Q[B_MODEL] = 3.0; + else if (S->data[POS_VB][r] > v) + Q[B_MODEL] = 2.0; + else if (S->data[POS_AB][r] > a) + Q[B_MODEL] = 1.0; + else + Q[B_MODEL] = 0.0; + if (gmt_M_is_dnan (S->data[POS_AB][r])) Q[B_MODEL] = GMT->session.d_NaN; /* Flag as undetermined */ + Q[E_MODEL] = Q[B_MODEL]; + if (S->data[T_MODEL][r] > a && S->data[POS_VT][r] > v && S->data[POS_FT][r] > f) + Q[T_MODEL] = 4.0; + else if (S->data[POS_AT][r] > a && S->data[POS_VT][r] > v) + Q[T_MODEL] = 3.0; + else if (S->data[POS_VT][r] > v) + Q[T_MODEL] = 2.0; + else if (S->data[POS_AT][r] > a) + Q[T_MODEL] = 1.0; + else + Q[T_MODEL] = 0.0; + if (gmt_M_is_dnan (S->data[POS_AT][r])) Q[T_MODEL] = GMT->session.d_NaN; /* Flag as undetermined */ + /* For Empirical quality, we only have width and amplitude. Quality should increase with amp and decrease with width. + * We form the ratio (amplitude/amp_cut) over (width/width_cut), take atan and scale the result from 0-4, truncated to int */ + Q[D_MODEL] = irint (8.0 * atan ((S->data[POS_AD][r] / a) / (S->data[POS_WD][r]/ w)) / M_PI); + if (gmt_M_is_dnan (S->data[POS_AD][r]) || gmt_M_is_dnan (S->data[POS_WD][r])) Q[D_MODEL] = GMT->session.d_NaN; /* Flag as undetermined */ + Q[U_MODEL] = 0.0; /* This will depend on the others selected */ +} + +GMT_LOCAL void Ensure_Continuous_Longitudes (struct GMTAPI_CTRL *API, struct GMT_DATASET *D) +{ + struct GMT_DATATABLE *T = D->table[0]; /* Since there is only input one table */ + struct GMT_QUAD *Q = gmt_quad_init (API->GMT, 1); + unsigned int way, k, loncol[N_LONG_COL] = {POS_XR, POS_XDL, POS_XD0, POS_XDR, POS_XTL, POS_XT0, POS_XTR, POS_XBL, POS_XB0, POS_XBR, POS_XEL, POS_XE0, POS_XER}; + uint64_t fz, row, col; + char *txt[2] = {"-180 to +180", "0 to 360"}; + for (fz = 0; fz < T->n_segments; fz++) { /* For each FZ to determine */ + for (row = 0; row < T->segment[fz]->n_rows; row++) + gmt_quad_add (API->GMT, Q, T->segment[fz]->data[GMT_X][row]); /* Consider this longitude, the one along the fZ */ + } + way = gmt_quad_finalize (API->GMT, Q); + GMT_Report (API, GMT_MSG_VERBOSE, "Range finder %g to %g, selecting longitude formatting for range %s\n", Q[0].min[way], Q[0].max[way], txt[way]); + API->GMT->current.io.geo.range = Q[0].range[way]; /* Set longitude format based on input range to ensure no jumps in output */ + + for (fz = 0; fz < T->n_segments; fz++) { /* For each FZ to determine */ + for (row = 0; row < T->segment[fz]->n_rows; row++) { + for (k = 0; k < N_LONG_COL; k++) { + col = loncol[k]; + gmt_lon_range_adjust (Q->range[way], &T->segment[fz]->data[col][row]); + } + } + } + gmt_M_free (API->GMT, Q); +} + +#define bailout(code) {gmt_M_free_options (mode); return (code);} +#define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); bailout(code);} + +struct TREND { /* Holds slope and intercept for each segment column we need to detrend */ + double slp[N_BLEND_COLS]; + double icp[N_BLEND_COLS]; +}; + +#define N_TCOLS 10 /* Number of columns to detrend before filtering */ + +EXTERN_MSC int GMT_fzblender (void *V_API, int mode, void *args) { + unsigned int fz, row; + int error = 0, n_d, n_g, k, n, item, status, ndig; + int col[N_BLEND_COLS][N_BLENDS] = /* Columns in the analyzis file for b,d,e,t,u trace parameters */ + { + {POS_XB0, POS_XD0, POS_XE0, POS_XT0, POS_XR}, /* FZ longitudes */ + {POS_YB0, POS_YD0, POS_YE0, POS_YT0, POS_YR}, /* FZ latitudes */ + {-1, -1, -1, -1, -1}, /* Skip distances */ + {POS_SB, POS_SD, POS_SE, POS_ST, POS_SD}, /* FZ model offsets */ + {POS_WB, POS_WD, POS_WB, POS_WT, POS_WD}, /* FZ model widths */ + {-1, -1, -1, -1, -1}, /* Put quality index here */ + {POS_XBL, POS_XDL, POS_XEL, POS_XTL, POS_XDL}, /* FZ left lon */ + {POS_YBL, POS_YDL, POS_YEL, POS_YTL, POS_YDL}, /* FZ left lat */ + {POS_XBR, POS_XDR, POS_XER, POS_XTR, POS_XDR}, /* FZ right lon */ + {POS_YBR, POS_YDR, POS_YER, POS_YTR, POS_YDR} /* FZ right lat */ + }; + int tcols[N_TCOLS] = {POS_XR, POS_YR, POS_XB0, POS_YB0, POS_SB, POS_WB, POS_XBL, POS_YBL, POS_XBR, POS_YBR}; + + char buffer[BUFSIZ], run_cmd[BUFSIZ], *cmd = NULL; + char source[GMT_VF_LEN] = {""}, destination[GMT_VF_LEN] = {""}; + + double Q[N_BLENDS], P[N_BLENDS], q_weight[N_BLENDS], sum_P, sum_w, sum_q, i_q_range, q_model; + + struct GMT_OPTION *options = NULL; + struct FZBLENDER_CTRL *Ctrl = NULL; + struct TREND *trend = NULL; + struct GMT_DATASET *Fin = NULL, *Fout = NULL; + struct GMT_DATATABLE *Tin = NULL, *Tout = NULL; + struct GMT_CTRL *GMT = NULL, *GMT_cpy = NULL; + struct GMTAPI_CTRL *API = gmt_get_api_ptr (V_API); /* Cast from void to GMTAPI_CTRL pointer */ + + /*----------------------- Standard module initialization and parsing ----------------------*/ + + if (API == NULL) return (GMT_NOT_A_SESSION); + if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */ + options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */ + + if (!options || options->option == GMT_OPT_USAGE) bailout (usage (API, GMT_USAGE)); /* Return the usage message */ + if (options->option == GMT_OPT_SYNOPSIS) bailout (usage (API, GMT_SYNOPSIS)); /* Return the synopsis */ + + /* Parse the program-specific arguments */ + + GMT = gmt_begin_module (API, THIS_MODULE_LIB, THIS_MODULE_NAME, &GMT_cpy); /* Save current state */ + if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error); + Ctrl = New_Ctrl (GMT); /* Allocate and initialize a new control structure */ + if ((error = parse (API, Ctrl, options))) Return (error); + + /*---------------------------- This is the fzblender main code ----------------------------*/ + + sprintf (buffer, "%s_analysis.txt", Ctrl->T.prefix); + Ctrl->In.file = strdup (buffer); + GMT->current.setting.io_header[GMT_OUT] = 1; /* To allow writing of headers */ + + GMT_Report (API, GMT_MSG_NORMAL, "Read FZ analysis file %s\n", Ctrl->In.file); + if ((Fin = GMT_Read_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, GMT_READ_NORMAL, NULL, Ctrl->In.file, NULL)) == NULL) Return ((error = GMT_DATA_READ_ERROR)); + + Ensure_Continuous_Longitudes (API, Fin); /* Set longitude to 0-360 or -180/180 so there are no jumps */ + + /* Set up the primary GMT_filter1d cmd call */ + + if (Ctrl->F.active) { /* Wants to filter before blending */ + /* Must remove linear trends from the lon/lat columns before filtering since median fails on sloping lines */ + Tin = Fin->table[0]; /* Since there is only input one table */ + trend = gmt_M_memory (GMT, NULL, Tin->n_segments, struct TREND); + for (fz = 0; fz < Tin->n_segments; fz++) { /* For each FZ to determine */ + GMT_Report (API, GMT_MSG_VERBOSE, "Detrend FZ %s [segment %ld]\n", Tin->segment[fz]->label, fz); + if (Ctrl->I.profile >= 0 || fz == (unsigned int)Ctrl->I.profile) continue; /* Skip all but selected profile */ + for (k = 0; k < N_TCOLS; k++) { /* Detrend key columns */ + gmtlib_detrend (GMT, Tin->segment[fz]->data[POS_DR], Tin->segment[fz]->data[tcols[k]], Tin->segment[fz]->n_rows, 0.0, &trend[fz].icp[k], &trend[fz].slp[k], -1); + } + } + if (Ctrl->D.active) { + /* Save the detrended temporary file */ + sprintf (buffer, "%s_detrended.txt", Ctrl->T.prefix); + GMT_Report (API, GMT_MSG_VERBOSE, "Save detrended data to temporary file %s\n", buffer); + if (GMT_Write_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, 0, NULL, buffer, Fin) != GMT_NOERROR) Return ((error = GMT_DATA_WRITE_ERROR)); + } + + /* Register output for filter1d results */ + /* Create virtual files for using the data in filter1d and another for holding the result */ + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN|GMT_IS_REFERENCE, Fin, source) != GMT_NOERROR) { + Return (API->error); + } + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_OUT|GMT_IS_REFERENCE, NULL, destination) == GMT_NOTSET) { + Return (API->error); + } + + GMT_Report (API, GMT_MSG_NORMAL, "Perform primary filtering\n"); + //sprintf (buffer, "-F%s -E -N%d %s ->%s", Ctrl->F.args, POS_DR, p_in_string, p_out_string); + sprintf (buffer, "-F%s -N%d %s ->%s", Ctrl->F.args, POS_DR, source, destination); + GMT_Report (API, GMT_MSG_DEBUG, "Args to primary filter1d: %s\n", buffer); + if ((status = GMT_Call_Module (API, "filter1d", GMT_MODULE_CMD, buffer))) { + GMT_Report (API, GMT_MSG_NORMAL, "GMT SYNTAX ERROR: Primary filtering failed with exit code %d!\n", status); + Return (status); + } + GMT_Report (API, GMT_MSG_DEBUG, "filter1d completed\n"); + /* Close the source virtual file and destroy the data set */ + if (GMT_Close_VirtualFile (GMT->parent, source) != GMT_NOERROR) { + Return (API->error); + } + GMT_Destroy_Data (API, &Fin); + + if (Ctrl->E.active) { /* Now apply the secondary filter */ + struct GMT_DATASET *D = NULL; + char s_in_string[GMT_LEN256], s_out_string[GMT_LEN256]; + /* Retrieve the primary filtering results */ + if ((D = GMT_Read_VirtualFile (API, destination)) == NULL) { + Return (API->error); + } + /* Close the destination virtual file */ + if (GMT_Close_VirtualFile (GMT->parent, destination) != GMT_NOERROR) { + Return (API->error); + } + if (Ctrl->D.active) { + /* Save the primary filtered file */ + sprintf (buffer, "%s_primary_filter_P.txt", Ctrl->T.prefix); + GMT_Report (API, GMT_MSG_VERBOSE, "Save primary filtered detrended data to temporary file %s\n", buffer); + if (GMT_Write_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, 0, NULL, buffer, D) != GMT_NOERROR) Return ((error = GMT_DATA_WRITE_ERROR)); + } + /* Setup in/out for secondary filter */ + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN|GMT_IS_REFERENCE, D, source) != GMT_NOERROR) { + Return (API->error); + } + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_OUT|GMT_IS_REFERENCE, NULL, destination) == GMT_NOTSET) { + Return (API->error); + } + //sprintf (buffer, "-F%s -E -N%d %s ->%s", Ctrl->E.args, POS_DR, s_in_string, s_out_string); + sprintf (buffer, "-F%s -N%d %s ->%s", Ctrl->E.args, POS_DR, source, destination); + GMT_Report (API, GMT_MSG_DEBUG, "Args to secondary filter1d: %s\n", buffer); + if ((status = GMT_Call_Module (API, "filter1d", GMT_MODULE_CMD, buffer))) { + GMT_Report (API, GMT_MSG_NORMAL, "GMT SYNTAX ERROR: Secondary filtering failed with exit code %d!\n", status); + Return (status); + } + if (GMT_Close_VirtualFile (GMT->parent, source) != GMT_NOERROR) { + Return (API->error); + } + GMT_Destroy_Data (API, &D); + } + /* Retrieve the final filtering results */ + if ((Fin = GMT_Read_VirtualFile (API, destination)) == NULL) { + Return (API->error); + } + /* Close the destination virtual file */ + if (GMT_Close_VirtualFile (GMT->parent, destination) != GMT_NOERROR) { + Return (API->error); + } + if (Ctrl->D.active && Ctrl->E.active) { + /* Save the primary or secondary filtered file */ + char F = (Ctrl->E.active) ? 'S' : 'P'; + char *str = (Ctrl->E.active) ? "secondary" : "primary"; + sprintf (buffer, "%s_primary_filter_%c.txt", Ctrl->T.prefix, F); + GMT_Report (API, GMT_MSG_VERBOSE, "Save %s filtered detrended data to temporary file %s\n", str, buffer); + if (GMT_Write_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, 0, NULL, buffer, Fin) != GMT_NOERROR) Return ((error = GMT_DATA_WRITE_ERROR)); + } + + /* Now restore original trends */ + GMT_Report (API, GMT_MSG_DEBUG, "Restore original trends\n"); + Tin = Fin->table[0]; /* Since there is only input one table */ + for (fz = 0; fz < Tin->n_segments; fz++) { /* For each FZ to determine */ + GMT_Report (API, GMT_MSG_VERBOSE, "Restore trends for FZ %s [segment %ld]\n", Tin->segment[fz]->label, fz); + if (Ctrl->I.profile >= 0 || fz == (unsigned int)Ctrl->I.profile) continue; /* Skip all but selected profile */ + for (k = 0; k < N_TCOLS; k++) { /* Restore trend to key columns */ + gmtlib_detrend (GMT, Tin->segment[fz]->data[POS_DR], Tin->segment[fz]->data[tcols[k]], Tin->segment[fz]->n_rows, 0.0, &trend[fz].icp[k], &trend[fz].slp[k], +1); + } + } + gmt_M_free (GMT, trend); + } + + /* OK, all input/filtering is completed */ + + Tin = Fin->table[0]; /* Since there is only input one table */ + if (Tin->segment[0]->n_columns < N_FZ_ANALYSIS_COLS) { /* Trouble */ + GMT_Message (API, GMT_TIME_NONE, "GMT SYNTAX ERROR: %s does not have %d columns\n", Ctrl->In.file, N_FZ_ANALYSIS_COLS); + Return (EXIT_FAILURE); + } + + if (Ctrl->D.active && Ctrl->F.active) { + sprintf (buffer, "%s_filtered.txt", Ctrl->T.prefix); + Ctrl->D.file = strdup (buffer); + GMT_Report (API, GMT_MSG_NORMAL, "Filtered analysis results saved to %s\n", Ctrl->D.file); + if (GMT_Write_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, 0, NULL, Ctrl->D.file, Fin) != GMT_NOERROR) Return ((error = GMT_DATA_WRITE_ERROR)); + } + + /* Specify geographic columns where needed for blend output */ + + GMT->current.io.col_type[GMT_OUT][OUT_LON0] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][OUT_LAT0] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][OUT_LONL] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][OUT_LATL] = GMT_IS_LAT; + GMT->current.io.col_type[GMT_OUT][OUT_LONR] = GMT_IS_LON; GMT->current.io.col_type[GMT_OUT][OUT_LATR] = GMT_IS_LAT; + + GMT_Report (API, GMT_MSG_DEBUG, "Perform blending\n"); + cmd = GMT_Create_Cmd (API, options); + sprintf (run_cmd, "# %s %s", GMT->init.module_name, cmd); /* Build command line argument string */ + gmt_M_free (GMT, cmd); + + Fout = gmt_alloc_dataset (GMT, Fin, 0, N_BLEND_COLS, GMT_ALLOC_NORMAL); /* Same table length as FZ, but with N_BLEND_COLS columns */ + Tout = Fout->table[0]; + Tout->n_headers = 3; + Tout->header = gmt_M_memory (GMT, NULL, Tout->n_headers, char *); + Tout->header[0] = strdup ("# Blended FZ traces"); + Tout->header[1] = strdup (run_cmd); + Tout->header[2] = strdup ("# lon\tlat\tdist\tshift\twidth\tqweight\tlon_l\tlat_l\tlon_r\tlat_r"); + + i_q_range = 1.0 / (Ctrl->Q.max - Ctrl->Q.min); + gmt_M_memset (q_weight, N_BLENDS, double); /* So those that are not set below remain 0 */ + + for (fz = 0; fz < Tin->n_segments; fz++) { /* For each FZ to determine */ + + GMT_Report (API, GMT_MSG_NORMAL, "Process FZ %s [segment %ld]\n", Tin->segment[fz]->label, fz); + + if (Ctrl->I.profile >= 0 || fz == (unsigned int)Ctrl->I.profile) { /* Skip all but selected profile */ + struct GMT_DATASEGMENT_HIDDEN *SH = gmt_get_DS_hidden (Tout->segment[fz]); + SH->mode = GMT_WRITE_SKIP; /* Ignore on output */ + continue; + } + + ndig = irint (floor (log10 ((double)Tin->segment[fz]->n_rows))) + 1; /* Determine how many decimals are needed for largest FZ id */ + + for (row = 0; row < Tin->segment[fz]->n_rows; row++) { /* Process each point along digitized FZ trace */ + + FZ_fit_quality (GMT, Tin->segment[fz], row, Ctrl->Z.amp_cut, Ctrl->Z.var_cut, Ctrl->Z.f_cut, Ctrl->Z.w_cut, Q); /* Compute quality indeces for blend, trough, empirical models */ + for (k = n = 0, sum_q = 0.0; k < N_BLENDS-1; k++) { /* Compute quality weights for each model trace */ + if (!Ctrl->S.mode[k]) continue; + q_weight[k] = (Q[k] - Ctrl->Q.min) * i_q_range; + sum_q += q_weight[k]; + n++; /* Count the candidates selected */ + } + q_model = (n) ? sum_q / n : 0.0; + q_weight[N_BLENDS-1] = 1.0 - q_model; /* Estimate remaining q_weight for user profile */ + + /* Now compute the blended output */ + + for (item = 0; item < N_BLEND_COLS; item++) { + if (item == OUT_DIST) { /* No blending, just pass on along-track distance */ + Tout->segment[fz]->data[item][row] = Tin->segment[fz]->data[POS_DR][row]; + continue; + } + if (item == OUT_QWHT) { /* Store the quality weight for model */ + Tout->segment[fz]->data[item][row] = q_model; + continue; + } + /* Get the 4 candidates for blending */ + for (k = 0; k < N_BLENDS; k++) P[k] = Tin->segment[fz]->data[col[item][k]][row]; + if (item == OUT_SHFT) P[N_BLENDS-1] = 0.0; /* Digitized trace defines origin so offset == 0 */ + if (item == OUT_LON0 || item == OUT_LONL || item == OUT_LONR) { /* Must be careful with longitudes */ + for (k = n_g = n_d = 0; k < N_BLENDS; k++) { /* Determine if we have longs across Greenwich */ + if (P[k] > 350.0) n_d++; + if (P[k] < 10.0) n_g++; + } + if (n_d && n_g) /* Some longitudes crossing 0/360 line, switch to -180/180 mode */ + for (k = 0; k < N_BLENDS; k++) if (P[k] > 180.0) P[k] -= 360.0; + } + for (k = 0, sum_P = sum_w = 0.0; k < N_BLENDS; k++) { /* Those with q_weight == 0 or not requested won't contribute */ + if (!Ctrl->S.mode[k]) continue; + sum_P += P[k] * q_weight[k] * Ctrl->S.weight[k]; + sum_w += q_weight[k] * Ctrl->S.weight[k]; + } + Tout->segment[fz]->data[item][row] = sum_P / sum_w; + } + } + + /* Update the header */ + + sprintf (buffer, "Blend result for trace FZ -L\"%s\" [segment %d]", Tin->segment[fz]->label, fz); + Tout->segment[fz]->header = strdup (buffer); + } + + /* Store final blended profiles */ + + sprintf (buffer, "%s_blend.txt", Ctrl->T.prefix); + Ctrl->T.file = strdup (buffer); + GMT_Report (API, GMT_MSG_NORMAL, "Save FZ blend results to %s\n", Ctrl->T.file); + if (GMT_Write_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_LINE, 0, NULL, Ctrl->T.file, Fout) != GMT_NOERROR) Return ((error = GMT_DATA_WRITE_ERROR)); + + Return (GMT_NOERROR); +} diff --git a/src/gsfml/fzinformer b/src/gsfml/fzinformer new file mode 100755 index 00000000000..0fd78bb554e --- /dev/null +++ b/src/gsfml/fzinformer @@ -0,0 +1,186 @@ +#!/usr/bin/env bash +#-------------------------------------------------------------------- +# Copyright (c) 2015-2023 by P. Wessel +# See LICENSE.TXT file for copying and redistribution conditions. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; version 3 or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# Contact info: http://www.soest.hawaii.edu/PT/GSFML +#-------------------------------------------------------------------- +# Script to make a plot of the statistical parameters +# for a given FZ segment +# +# Author: Paul Wessel +# Date: 01-DEC-2023 (Requires GMT >= 6) +# Mode: GMT classic mode +#-------------------------------------------------------------------- + +. fz_funcs.sh # Load in FZ-specific shell functions +if [ $# -eq 0 ]; then + version=`fz_get_version` +cat << EOF >&2 + fzinformer $version - Plot along-FZ statistical information + + Usage: fzinformer [-D] [-F] [-I][-N] [-S] [-T] [-W] + + OPTIONS: + -D selected the filtered data [raw]. + -F sets max F amplitude (log scale used) [10000]. + -I select the FZ trace to report on [0 or first]. + -N sets max VGG amplitude [200]. + -S sets max +/- shift range [25]. + -T sets the profile prefix [fztrack]. + -V Report on progress [quiet]. + -W sets max W amplitude [50]. + +EOF + exit +fi + +trap 'fz_cleanup 1' 1 2 3 15 # Set interrup handling + +# Default values +filtered=0 +verbose=0 +P=0 +amax=200 +fmax=10000 +smax=25 +wmax=50 +prefix=fztrack + +while [ ! x"$1" = x ]; do + case $1 + in + -D) filtered=1; # Used the filtered data + shift;; + -F*) fmax=`fz_get_arg $1` # max F + shift;; + -I*) P=`fz_get_arg $1` # profile argument + shift;; + -N*) amax=`fz_get_arg $1` # max amplitude + shift;; + -S*) smax=`fz_get_arg $1` # max +/- shift + shift;; + -T*) prefix=`fz_get_arg $1` # Get file prefix + shift;; + -W*) wmax=`fz_get_arg $1` # max width + shift;; + -V) verbose=1; # Gave a VGG grid + shift;; + -*) echo "$0: Unrecognized option $1" 1>&2; # Bad option argument + exit 1;; + esac +done + +if [ $filtered -eq 0 ]; then + AFILE=${prefix}_analysis.txt +else + AFILE=${prefix}_filtered.txt +fi +BFILE=${prefix}_blend.txt +PS=${prefix}_stat.ps +PDF=${prefix}_stat.pdf +#----------------------------------------- +ymargin=1 +xmargin=1 +spacing=0.175 +W=6.3 +H=1.2 +xu=`gmt math -Q -0.75 1 $xmargin SUB ADD =` +yu=`gmt math -Q -0.75 1 $ymargin SUB ADD =` +# Extract our segment */ +gmt convert -Q$P $AFILE > /tmp/t.txt +# How many points along segment? +n_cross=`cat /tmp/t.txt | wc -l | awk '{printf "%d\n", $1-1}'` +yup=`gmt math -Q $H $spacing ADD =` +gmt info $AFILE -C -I1/1/2/10/0.01/1/1/5/5/5/1 > $$.info +dmin=`cut -f5 $$.info` +dmax=`cut -f6 $$.info` +gmt psbasemap -R$dmin/$dmax/0/1 -JX6i/8.9i -P -U/${xu}i/${yu}i/"$prefix" -K -B+gwhite -X${xmargin}i -Y${ymargin}i > $PS +# Plot blend and u values +x=`fz_col_id DR` +y=`fz_col_id BL` +gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-0.05/1.05 -JX${W}i/${H}i -Bxa500f100+l"Distance along FZ"+u"km" -Bya0.2f0.1 -BWSnE -Y0.25i -O -K -W1p --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i >> $PS +y=`fz_col_id UT` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS +y=`fz_col_id UB` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS +echo "$dmax 1.05 C" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS +echo "$dmin 1.05 A" | gmt pstext -R$dmin/$dmax/-0.05/1.05 -J -O -K -Gwhite -W0.25p -F+jTL+f9p -Dj0.05i/0.05i >> $PS +# Plot directions +y=`fz_col_id OR` +gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-1.1/1.1 -JX${W}i/${H}i -Bxa500f100 -Bya1g5 -BWsnE -O -K -W1p -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i >> $PS +echo "$dmax 0 O" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jBR+f9p -Dj0.05i/0.05i >> $PS +# Plot offsets +y=`fz_col_id SD` +gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-$smax/$smax -JX${W}i/${H}i -Bxa500f100 -Bya5f1g100 -BWsnE -O -K -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS +y=`fz_col_id ST` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS +y=`fz_col_id SB` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS +echo "$dmax $smax @~D@~" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS +# Plot widths +y=`fz_col_id WD` +gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/0/$wmax -JX${W}i/${H}i -Bxa500f100 -Bya10f5 -BWsnE -O -K -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS +y=`fz_col_id WT` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS +y=`fz_col_id WB` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS +echo "$dmax $wmax W" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS +gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS +$dmin 15 +$dmax 15 +EOF +# Plot amplitudes +y=`fz_col_id AD` +gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/0/$amax -JX${W}i/${H}i -Bxa500f100 -Bya50f10g1000 -BWsnE -O -K -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS +y=`fz_col_id AT` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS +y=`fz_col_id AB` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS +echo "$dmax $amax A" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS +gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS +$dmin 25 +$dmax 25 +EOF +# Plot variance reductions +y=`fz_col_id VT` +gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-5/105 -JX${W}i/${H}i -Bxa500f100 -Bya20f5 -BWsnE -O -K -W1p,green -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS +y=`fz_col_id VB` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS +echo "$dmax 105 V" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS +gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS +$dmin 50 +$dmax 50 +EOF +# Plot F values +y=`fz_col_id FT` +gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/1/$fmax -JX${W}i/${H}il -Bxa500f100 -Bya1pf3 -BWsE -O -K -W1p,green -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS +echo "$dmax $fmax F" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS +y=`fz_col_id FB` +gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS +gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS +$dmin 50 +$dmax 50 +EOF +#grep -v '^>' $AFILE | cut -f3,11 | gmt psxy -R$dmin/$dmax/0/4 -JX${W}i/${H}i -Bxa500f100 -Bya1f1+l"Q" -BWse -O -K -W1p -Y${yup}i --FONT_ANNOT_PRIMARY=10 >> $PS +gmt psbasemap -R0/$n_cross/0/100 -JX${W}i/${H}i -Bxa20f1+l"FZ ID $P" -By0 -BN -O -K --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i >> $PS +gmt psxy -R -J -O -T >> $PS +gmt psconvert -Tf $PS +if [ $verbose -eq 1 ]; then + echo "fzinformer: Final plot is called $PDF" >&2 +fi +os=`uname -s` +if [ $os = "Darwin" ]; then + open $PDF +fi +rm -f $PS +fz_cleanup 1 diff --git a/src/gsfml/fzmapper b/src/gsfml/fzmapper new file mode 100755 index 00000000000..54ec61069f7 --- /dev/null +++ b/src/gsfml/fzmapper @@ -0,0 +1,240 @@ +#!/usr/bin/env bash +#-------------------------------------------------------------------- +# Copyright (c) 2015-2023 by P. Wessel +# See LICENSE.TXT file for copying and redistribution conditions. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; version 3 or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# Contact info: http://www.soest.hawaii.edu/PT/GSFML +#-------------------------------------------------------------------- +# Bash script to make a single, large-format GMT map of the locations +# of all cross profiles for a given FZ segment. +# +# Author: Paul Wessel +# Date: 01-DEC-2023 (Requires GMT >= 6) +# Mode: GMT classic mode +#-------------------------------------------------------------------- + +. fz_funcs.sh # Load in FZ-specific shell functions +VGG=@earth_vgg_01m +SCL=0.1 +if [ $# -eq 0 ]; then + version=`fz_get_version` +cat << EOF >&2 + fzmapper $version - Make Mercator map of FZ traces and cross-profiles + + Usage: fzmapper [-A] [-F] [-G] [-L] [-O] [-S] [-T] [-V] [-W[c|i]] + + OPTIONS: + -A Plot the analysis results from fzanalysis, if available [no results]. + -F contains the original FZ track(s). + -G is name of global grid file [$VGG]. + -L sets how often to annotate profiles [1]. + -O Run as GMT overlay (i.e., pass -O -K) and send to stdout. + No PDF is made. + -S Plot the smooth curve from fzblender, if available [no smooth curve]. + -T sets the profile prefix [fztrack]. + -V Report on progress [quiet]. + -W specifies the map width (e.g., 10i or 50c). + Append units c or i [Default uses PROJ_LENGTH_UNIT]. + +EOF + exit +fi + +trap 'fz_cleanup 1' 1 2 3 15 # Set interrup handling +# Default values +W=6 +N=1 +F="" +blend=0 +anal=0 +OL=0 +verbose=0 +prefix=fztrack + +while [ ! x"$1" = x ]; do + case $1 + in + -A) anal=1 # Overlay analysis result if possible + shift;; + -W*) W=`fz_get_dim $1` # Width of map + shift;; + -F*) ORIG=`fz_get_arg $1`; # Original unsampled tracks + shift;; + -G*) VGG=`fz_get_arg $1`; # Name of grid file + shift;; + -L*) N=`fz_get_arg $1`; # Annotate every N'th profile + shift;; + -O) OL=1; # Plot as overlay to stdout + plot=1; + shift;; + -S) blend=1 # Overlay blend if possible + shift;; + -T*) prefix=`fz_get_arg $1` # Get file prefix + shift;; + -V) verbose=1; # Verbose + shift;; + -*) echo "$0: Unrecognized option $1" 1>&2; # Bad option argument + exit 1;; + esac +done + +# Make sure we convert to inches +#----------------------------------------- +CFILE=${prefix}_resampled.txt # The resampled tracks from grdtrack -D +if [ ! -f $CFILE ]; then # Cannot do it yet anyway + anal=0 + echo "$0: Resampled file $CFILE not found - cannot make plot" >&2 + exit +fi +XFILE=${prefix}_cross.txt # Crossprofiles from fzmodeler +if [ ! -f $XFILE ]; then # Cannot do it yet anyway + anal=0 + echo "$0: Cross-profile file $XFILE not found - cannot make plot" >&2 + exit +fi +TFILE=${prefix}_analysis.txt # The results from fzmodeler +if [ ! -f $TFILE ] && [ $anal -eq 1 ]; then # Cannot do it yet anyway + anal=0 + echo "$0: Analysis file $TFILE not found - ignored" >&2 +fi +if [ $OL -eq 1 ]; then + PS=/tmp/map.ps # PostScript plot file + PSargs="-O -K" +else + PS=${prefix}_map.ps # PostScript plot file + PSargs="-P -K" + PDF=${prefix}_map.pdf # Final PDF plot file +fi +. ${prefix}_par.txt # Read and assign parameters for these profiles +#------------------------------------------------------------------------------------------------------ +# All dimensions are now in inches, regardless of what the user's units are. +# Cross-profiles have lon,lat,dist,azimuth,vgg,age,fzdist columns. +# Assign variables and calculate dimensions (inches used throughout) +#------------------------------------------------------------------------------------------------------ +ymargin=0.75 # Bottom margin +xmargin=1 # Left margin +gmt set PROJ_ELLIPSOID Sphere # Since we are plotting VGG +n_cross=`gmt convert -L $XFILE | wc -l` # Number of cross-profiles +ndig=`gmt math -Q $n_cross LOG10 FLOOR 1 ADD =` # Number of digits to use for running numbers +gmt info $XFILE -C -I2/2/2/5/10/10/10/10/10 -fg > $$.info # Get clean multiples of min/max for each column +xmin=`cut -f1 $$.info` # West boundary +xmax=`cut -f2 $$.info` # East boundary +ymin=`cut -f3 $$.info` # South boundary +ymax=`cut -f4 $$.info` # North boundary +width2=`gmt math -Q $W 2 $xmargin MUL ADD =` # Width of entire plot including margins +R=-R$xmin/$xmax/$ymin/$ymax # Region -R option +height=`echo $xmax $ymax | gmt mapproject $R -JM${W}i -Di | cut -f2` # Map height +height2=`gmt math -Q $height 2 $ymargin MUL ADD =` # Plot height including margins +#------------------------------------------------------------------------------------------------------ +# Ready for plotting +if [ $verbose -eq 1 ]; then + echo "fzmapper: Papersize is ${width2}i by ${height2}i" >&2 +fi +#------------------------------------------------------------------------------------------------------ +if [ $OL -eq 1 ]; then + PSargs="-O -K" +else + PSargs="-P -K -X${xmargin}i -Y${ymargin}i --PS_MEDIA=${width2}ix${height2}i" +fi +gmt makecpt -Cgray -T-60/60/5 -Z > $$.cpt # Make basic -60 to + 60 Eotvos grayscale CPT +xu=`gmt math -Q -0.75 1 $xmargin SUB ADD =` # Placement x for -U logo and label +yu=`gmt math -Q -0.75 1 $ymargin SUB ADD =` # Placement y for -U logo and label +# Lay down VGG image +gmt grdimage ${VGG} -C$$.cpt $R -JX${W}i/${height}i $PSargs >| $PS +# Overlay geographic basemap and set -U label +gmt psbasemap $R -JM${W}i -O -B5f1g90 -BWSne -K -U/${xu}i/${yu}i/"${prefix}: Map view" >> $PS +# Draw resampled FZ tracks as blue solid line +gmt psxy -R -J -O -K $CFILE -W0.5p,blue >> $PS +# Plot original digitized points as dark blue squares +if [ ! "X${ORIG}" = "X" ]; then + gmt psxy -R -J -O -K $ORIG -Ss0.04i -Gdarkblue >> $PS +fi +P=0 +# Make color table for quality weights (0-1) +gmt makecpt -Cpolar -T0/1/0.05 -Z > $$.cpt +cat << EOF >> $$.cpt2 +-0.125 red 0.125 red +0.125 orange 0.375 orange +0.375 yellow 0.625 yellow +0.625 lightgreen 0.875 lightgreen +0.875 green 1.125 green +EOF + +# Process each crossing profile individually +while [ $P -lt $n_cross ]; do + item=`echo $P $ndig | awk '{printf "%*.*d\n", $2, $2, $1}'` # Format an integer as profile identifier + gmt convert -Q$P $XFILE > $$.raw # Extract the next profile to plot (includes the segment header) + grep -v '>' $$.raw > $$.tmp # Get this cross profile without header + header=`head -1 $$.raw` # Get this cross profile's header + az=`fz_get_item "$header" az` # Extract the azimuth of this profile + tail -1 $$.raw | cut -f1,2 > $$.tail # Place the end coordinates of profile in file $$.tail + + gmt psxy $$.tmp -R -J -O -K -Wfaint,lightblue >> $PS # Plot cross-profile as faint, lightblue lines + go=`gmt math -Q $P $N MOD 0 EQ =` # Determine when to annotate profiles + if [ $go -eq 1 ]; then # OK, want to place text ID for this cross profile + side=`gmt math -Q $az 180 LT =` # Determine which side to place profile label + if [ $side -eq 1 ]; then + awk '{ printf "%s %s %s LM %s\n", $1, $2, '"$az"', '"$item"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS + else + awk '{ printf "%s %s %s RM %s\n", $1, $2, '"$az"', '"$item"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS + fi + fi + P=`expr $P + 1` # Goto next profile +done +# Plot resampled digitized line in magenta +gmt psxy -R -J -O -K $CFILE -W0.25p,magenta >> $PS +# Plot empirical trough locations in red +x=`fz_col_id XD0` +y=`fz_col_id YD0` +if [ $anal -eq 1 ]; then + gmt psxy $TFILE -R -J -O -K -Sc0.02i -Gred -i$x,$y >> $PS + # Plot blend trough locations in green + x=`fz_col_id XB0` + y=`fz_col_id YB0` + gmt psxy $TFILE -R -J -O -K -Sc0.02i -Ggreen3 -i$x,$y >> $PS + # Plot edge blend locations in blue + x=`fz_col_id XE0` + y=`fz_col_id YE0` + gmt psxy $TFILE -R -J -O -K -Sc0.02i -Gblue -i$x,$y >> $PS +fi +if [ $blend -eq 1 ]; then + BFILE=${prefix}_blend.txt # Blended solution from fzblender + if [ -f $BFILE ]; then + # Plot best blend model as cyan line with colored circles reflecting quality + gmt psxy $BFILE -R -J -O -K -W0.5p,cyan >> $PS + gmt psxy $BFILE -R -J -O -K -Sc0.03i -C$$.cpt2 -i0,1,5 >> $PS + # Add error bounds as dashed orange lines + gmt psxy $BFILE -R -J -O -K -W0.25p,orange,- -i6,7 >> $PS + gmt psxy $BFILE -R -J -O -K -W0.25p,orange,- -i8,9 >> $PS + else + echo "$0: Blend file $BFILE not found - ignored" >&2 + fi +fi +if [ $OL -eq 1 ]; then + cat $PS +else + # Finalize plot + gmt psxy -R -J -O -T >> $PS + # Convert the PS to a PDF file + gmt psconvert -Tf $PS + # Delete temporary files and the PS file + os=`uname -s` + if [ $verbose -eq 1 ]; then + echo "fzmapper: Final map is called $PDF" >&2 + fi + if [ $os = "Darwin" ]; then + open $PDF + fi +fi + +rm -f $PS +fz_cleanup 1 diff --git a/src/gsfml/fzmodeler b/src/gsfml/fzmodeler new file mode 100755 index 00000000000..338dcae9bc7 --- /dev/null +++ b/src/gsfml/fzmodeler @@ -0,0 +1,179 @@ +#!/usr/bin/env bash +#-------------------------------------------------------------------- +# Copyright (c) 2015-2023 by P. Wessel +# See LICENSE.TXT file for copying and redistribution conditions. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; version 3 or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# Contact info: http://www.soest.hawaii.edu/PT/GSFML +#-------------------------------------------------------------------- +# Simulate a FZ based on simple Pac/Atl blend model w/wo compression +# +# Author: Paul Wessel +# Date: 01-DEC-2023 (Requires GMT >= 6) +# Mode: GMT classic mode +#-------------------------------------------------------------------- + +function G0 () { # Gaussian - The Atlantic signal. Expects: x0 x1 dx center width d2km + D2KM=$6 + gmt math -T$1/$2/$3 T $D2KM MUL $4 SUB $5 DIV 2 POW NEG EXP = +} +function G1 () { # d/dx Gaussian - The Pacific signal. Expects: x0 x1 dx center width d2km + D2KM=$6 + i_A=`gmt math -Q 2 SQRT -0.5 EXP MUL INV =` # Amplitude scaling + gmt math -T$1/$2/$3 T $D2KM MUL $4 SUB $5 DIV DUP 2 POW NEG EXP MUL $i_A MUL = +} +function G2 () { # d2/dx2 Gaussian - The Compression signal. Expects: x0 x1 dx center width d2km + D2KM=$6 + i_A=`gmt math -Q E =` # Amplitude scaling + gmt math -T$1/$2/$3 T $D2KM MUL $4 SUB $5 DIV 2 POW DUP NEG EXP MUL $i_A MUL = +} +function synthFZ () { # Combined signal. Expects: x0 x1 dx center width m u A km? + if [ $9 -eq 1 ]; then + D2KM=1 + else + D2KM=111.1950797 + fi + m=$6 + u=$7 + m1=`gmt math -Q 1 $m SUB =` # (1-m) + G0 $1 $2 $3 $4 $5 $D2KM > /tmp/G0 + G1 $1 $2 $3 $4 $5 $D2KM > /tmp/G1 + G2 $1 $2 $3 $4 $5 $D2KM > /tmp/G2 + gmt math /tmp/G2 $u MUL /tmp/G0 SUB $m1 MUL /tmp/G1 $m MUL ADD NORM $8 MUL = +} + +. fz_funcs.sh # Load in FZ-specific shell functions +name=fzprof +if [ $# -eq 0 ]; then + version=`fz_get_version` +cat << EOF >&2 + fzmodeler $version - Make and optionally plot a synthetic FZ profile + + Usage: fzmodeler [-A] [-C] [-D//] + [-F] [-M] [-N] [-O] [-S] [-W] [-P] + + OPTIONS: + -A sets FZ asymmetry between "Pacific" (1) and "Atlantic" (0) [0]. + -C sets FZ compression (0-1) [0]. + -D sets domain [-5/5/2m or -100/100/2; see -M]. + -F sets output file name prefix [$name]. + Give - to write to stdout. + -M means -D is given in degrees/degrees/minutes [km]. + -N sets max VGG amplitude [100]. + -O Run as GMT overlay (i.e., pass -O -K) and send to stdout. + No PDF is made and no datafile is saved. + -P plot to fzprof.pdf. + -S sets FZ shift from origin in km [0]. + -V Report on progress [quiet]. + -W sets FZ width in km [25]. + +EOF + exit +fi + +trap 'fz_cleanup 1' 1 2 3 15 # Set interrup handling +# Default values +verbose=0 +plot=0 +asym=0 +comp=0 +X0=0 +amp=100 +width=25 +OL=0 +X=6i/2i +km=1 +while [ ! x"$1" = x ]; do + case $1 + in + -A*) asym=`fz_get_arg $1` # asymmetry + shift;; + -C*) comp=`fz_get_arg $1` # compression + shift;; + -D*) domain=`fz_get_arg $1` # min/max/inc domain + shift;; + -F*) name=`fz_get_arg $1` # file name + shift;; + -M) km=0; # Domain given in degrees + shift;; + -N*) amp=`fz_get_arg $1` # amplitude + shift;; + -O) OL=1; # Plot as overlay to stdout + plot=1; + shift;; + -P) plot=1; # Plot and make PDF + shift;; + -S*) X0=`fz_get_arg $1`; # FZ offset + shift;; + -V) verbose=1; # Verbose + shift;; + -W*) width=`fz_get_arg $1` # FZ width + shift;; + -X*) X=`fz_get_arg $1` # Reset plot size + shift;; + *) echo "$0: Unrecognized option $1" 1>&2; # Bad option argument + exit 1;; + esac +done +#-------------- +if [ "X$domain" = "X" ]; then # Default settings + if [ $km -eq 0 ]; then + domain=-100/100/2 + else + domain=-5/5/2 + fi +fi +if [ "X$name" = "X-" ]; then + out=1 + name=/tmp/$$ + plot=0 +fi +w=`echo $domain |cut -d'/' -f1` +e=`echo $domain |cut -d'/' -f2` +dm=`echo $domain |cut -d'/' -f3` +if [ $km -eq 0 ]; then + dx=`gmt math -Q $dm 60 DIV =` + tick=2f1 +else + dx=$dm + tick=50f10 +fi + +(synthFZ $w $e $dx $X0 $width $asym $comp $amp $km > $name.txt) 2> /dev/null +if [ $plot -eq 1 ]; then + if [ $OL -eq 1 ]; then + gmt psxy -R$w/$e/-$amp/$amp -JX$X -Bx${tick}g100 -By50f10g50 -BWSne $name.txt -W2p -O -K + rm -f $name.txt + else + gmt psxy -R$w/$e/-$amp/$amp -JX$X -P -Bx${tick}g100 -By50f10g50 -BWSne $name.txt -W2p > $name.ps + gmt psconvert $name.ps -Tf -P -A + rm -f $name.ps + if [ $os = "Darwin" ]; then + open $name.pdf + fi + if [ $verbose -eq 1 ]; then + echo "$0: Synthetic FZ profile plotted in file $name.pdf" + echo "$0: Synthetic FZ profile stored in file $name.txt" + fi + fi +elif [ $verbose -eq 1 ]; then + if [ $out -eq 1 ]; then + cat $name.txt + echo "$0: Synthetic FZ profile written to stdout" + rm -f $name.txt + else + echo "$0: Synthetic FZ profile stored in file $name.txt" + fi +fi +if [ $out -eq 1 ]; then + cat $name.txt + rm -f $name.txt +fi diff --git a/src/gsfml/fzprofiler b/src/gsfml/fzprofiler new file mode 100755 index 00000000000..6e3f932e0e7 --- /dev/null +++ b/src/gsfml/fzprofiler @@ -0,0 +1,269 @@ +#!/bin/bash +#-------------------------------------------------------------------- +# Copyright (c) 2015-2023 by P. Wessel +# See LICENSE.TXT file for copying and redistribution conditions. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; version 3 or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# Contact info: http://www.soest.hawaii.edu/PT/GSFML +#-------------------------------------------------------------------- +# Bash script to make a single large-format GMT plot of all cross- +# profiles for a given FZ segment. We select the dimensions of a +# single profile panel and scale up to determine the custom paper +# needed. +# +# Author: Paul Wessel +# Date: 01-DEC-2023 (Requires GMT >= 6) +# Mode: GMT classic mode +#-------------------------------------------------------------------- + +. fz_funcs.sh # Load in FZ-specific shell functions +if [ $# -eq 0 ]; then + version=`fz_get_version` +cat << EOF >&2 + fzprofiler $version - Plot one or all FZ cross-profiles + + Usage: fzprofiler [-H[c|i]] [-I] [-L] [-N] [-T] [-V] [-W[c|i]] + + OPTIONS: + -H specify the height of each profile plot. + Append units c or i [Default uses PROJ_LENGTH_UNIT]. + -I Picks a single profile ID to plot (first is 0) [all]. + -L sets labeling increment for profiles [1]. + -N sets the number of plot columns [1]. + -T sets the profile prefix [fztrack]. + -V Report on progress [quiet]. + -W specify the width of each profile plot. + Append units c or i [Default uses PROJ_LENGTH_UNIT]. + +EOF + exit +fi + +trap 'fz_cleanup 1' 1 2 3 15 # Set interrup handling +#default values +ncols=1 +W=6 +H=2 +inc=1 +P=-1 +verbose=0 +prefix=fztrack + +while [ ! x"$1" = x ]; do + case $1 + in + -W*) W=`fz_get_dim $1` # Width of each sub-panel with one profile + shift;; + -H*) H=`fz_get_dim $1` # Height of each sub-panel with one profile + shift;; + -I*) P=`fz_get_arg $1`; # Specific profile + shift;; + -L*) inc=`fz_get_arg $1`; # Profile increment + shift;; + -N*) ncols=`fz_get_arg $1`; # Number of sub-panel columns + shift;; + -T*) prefix=`fz_get_arg $1` # Get file prefix + shift;; + -V) verbose=1; # Gave a VGG grid + shift;; + -*) echo "$0: Unrecognized option $1" 1>&2; # Bad option argument + exit 1;; + esac +done + +XFILE=${prefix}_cross.txt # Cross-profiles file +# make sure we convert to inches +PS=${prefix}_cross.ps # Resulting PostScript file +PDF=${prefix}_cross.pdf # Final PDF file for plot +. ${prefix}_par.txt # Read and assign parameters for these profiles +#------------------------------------------------------------------------------------------------------ +# All dimensions are now in inches, regardless of what the user's units are. +# Cross-profiles have lon,lat,dist,azimuth,vgg,age,fzdist columns. +# Assign variables and calculate dimensions (inches used throughout) +#------------------------------------------------------------------------------------------------------ +space=0.50 # Space between columns of panels +ymargin=0.75 # Bottom margin +xmargin=1 # Left margin +zone=`gmt math -Q $CORR_WIDTH 0.5 MUL =` # half-width of central corridor +n_cross=`gmt convert -L $XFILE | wc -l` # Number of cross-profiles +ndig=`gmt math -Q $n_cross LOG10 FLOOR 1 ADD =` # Number of digits to use for running numbers +dmin=`gmt math -Q $CROSS_LENGTH 0.5 MUL NEG =` # Only plot the central 50% of the cross profiles +dmax=`gmt math -Q $CROSS_LENGTH 0.5 MUL =` +gmt info $XFILE -C -I2/2/2/5/10/10/10/10/10 > $$.info # Get clean multiples of min/max for each column +vmin=`cut -f9 $$.info` # Low VGG bounds +vmax=`cut -f10 $$.info` # High VGG bounds +vinc=`gmt math -Q $vmax $vmin SUB 50 DIV CEIL 10 MUL =` # VGG scale bar length is ~1/5 the range, in multiples of 10 +vinc2=`gmt math -Q $vinc 2 DIV =` # +- half vinc +amin=`cut -f11 $$.info` # Low age bounds +amax=`cut -f12 $$.info` # High age bounds +range=`gmt math -Q $vmax $vmin SUB =` # VGG range for this panel +if [ $amin = "NaN" ]; then + got_age=0 +else + got_age=1 + arange=`gmt math -Q $amax $amin SUB =` # Age range for this panel + am=`gmt math -Q $amin $arange 0.5 MUL ADD =` # Mid-age value + am1=`gmt math -Q $am 5 SUB =` # am1/am2 are 1- Myr apart and will serve as age scale bar + am2=`gmt math -Q $am 5 ADD =` + atxt=" and $arange Myr (dashed orange line)" +fi +if [ $P -ge 0 ]; then # Selected to plot a single profile + nrows=1 # Obviously only a single row + single=1 # TRUE for this case + txt=" $P" # Text identifying the profile +else + P=0 # Do all profiles + nrows=`gmt math -Q $n_cross $inc DIV $ncols DIV CEIL =` # The number of rows depends on how many columns we have and how often we plot + single=0 # FALSE for this case + txt="s" # Text identifying all profiles (plural s) +fi +height=`gmt math -Q $H $nrows MUL =` # Height of all panels +width=`gmt math -Q $W $ncols MUL $ncols 1 SUB $space MUL ADD =` # Width of all plot columns together +width2=`gmt math -Q $width 2 $xmargin MUL ADD =` # PLot width, including margings +height2=`gmt math -Q $height 2 $ymargin MUL ADD =` # Plot height, including margins +xu=`gmt math -Q -0.75 1 $xmargin SUB ADD =` # Placement x for -U logo and label +yu=`gmt math -Q -0.75 1 $ymargin SUB ADD =` # Placement y for -U logo and label +VB=`gmt math -Q $vmax 0.75 MUL =` # VGG-value to use for placement of blend width indicator symbol +VT=`gmt math -Q $vmax 0.50 MUL =` # VGG-value to use for placement of trough width indicator symbol +VD=`gmt math -Q $vmax 0.25 MUL =` # VGG-value to use for placement of data width indicator symbol +#------------------------------------------------------------------------------------------------------ +# Ready for plotting +if [ $verbose -eq 1 ]; then + echo "fzprofiler: Papersize is ${width2}i by ${height2}i; vertical range per row panel is $range Eotvos${atxt}." >&2 +fi +#------------------------------------------------------------------------------------------------------ +# Draw the outline of the combined rowsxcols panels; add title and -U label, using a custom paper size tailored to fit the plot +gmt psbasemap -R0/$width/0/$height -Jx1i -P -Xa${xmargin}i -Ya${ymargin}i -B+gwhite -K -U/${xu}i/${yu}i/"${prefix}: Cross profile${txt}" --PS_MEDIA=${width2}ix${height2}i >| $PS +let row=9999 # This will be reset to 1 immediately in the loop below +let col=0 # This will be reset to 1 in the loop. We start from left-most column (1) and work to the right +while [ $P -lt $n_cross ]; do # As long as there are profiles left + if [ $verbose -eq 1 ]; then + echo "fzprofiler: Plotting profile $P" >&2 + fi + let row=row+1 # Go to next row (row = 1 is the first row) + if [ $row -gt $nrows ]; then # Must go to next column + let row=1 # Back to the bottom + let col=col+1 # Move to next column + let frame=1 # Time to plot a basemap again for the entire column + if [ $col -gt 1 ]; then # Draw the central d = 0 line for the entire column + gmt psbasemap -R$dmin/$dmax/0/$height -JX${W}i/${height}i -O -K -Bx0g1000 -By0 -Xa${xpos}i -Ya${ymargin}i >> $PS + fi + + fi + xpos=`gmt math -Q $col 1 SUB $W $space ADD MUL $xmargin ADD =` # Determines the x position of the current panel's LL corner + ypos=`gmt math -Q $nrows $row SUB $H MUL $ymargin ADD =` # Determines the y position of the current panel's LL corner + xposL=`gmt math -Q $xpos 0.15 SUB =` # We will plot a VGG scale bar 0.15 inches to the left of each panel + xposR=`gmt math -Q $xpos 0.15 ADD =` # We will plot an Age scale bar 0.15 inches to the right of each panel + if [ $frame -eq 1 ]; then # Plot the central corridor in light blue color, annotate the distance axis + gmt psxy -R$dmin/$dmax/0/$height -JX${W}i/${height}i -O -K -Glightblue -Bx20f5 -By0 -BwSne -Xa${xpos}i -Ya${ymargin}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 <<- EOF >> $PS + -${zone} 0 + ${zone} 0 + ${zone} $height + -${zone} $height + EOF + let frame=0 + fi + gmt convert -Q$P $XFILE > $$.raw # Extract the profile to plot (includes the segment header) + header=`head -1 $$.raw` # Get this cross profile's header + # Pull out several parameter values from the segment header, via strings such as WD=25 + + az=`fz_get_item "$header" az` # Extract the azimuth of this profile + mb=`fz_get_item "$header" mb` # Extract the blend parameter for best-fitting model + OB=`fz_get_item "$header" OB` # Extract the offset parameter for best-fitting blend model + WB=`fz_get_item "$header" WB` # Extract the width parameter for best-fitting blend model + UB=`fz_get_item "$header" UB` # Extract the compression parameter for best-fitting blend model + OT=`fz_get_item "$header" OT` # Extract the offset parameter for best-fitting trough model + WT=`fz_get_item "$header" WT` # Extract the width parameter for best-fitting trough model + UT=`fz_get_item "$header" UT` # Extract the compression parameter for best-fitting trough model + OD=`fz_get_item "$header" OD` # Extract trough location parameter for the data + WD=`fz_get_item "$header" WD` # Extract the width estimate of the data trough + OE=`fz_get_item "$header" OE` # Extract the offset parameter for best-fitting edge model + WT2=`gmt math -Q $WT 0.5 MUL =` # Compute half-widths + WB2=`gmt math -Q $WB 0.5 MUL =` + northsouth=`gmt math -Q $az ABS 45 LE =` # Determine if profile is mostly E-W or S-N + if [ $northsouth -eq 1 ]; then # It is mostly S to N + L="S" + R="N" + else # It is mostly E to W + L="W" + R="E" + fi + # Build a polygon the plot as lightcyan the +- 2 sigma uncertainty on the trough location OT + echo $OT $WT $vmin $vmax | awk '{printf "%g\t%s\n%g\t%s\n%g\t%s\n%g\t%s\n", $1-0.5*$2/3, $3, $1+0.5*$2/3, $3, $1+0.5*$2/3, $4, $1-0.5*$2/3, $4}' > $$.w + y=`gmt math -Q $P $H MUL 1 ADD =` + # Plot the uncertainty area on OT as lightcyan + gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -Bx0 -Byf1000g1000 -Bwe -O -K $$.w -Glightcyan -Xa${xpos}i -Ya${ypos}i >> $PS + # Plot the data as red circles connected by a thin dotted red line + gmt psxy $$.raw -i2,4 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Wthinnest,red,. -Xa${xpos}i -Ya${ypos}i >> $PS + gmt psxy $$.raw -i2,4 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Sc0.04i -Gred -Xa${xpos}i -Ya${ypos}i >> $PS + # Plot the trough model as thin solid green3 line + gmt psxy $$.raw -i2,7 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -B0 -Bsn -O -K -Wthin,green3 -Xa${xpos}i -Ya${ypos}i --MAP_FRAME_PEN=faint >> $PS + # Plot the blend model as thin blue line + gmt psxy $$.raw -i2,8 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Wthin,blue -Xa${xpos}i -Ya${ypos}i >> $PS + if [ $got_age -eq 1 ]; then + # Plot the crustal ages as thin dashed orange line + gmt psxy $$.raw -i2,5 -R$dmin/$dmax/$amin/$amax -JX${W}i/${H}i -O -K -Wthin,orange,- -Xa${xpos}i -Ya${ypos}i >> $PS + fi + # Place width error-bar and trough symbol for the blend model + echo $OB $VB $WB2 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Ex/thin,blue -Gblue -Wthinnest -Si0.075i -Xa${xpos}i -Ya${ypos}i >> $PS + # Place width error-bar and trough symbol for the trough model + echo $OT $VT $WT2 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Ex/thin,green3 -Wthinnest -Si0.075i -Ggreen3 -Xa${xpos}i -Ya${ypos}i >> $PS + # Place width error-bar and max-slope (edge) symbol for the blend model + echo $OE 0.0 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Wthinnest -Sc0.075i -Gblue -Xa${xpos}i -Ya${ypos}i >> $PS + if [ "$WD" = "NaN" ] || [ "$WD" = "nan" ]; then # Cannot do it + echo "WD is NaN - skipped" >&2 + else + WD2=`gmt math -Q $WD 0.5 MUL =` # Compute half-width + echo $OD $VD $WD2 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Ex/thin,red -Wthinnest -Si0.075i -Gred -Xa${xpos}i -Ya${ypos}i >> $PS + fi + # Place profile ID in upper-left corner of panel + echo "$dmin $vmax LT $P" | gmt pstext -R$dmin/$dmax/$vmin/$vmax -J -O -K -Dj0.05i/0.05i -C0.01i/0.01i -F+f7p,Helvetica,white+a0+j -Gblack -To -W0.5p -Xa${xpos}i -Ya${ypos}i >> $PS + # Write blend value in upper-right corner of panel + echo "$dmax $vmax RT @;green3;u@-t@- = ${UT}@;; @;blue;u@-b@- = $UB m = ${mb}@;;" | gmt pstext -R -J -O -K -Dj0.05i/0.05i -F+f7p,Helvetica+a0+j -Xa${xpos}i -Ya${ypos}i >> $PS + # Write the W-E or S-N labels on left/right side of the top of the panel + echo "$dmin $vmax LT $L" | gmt pstext -R -J -O -K -Dj0.05i/0.2i -F+f12p,Helvetica-Bold+a0+j -Xa${xpos}i -Ya${ypos}i >> $PS + echo "$dmax $vmax RT $R" | gmt pstext -R -J -O -K -Dj0.05i/0.2i -F+f12p,Helvetica-Bold+a0+j -Xa${xpos}i -Ya${ypos}i >> $PS + # Draw $vinc Eotvos scale bar to the left of the panel + gmt psxy -R -J -O -K -W2p,red -Xa${xposL}i -Ya${ypos}i <<- EOF >> $PS + $dmin -${vinc2} + $dmin ${vinc2} + EOF + # Label the VGG scale bar with "$vinc" + echo $dmin 0 $vinc | gmt pstext -R -J -O -K -F+f6p,Helvetica+a0+jCM -C0.01i/0.01i -Gwhite -To -W0.5p -N -Xa${xposL}i -Ya${ypos}i >> $PS + if [ $got_age -eq 1 ]; then + # Draw 10 Myr scale bar to the right of the panel + gmt psxy -R$dmin/$dmax/$amin/$amax -J -O -K -W2p,orange -Xa${xposR}i -Ya${ypos}i <<- EOF >> $PS + $dmax $am1 + $dmax $am2 + EOF + # Label the age scale bar with "10" + echo $dmax $am 10 | gmt pstext -R -J -O -K -F+f6p,Helvetica+a0+jCM -C0.01i/0.01i -Gwhite -To -W0.5p -N -Xa${xposR}i -Ya${ypos}i >> $PS + fi + if [ $single -eq 1 ]; then # Set P to last profile so the loop will exit immediately + P=$n_cross + else # March on to the next profile + let P=P+inc + fi +done +# Finalize plot by drawing the d = 0 line for the last panel +gmt psbasemap -R$dmin/$dmax/0/$height -JX${W}i/${height}i -O -Bx0g1000 -By0 -Xa${xpos}i -Ya${ymargin}i >> $PS +# Convert the PS to a PDF file +gmt psconvert -Tf $PS +os=`uname -s` +if [ $verbose -eq 1 ]; then + echo "fzprofiler: Final plot is called $PDF" >&2 +fi +if [ $os = "Darwin" ]; then + open $PDF +fi + +rm -f $PS +fz_cleanup 1 diff --git a/src/gsfml/gsfml_config.h.in b/src/gsfml/gsfml_config.h.in new file mode 100644 index 00000000000..435642829cd --- /dev/null +++ b/src/gsfml/gsfml_config.h.in @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2015-2023 by P. Wessel + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: http://www.soest.hawaii.edu/PT/GSFML + *-------------------------------------------------------------------- + */ + +#pragma once +#ifndef _GSFML_CONFIG_H +#define _GSFML_CONFIG_H +#define GSFML_PACKAGE_VERSION "@GSFML_PACKAGE_VERSION@" +#endif /* !_GSFML_CONFIG_H */ diff --git a/src/gsfml/gsfml_glue.c b/src/gsfml/gsfml_glue.c new file mode 100644 index 00000000000..4bfe8716c4d --- /dev/null +++ b/src/gsfml/gsfml_glue.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012-2022 by the GMT Team (https://www.generic-mapping-tools.org/team.html) + * See LICENSE.TXT file for copying and redistribution conditions. + */ +/* gmt_gsfml_glue.c populates the external array of this shared lib with + * module parameters such as name, group, purpose and keys strings. + * This file also contains the following convenience functions to + * display all module purposes, list their names, or return keys or group: + * + * int gsfml_module_show_all (void *API); + * int gsfml_module_list_all (void *API); + * int gsfml_module_classic_all (void *API); + * + * These functions may be called by gmt --help and gmt --show-modules + * + * Developers of external APIs for accessing GMT modules will use this + * function indirectly via GMT_Encode_Options to retrieve option keys + * needed for module arg processing: + * + * const char * gsfml_module_keys (void *API, char *candidate); + * const char * gsfml_module_group (void *API, char *candidate); + * + * All functions are exported by the shared gsfml library so that gmt can call these + * functions by name to learn about the contents of the library. + */ + +#include "gmt_dev.h" + +/* Sorted array with information for all GMT gsfml modules */ +static struct GMT_MODULEINFO modules[] = { + {"fzanalyzer", "fzanalyzer", "gsfml", "Analysis of fracture zones using crossing profiles", "DO"}, + {"fzblender", "fzblender", "gsfml", "Produce a smooth blended FZ trace", "DO"}, + {"mlconverter", "mlconverter", "gsfml", "Convert chrons to ages using selected magnetic timescale", "DO"}, + {NULL, NULL, NULL, NULL, NULL} /* last element == NULL detects end of array */ +}; + +/* Pretty print all shared module names and their purposes for gmt --help */ +EXTERN_MSC int gsfml_module_show_all (void *API) { + return (GMT_Show_ModuleInfo (API, modules, "GMT supplemental modules for GSFML", GMT_MODULE_HELP)); +} + +/* Produce single list on stdout of all shared module names for gmt --show-modules */ +EXTERN_MSC int gsfml_module_list_all (void *API) { + return (GMT_Show_ModuleInfo (API, modules, NULL, GMT_MODULE_SHOW_MODERN)); +} + +/* Produce single list on stdout of all shared module names for gmt --show-classic [i.e., classic mode names] */ +EXTERN_MSC int gsfml_module_classic_all (void *API) { + return (GMT_Show_ModuleInfo (API, modules, NULL, GMT_MODULE_SHOW_CLASSIC)); +} + +/* Lookup module id by name, return option keys pointer (for external API developers) */ +EXTERN_MSC const char *gsfml_module_keys (void *API, char *candidate) { + return (GMT_Get_ModuleInfo (API, modules, candidate, GMT_MODULE_KEYS)); +} + +/* Lookup module id by name, return group char name (for external API developers) */ +EXTERN_MSC const char *gsfml_module_group (void *API, char *candidate) { + return (GMT_Get_ModuleInfo (API, modules, candidate, GMT_MODULE_GROUP)); +} diff --git a/src/gsfml/mlconverter.c b/src/gsfml/mlconverter.c new file mode 100644 index 00000000000..ed71babbcb9 --- /dev/null +++ b/src/gsfml/mlconverter.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2015-2023 by P. Wessel + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: http://www.soest.hawaii.edu/PT/GSFML + *-------------------------------------------------------------------- + * + * mlconverter converts chron strings and anomaly end (y|o) to age using + * a magnetic timescale. The input files must be the OGT/GMT-formatted + * ML_*.gmt files distributed by the GSFML project. + * + * Author: Paul Wessel + * Date: 01-DEC-2023 (Requires GMT >= 6) + */ + +#define THIS_MODULE_NAME "mlconverter" +#define THIS_MODULE_LIB "gsfml" +#define THIS_MODULE_PURPOSE "Convert chrons to ages using selected magnetic timescale" +#define THIS_MODULE_LIB_PURPOSE "GMT supplemental modules for GSFML" +#define THIS_MODULE_KEYS "DO" +#define THIS_MODULE_NEEDS "" +#define THIS_MODULE_OPTIONS "-:>RVabfghior" + +#include "gmt_dev.h" +#include "fz_analysis.h" + +#define ML_GEEK2007 0 +#define ML_CK1995 1 +#define ML_GST2004 2 +#define ML_GST2012 3 + +#define ML_NORMAL 0 +#define ML_REVERSE 1 +#define ML_YOUNG 0 +#define ML_OLD 1 + +struct MLCONVERTER_CTRL { + struct A { /* -A */ + bool active; + } A; + struct G { /* -G */ + bool active; + unsigned int mode; + } G; + struct S { /* -S */ + bool active; + } S; + struct T { /* -T[g|c|s] */ + bool active; + unsigned int mode; + } T; +}; + +EXTERN_MSC int gmtlib_append_ogr_item (struct GMT_CTRL *GMT, char *name, unsigned int type, struct GMT_OGR *S); +EXTERN_MSC void gmtlib_write_ogr_header (FILE *fp, struct GMT_OGR *G); + +static void *New_Ctrl (struct GMT_CTRL *GMT) { /* Allocate and initialize a new control structure */ + struct MLCONVERTER_CTRL *C; + + C = gmt_M_memory (GMT, NULL, 1, struct MLCONVERTER_CTRL); + + /* Initialize values whose defaults are not 0/false/NULL */ + return (C); +} + +static void Free_Ctrl (struct GMT_CTRL *GMT, struct MLCONVERTER_CTRL *C) { /* Deallocate control structure */ + if (!C) return; + gmt_M_free (GMT, C); +} + +static int usage (struct GMTAPI_CTRL *API, int level) +{ + const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_NAME, THIS_MODULE_PURPOSE); + if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); + GMT_Usage (API, 0, "usage: %s [] [-A] [-G[s]] [-S] [-Tc|g|o|s] [%s]\n", name, GMT_V_OPT); + + if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS); + + GMT_Message (API, GMT_TIME_NONE, " OPTIONAL ARGUMENTS:\n"); + + GMT_Usage (API, 1, "\n-A Append metadata to data record as extra columns [Only write lon lat age]."); + GMT_Usage (API, 1, "\n-G Generate an extended OGR/GMT table by appending the crustal age. " + "Append s to repair any lax chron nomenclature, if needed."); + GMT_Usage (API, 1, "\n-S Strict chron nomenclature expected; report any lax use [do the best we can]"); + GMT_Usage (API, 1, "\n-Tc|g|o|s]"); + GMT_Usage (API, -2, "Select a magnetic time scale:"); + GMT_Usage (API, 3, "c: Cande and Kent, 1995."); + GMT_Usage (API, 3, "g: Gee and Kent, 2007 [Default]."); + GMT_Usage (API, 3, "o: Ogg, 2012."); + GMT_Usage (API, 3, "s: Gradstein, 2004."); + GMT_Option (API, "V,."); + + return (GMT_MODULE_USAGE); +} + +static int parse (struct GMTAPI_CTRL *API, struct MLCONVERTER_CTRL *Ctrl, struct GMT_OPTION *options) { + + /* This parses the options provided to grdsample and sets parameters in CTRL. + * Any GMT common options will override values set previously by other commands. + * It also replaces any file names specified as input or output with the data ID + * returned when registering these sources/destinations with the API. + */ + + unsigned int n_files = 0, n_errors = 0; + struct GMT_OPTION *opt = NULL; + + for (opt = options; opt; opt = opt->next) { + switch (opt->option) { + + case '<': /* Skip input files */ + n_files++; + break; + + /* Processes program-specific parameters */ + + case 'A': + n_errors += gmt_M_repeated_module_option (API, Ctrl->A.active); + break; + case 'G': + n_errors += gmt_M_repeated_module_option (API, Ctrl->G.active); + if (opt->arg[0] == 's') Ctrl->G.mode = 1; + break; + case 'S': + n_errors += gmt_M_repeated_module_option (API, Ctrl->S.active); + break; + case 'T': + n_errors += gmt_M_repeated_module_option (API, Ctrl->T.active); + switch (opt->arg[0]) { + case 'c': Ctrl->T.mode = ML_CK1995; break; + case 'g': Ctrl->T.mode = ML_GEEK2007; break; + case 'o': Ctrl->T.mode = ML_GST2012; break; + case 's': Ctrl->T.mode = ML_GST2004; break; + default: + GMT_Message (API, GMT_TIME_NONE, "Error: Not a valid time scale for option -T [%c].\n", (int)opt->arg[0]); + n_errors++; + break; + } + break; + + default: /* Report bad options */ + n_errors += gmt_default_error (API->GMT, opt->option); + break; + } + } + + n_errors += gmt_M_check_condition (API->GMT, Ctrl->A.active && Ctrl->G.active, "GMT SYNTAX ERROR: Cannot use both -A and -G.\n"); + return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR); +} + +#define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); return (code);} + +struct ML_CHRON { /* Holds chron and young/old ages */ + double young, old; +}; + +static int ML_lookup (char *chron, char *names[]) +{ + int k = 0; + while (names[k] && strcmp (chron, names[k])) k++; + return (names[k] ? k : -1); +} + +int GMT_mlconverter (void *V_API, int mode, void *args) { + int k, j, n_read = 0, side, polarity, error, n_lax = 0, n_bad = 0; + bool first = true; + + double age, *in = NULL; + + EXTERN_MSC void gmt_str_toupper (char *string); + char record[GMT_BUFSIZ], chron[16], c, **Cname[2] = {NULL, NULL}, **Cname2[2] = {NULL, NULL}; + static char *Chron_Normal[] = { +#include "Chron_Normal.h" + }; + static char *Chron_Reverse[] = { +#include "Chron_Reverse.h" + }; + static char *Chron_Normal2[] = { +#include "Chron_Normal2.h" + }; + static char *Chron_Reverse2[] = { +#include "Chron_Reverse2.h" + }; + static struct ML_CHRON Geek2007n[] = { +#include "Geek2007n.h" + }; + static struct ML_CHRON Geek2007r[] = { +#include "Geek2007r.h" + }; + static struct ML_CHRON CK1995n[] = { +#include "CK1995n.h" + }; + static struct ML_CHRON CK1995r[] = { +#include "CK1995r.h" + }; + static struct ML_CHRON GST2004n[] = { +#include "GST2004n.h" + }; + static struct ML_CHRON GST2004r[] = { +#include "GST2004r.h" + }; + static struct ML_CHRON GST2012n[] = { +#include "GST2012n.h" + }; + static struct ML_CHRON GST2012r[] = { +#include "GST2012r.h" + }; + struct ML_CHRON *M[2] = {NULL, NULL}; + struct GMT_RECORD *In = NULL, *Out = NULL; + struct MLCONVERTER_CTRL *Ctrl = NULL; + struct GMT_OPTION *options = NULL; + struct GMT_CTRL *GMT = NULL, *GMT_cpy = NULL; + struct GMTAPI_CTRL *API = gmt_get_api_ptr (V_API); /* Cast from void to GMTAPI_CTRL pointer */ + + /*----------------------- Standard module initialization and parsing ----------------------*/ + + if (API == NULL) return (GMT_NOT_A_SESSION); + if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */ + options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */ + + if (!options || options->option == GMT_OPT_USAGE) return (usage (API, GMT_USAGE)); /* Return the usage message */ + if (options->option == GMT_OPT_SYNOPSIS) return (usage (API, GMT_SYNOPSIS)); /* Return the synopsis */ + + /* Parse the program-specific arguments */ + + GMT = gmt_begin_module (API, THIS_MODULE_LIB, THIS_MODULE_NAME, &GMT_cpy); /* Save current state */ + if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error); + Ctrl = New_Ctrl (GMT); /* Allocate and initialize a new control structure */ + if ((error = parse (API, Ctrl, options))) Return (error); + + /*---------------------------- This is the mlconverter main code ----------------------------*/ + + switch (Ctrl->T.mode) { /* Set pointer to selected timescale young/old tables */ + case ML_GEEK2007: + M[ML_NORMAL] = Geek2007n; + M[ML_REVERSE] = Geek2007r; + break; + case ML_CK1995: + M[ML_NORMAL] = CK1995n; + M[ML_REVERSE] = CK1995r; + break; + case ML_GST2004: + M[ML_NORMAL] = GST2004n; + M[ML_REVERSE] = GST2004r; + break; + case ML_GST2012: + M[ML_NORMAL] = GST2012n; + M[ML_REVERSE] = GST2012r; + break; + } + Cname[ML_NORMAL] = Chron_Normal; /* Set pointer to the two timescale chron with strict names */ + Cname[ML_REVERSE] = Chron_Reverse; + Cname2[ML_NORMAL] = Chron_Normal2; /* Set pointer to the two timescale chron with uppercase/no period/hyphen names */ + Cname2[ML_REVERSE] = Chron_Reverse2; + + GMT->current.setting.io_header[GMT_OUT] = true; /* To allow writing of headers */ + Out = gmt_new_record (GMT, NULL, record); + + /* We know which columns are geographical */ + GMT->current.io.col_type[GMT_IN][GMT_X] = GMT->current.io.col_type[GMT_OUT][GMT_X] = GMT_IS_LON; + GMT->current.io.col_type[GMT_IN][GMT_Y] = GMT->current.io.col_type[GMT_OUT][GMT_Y] = GMT_IS_LAT; + + if ((error = GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, GMT_ADD_DEFAULT, 0, options))) Return (error); /* Register data input */ + if ((error = GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_TEXT, GMT_OUT, GMT_ADD_DEFAULT, 0, options))) Return (error); /* Establishes data output */ + if ((error = GMT_Begin_IO (API, GMT_IS_DATASET, GMT_IN, GMT_HEADER_ON))) Return (error); /* Enables data input and sets access mode */ + if ((error = GMT_Begin_IO (API, GMT_IS_DATASET, GMT_OUT, GMT_HEADER_ON))) Return (error); /* Enables data output and sets access mode */ + if ((error = GMT_Set_Columns (API, GMT_OUT, 0, GMT_COL_FIX)) != GMT_NOERROR) Return (error); /* Only text records here */ + + do { /* Keep returning records until we reach EOF */ + if ((In = GMT_Get_Record (API, GMT_READ_DATA, NULL)) == NULL) { /* Read next record, get NULL if special case */ + if (gmt_M_rec_is_error (GMT)) /* Bail if there are any read errors */ + Return (GMT_RUNTIME_ERROR); + if (gmt_M_rec_is_any_header (GMT)) /* Skip all headers */ + continue; + if (gmt_M_rec_is_eof (GMT)) /* Reached end of file */ + break; + } + + /* Data record to process */ + + n_read++; + in = In->data; + + if (Ctrl->G.active && first) { /* Write out new OGR file based on the metadata and just echo the data record */ + gmtlib_append_ogr_item (GMT, "AnomalyAge", GMT_DOUBLE, GMT->current.io.OGR); + gmtlib_write_ogr_header (API->object[API->current_item[GMT_OUT]]->fp, GMT->current.io.OGR); + first = false; + } + + /* Here we have a data record and the OGR has been parsed */ + + c = GMT->current.io.OGR->tvalue[1][0]; + side = (c == 'y' || c == 'Y') ? ML_YOUNG : ML_OLD; + c = GMT->current.io.OGR->tvalue[0][strlen(GMT->current.io.OGR->tvalue[0])-1]; + polarity = (c == 'n' || c == 'N') ? ML_NORMAL : ML_REVERSE; + strcpy (chron, GMT->current.io.OGR->tvalue[0]); + k = ML_lookup (chron, Cname[polarity]); /* Try exact name standard */ + if (k == -1) { /* Did not find this. Try again without any dots or hyphens */ + k = j = 0; while ((c = GMT->current.io.OGR->tvalue[0][k++])) if (!(c == '.' || c == '-')) chron[j++] = c; + chron[j] = 0; + gmt_str_toupper (chron); + k = ML_lookup (chron, Cname2[polarity]); /* Try lax standard */ + if (k >= 0) { /* Report the problem */ + strcpy (chron, Cname[polarity][k]); + if (Ctrl->S.active) { /* Refuse to convert a lax chron */ + GMT_Report (API, GMT_MSG_NORMAL, "File has lax chron %s but standard says %s\n", GMT->current.io.OGR->tvalue[0], Cname[polarity][k]); + k = -1; + } + n_lax++; + } + } + if (k == -1) { /* Did not find this either */ + age = -1.0; + n_bad++; + strcpy (chron, GMT->current.io.OGR->tvalue[0]); + } + else { + age = (side == ML_YOUNG) ? M[polarity][k].young : M[polarity][k].old; + } + if (age < 0.0) age = GMT->session.d_NaN; + + if (Ctrl->G.active) { /* Write out a new OGR record based on the metadata and just echo the data record */ + record[0] = 0; /* Clean muzzle */ + strcat (record, "# @D"); /* OGR metadata record */ + record[0] = '#'; record[1] = ' '; record[2] = 0; /* Start a comment */ + strcat (record, (Ctrl->G.mode) ? chron : GMT->current.io.OGR->tvalue[0]); + for (k = 1; k < 6; k++) { + strcat (record, "|"); + strcat (record, GMT->current.io.OGR->tvalue[k]); + } + strcat (record, "|"); + gmt_add_to_record (GMT, record, age, GMT_Z, GMT_OUT, 0); /* Format our output age value */ + GMT_Put_Record (API, GMT_WRITE_TABLE_HEADER, record); /* Write this to output */ + GMT_Put_Record (API, GMT_WRITE_DATA, Out); /* Write this to output */ + } + else { + record[0] = 0; /* Clean muzzle */ + gmt_add_to_record (GMT, record, in[GMT_X], GMT_X, GMT_OUT, 2); /* Format our longitude */ + gmt_add_to_record (GMT, record, in[GMT_Y], GMT_Y, GMT_OUT, 2); /* Format our latitude */ + gmt_add_to_record (GMT, record, age, GMT_Z, GMT_OUT, 0); /* Format our output age value */ + if (Ctrl->A.active) {/* Append record */ + for (k = 0; k < 6; k++) { + strcat (record, GMT->current.setting.io_col_separator); + strcat (record, GMT->current.io.OGR->tvalue[k]); + } + } + GMT_Put_Record (API, GMT_WRITE_TEXT, Out); /* Write this to output */ + } + } while (true); + + gmt_M_free (GMT, Out); + + if ((error = GMT_End_IO (API, GMT_IN, 0))) Return (error); /* Disables further data input */ + if ((error = GMT_End_IO (API, GMT_OUT, 0))) Return (error); /* Disables further data input */ + + GMT_Report (API, GMT_MSG_NORMAL, "Encountered a total of %ld chrons\n", n_read); + if (n_bad) GMT_Report (API, GMT_MSG_NORMAL, "Encountered %ld chrons that could not be converted to age with current timescale\n", n_bad); + if (n_lax) GMT_Report (API, GMT_MSG_NORMAL, "Encountered %ld chrons that failed to conform to strict chron nomenclature\n", n_lax); + + Return (GMT_NOERROR); +} From 707493de760b4ba9206a2aa3355094fed5791fde Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 14:57:11 +0100 Subject: [PATCH 02/20] Update a bit --- src/gsfml/CMakeLists.txt | 2 +- src/gsfml/fzanalyzer.c | 9 +++++---- src/gsfml/fzblender.c | 9 +++++---- src/gsfml/mlconverter.c | 10 ++++++---- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/gsfml/CMakeLists.txt b/src/gsfml/CMakeLists.txt index 906410b943a..11ac64c3624 100644 --- a/src/gsfml/CMakeLists.txt +++ b/src/gsfml/CMakeLists.txt @@ -26,7 +26,7 @@ set (SUPPL_NAME gsfml) set (SUPPL_HEADERS CK1995n.h Chron_Normal.h Chron_Reverse.h GST2004n.h GST2012n.h Geek2007n.h - CK1995r.h Chron_Normal2.h Chron_Reverse2.h GST2004r.h GST2012r.h Geek2007r.h) + CK1995r.h Chron_Normal2.h Chron_Reverse2.h GST2004r.h GST2012r.h Geek2007r.h fz_analysis.h) AUX_SOURCE_DIRECTORY (longopt SUPPL_LONG_OPT_H) set (SUPPL_PROGS_SRCS fzanalyzer.c fzblender.c mlconverter.c) diff --git a/src/gsfml/fzanalyzer.c b/src/gsfml/fzanalyzer.c index 98cfef4589f..6fba5c7e8b8 100644 --- a/src/gsfml/fzanalyzer.c +++ b/src/gsfml/fzanalyzer.c @@ -20,10 +20,10 @@ * Date: 01-DEC-2023 (Requires GMT >= 6) */ -#define THIS_MODULE_NAME "fzanalyzer" +#define THIS_MODULE_CLASSIC_NAME "fzanalyzer" +#define THIS_MODULE_MODERN_NAME "fzanalyzer" #define THIS_MODULE_LIB "gsfml" #define THIS_MODULE_PURPOSE "Analysis of fracture zones using crossing profiles" -#define THIS_MODULE_LIB_PURPOSE "GMT supplemental modules for GSFML" #define THIS_MODULE_KEYS "DO" #define THIS_MODULE_NEEDS "" #define THIS_MODULE_OPTIONS "-Vb:hios>" @@ -690,7 +690,7 @@ EXTERN_MSC int GMT_fzanalyzer (void *V_API, int mode, void *args) { uint64_t n_FZ_widths, n_FZ_asym, n_FZ_comp, np_cross, n_half_cross, ii; uint64_t fz, ku, row, col, xseg; - char buffer[BUFSIZ], run_cmd[BUFSIZ], add[BUFSIZ], *cmd = NULL, *file = NULL; + char buffer[BUFSIZ] = {""}, run_cmd[BUFSIZ] = {""}, add[BUFSIZ] = {""}, *cmd = NULL, *file = NULL; double fz_inc, corridor_half_width, cross_length, threshold, results[N_RESULTS], best_loc[4]; double *FZ_width = NULL, *FZ_asym = NULL, *FZ_comp = NULL, ages[2], *comp[N_SHAPES]; @@ -716,7 +716,8 @@ EXTERN_MSC int GMT_fzanalyzer (void *V_API, int mode, void *args) { /* Parse the program-specific arguments */ - GMT = gmt_begin_module (API, THIS_MODULE_LIB, THIS_MODULE_NAME, &GMT_cpy); /* Save current state */ + if ((GMT = gmt_init_module (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_KEYS, THIS_MODULE_NEEDS, module_kw, &options, &GMT_cpy)) == NULL) + bailout (API->error); /* Save current state */ if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error); Ctrl = New_Ctrl (GMT); /* Allocate and initialize a new control structure */ if ((error = parse (API, Ctrl, options))) Return (error); diff --git a/src/gsfml/fzblender.c b/src/gsfml/fzblender.c index 80e39e29f0d..dee5c814819 100644 --- a/src/gsfml/fzblender.c +++ b/src/gsfml/fzblender.c @@ -20,10 +20,10 @@ * Date: 01-DEC-2023 (Requires GMT >= 6) */ -#define THIS_MODULE_NAME "fzblender" +#define THIS_MODULE_CLASSIC_NAME "fzblender" +#define THIS_MODULE_MODERN_NAME "fzblender" #define THIS_MODULE_LIB "gsfml" #define THIS_MODULE_PURPOSE "Produce a smooth blended FZ trace" -#define THIS_MODULE_LIB_PURPOSE "GMT supplemental modules for GSFML" #define THIS_MODULE_KEYS "DO" #define THIS_MODULE_NEEDS "" #define THIS_MODULE_OPTIONS "-Vh>" @@ -376,7 +376,7 @@ EXTERN_MSC int GMT_fzblender (void *V_API, int mode, void *args) { }; int tcols[N_TCOLS] = {POS_XR, POS_YR, POS_XB0, POS_YB0, POS_SB, POS_WB, POS_XBL, POS_YBL, POS_XBR, POS_YBR}; - char buffer[BUFSIZ], run_cmd[BUFSIZ], *cmd = NULL; + char buffer[BUFSIZ] = {""}, run_cmd[BUFSIZ] = {""}, *cmd = NULL; char source[GMT_VF_LEN] = {""}, destination[GMT_VF_LEN] = {""}; double Q[N_BLENDS], P[N_BLENDS], q_weight[N_BLENDS], sum_P, sum_w, sum_q, i_q_range, q_model; @@ -400,7 +400,8 @@ EXTERN_MSC int GMT_fzblender (void *V_API, int mode, void *args) { /* Parse the program-specific arguments */ - GMT = gmt_begin_module (API, THIS_MODULE_LIB, THIS_MODULE_NAME, &GMT_cpy); /* Save current state */ + if ((GMT = gmt_init_module (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_KEYS, THIS_MODULE_NEEDS, module_kw, &options, &GMT_cpy)) == NULL) + bailout (API->error); /* Save current state */ if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error); Ctrl = New_Ctrl (GMT); /* Allocate and initialize a new control structure */ if ((error = parse (API, Ctrl, options))) Return (error); diff --git a/src/gsfml/mlconverter.c b/src/gsfml/mlconverter.c index ed71babbcb9..63785d7f6ef 100644 --- a/src/gsfml/mlconverter.c +++ b/src/gsfml/mlconverter.c @@ -22,10 +22,10 @@ * Date: 01-DEC-2023 (Requires GMT >= 6) */ -#define THIS_MODULE_NAME "mlconverter" +#define THIS_MODULE_CLASSIC_NAME "mlconverter" +#define THIS_MODULE_MODERN_NAME "mlconverter" #define THIS_MODULE_LIB "gsfml" #define THIS_MODULE_PURPOSE "Convert chrons to ages using selected magnetic timescale" -#define THIS_MODULE_LIB_PURPOSE "GMT supplemental modules for GSFML" #define THIS_MODULE_KEYS "DO" #define THIS_MODULE_NEEDS "" #define THIS_MODULE_OPTIONS "-:>RVabfghior" @@ -156,6 +156,7 @@ static int parse (struct GMTAPI_CTRL *API, struct MLCONVERTER_CTRL *Ctrl, struct return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR); } +#define bailout(code) {gmt_M_free_options (mode); return (code);} #define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); return (code);} struct ML_CHRON { /* Holds chron and young/old ages */ @@ -176,7 +177,7 @@ int GMT_mlconverter (void *V_API, int mode, void *args) { double age, *in = NULL; EXTERN_MSC void gmt_str_toupper (char *string); - char record[GMT_BUFSIZ], chron[16], c, **Cname[2] = {NULL, NULL}, **Cname2[2] = {NULL, NULL}; + char record[GMT_BUFSIZ] = {""}, chron[16] = {""}, c, **Cname[2] = {NULL, NULL}, **Cname2[2] = {NULL, NULL}; static char *Chron_Normal[] = { #include "Chron_Normal.h" }; @@ -231,7 +232,8 @@ int GMT_mlconverter (void *V_API, int mode, void *args) { /* Parse the program-specific arguments */ - GMT = gmt_begin_module (API, THIS_MODULE_LIB, THIS_MODULE_NAME, &GMT_cpy); /* Save current state */ + if ((GMT = gmt_init_module (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_KEYS, THIS_MODULE_NEEDS, module_kw, &options, &GMT_cpy)) == NULL) + bailout (API->error); /* Save current state */ if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error); Ctrl = New_Ctrl (GMT); /* Allocate and initialize a new control structure */ if ((error = parse (API, Ctrl, options))) Return (error); From d2256d211ed63360e1db19715f24393ccb0efd77 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 15:19:22 +0100 Subject: [PATCH 03/20] Update CMakeLists.txt --- src/gsfml/CMakeLists.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/gsfml/CMakeLists.txt b/src/gsfml/CMakeLists.txt index 11ac64c3624..a2649d592d2 100644 --- a/src/gsfml/CMakeLists.txt +++ b/src/gsfml/CMakeLists.txt @@ -32,4 +32,23 @@ AUX_SOURCE_DIRECTORY (longopt SUPPL_LONG_OPT_H) set (SUPPL_PROGS_SRCS fzanalyzer.c fzblender.c mlconverter.c) set (SUPPL_EXAMPLE_FILES README.gsfml) -set (SUPPL_EXAMPLE_PROGS fz_funcs.sh fzinformer fzmapper fzmodeler fzprofiler) +install (PROGRAMS fz_funcs.sh + RENAME fz_funcs${GMT_INSTALL_NAME_SUFFIX}.sh + DESTINATION ${GMT_BINDIR} + COMPONENT Runtime) +install (PROGRAMS fzinformer + RENAME fz_funcs${GMT_INSTALL_NAME_SUFFIX} + DESTINATION ${GMT_BINDIR} + COMPONENT Runtime) +install (PROGRAMS fzmapper + RENAME fz_funcs${GMT_INSTALL_NAME_SUFFIX} + DESTINATION ${GMT_BINDIR} + COMPONENT Runtime) +install (PROGRAMS fzmodeler + RENAME fzmodeler${GMT_INSTALL_NAME_SUFFIX} + DESTINATION ${GMT_BINDIR} + COMPONENT Runtime) +install (PROGRAMS fzprofiler + RENAME fzprofiler${GMT_INSTALL_NAME_SUFFIX} + DESTINATION ${GMT_BINDIR} + COMPONENT Runtime) From 20a15c3a869df217d06cd3d119cb45b03bd2ff10 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 15:32:55 +0100 Subject: [PATCH 04/20] Add longopt dir with files Unfilled *_inc.h files --- src/gsfml/CMakeLists.txt | 3 +- src/gsfml/fzblender.c | 8 ++--- src/gsfml/longopt/fzanalyzer_inc.h | 53 +++++++++++++++++++++++++++++ src/gsfml/longopt/fzblender_inc.h | 53 +++++++++++++++++++++++++++++ src/gsfml/longopt/mlconverter_inc.h | 41 ++++++++++++++++++++++ 5 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 src/gsfml/longopt/fzanalyzer_inc.h create mode 100644 src/gsfml/longopt/fzblender_inc.h create mode 100644 src/gsfml/longopt/mlconverter_inc.h diff --git a/src/gsfml/CMakeLists.txt b/src/gsfml/CMakeLists.txt index a2649d592d2..4768be26ac1 100644 --- a/src/gsfml/CMakeLists.txt +++ b/src/gsfml/CMakeLists.txt @@ -29,7 +29,8 @@ set (SUPPL_HEADERS CK1995n.h Chron_Normal.h Chron_Reverse.h GST2004n.h GST2012 CK1995r.h Chron_Normal2.h Chron_Reverse2.h GST2004r.h GST2012r.h Geek2007r.h fz_analysis.h) AUX_SOURCE_DIRECTORY (longopt SUPPL_LONG_OPT_H) -set (SUPPL_PROGS_SRCS fzanalyzer.c fzblender.c mlconverter.c) +set (SUPPL_PROGS_SRCS fzanalyzer.c fzblender.c mlconverter.c ${SUPPL_LONG_OPT_H}) +set (SUPPL_LIB_SRCS ${SUPPL_PROGS_SRCS}) set (SUPPL_EXAMPLE_FILES README.gsfml) install (PROGRAMS fz_funcs.sh diff --git a/src/gsfml/fzblender.c b/src/gsfml/fzblender.c index dee5c814819..fafb4e7cfba 100644 --- a/src/gsfml/fzblender.c +++ b/src/gsfml/fzblender.c @@ -63,10 +63,6 @@ struct FZBLENDER_CTRL { bool active; char *file; } In; - struct I { /* -I */ - bool active; - int profile; - } I; struct D { /* -D */ bool active; char *file; @@ -79,6 +75,10 @@ struct FZBLENDER_CTRL { bool active; char *args; /* Full filter args for filter1d */ } F; + struct I { /* -I */ + bool active; + int profile; + } I; struct Q { /* -Q/ */ bool active; double min, max; diff --git a/src/gsfml/longopt/fzanalyzer_inc.h b/src/gsfml/longopt/fzanalyzer_inc.h new file mode 100644 index 00000000000..6fcfbe224e6 --- /dev/null +++ b/src/gsfml/longopt/fzanalyzer_inc.h @@ -0,0 +1,53 @@ +/*-------------------------------------------------------------------- + * + * Copyright (c) 1991-2023 by the GMT Team (https://www.generic-mapping-tools.org/team.html) + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: www.generic-mapping-tools.org + *--------------------------------------------------------------------*/ + +#ifndef FZANALYZER_INC_H +#define FZANALYZER_INC_H + +/* Translation table from long to short module options, directives and modifiers */ + +static struct GMT_KEYWORD_DICTIONARY module_kw[] = { + /* separator, short_option, long_option, + short_directives, long_directives, + short_modifiers, long_modifiers */ + { 0, 'A', "", + "", "", + "", "" }, + { 0, 'C', "", + "", "", + "", "" }, + { 0, 'D', "", + "", "", + "", "" }, + { 0, 'F', "", + "", "", + "", "" }, + { 0, 'I', "", + "", "", + "", "" }, + { 0, 'S', "", + "", "", + "", "" }, + { 0, 'T', "", + "", "", + "", "" }, + { 0, 'W', "", + "", "", + "", "" }, + { 0, '\0', "", "", "", "", ""} /* End of list marked with empty option and strings */ +}; +#endif /* !FZANALYZER_INC_H */ diff --git a/src/gsfml/longopt/fzblender_inc.h b/src/gsfml/longopt/fzblender_inc.h new file mode 100644 index 00000000000..a8a13f0f762 --- /dev/null +++ b/src/gsfml/longopt/fzblender_inc.h @@ -0,0 +1,53 @@ +/*-------------------------------------------------------------------- + * + * Copyright (c) 1991-2023 by the GMT Team (https://www.generic-mapping-tools.org/team.html) + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: www.generic-mapping-tools.org + *--------------------------------------------------------------------*/ + +#ifndef FZBLENDER_INC_H +#define FZBLENDER_INC_H + +/* Translation table from long to short module options, directives and modifiers */ + +static struct GMT_KEYWORD_DICTIONARY module_kw[] = { + /* separator, short_option, long_option, + short_directives, long_directives, + short_modifiers, long_modifiers */ + { 0, 'D', "", + "", "", + "", "" }, + { 0, 'E', "", + "", "", + "", "" }, + { 0, 'F', "", + "", "", + "", "" }, + { 0, 'I', "", + "", "", + "", "" }, + { 0, 'Q', "", + "", "", + "", "" }, + { 0, 'S', "", + "", "", + "", "" }, + { 0, 'T', "", + "", "", + "", "" }, + { 0, 'Z', "", + "", "", + "", "" }, + { 0, '\0', "", "", "", "", ""} /* End of list marked with empty option and strings */ +}; +#endif /* !FZBLENDER_INC_H */ diff --git a/src/gsfml/longopt/mlconverter_inc.h b/src/gsfml/longopt/mlconverter_inc.h new file mode 100644 index 00000000000..59e2b8dfc51 --- /dev/null +++ b/src/gsfml/longopt/mlconverter_inc.h @@ -0,0 +1,41 @@ +/*-------------------------------------------------------------------- + * + * Copyright (c) 1991-2023 by the GMT Team (https://www.generic-mapping-tools.org/team.html) + * See LICENSE.TXT file for copying and redistribution conditions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3 or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * Contact info: www.generic-mapping-tools.org + *--------------------------------------------------------------------*/ + +#ifndef MLCONVERTER_INC_H +#define MLCONVERTER_INC_H + +/* Translation table from long to short module options, directives and modifiers */ + +static struct GMT_KEYWORD_DICTIONARY module_kw[] = { + /* separator, short_option, long_option, + short_directives, long_directives, + short_modifiers, long_modifiers */ + { 0, 'A', "", + "", "", + "", "" }, + { 0, 'G', "", + "", "", + "", "" }, + { 0, 'S', "", + "", "", + "", "" }, + { 0, 'T', "", + "", "", + "", "" }, + { 0, '\0', "", "", "", "", ""} /* End of list marked with empty option and strings */ +}; +#endif /* !MLCONVERTER_INC_H */ From 4112069820c2ef0dfc000a40586d3f042a0f3652 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 15:35:46 +0100 Subject: [PATCH 05/20] Remove the configure file --- src/gsfml/fz_analysis.h | 2 -- src/gsfml/gsfml_config.h.in | 22 ---------------------- 2 files changed, 24 deletions(-) delete mode 100644 src/gsfml/gsfml_config.h.in diff --git a/src/gsfml/fz_analysis.h b/src/gsfml/fz_analysis.h index 13d48226ab1..f608d8b510e 100644 --- a/src/gsfml/fz_analysis.h +++ b/src/gsfml/fz_analysis.h @@ -23,8 +23,6 @@ #ifndef _FZ_ANALYSIS_H #define _FZ_ANALYSIS_H -#include "gsfml_config.h" - #define DEF_D_WIDTH 25.0 /* Default width of central corridor */ #define DEF_L_MIN 0.0 /* Minimum compression for search */ #define DEF_L_MAX 1.0 /* Maximum compression for search */ diff --git a/src/gsfml/gsfml_config.h.in b/src/gsfml/gsfml_config.h.in deleted file mode 100644 index 435642829cd..00000000000 --- a/src/gsfml/gsfml_config.h.in +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2015-2023 by P. Wessel - * See LICENSE.TXT file for copying and redistribution conditions. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; version 3 or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * Contact info: http://www.soest.hawaii.edu/PT/GSFML - *-------------------------------------------------------------------- - */ - -#pragma once -#ifndef _GSFML_CONFIG_H -#define _GSFML_CONFIG_H -#define GSFML_PACKAGE_VERSION "@GSFML_PACKAGE_VERSION@" -#endif /* !_GSFML_CONFIG_H */ From c2d23abd1263dd4eaa10612583443a603be763a1 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 15:58:25 +0100 Subject: [PATCH 06/20] include the longopt files --- src/gsfml/fzanalyzer.c | 3 ++- src/gsfml/fzblender.c | 3 ++- src/gsfml/mlconverter.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gsfml/fzanalyzer.c b/src/gsfml/fzanalyzer.c index 6fba5c7e8b8..e74fed5f98b 100644 --- a/src/gsfml/fzanalyzer.c +++ b/src/gsfml/fzanalyzer.c @@ -30,6 +30,7 @@ #include "gmt_dev.h" #include "fz_analysis.h" +#include "longopt/fzanalyzer_inc.h" #define DEF_FZ_GAP 5.0 /* Half-width of FZ gap centered on d0 where we ignore ages in fitting a + b(d-d0) + c*H(d-d0) */ @@ -529,7 +530,7 @@ static void Free_Ctrl (struct GMT_CTRL *GMT, struct FZMODELER_CTRL *C) { /* Deal } static int usage (struct GMTAPI_CTRL *API, int level) { - const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_NAME, THIS_MODULE_PURPOSE); + const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE); if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); GMT_Usage (API, 0, "usage: %s -F [-C//] " "[-A//] [-D] [-I[/]] " diff --git a/src/gsfml/fzblender.c b/src/gsfml/fzblender.c index fafb4e7cfba..9294ee9e8b9 100644 --- a/src/gsfml/fzblender.c +++ b/src/gsfml/fzblender.c @@ -30,6 +30,7 @@ #include "gmt_dev.h" #include "fz_analysis.h" +#include "longopt/fzblender_inc.h" #define DEF_Q_MIN 0.0 /* Minimum quality index */ #define DEF_Q_MAX 4.0 /* Maximum quality index */ @@ -134,7 +135,7 @@ static void Free_Ctrl (struct GMT_CTRL *GMT, struct FZBLENDER_CTRL *C) { /* Deal } static int usage (struct GMTAPI_CTRL *API, int level) { - const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_NAME, THIS_MODULE_PURPOSE); + const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE); if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); GMT_Usage (API, 0, "usage: %s [-F] [-D] [-E] [-I] " "[-Q/] [-Sbdetu[]] [-T] [%s] [-Z]\n\n", GMT_V_OPT); diff --git a/src/gsfml/mlconverter.c b/src/gsfml/mlconverter.c index 63785d7f6ef..f79eb9c21eb 100644 --- a/src/gsfml/mlconverter.c +++ b/src/gsfml/mlconverter.c @@ -32,6 +32,7 @@ #include "gmt_dev.h" #include "fz_analysis.h" +#include "longopt/mlconverter_inc.h" #define ML_GEEK2007 0 #define ML_CK1995 1 @@ -79,7 +80,7 @@ static void Free_Ctrl (struct GMT_CTRL *GMT, struct MLCONVERTER_CTRL *C) { /* De static int usage (struct GMTAPI_CTRL *API, int level) { - const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_NAME, THIS_MODULE_PURPOSE); + const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE); if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); GMT_Usage (API, 0, "usage: %s [] [-A] [-G[s]] [-S] [-Tc|g|o|s] [%s]\n", name, GMT_V_OPT); From 22f6e789d6195d18ebdfe2f08ccfa677cf162999 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 17:06:12 +0100 Subject: [PATCH 07/20] All compile and run via gmt --- src/gsfml/fzanalyzer.c | 5 ++--- src/gsfml/fzblender.c | 5 ++--- src/gsfml/mlconverter.c | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/gsfml/fzanalyzer.c b/src/gsfml/fzanalyzer.c index e74fed5f98b..94228a99d73 100644 --- a/src/gsfml/fzanalyzer.c +++ b/src/gsfml/fzanalyzer.c @@ -535,7 +535,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) { GMT_Usage (API, 0, "usage: %s -F [-C//] " "[-A//] [-D] [-I[/]] " "-S[c]] [-T] [%s] [-W//] " - "%s] [%s] [%s]", name, GMT_V_OPT, GMT_colon_OPT, GMT_b_OPT, GMT_i_OPT); + "%s] [%s] [%s]\n", name, GMT_V_OPT, GMT_colon_OPT, GMT_b_OPT, GMT_i_OPT); if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS); @@ -712,8 +712,7 @@ EXTERN_MSC int GMT_fzanalyzer (void *V_API, int mode, void *args) { if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */ options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */ - if (!options || options->option == GMT_OPT_USAGE) bailout (usage (API, GMT_USAGE)); /* Return the usage message */ - if (options->option == GMT_OPT_SYNOPSIS) bailout (usage (API, GMT_SYNOPSIS)); /* Return the synopsis */ + if ((error = gmt_report_usage (API, options, 0, usage)) != GMT_NOERROR) bailout (error); /* Give usage if requested */ /* Parse the program-specific arguments */ diff --git a/src/gsfml/fzblender.c b/src/gsfml/fzblender.c index 9294ee9e8b9..22055b38bbc 100644 --- a/src/gsfml/fzblender.c +++ b/src/gsfml/fzblender.c @@ -138,7 +138,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) { const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE); if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); GMT_Usage (API, 0, "usage: %s [-F] [-D] [-E] [-I] " - "[-Q/] [-Sbdetu[]] [-T] [%s] [-Z]\n\n", GMT_V_OPT); + "[-Q/] [-Sbdetu[]] [-T] [%s] [-Z]\n", name, GMT_V_OPT); if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS); @@ -396,8 +396,7 @@ EXTERN_MSC int GMT_fzblender (void *V_API, int mode, void *args) { if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */ options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */ - if (!options || options->option == GMT_OPT_USAGE) bailout (usage (API, GMT_USAGE)); /* Return the usage message */ - if (options->option == GMT_OPT_SYNOPSIS) bailout (usage (API, GMT_SYNOPSIS)); /* Return the synopsis */ + if ((error = gmt_report_usage (API, options, 0, usage)) != GMT_NOERROR) bailout (error); /* Give usage if requested */ /* Parse the program-specific arguments */ diff --git a/src/gsfml/mlconverter.c b/src/gsfml/mlconverter.c index f79eb9c21eb..9cc342452a2 100644 --- a/src/gsfml/mlconverter.c +++ b/src/gsfml/mlconverter.c @@ -158,7 +158,7 @@ static int parse (struct GMTAPI_CTRL *API, struct MLCONVERTER_CTRL *Ctrl, struct } #define bailout(code) {gmt_M_free_options (mode); return (code);} -#define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); return (code);} +#define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); return (code); bailout(code);} struct ML_CHRON { /* Holds chron and young/old ages */ double young, old; @@ -228,8 +228,7 @@ int GMT_mlconverter (void *V_API, int mode, void *args) { if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */ options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */ - if (!options || options->option == GMT_OPT_USAGE) return (usage (API, GMT_USAGE)); /* Return the usage message */ - if (options->option == GMT_OPT_SYNOPSIS) return (usage (API, GMT_SYNOPSIS)); /* Return the synopsis */ + if ((error = gmt_report_usage (API, options, 0, usage)) != GMT_NOERROR) bailout (error); /* Give usage if requested */ /* Parse the program-specific arguments */ From 4c8eb21c6e3bcd936f1600f5319b57b9e2e6af2d Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 23:22:47 +0100 Subject: [PATCH 08/20] Add rst docs --- .../source/supplements/gsfml/fzanalyzer.rst | 303 ++++++++++++++++++ .../source/supplements/gsfml/fzblender.rst | 221 +++++++++++++ .../source/supplements/gsfml/fzinformer.rst | 155 +++++++++ doc/rst/source/supplements/gsfml/fzmapper.rst | 110 +++++++ .../source/supplements/gsfml/fzmodeler.rst | 121 +++++++ .../source/supplements/gsfml/fzprofiler.rst | 118 +++++++ .../source/supplements/gsfml/mlconverter.rst | 116 +++++++ 7 files changed, 1144 insertions(+) create mode 100644 doc/rst/source/supplements/gsfml/fzanalyzer.rst create mode 100644 doc/rst/source/supplements/gsfml/fzblender.rst create mode 100644 doc/rst/source/supplements/gsfml/fzinformer.rst create mode 100644 doc/rst/source/supplements/gsfml/fzmapper.rst create mode 100644 doc/rst/source/supplements/gsfml/fzmodeler.rst create mode 100644 doc/rst/source/supplements/gsfml/fzprofiler.rst create mode 100644 doc/rst/source/supplements/gsfml/mlconverter.rst diff --git a/doc/rst/source/supplements/gsfml/fzanalyzer.rst b/doc/rst/source/supplements/gsfml/fzanalyzer.rst new file mode 100644 index 00000000000..85aa83c8cef --- /dev/null +++ b/doc/rst/source/supplements/gsfml/fzanalyzer.rst @@ -0,0 +1,303 @@ +.. index:: ! fzanalyzer +.. include:: ../module_supplements_purpose.rst_ + +********** +fzanalyzer +********** + +|fzanalyzer_purpose| + +Synopsis +-------- + +.. include:: ../../common_SYN_OPTs.rst_ + +**gmt fzanalyzer** *crossprofiles* +[ |-A|\ *min*/*max*/*inc* ] +[ |-C|\ *min*/*max*/*inc* ] +[ |-D|\ *corrwidth* ] +[ |-I|\ *FZ*[/*profile*] ] +[ -S[\ **c**]] +[ |-T|\ *prefix* ] +[ |SYN_OPT-V| ] +[ |-W|\ *min*/*max*/*inc* ] +[ |SYN_OPT-bo| ] +[ |SYN_OPT-do| ] +[ |SYN_OPT-i| ] +[ |SYN_OPT-o| ] +[ |SYN_OPT--| ] + +|No-spaces| + +Description +----------- + +**fzanalyzer** is a tool developed as part of the Global Seafloor Fabric +and Magnetic Lineation Project [see `GSFML `_ for a full +description of the project]. It reads processed fracture zone (FZ) traces and cross-profiles as +produced by :doc:`grdtrack`. It then analyzes the trace of each FZ +by examining cross-sections orthogonal to the FZ trend and modeling these profiles +using a blend model of "Atlantic"-style symmetric troughs and "Pacific"-style asymmetric, +dipole-like anomalies, modulated with some peripheral bulges ("compression"). +We also fit just the symmetric trough model and +examine the empirical data minimum and trough width. Estimates are made +of the width of the data trough and 1-sigma uncertainties on the best FZ locations +given by the various models. We also compute several statistical measures and return +all the model parameters as a function of distances along each FZ. + + +Required Arguments +------------------ + +*crossprofiles* + This file is a table with cross-profiles as produced by :doc:`grdtrack` **-C** + from an approximate digitized trace (with *lon*, *lat*) of one or more FZs. + This is an ASCII (or binary, see **-bi**) file that must contain 7 data columns: + *lon, lat, dist, azimuth, vgg, age, fzdist*. + +.. _-F: + +**-F**\ Here, *fzlines* is a file with resampled track lines obtained by running :doc:`grdtrack` **-D**. +As for *crossprofiles* the file must contain the same 7 data columns *lon, lat, dist, azimuth, vgg, age, fzdist*. + +Optional Arguments +------------------ + +.. _-A: + +**-A**\ *min*/*max*/*inc* + Specifies one or three parameters that control how the blending of the model signals will be done. + Here, *min* is the minimum asymmetry value [0, i.e., "Atlantic" symmetric trough], + *max* is the maximum asymmetry [1], i.e., "Pacific" dipole signal], and *inc* is the + increment used for the search [0.05]. To specify just a single asymmetry value (no search), + just provide the single desired asymmetry. + +.. _-C: + +**-C**\ *min*/*max*/*inc* + Specifies one or three parameters that control how the search for the "compression" model signal will be done. + Here, *min* is the minimum compression value [0], *max* is the maximum compression [1, i.e., + "Mexican Hat" end-member], and *inc* is the increment used for the search [0.05]. + To specify just a single compression value (no search), just provide the single desired compression value.. + +.. _-D: + +**-D**\ *corrwidth* + Specifies a *corrwidth* (in km) that sets the width of the central corridor [25]. The purpose + of this corridor is to constrain how far off center we may seek to relocate the location of the FZ trough. + +.. _-I: + +**-I**\ *FZ*[/*profile*] + By default, we will analyze the cross-profiles generated for all FZs. However, + you can use |-I| to specify a particular FZ *id* id (first *id* is 0). + Optionally, you can select that only one *profile* from that FZ be processed [Default is all]. + Note that the output files will still contain all profiles but derived quantities will be + zero except for the chosen profiles. + +.. _-S: + + +**-S** + Output the parameters set by the command-line options in a format suitable for inclusion + in a Bourne/bash shell script. Alternatively, append **c* for csh/tcsh syntax. + +.. _-T: + +**-T**\ *prefix* + Sets the file name prefix used for all output files [*fztrack*]. + +.. |Add_-V| replace:: |Add_-V_links| +.. include:: /explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** + +.. _-W: + +**-W**\ *min*/*max*/*inc* + Specifies three parameters that control how the modeling of the cross-FZ signal will be done. + Here, *min* is the minimum FZ signal width (in km) for a nonlinear width search [1], + *max* is the maximum width [50], and *inc* is the increment used for the width search [1]. + It is recommended to determine suitable limits of a particular region and tune |-W| accordingly. + Selecting too wide a range might lead to spurious fits driven by data features not associated with + the FZ trough. + +.. |Add_-bo| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-bo.rst_ + +.. |Add_-do| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-do.rst_ + +.. include:: ../../explain_-icols.rst_ + +.. include:: ../../explain_-ocols.rst_ + +.. include:: ../../explain_-q.rst_ + +.. include:: ../../explain_help.rst_ + +Input Files +----------- + +The two input files are themselves generated by running :doc:`grdtrack` first. This step +requires a set of digitized FZ tracks (*lon*, *lat*) and three data grids: (a) a +VGG vertical gravity gradient file, (b) a 2 minute crustal age grid, and (c) +a grid with distance to the nearest FZ in km, listed in that order. The critical file is the +VGG grid. If you don't have or care about ages and distances you can make dummy grids that +are all NaNs. You design your cross-profile layout and resampled FZ trackes using :doc:`grdtrack` +options **-C** and **-D**.. + +Nearest Fracture Zone Distances +------------------------------- + +You can use :doc:`grdmath` to create the nearest fracture zone distance grid (in km) required +to prepare the profiles. A typical command suitable for the Nazca plate area might be:: + + gmt grdmath -R-120/-65/-50/5 -I5m -fg digitize.txt LDIST DEG2KM = dist2fz.nc + +Since this is a very slow calculation for numerous FZs it is not necessary to use a very high resolution +in |-I| since the distances change smoothly and interpolation will be approximately correct. Consider +making a global grid but do it in quadrants (or smaller region chunks) and run concurrently on a multi-core +computer. For example, to make a global grid from quadrants, one may run:: + + gmt grdmath -R0/180/0/90 -I2m -fg -V3 global_FZ.txt LDIST DEG2KM = WN.nc + gmt grdmath -R180/360/0/90 -I2m -fg -V3 FZ_KM.txt LDIST DEG2KM = EN.nc + gmt grdmath -R0/180/-90/0 -I2m -fg -V3 FZ_KM.txt LDIST DEG2KM = WS.nc + gmt grdmath -R180/360/-90/0 -I2m -fg -V3 FZ_KM.txt LDIST DEG2KM = ES.nc + +then blend these together into a global grid with:: + + gmt grdblend -Rg -I2 -fg EN.nc WN.nc ES.nc WS.nc -Gdist2FZ.nc -V + rm -f WN.nc EN.nc WS.nc ES.nc + +To make NaN grids for ages and/or distances for the Nazca area, use + + gmt grdmath -R-120/-65/-50/5 -I5m -fg 0 0 NaN = ages.nc + +**fzanalyzer** can produce up to three output files; these are described below: + +Output Files +------------ + + #. File *prefix*_analysis.txt contains the results of the analysis for each cross + profile. There 61 output columns containing the fitted or observed values (see + DETERMINED PARAMETERS). This file is used by :doc:`fzblender` to produce a smooth + and optimal fit to the fracture zone. + #. File *prefix*_cross.txt contains both observed and predicted best-fitting models + for each cross profile. It can be used for plotting and visual analysis of the + results on a profile-by-profile basis. + #. The *prefix*_par.[c]sh is either a Bourne (|-S|) or cshell (|-S|\ **c**) script + that contains all parameters specified by the command line as shell variables. You + can include this script in custom mapping or analysis scripts and use the variables + as you see fit. + #. Finally, while not an output file from **fzanalyzer**, you should use the name + *prefix*_resampled.txt for the output of :doc:`grdtrack` **-D** as that is what the + scripts for plotting expect. + +Examples +-------- + +To analyze digitized FZs we use the Sandwell/Smith VGG (1 minute vertical gravity gradient +@earth_vgg_01m), a 1-minute age grid (@earth_ages_01m), and a nearest-FZ distance grid +(in km). Given the potential FZ locations in the multi-segment file fz_digitized.txt, we +specify a 40 km cross-profile length, with profiles spaced every 5 km, and use an +along-cross-profile sampling interval of 2 km, by running:: + + gmt grdtrack fz_digitized.txt -C40k/2k/5k -G@earth_vgg_01m -G@earth_ages_01m -Gdist.nc -Dtraces_resampled.txt -fg --FORMAT_GEO_OUT=ddd.xxxx --FORMAT_FLOAT_OUT=%.1f > xprofiles.txt + +These two data tables can now be used with **fzanalyzer** to analyze the traces. Here, +we specify a 20 km central corridor and accept default values for most settings:: + + gmt fzanalyzer xprofiles.txt -D20 -Ftraces_resampled.txt -Ttraces -S --FORMAT_GEO_OUT=ddd.xxxx --FORMAT_FLOAT_OUT=%.1f + +You can then make plots of these cross-profiles with best-fitting curves and parameters +indicated by using + + fzprofiler traces -W6i -H2i -N2 + +which will plot all cross-profiles in separate 6x2 inch cross-sections stacked in one vertical panel. +You can show this information in map view via + + fzmapper traces -W9i -L1 -Ffz_digitized.txt + +See the :doc:`fzprofiler` and :doc:`fzmapper` documentation for further details. + +Determined Parameters +--------------------- + +Here are the header codes for each of the 61 output columns and what they represent: + + - **XR**: Longitude of raw digitized trace. + - **YR**: Latitude of raw digitized trace. + - **DR**: Distance at digitized points along raw digitized trace. + - **AR**: Azimuth at digitized points along raw digitized trace. + - **ZR**: Data value at digitizing locations + - **TL**: Crustal age estimate at left side of FZ (negative distances). + - **TR**: Crustal age estimate at right side of FZ (positive distances). + - **SD**: Shift of data minimum (in km) from raw line origin. + - **ST**: Shift of trough model minimum (in km) from raw line origin. + - **SB**: Shift of blend model minimum (in km) from raw line origin. + - **SE**: Shift of blend model maximum slope (in km) from raw line origin. + - **BL**: Best blend value [0-1]. + - **OR**: Orientation of blend model profile (-1 means left side is old, +1 means left side is young). + - **WD**: Width of data trough. + - **WT**: Width of model trough (for trough model). + - **WB**: Width of model trough (for blend model). + - **AD**: Peak-to-trough amplitude from data. + - **AT**: Peak-to-trough amplitude from model (for trough model). + - **AB**: Peak-to-trough amplitude from model (blend). + - **UT**: Compression indicator (for trough model). + - **UB**: Compression indicator (for blend model). + - **VT**: Variance reduction (%) from model (for trough model). + - **VB**: Variance reduction (%) from model (for blend model). + - **FT**: F-statistic (for trough model). + - **FB**: F-statistic (for blend model). + - **XDL**: Longitude of data minimum left bounds. + - **XD0**: Longitude of data minimum. + - **XDR**: Longitude of data minimum right bounds. + - **YDL**: Latitude of data minimum left bounds. + - **YD0**: Latitude of data minimum. + - **YDR**: Latitude of data minimum right bounds. + - **ZDL**: Value of data minimum left bounds. + - **ZD0**: Value of data minimum. + - **ZDR**: Value of data minimum right bounds. + - **XTL**: Longitude of minimum (for trough model) left bounds. + - **XT0**: Longitude of minimum (for trough model). + - **XTR**: Longitude of minimum (for trough model) right bounds. + - **YTL**: Latitude of minimum (for trough model) left bounds. + - **YT0**: Latitude of minimum (for trough model). + - **YTR**: Latitude of minimum (for trough model) right bounds. + - **ZTL**: Model prediction (for trough model) at left bounds. + - **ZT0**: Model prediction minimum (for trough model). + - **ZTR**: Model prediction (for trough model) at right bounds. + - **XBL**: Longitude of minimum (for blend model) left bounds. + - **XB0**: Longitude of minimum (for blend model). + - **XBR**: Longitude of minimum (for blend model) right bounds. + - **YBL**: Latitude of minimum (for blend model) left bounds. + - **YB0**: Latitude of minimum (for blend model). + - **YBR**: Latitude of minimum (for blend model) right bounds. + - **ZBL**: Model prediction (for blend model) at left bounds. + - **ZB0**: Model prediction minimum (for blend model). + - **ZBR**: Model prediction (for blend model) at right bounds. + - **XEL**: Longitude of maximum slope (for blend model) left bounds. + - **XE0**: Longitude of maximum slope (for blend model). + - **XER**: Longitude of maximum slope (for blend model) right bounds. + - **YEL**: Latitude of maximum slope (for blend model) left bounds. + - **YE0**: Latitude of maximum slope (for blend model). + - **YER**: Latitude of maximum slope (for blend model) right bounds. + - **ZEL**: Model prediction at maximum slope (for blend model) at left bounds. + - **ZE0**: Model prediction at maximum slope (for blend model). + - **ZER**: Model prediction at maximum slope (for blend model) at right bounds. + +See Also +-------- + +:doc:`gmt ` +:doc:`fzblender `, +:doc:`fzinformer `, +:doc:`fzmapper `, +:doc:`fzmodeler `, +:doc:`fzprofiler `, +:doc:`grdmath `, +:doc:`grdtrack `, +:doc:`mlconverter ` diff --git a/doc/rst/source/supplements/gsfml/fzblender.rst b/doc/rst/source/supplements/gsfml/fzblender.rst new file mode 100644 index 00000000000..28ffe954b30 --- /dev/null +++ b/doc/rst/source/supplements/gsfml/fzblender.rst @@ -0,0 +1,221 @@ +.. index:: ! fzblender +.. include:: ../module_supplements_purpose.rst_ + +********* +fzblender +********* + +|fzblender_purpose| + +Synopsis +-------- + +.. include:: ../../common_SYN_OPTs.rst_ + +**gmt fzblender** [ |-D| ] +[ |-E|\ *sfilter* ] +[ |-F|\ *pfilter* ] +[ |-I|\ *FZid* ] +[ |-Q|\ *q_min*/*q_max* ] +[ |-S|\ **code**\ [*weight*] ] +[ |-T|\ *prefix* ] +[ GMT_V_OPT ] +[ |-Z|\ *acut*/*vcut*/*fcut*/*wcut* ] + +|No-spaces| + +Description +----------- + +**fzblender* is a tool developed as part of the Global Seafloor Fabric +and Magnetic Lineation Project [see `GSFML `_ for a full +description of the project]. It reads an analysis file produced by +:doc:`fzanalyzer` and optionally filters those results along track. Then, given the +specified signal codes we will produce an optimal FZ track that is a +weighted blend between the user's original digitized trace and one or more +of the model traces obtained by :doc:`fzanalyzer`. The blend is based on +quality indices determined for the model traces: If the quality index is +high we favor this track, else we favor the digitized line; in between values +leads to a weighted blend. We expect to read the analysis results from the +file *prefix*_analysis.txt produced by :doc:`fzanalyzer`; the blend results +will be written to file *prefix*_blend.txt. Optionally, the intermediate +filtered analysis file can be written to *prefix*_filtered.txt if |-D| is given. + +Optional Arguments +------------------ + +.. _-D: + +**-D** + Do not remove filtered output but save them to IT(prefix)_filtered.txt. [By default we delete these intermediate files]. + +.. _-E: + +**-E**\ *sfilter* + Apply a s\ **E**\ condary filter after the primary required filter has completed. + This is sometimes useful if you apply a robust filter first, which may result in + short length-scale noise after removing gross outliers. See |-F| for how to specify the filter. + +.. _-F: + +**-F**\ *pfilter* + Sets the along-track primary filter. Choose among convolution and non-convolution filters. + Append the filter directive followed by the full (6-sigma) IT(width). Available convolution filters are: + + - **b**: Boxcar: All weights are equal. + - **c**: Cosine Arch: Weights follow a cosine arch curve. + - **g**: Gaussian: Weights are given by a Gaussian function. + + Non-convolution filters are: + + - **m**: Median: Returns median value. + - **p**: Maximum likelihood probability (a mode estimator): Return modal value. + If more than one mode is found we return their average value. Append - or + to + the filter width if you rather want to return the smallest or largest of the modal + values. + - **l**: Lower: Return the minimum of all values. + - **L**: Lower: Return minimum of all positive values only. + - **u**: Upper: Return maximum of all values. + - **U**: Upper: Return maximum or all negative values only. + +In the case of **L**\|\| **U** it is possible that no data passes the initial sign test; in that case +the filter will return 0.0. + +.. _-I: + +**-I**\ *FZ*[/*profile*] + By default, we will analyze the cross-profiles generated for all FZs. However, + you can use |-I| to specify a particular FZ *id* id (first *id* is 0). + +.. _-Q: + +**-Q**\ *q_min*/*q_max* + Sets the range of quality indices that will be used in the blended result. + The quality index *q(d)* ranges from *q_min*) (0 or bad) to *q_max* (1 or very good) and varies + continuously with distance IT(d) along the FZ trace. The quality weight assigned to + the modeled FZ trace is *w_q(d)* = (*q(d)* - *q_min*)/(*q_max* - *q_min*)), + unless *w_q(d)* > *q_max*) (*w_q(d)* = 1) or *w_q(d)* < *q_min*) (*w_q(d)* = 0). You can use the |-Q| + option to change this weight assignment. The quality weight assigned to the digitized FZ trace is + *w_q(d)* = 1 - mean{model quality weights} (see |-S|). For the calculation of quality indices, see |-Z|. + +.. _-S: + +**-Scode**\ [*weight*] + Specify the model and data traces you wish to blend and the relative custom weights + of each [Defaults to 1 for all traces]. Repeat this option for each trace to consider. + If you specify more than one model trace then the models are first averaged according to their quality + indices and weights before blending with the digitized trace (if specified). Hence, the quality index assigned + to the digitized trace is *q_r* = 1 - mean(model quality indices). The final blend is thus a weighted + average that takes into account both the quality indices and the custom weights (if specified). + Choose among these traces: + + - **b**: The trough location for the optimal trough/edge model blend model. This is the best fit obtained to the data using + a blend of "Atlantic"-, "Pacific"-, and "Compression"-style synthetic shapes. + - **d**: This is the empirical picks of the trough locations along the trace. + - **e**: This is the location of maximum slope for the optimal trough/edge model blend model. + - **t**: This is the best fit using the "Atlantic"-style trough model only. + - **u**: The user's original digitized trace. + + In addition to the blended FZ locations, we also output estimates of the FZ width and the traces + of the 1-sigma boundaries on either side of the FZ. + +.. _-T: + +**-T**\ *prefix* + Sets the file name prefix used for all output files [*fztrack*]. + +.. |Add_-V| replace:: |Add_-V_links| +.. include:: /explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** + +.. _-Z: + +**-Z**\ *acut*/*vcut*/*fcut*/*wcut* + We will attempt to assign a single quality index *Q* that summarize how good we + believe a model fit to be. This assignment relies of four threshold values + that need to be determined empirically. Here, *a_cut* is the minimum peak-to-trough amplitude + (in Eotvos) of a model for the crossing profile [25], *v_cut* is the minimum + variance reduction offered by the model (in %) [50], *f_cu* is + the minimum F statistic computed for the model [50], and *w_cut* is a typical + FZ trough width (in km) [15]. Currently, the first three quantities + are used to arrive at a 5-level quality index (0-1) for fitted models, as follows: (1) Very Good: Requires + model parameters to exceed all three thresholds; (0.75) Good: Requires amplitude and + variance reduction to exceed thresholds; (0.5) Fair: Requires the variance reduction only + to exceed its threshold; (0.25) Poor: Requires the amplitude only to exceed its threshold; + and (0) Bad: None of the criteria were met. We compute separate quality indices for the + trough and blend models. For the empirical trough model we only have estimates or peak-to-trough + amplitude, IT(A), and trough width, IT(W). Here, we form the ratio (*A*/*a_cut*) over + (*W*/*w_cut*), take :math:`\tan^{-1}` of this ratio and scale the result to yield the range 0-1 rounded + to the nearest multiple of 0.25. + +.. |Add_-bo| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-bo.rst_ + +.. |Add_-do| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-do.rst_ + +.. include:: ../../explain_-icols.rst_ + +.. include:: ../../explain_-ocols.rst_ + +.. include:: ../../explain_-q.rst_ + +.. include:: ../../explain_help.rst_ + +.. include:: ../../explain_precision.rst_ + +Output Columns +-------------- + +**fzblender** reports 10 columns of data, which are *lon, lat, dist, shift, width, +qweight, lon_l, lat_l, lon_r, lat_r*, where *lon, lat* contain the blended track +along *dist*, with across-track *widt* and *shift* in origin. The blend +obtained a quality weight of *qweight*, and the four last columns contains the +coordinates for the left/right bounds along the FZ. + +Filtering +--------- + +Filtering always runs of of data near the FZ end points. We utilize :doc:`filter1d` with its +**-E** option to extend the result to the end. Because we are filtering data columns that may +contain a strong trend (e.g., longitude versus along-track distance) we first remove such +linear trends before filtering, then restore the trends before blending. However, you should +be cautions in interpreting the blended results close to the ends of the FZs. You can examine +the effect of filtering more directly by using the |-D| option to save the filtered profiles. + +Blend Considerations +-------------------- + +Note that of the various directives in |-S|, the **e** is different in that it reflects +the FZ location estimate based on the theoretical prediction that the FZ crossing may be +associated with the steepest VGG slope. As such it will be offset from the trough by +several km (unless the blend is mostly "Atlantic") and combining it with the others +is unlikely to be productive. It is best used by itself with filtering. + +Examples +-------- + +To produce a weighted average of your digitized trace, the empirical trough locations, +and the trough model locations, giving the empirical locations a weight of 2 and the +model troughs a weight of 1, reading the file Pac_analysis.txt and selecting a median +filter of 70 km width followed by a 50-km Gaussian filter, try:: + + gmt fzblender -Su1 -Sd2 -St1 -Fm70 -Eg50 -TPac + +To produce a smooth trace of the maximum slope locations along track for the +same file, we try the same filters with the command + + gmt fzblender -Se -Fm70 -Eg50 -TPac + +See Also +-------- + +:doc:`gmt ` +:doc:`fzanalyzer `, +:doc:`fzinformer `, +:doc:`fzmapper `, +:doc:`fzmodeler `, +:doc:`fzprofiler `, +:doc:`filter1d `, +:doc:`mlconverter ` diff --git a/doc/rst/source/supplements/gsfml/fzinformer.rst b/doc/rst/source/supplements/gsfml/fzinformer.rst new file mode 100644 index 00000000000..9dc6bd2fe65 --- /dev/null +++ b/doc/rst/source/supplements/gsfml/fzinformer.rst @@ -0,0 +1,155 @@ +.. index:: ! fzinformer +.. include:: ../module_supplements_purpose.rst_ + +********** +fzinformer +********** + +|fzinformer_purpose| + +Synopsis +-------- + +.. include:: ../../common_SYN_OPTs.rst_ + +**gmt fzinformer** [ |-D| ] +[ |-F|\ *max* ] +[ |-I|\ *profile* ] +[ |-N|\ *max* ] +[ |-S|\ *max* ] +[ |-T|\ *prefix* ] +[ |-W|\ *max* ] +[ GMT_V_OPT ] + +|No-spaces| + +Description +----------- + +**fzinformer** is a script developed as part of the Global Seafloor Fabric +and Magnetic Lineation Project [see `GSFML `_ for a full +description of the project]. It make plots of statistical information obtained +by :doc:1fzanalyzer1 as a function of position along a fracture zone (FZ). + +Optional Arguments +------------------ + +.. _-D: + +**-D** + Use the filtered output from :doc:`fzblender` instead of the raw analysis file in making + the plot. This requires that you ran :doc:`fzblender` with the **-D** option. + +.. _-F: + +**-F**\ *max* + Sets the maximum *F*-statistic amplitude for the plot [10000]. A logarithmic + scale is used for this panel; all others are linear. + +.. _-I: + +**-I**\ *profile* + By default we plot all the cross-profiles in one stack. To select a single + profile only, append the running number of the profile, where 0 is the first profile. + +.. _-N: + +**-N**\ *max* + Sets the maximum range of VGG amplitudes (in Eotvos) for the plot [200]. + +.. _-S: + +**-S**\ *max* + Sets the maximum (±) half-range of FZ offsets (in km) [25]. + +.. _-T: + +**-T**\ *prefix* + Sets the file name prefix used when running :doc:`fzanalyzer` and :doc:`fzblender` + [The default is *fztrack*]. The files used here are *prefix*_analysis.txt + (or *prefix*_filtered.txt if |-D| is used) and *prefix*_blend.txt. + +.. _-W: + +**-W**\ *max* + Sets the maximum range of FZ widths (in km) [50]. + +.. |Add_-V| replace:: |Add_-V_links| +.. include:: /explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** + +.. _-Z: + +**-Z**\ *acut*/*vcut*/*fcut*/*wcut* + We will attempt to assign a single quality index *Q* that summarize how good we + believe a model fit to be. This assignment relies of four threshold values + that need to be determined empirically. Here, *a_cut* is the minimum peak-to-trough amplitude + (in Eotvos) of a model for the crossing profile [25], *v_cut* is the minimum + variance reduction offered by the model (in %) [50], *f_cu* is + the minimum F statistic computed for the model [50], and *w_cut* is a typical + FZ trough width (in km) [15]. Currently, the first three quantities + are used to arrive at a 5-level quality index (0-1) for fitted models, as follows: (1) Very Good: Requires + model parameters to exceed all three thresholds; (0.75) Good: Requires amplitude and + variance reduction to exceed thresholds; (0.5) Fair: Requires the variance reduction only + to exceed its threshold; (0.25) Poor: Requires the amplitude only to exceed its threshold; + and (0) Bad: None of the criteria were met. We compute separate quality indices for the + trough and blend models. For the empirical trough model we only have estimates or peak-to-trough + amplitude, IT(A), and trough width, IT(W). Here, we form the ratio (*A*/*a_cut*) over + (*W*/*w_cut*), take :math:`\tan^{-1}` of this ratio and scale the result to yield the range 0-1 rounded + to the nearest multiple of 0.25. + +.. |Add_-bo| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-bo.rst_ + +.. |Add_-do| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-do.rst_ + +.. include:: ../../explain_-icols.rst_ + +.. include:: ../../explain_-ocols.rst_ + +.. include:: ../../explain_-q.rst_ + +.. include:: ../../explain_help.rst_ + +Plot Features +------------- + +**fzinformer** packs much information into each plot by using different symbols and +colors. Empirical information obtained from raw data are shown in red. Information +derived from a forced trough FZ model are shown in green, while the information derived +from the optimal blend model are shown in blue. We present 7 panels for each FZ. Panel +1 (top) shows how the *F*-statistic parameter varies with distance for the trough (green) +and blend (blue) models. Panel 2 shows the reduction in variance for the same two models. +Panel 3 shows the maximum amplitude for the two models and the empirical data (red). +Panel 4 shows the width of the FZ signal for all three data. Panel 5 presents the offset +(in km) between the digitized trace and the optimal FZ locations (one curve for each type). +Panel 6 shows which side (left is -1, right = +1) is the young side assuming a Pacific +edge-anomaly model (it will tend to jump back and forth where the signal is close to +symmetric and should only be used when we have clearly asymmetric signals). Finally, panel 7 shows +the compression parameter **C for the blend and trough models, as well as the blend parameter *A* +(black line) for the optimal blend model. + +Examples +-------- + +To look at the statistics for the 5th (0 is first) FZ analyzed as part of a larger group called traces, +accepting default values except we override the maximum amplitude by using 100, +try:: + + fzinformer -Ttraces -N100 -I5 + +The statistical plot will be named *prefix*_stat.pdf. + +See Also +-------- + +:doc:`gmt ` +:doc:`fzanalyzer `, +:doc:`fzblender ` +:doc:`mlconverter `, +:doc:`fzmapper `, +:doc:`fzmodeler `, +:doc:`fzprofiler `, +:doc:`grdtrack `, diff --git a/doc/rst/source/supplements/gsfml/fzmapper.rst b/doc/rst/source/supplements/gsfml/fzmapper.rst new file mode 100644 index 00000000000..43bab503366 --- /dev/null +++ b/doc/rst/source/supplements/gsfml/fzmapper.rst @@ -0,0 +1,110 @@ +.. index:: ! fzmapper +.. include:: ../module_supplements_purpose.rst_ + +******** +fzmapper +******** + +|fzmapper_purpose| + +Synopsis +-------- + +.. include:: ../../common_SYN_OPTs.rst_ + +**gmt fzmapper** [ |-A| ] +[ |-F|\ *origfile* ] +[ |-G|\ *vgg_grid* ] +[ |-L|\ *labelint* ] +[ |-O| ] +[ |-S| ] +[ |-T|\ *prefix* ] +[ |-W|\ *width*[**c**\|\ **i**\|\ **p**] ] +[ GMT_V_OPT ] + +|No-spaces| + +Description +----------- + +**fzmapper** is a Bash script developed as part of the Global Seafloor Fabric +and Magnetic Lineation Project [see `GSFML `_ for a full +description of the project]. It make a Mercator map of cross-profiles from the +processed fracture zone (FZ) traces and cross-profiles as +produced by :doc:`grdtrack`. Optionally, overlay analysis and blend results. + +Optional Arguments +------------------ + +.. _-A: + +**-A** + In addition to the resampled FZ trace and the cross-profiles, overlay the + result of :doc:`fzanalyzer` as color-coded points (red for data, green for trough, + and blue for blend model) [No model results]. + +.. _-F: + +**-F**\ *profile* + This is the original digitized FZ traces that was given as input to:doc:`grdtrack`. + +.. _-G: + +**-G**\ *vgg_grid* + Optionally, supply the name of the VGG grid to use as background [@earth_vgg_02m]. + +.. _-O: + +**-O** + Instead of making a stand-alone PDF plot, write a PostScript overlay to stdout, + i.e., make the plot using the GMT **-O -K** options. + +.. _-S: + +**-S** + Overlay the smoothed FZ trace produced by :doc:`fzblender` [no overlay]. + +.. _-T: + +**-T**\ *prefix* + Sets the file name prefix used for all input files as produced by + :doc:`fzanalyzer`. The default is *fztrack*. The files are *prefix*_cross.txt and + *prefix*_par.txt as well as the resampled output from :doc:`grdtrack` which + should be called *prefix*_resampled.txt. When |-S| is set we also look for *prefix*_blend.txt + as produced by :doc:`fzblender`, and with |-A| we also look for *prefix*_analysis.txt. + +.. _-W: + +**-W**\ *width*\ [**c**\|\ **i**\|\ **p**] + Sets the *width* of the Mercator map. Unless the measure unit is appended the + unit is assumed to be whatever the GMT default :term:`PROJ_LENGTH_UNIT` is currently set to. + +.. |Add_-V| replace:: |Add_-V_links| +.. include:: /explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** + +Examples +-------- + +To look at the cross-profiles and the best-fit models and optimal FZ locations in +map view, with the prefix used previously as "traces", using a 9 inch wide Mercator, +and only label every other profile, try:: + + fzmapper -Ttraces -W9i -L2 -Fguides.xy -S -V -A + +where we use the original digitized FZ locations guides.xy, choosing to annotate every +other profile. The final map will be named *prefix*_map.pdf. For cross-section +profiles, see :doc:`fzprofiler`. + +See Also +-------- + +:doc:`gmt ` +:doc:`fzanalyzer `, +:doc:`fzblender ` +:doc:`mlconverter `, +:doc:`fzinformer `, +:doc:`fzmodeler `, +:doc:`fzprofiler `, +:doc:`grdtrack `, diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst new file mode 100644 index 00000000000..2417558165a --- /dev/null +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -0,0 +1,121 @@ +.. index:: ! fzmodeler +.. include:: ../module_supplements_purpose.rst_ + +********* +fzmodeler +********* + +|fzmodeler_purpose| + +Synopsis +-------- + +.. include:: ../../common_SYN_OPTs.rst_ + +**gmt fzmodeler** [ |-A|\ *asymmetry* ] +[ |-C|\ *compression* ] +[ |-D|\ *min*/*max*/*inc* ] +[ |-F|\ *prefix* ] +[ |-M| ] +[ |-N|\ *amplitude* ] +[ |-O| ] +[ |-P| ] +[ |-S|\ *shift* ] +[ GMT_V_OPT ] +[ |-W|\ *width* ] + +|No-spaces| + +Description +----------- + +**zmodeler** is a script developed as part of the Global Seafloor Fabric +and Magnetic Lineation Project [see www.soest.hawaii.edu/PT/GSFML for a full +description of the project]. It builds a synthetic model cross-profile given +the chosen model parameters and optionally images the profile via a PDF plot. + +Optional Arguments +------------------ + +.. _-A: + +**-A**\ *asymmetry* + Sets the asymmetry parameter used for the blend between symmetric ("Atlantic") + and asymmetric ("Pacific") signals [0]. + +.. _-C: + +**-C**\ *compression* + Sets the amount of compression (0-1) to use in the blending [0]. + +.. _-D: + +**-D**\ *min*/*max*/*inc* + Sets the domain for which to evaluate the model. If |-M| is used then + the domain is expected to be in km; otherwise *min* and *max* will be + expected to be in degrees of latitude which *inc* will be decoded as + arc minutes [-5/5/2 or -100/100/2, depending on |-M|]. + +.. _-F: + +**-F**\ *prefix* + Set the output prefix for the model profile [fzprof]. Give |-F|\ **-** to send + the model profile to stdout. + +.. _-M: + +**-M** + The chosen domain (|-D|) is given degrees of latitude, with increment in arc minutes + [Default is in km]. + +.. _-N: + +**-N**\ *amplitude* + Sets the peak-to-trough amplitude of the blended signal [100]. + +.. _-O: + +**-O** + Instead of making a stand-alone PDF plot, write a PostScript overlay to stdout, + i.e., make the plot using the GMT **-O -K** options. Requires (or sets) |-P|. + +.. _-P: + +**-P** + Produce a PDF plot (named *prefix*.pdf) of the synthetic FZ profile [no plot]. + +.. _-S: + +**-S**\ *shift* + Sets the shift of the FZ location from the origin, in km [0]. + +.. |Add_-V| replace:: |Add_-V_links| +.. include:: /explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** + +.. _-W: + +**-W**\ *width* + Sets the full width of the FZ, in km [25]. + +Examples +-------- + +To plot a synthetic profile for the Pacific, using otherwise default arguments, +try:: + fzmodeler -C1 -V + +The final plot will be named *prefix*.pdf, with the model data in *prefix*.txt. + +See Also +-------- + +:doc:`gmt ` +:doc:`fzanalyzer `, +:doc:`fzblender ` +:doc:`mlconverter `, +:doc:`fzinformer `, +:doc:`fzprofiler `, +:doc:`fzmapper `, +:doc:`grdtrack ` diff --git a/doc/rst/source/supplements/gsfml/fzprofiler.rst b/doc/rst/source/supplements/gsfml/fzprofiler.rst new file mode 100644 index 00000000000..c646335d2ca --- /dev/null +++ b/doc/rst/source/supplements/gsfml/fzprofiler.rst @@ -0,0 +1,118 @@ +.. index:: ! fzprofiler +.. include:: ../module_supplements_purpose.rst_ + +********** +fzprofiler +********** + +|fzprofiler_purpose| + +Synopsis +-------- + +.. include:: ../../common_SYN_OPTs.rst_ + +**gmt fzprofiler** [ |-H|\ *height*[**c**\|\ **i**\|\ **p**] ] +[ |-I|\ *profile* ] +[ |-L|\ *inc* ] +[ |-M|\ *ncols* ] +[ |-T|\ *prefix* ] +[ GMT_V_OPT ] +[ |-W|\ *width*[**c**\|\ **i**\|\ **p**] ] + +|No-spaces| + +Description +----------- + +**fzprofiler** is a script developed as part of the Global Seafloor Fabric +and Magnetic Lineation Project [see `GSFML `_ for a full +description of the project]. It plots the cross-profiles and the information produced by :doc:`fzanalyzer`. +All plots are combined into one plot using whatever custom page size is needed to fit the individual plots given +their specifications. + +Optional Arguments +------------------ + +.. _-H: + +**-H**\ *width*\ [**c**\|\ **i**\|\ **p**] + Sets the plot height of an individual profile. Unless the measure unit is appended the + unit is assumed to be whatever the GMT default :term:`PROJ_LENGTH_UNIT` is currently set to. + +.. _-I: + +**-I**\ *profile* + By default we plot all the cross-profiles in one stack. To select a single + profile only, append the running number of the profile, where 0 is the first profile. + +.. _-L: + +**-L**\ *inc* + Determines which profiles to plot. By default we plot every profile (*inc* = 1). + Use |-L| to plot every *inc* profile instead [1]. + +.. _-N: + +**-N**\ *ncols* + Spread profiles across *ncols* columns. If *ncols* = 1 + then all profiles are stacked vertically in one long panel; if *ncols* = 2 + then we split the profiles evenly between two columns, etc. + +.. _-T: + +**-T**\ *prefix* + Sets the file name *prefix* used for all input files as produced by + :doc:`fzanalyzer`. The default is fztrack. The files are *prefix*_cross.txt, *prefix*_analysis.txt, + *prefix*_par.txt as well as the resampled output from :doc:`grdtrack` which + should be called *prefix*_resampled.txt. + +.. _-W: + +**-W**\ *width*\ [**c**\|\ **i**\|\ **p**] + Similarly sets the plot width of an individual profile. For units, see |-H|. + +.. |Add_-V| replace:: |Add_-V_links| +.. include:: /explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** + +Plot Features +------------- + +**fzprofiler** packs much information into each plot by using different symbols and +colors. The cross-profile VGG data are plotted as red circles connected by a faint +red dotted line. The central corridor set with :doc:`fzanalyzer` **-D** is shown in light +blue. Black line is the best symmetric +trough model; inverted triangle indicates the best location of the FZ (trough) and +its error bars reflect the half-width. Blue line is the best asymmetric blend model; +circle shows the best location of the maximum VGG slope. Finally, the inverted +red triangle and half-width error bar shows the best empirical trough location. Dashed +orange line shows the crustal age variations. Profile orientation is +indicated by the W-E or S-N letters, with vertical scale shown on the left (VGG) and +right (age). Finally, each panel prints the best blend parameters. + +Examples +-------- + +To look at the cross-profiles and the best-fit models and optimal FZ locations on +a per-profiles basis, with the prefix used previously as "traces", and placing the +profiles into two columns, each 6 inches wide with individual plots 2 inches tall, +try:: + + fzprofiler -Ttraces -W6i -H2i -N2 -V + +The final plot will be named *prefix*_cross.pdf. To see the same profiles in map +view, use :doc:`fzmapper`. To plot a synthetic profile, see :doc:`fzmodeler`. + +See Also +-------- + +:doc:`gmt ` +:doc:`fzanalyzer `, +:doc:`fzblender ` +:doc:`mlconverter `, +:doc:`fzinformer `, +:doc:`fzmodeler `, +:doc:`fzmapper `, +:doc:`grdtrack `, diff --git a/doc/rst/source/supplements/gsfml/mlconverter.rst b/doc/rst/source/supplements/gsfml/mlconverter.rst new file mode 100644 index 00000000000..9725dc4dd76 --- /dev/null +++ b/doc/rst/source/supplements/gsfml/mlconverter.rst @@ -0,0 +1,116 @@ +.. index:: ! mlconverter +.. include:: ../module_supplements_purpose.rst_ + +*********** +mlconverter +*********** + +|mlconverter_purpose| + +Synopsis +-------- + +.. include:: ../../common_SYN_OPTs.rst_ + +**gmt mlconverter** [ *ML_data* ] +[ |-A| ] +[ |-G|\ *s** ] +[ |-I|\ *FZid* ] +[ |-T|\ c**\ |\ **g**\ |\ **o**\ |\ **s** ] +[ GMT_V_OPT ] + +|No-spaces| + +Description +----------- + +**mlconverter** is a module developed as part of the Global Seafloor Fabric +and Magnetic Lineation Project [[see `GSFML `_ for a full +description of the project]. It reads a magnetic pick data file (or stdin) +and converts chron textstrings to ages using a selected magnetic time scale. +The input data must be OGR/GMT data files of the form distributed by the +GSFML project. + +Optional Arguments +------------------ + +*ML_data* + A magnetic ML pick data OGR/GMT file. If not given then we read standard input. + +.. _-A: + +**-A** + Append the metadata to the output records as additional columns [Default only + writes *lon*, *lat*, *age* records]. + +.. _-G: + +**-G**\ [**s**] + Generate an extended OGR/GMT table by appending the crustal age. + Append **s** to repair any lax chron nomenclature, if needed. + +.. _-T: + +**-Tc**\ |\ **g**\ |\ **o**\ |\ **s** + Select the magnetic time scale to use. Choose from **g** (Gee and Kent, 2007), + **o** (Ogg, 2012), **s** (Gradstein, 2004), or **c** (Cande and Kent, 1995) [**g**]. +.TP + +.. |Add_-V| replace:: |Add_-V_links| +.. include:: /explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** + +.. _-Z: + +**-Z**\ *acut*/*vcut*/*fcut*/*wcut* + We will attempt to assign a single quality index *Q* that summarize how good we + believe a model fit to be. This assignment relies of four threshold values + that need to be determined empirically. Here, *a_cut* is the minimum peak-to-trough amplitude + (in Eotvos) of a model for the crossing profile [25], *v_cut* is the minimum + variance reduction offered by the model (in %) [50], *f_cu* is + the minimum F statistic computed for the model [50], and *w_cut* is a typical + FZ trough width (in km) [15]. Currently, the first three quantities + are used to arrive at a 5-level quality index (0-1) for fitted models, as follows: (1) Very Good: Requires + model parameters to exceed all three thresholds; (0.75) Good: Requires amplitude and + variance reduction to exceed thresholds; (0.5) Fair: Requires the variance reduction only + to exceed its threshold; (0.25) Poor: Requires the amplitude only to exceed its threshold; + and (0) Bad: None of the criteria were met. We compute separate quality indices for the + trough and blend models. For the empirical trough model we only have estimates or peak-to-trough + amplitude, IT(A), and trough width, IT(W). Here, we form the ratio (*A*/*a_cut*) over + (*W*/*w_cut*), take :math:`\tan^{-1}` of this ratio and scale the result to yield the range 0-1 rounded + to the nearest multiple of 0.25. + +.. |Add_-bo| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-bo.rst_ + +.. |Add_-do| unicode:: 0x20 .. just an invisible code +.. include:: ../../explain_-do.rst_ + +.. include:: ../../explain_-icols.rst_ + +.. include:: ../../explain_-ocols.rst_ + +.. include:: ../../explain_-q.rst_ + +.. include:: ../../explain_help.rst_ + +Examples +-------- + +To convert chrons to ages using the Cande and Kent, 1995 timescale, and append the +metadata at the end of the record, try:: + + gmt mlconverter -A -Tc ML_datafile.gmt > convertedfile.txt + +See Also +-------- + +:doc:`gmt ` +:doc:`fzanalyzer `, +:doc:`fzblender ` +:doc:`fzinformer `, +:doc:`fzmapper `, +:doc:`fzmodeler `, +:doc:`fzprofiler `, +:doc:`grdtrack `, From 7477bfaa53b07282fb0a238ef5522849b646d856 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 23:37:43 +0100 Subject: [PATCH 09/20] Update module listing in RST for modern and classic --- doc/rst/source/modules-classic.rst | 33 ++++++++++++++++++++++++++++++ doc/rst/source/modules.rst | 26 +++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/doc/rst/source/modules-classic.rst b/doc/rst/source/modules-classic.rst index 152145322a5..52823e5c3db 100644 --- a/doc/rst/source/modules-classic.rst +++ b/doc/rst/source/modules-classic.rst @@ -127,6 +127,13 @@ All modules are requested via a call to the :doc:`gmt` program. supplements/geodesy/earthtide supplements/geodesy/gpsgridder supplements/geodesy/psvelo + supplements/gsfml/fzanalyzer + supplements/gsfml/fzblender + supplements/gsfml/fzinformer + supplements/gsfml/fzmapper + supplements/gsfml/fzmodeler + supplements/gsfml/fzprofile + supplements/gsfml/mlconverter supplements/gshhg/gshhg supplements/img/img2grd supplements/mgd77/mgd77convert @@ -290,6 +297,13 @@ Supplemental Modules - :doc:`/supplements/geodesy/earthtide` - :doc:`/supplements/geodesy/gpsgridder` - :doc:`/supplements/geodesy/psvelo` + - :doc:`/supplements/gsfml/fzanalyzer` + - :doc:`/supplements/gsfml/fzblender` + - :doc:`/supplements/gsfml/fzinformer` + - :doc:`/supplements/gsfml/fzmapper` + - :doc:`/supplements/gsfml/fzmodeler` + - :doc:`/supplements/gsfml/fzprofile` + - :doc:`/supplements/gsfml/mlconverter` - :doc:`/supplements/gshhg/gshhg` - :doc:`/supplements/img/img2grd` - :doc:`/supplements/mgd77/mgd77convert` @@ -605,6 +619,25 @@ geodesy | :doc:`/supplements/geodesy/psvelo` | |psvelo_purpose| | +--------------------------------------------+----------------------+ +GSFML +----- + ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzblende` | |fzblende| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzinformer` | |fzinformer| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzmapper` | |fzmapper| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/mlconverter | |mlconverter| | ++--------------------------------------+----------------------+ + GSHHG ----- diff --git a/doc/rst/source/modules.rst b/doc/rst/source/modules.rst index 11ab459dd2f..246ea744f80 100644 --- a/doc/rst/source/modules.rst +++ b/doc/rst/source/modules.rst @@ -302,6 +302,13 @@ Supplemental Modules - :doc:`/supplements/geodesy/earthtide` - :doc:`/supplements/geodesy/gpsgridder` - :doc:`/supplements/geodesy/velo` + - :doc:`/supplements/gsfml/fzanalyzer` + - :doc:`/supplements/gsfml/fzblender` + - :doc:`/supplements/gsfml/fzinformer` + - :doc:`/supplements/gsfml/fzmapper` + - :doc:`/supplements/gsfml/fzmodeler` + - :doc:`/supplements/gsfml/fzprofile` + - :doc:`/supplements/gsfml/mlconverter` - :doc:`/supplements/gshhg/gshhg` - :doc:`/supplements/img/img2grd` - :doc:`/supplements/mgd77/mgd77convert` @@ -636,6 +643,25 @@ geodesy | :doc:`/supplements/geodesy/velo` | |velo_purpose| | +--------------------------------------------+----------------------+ +GSFML +----- + ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzblende` | |fzblende| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzinformer` | |fzinformer| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzmapper` | |fzmapper| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler| | ++--------------------------------------+----------------------+ +| :doc:`/supplements/gsfml/mlconverter | |mlconverter| | ++--------------------------------------+----------------------+ + GSHHG ----- From 079c9dcbc395686dbc3fa0fb7b5538086a2a4cce Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Fri, 1 Dec 2023 23:51:03 +0100 Subject: [PATCH 10/20] FInalize web layout --- doc/rst/source/modules-classic.rst | 30 +++++++++---------- doc/rst/source/modules.rst | 30 +++++++++---------- .../module_supplements_purpose.rst_ | 6 ++++ 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/doc/rst/source/modules-classic.rst b/doc/rst/source/modules-classic.rst index 52823e5c3db..750e0d5625a 100644 --- a/doc/rst/source/modules-classic.rst +++ b/doc/rst/source/modules-classic.rst @@ -622,21 +622,21 @@ geodesy GSFML ----- -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzblende` | |fzblende| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzinformer` | |fzinformer| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzmapper` | |fzmapper| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/mlconverter | |mlconverter| | -+--------------------------------------+----------------------+ ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzblende` | |fzblender_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmapper` | |fzmapper_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/mlconverter | |mlconverter_purpose| | ++--------------------------------------+-----------------------+ GSHHG ----- diff --git a/doc/rst/source/modules.rst b/doc/rst/source/modules.rst index 246ea744f80..c9ed1a1473d 100644 --- a/doc/rst/source/modules.rst +++ b/doc/rst/source/modules.rst @@ -646,21 +646,21 @@ geodesy GSFML ----- -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzblende` | |fzblende| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzinformer` | |fzinformer| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzmapper` | |fzmapper| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler| | -+--------------------------------------+----------------------+ -| :doc:`/supplements/gsfml/mlconverter | |mlconverter| | -+--------------------------------------+----------------------+ ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzblende` | |fzblender_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmapper` | |fzmapper_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler_purpose| | ++--------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/mlconverter | |mlconverter_purpose| | ++--------------------------------------+-----------------------+ GSHHG ----- diff --git a/doc/rst/source/supplements/module_supplements_purpose.rst_ b/doc/rst/source/supplements/module_supplements_purpose.rst_ index 08584edd66d..2f4e2ebb524 100644 --- a/doc/rst/source/supplements/module_supplements_purpose.rst_ +++ b/doc/rst/source/supplements/module_supplements_purpose.rst_ @@ -8,6 +8,12 @@ .. |psvelo_purpose| replace:: Plot velocity vectors, crosses, anisotropy bars and wedges +.. |fzanalyzer_purpose| replace:: Analysis of fracture zones using crossing profiles + +.. |fzblender_purpose| replace:: Produce a smooth blended FZ trace + +.. |mlconverter_purpose| replace:: Convert chrons to ages using selected magnetic timescale + .. |gshhg_purpose| replace:: Extract data tables from binary GSHHG or WDBII data files .. |img2grd_purpose| replace:: Extract a subset from an img file in Mercator or Geographic format From e1fd1474e5b32f2c025717999cc85630d47dfe97 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sat, 2 Dec 2023 00:39:12 +0100 Subject: [PATCH 11/20] Wrap up purposes --- doc/rst/source/modules-classic.rst | 2 +- doc/rst/source/modules.rst | 2 +- doc/rst/source/supplements/gsfml/fzinformer.rst | 2 +- doc/rst/source/supplements/gsfml/fzmapper.rst | 2 +- doc/rst/source/supplements/gsfml/fzmodeler.rst | 2 +- doc/rst/source/supplements/gsfml/fzprofiler.rst | 2 +- .../supplements/module_supplements_purpose.rst_ | 8 ++++++++ src/gmt_make_module_purpose.sh | 13 +++++++++++++ 8 files changed, 27 insertions(+), 6 deletions(-) diff --git a/doc/rst/source/modules-classic.rst b/doc/rst/source/modules-classic.rst index 750e0d5625a..d6e2d54fa91 100644 --- a/doc/rst/source/modules-classic.rst +++ b/doc/rst/source/modules-classic.rst @@ -625,7 +625,7 @@ GSFML +--------------------------------------+-----------------------+ | :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | +--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzblende` | |fzblender_purpose| | +| :doc:`/supplements/gsfml/fzblender` | |fzblender_purpose| | +--------------------------------------+-----------------------+ | :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | +--------------------------------------+-----------------------+ diff --git a/doc/rst/source/modules.rst b/doc/rst/source/modules.rst index c9ed1a1473d..ca214b4a06b 100644 --- a/doc/rst/source/modules.rst +++ b/doc/rst/source/modules.rst @@ -649,7 +649,7 @@ GSFML +--------------------------------------+-----------------------+ | :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | +--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzblende` | |fzblender_purpose| | +| :doc:`/supplements/gsfml/fzblender` | |fzblender_purpose| | +--------------------------------------+-----------------------+ | :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | +--------------------------------------+-----------------------+ diff --git a/doc/rst/source/supplements/gsfml/fzinformer.rst b/doc/rst/source/supplements/gsfml/fzinformer.rst index 9dc6bd2fe65..fdb9752cdea 100644 --- a/doc/rst/source/supplements/gsfml/fzinformer.rst +++ b/doc/rst/source/supplements/gsfml/fzinformer.rst @@ -12,7 +12,7 @@ Synopsis .. include:: ../../common_SYN_OPTs.rst_ -**gmt fzinformer** [ |-D| ] +**zinformer** [ |-D| ] [ |-F|\ *max* ] [ |-I|\ *profile* ] [ |-N|\ *max* ] diff --git a/doc/rst/source/supplements/gsfml/fzmapper.rst b/doc/rst/source/supplements/gsfml/fzmapper.rst index 43bab503366..c4ca01d03cb 100644 --- a/doc/rst/source/supplements/gsfml/fzmapper.rst +++ b/doc/rst/source/supplements/gsfml/fzmapper.rst @@ -12,7 +12,7 @@ Synopsis .. include:: ../../common_SYN_OPTs.rst_ -**gmt fzmapper** [ |-A| ] +**fzmapper** [ |-A| ] [ |-F|\ *origfile* ] [ |-G|\ *vgg_grid* ] [ |-L|\ *labelint* ] diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst index 2417558165a..98a53ae27fe 100644 --- a/doc/rst/source/supplements/gsfml/fzmodeler.rst +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -12,7 +12,7 @@ Synopsis .. include:: ../../common_SYN_OPTs.rst_ -**gmt fzmodeler** [ |-A|\ *asymmetry* ] +**fzmodeler** [ |-A|\ *asymmetry* ] [ |-C|\ *compression* ] [ |-D|\ *min*/*max*/*inc* ] [ |-F|\ *prefix* ] diff --git a/doc/rst/source/supplements/gsfml/fzprofiler.rst b/doc/rst/source/supplements/gsfml/fzprofiler.rst index c646335d2ca..d55583f90a8 100644 --- a/doc/rst/source/supplements/gsfml/fzprofiler.rst +++ b/doc/rst/source/supplements/gsfml/fzprofiler.rst @@ -12,7 +12,7 @@ Synopsis .. include:: ../../common_SYN_OPTs.rst_ -**gmt fzprofiler** [ |-H|\ *height*[**c**\|\ **i**\|\ **p**] ] +**fzprofiler** [ |-H|\ *height*[**c**\|\ **i**\|\ **p**] ] [ |-I|\ *profile* ] [ |-L|\ *inc* ] [ |-M|\ *ncols* ] diff --git a/doc/rst/source/supplements/module_supplements_purpose.rst_ b/doc/rst/source/supplements/module_supplements_purpose.rst_ index 2f4e2ebb524..429e613fb4f 100644 --- a/doc/rst/source/supplements/module_supplements_purpose.rst_ +++ b/doc/rst/source/supplements/module_supplements_purpose.rst_ @@ -130,3 +130,11 @@ .. |x2sys_solve_purpose| replace:: Determine least-squares systematic correction from crossovers +.. |fzinformer| replace:: Bash script to plot statistical information related to fracture zones + +.. |fzmapper| replace:: Bash script to plot fracture zone cross-profiles on a Mercator map + +.. |fzmodeler| replace:: Bash script to build fracture zone cross-profile model + +.. |fzprofiler| replace:: Bash script to plot fracture zone cross-profiles + diff --git a/src/gmt_make_module_purpose.sh b/src/gmt_make_module_purpose.sh index 8b92dd243fd..728f7df83d1 100755 --- a/src/gmt_make_module_purpose.sh +++ b/src/gmt_make_module_purpose.sh @@ -59,4 +59,17 @@ while read program; do done < ${TMPDIR}/gmt_supplements_modules.lst rm -f ${TMPDIR}/gmt_supplements_modules.lst +# Add purpose for a few GSFML bash scripts (i.e, not .c code) + +cat <<- EOF >> ${FILE_SUPPL_MODULE_PURPOSE} +.. |fzinformer| replace:: Bash script to plot statistical information related to fracture zones + +.. |fzmapper| replace:: Bash script to plot fracture zone cross-profiles on a Mercator map + +.. |fzmodeler| replace:: Bash script to build fracture zone cross-profile model + +.. |fzprofiler| replace:: Bash script to plot fracture zone cross-profiles + +EOF + echo "Writing done" From fa4786283e79817c504a47042d609c8667957817 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sat, 2 Dec 2023 07:31:43 +0100 Subject: [PATCH 12/20] Update gsfml doc links and fix typos --- doc/rst/source/modules-classic.rst | 32 +++++++++---------- doc/rst/source/modules.rst | 32 +++++++++---------- .../module_supplements_purpose.rst_ | 8 ++--- src/gmt_make_module_purpose.sh | 8 ++--- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/doc/rst/source/modules-classic.rst b/doc/rst/source/modules-classic.rst index d6e2d54fa91..e50179188d0 100644 --- a/doc/rst/source/modules-classic.rst +++ b/doc/rst/source/modules-classic.rst @@ -302,7 +302,7 @@ Supplemental Modules - :doc:`/supplements/gsfml/fzinformer` - :doc:`/supplements/gsfml/fzmapper` - :doc:`/supplements/gsfml/fzmodeler` - - :doc:`/supplements/gsfml/fzprofile` + - :doc:`/supplements/gsfml/fzprofiler` - :doc:`/supplements/gsfml/mlconverter` - :doc:`/supplements/gshhg/gshhg` - :doc:`/supplements/img/img2grd` @@ -622,21 +622,21 @@ geodesy GSFML ----- -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzblender` | |fzblender_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzmapper` | |fzmapper_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/mlconverter | |mlconverter_purpose| | -+--------------------------------------+-----------------------+ ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzblender` | |fzblender_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmapper` | |fzmapper_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/mlconverter` | |mlconverter_purpose| | ++---------------------------------------+-----------------------+ GSHHG ----- diff --git a/doc/rst/source/modules.rst b/doc/rst/source/modules.rst index ca214b4a06b..1acd1091211 100644 --- a/doc/rst/source/modules.rst +++ b/doc/rst/source/modules.rst @@ -307,7 +307,7 @@ Supplemental Modules - :doc:`/supplements/gsfml/fzinformer` - :doc:`/supplements/gsfml/fzmapper` - :doc:`/supplements/gsfml/fzmodeler` - - :doc:`/supplements/gsfml/fzprofile` + - :doc:`/supplements/gsfml/fzprofiler` - :doc:`/supplements/gsfml/mlconverter` - :doc:`/supplements/gshhg/gshhg` - :doc:`/supplements/img/img2grd` @@ -646,21 +646,21 @@ geodesy GSFML ----- -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzblender` | |fzblender_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzmapper` | |fzmapper_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler_purpose| | -+--------------------------------------+-----------------------+ -| :doc:`/supplements/gsfml/mlconverter | |mlconverter_purpose| | -+--------------------------------------+-----------------------+ ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzanalyzer` | |fzanalyzer_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzblender` | |fzblender_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzinformer` | |fzinformer_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmapper` | |fzmapper_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzmodeler` | |fzmodeler_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/fzprofiler` | |fzprofiler_purpose| | ++---------------------------------------+-----------------------+ +| :doc:`/supplements/gsfml/mlconverter` | |mlconverter_purpose| | ++---------------------------------------+-----------------------+ GSHHG ----- diff --git a/doc/rst/source/supplements/module_supplements_purpose.rst_ b/doc/rst/source/supplements/module_supplements_purpose.rst_ index 429e613fb4f..194c03c9eae 100644 --- a/doc/rst/source/supplements/module_supplements_purpose.rst_ +++ b/doc/rst/source/supplements/module_supplements_purpose.rst_ @@ -130,11 +130,11 @@ .. |x2sys_solve_purpose| replace:: Determine least-squares systematic correction from crossovers -.. |fzinformer| replace:: Bash script to plot statistical information related to fracture zones +.. |fzinformer_purpose| replace:: Bash script to plot statistical information related to fracture zones -.. |fzmapper| replace:: Bash script to plot fracture zone cross-profiles on a Mercator map +.. |fzmapper_purpose| replace:: Bash script to plot fracture zone cross-profiles on a Mercator map -.. |fzmodeler| replace:: Bash script to build fracture zone cross-profile model +.. |fzmodeler_purpose| replace:: Bash script to build fracture zone cross-profile model -.. |fzprofiler| replace:: Bash script to plot fracture zone cross-profiles +.. |fzprofiler_purpose| replace:: Bash script to plot fracture zone cross-profiles diff --git a/src/gmt_make_module_purpose.sh b/src/gmt_make_module_purpose.sh index 728f7df83d1..718cfc93794 100755 --- a/src/gmt_make_module_purpose.sh +++ b/src/gmt_make_module_purpose.sh @@ -62,13 +62,13 @@ rm -f ${TMPDIR}/gmt_supplements_modules.lst # Add purpose for a few GSFML bash scripts (i.e, not .c code) cat <<- EOF >> ${FILE_SUPPL_MODULE_PURPOSE} -.. |fzinformer| replace:: Bash script to plot statistical information related to fracture zones +.. |fzinformer_purpose| replace:: Bash script to plot statistical information related to fracture zones -.. |fzmapper| replace:: Bash script to plot fracture zone cross-profiles on a Mercator map +.. |fzmapper_purpose| replace:: Bash script to plot fracture zone cross-profiles on a Mercator map -.. |fzmodeler| replace:: Bash script to build fracture zone cross-profile model +.. |fzmodeler_purpose| replace:: Bash script to build fracture zone cross-profile model -.. |fzprofiler| replace:: Bash script to plot fracture zone cross-profiles +.. |fzprofiler_purpose| replace:: Bash script to plot fracture zone cross-profiles EOF From 3f05eef5eb6a8c1676aafdcab393013fc0d8023b Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sat, 2 Dec 2023 08:34:36 +0100 Subject: [PATCH 13/20] Fix RST issues --- .../source/supplements/gsfml/fzanalyzer.rst | 38 ++++++++----- .../source/supplements/gsfml/fzblender.rst | 53 +++++++++++-------- .../source/supplements/gsfml/fzinformer.rst | 31 ++++++----- doc/rst/source/supplements/gsfml/fzmapper.rst | 29 ++++++---- .../source/supplements/gsfml/fzmodeler.rst | 12 ++++- .../source/supplements/gsfml/fzprofiler.rst | 35 ++++++------ .../source/supplements/gsfml/mlconverter.rst | 24 +++++---- src/gsfml/fzanalyzer.c | 8 +-- 8 files changed, 140 insertions(+), 90 deletions(-) diff --git a/doc/rst/source/supplements/gsfml/fzanalyzer.rst b/doc/rst/source/supplements/gsfml/fzanalyzer.rst index 85aa83c8cef..3ffabdcce53 100644 --- a/doc/rst/source/supplements/gsfml/fzanalyzer.rst +++ b/doc/rst/source/supplements/gsfml/fzanalyzer.rst @@ -13,11 +13,12 @@ Synopsis .. include:: ../../common_SYN_OPTs.rst_ **gmt fzanalyzer** *crossprofiles* +|-F|\ *fzlines* [ |-A|\ *min*/*max*/*inc* ] [ |-C|\ *min*/*max*/*inc* ] [ |-D|\ *corrwidth* ] -[ |-I|\ *FZ*[/*profile*] ] -[ -S[\ **c**]] +[ |-I|\ *FZ*\ [/*profile*] ] +[ |-S|\ [**b**\|\ **c**]] [ |-T|\ *prefix* ] [ |SYN_OPT-V| ] [ |-W|\ *min*/*max*/*inc* ] @@ -57,8 +58,10 @@ Required Arguments .. _-F: -**-F**\ Here, *fzlines* is a file with resampled track lines obtained by running :doc:`grdtrack` **-D**. -As for *crossprofiles* the file must contain the same 7 data columns *lon, lat, dist, azimuth, vgg, age, fzdist*. +**-F**\ *fzlines* + Here, *fzlines* is a file with resampled track lines obtained by running :doc:`grdtrack` **-D**. + As for *crossprofiles* the file must contain the same 7 data columns *lon, lat, dist, azimuth, vgg, age, fzdist*. + See INPUT FILES for more details. Optional Arguments ------------------ @@ -88,7 +91,7 @@ Optional Arguments .. _-I: -**-I**\ *FZ*[/*profile*] +**-I**\ *FZ*\ [/*profile*] By default, we will analyze the cross-profiles generated for all FZs. However, you can use |-I| to specify a particular FZ *id* id (first *id* is 0). Optionally, you can select that only one *profile* from that FZ be processed [Default is all]. @@ -98,9 +101,9 @@ Optional Arguments .. _-S: -**-S** +**-S**\ [**b**\|\ **c**] Output the parameters set by the command-line options in a format suitable for inclusion - in a Bourne/bash shell script. Alternatively, append **c* for csh/tcsh syntax. + in a Bourne/bash shell script. Alternatively, append **c** for csh/tcsh syntax. .. _-T: @@ -108,7 +111,7 @@ Optional Arguments Sets the file name prefix used for all output files [*fztrack*]. .. |Add_-V| replace:: |Add_-V_links| -.. include:: /explain_-V.rst_ +.. include:: ../../explain_-V.rst_ :start-after: **Syntax** :end-before: **Description** @@ -179,19 +182,19 @@ To make NaN grids for ages and/or distances for the Nazca area, use Output Files ------------ - #. File *prefix*_analysis.txt contains the results of the analysis for each cross + #. File *prefix*\ _analysis.txt contains the results of the analysis for each cross profile. There 61 output columns containing the fitted or observed values (see DETERMINED PARAMETERS). This file is used by :doc:`fzblender` to produce a smooth and optimal fit to the fracture zone. - #. File *prefix*_cross.txt contains both observed and predicted best-fitting models + #. File *prefix*\ _cross.txt contains both observed and predicted best-fitting models for each cross profile. It can be used for plotting and visual analysis of the results on a profile-by-profile basis. - #. The *prefix*_par.[c]sh is either a Bourne (|-S|) or cshell (|-S|\ **c**) script + #. The *prefix*\ _par.[c]sh is either a Bourne (|-S|) or cshell (|-S|\ **c**) script that contains all parameters specified by the command line as shell variables. You can include this script in custom mapping or analysis scripts and use the variables as you see fit. #. Finally, while not an output file from **fzanalyzer**, you should use the name - *prefix*_resampled.txt for the output of :doc:`grdtrack` **-D** as that is what the + *prefix*\ _resampled.txt for the output of :doc:`grdtrack` **-D** as that is what the scripts for plotting expect. Examples @@ -211,12 +214,12 @@ we specify a 20 km central corridor and accept default values for most settings: gmt fzanalyzer xprofiles.txt -D20 -Ftraces_resampled.txt -Ttraces -S --FORMAT_GEO_OUT=ddd.xxxx --FORMAT_FLOAT_OUT=%.1f You can then make plots of these cross-profiles with best-fitting curves and parameters -indicated by using +indicated by using:: fzprofiler traces -W6i -H2i -N2 which will plot all cross-profiles in separate 6x2 inch cross-sections stacked in one vertical panel. -You can show this information in map view via +You can show this information in map view via:: fzmapper traces -W9i -L1 -Ffz_digitized.txt @@ -301,3 +304,10 @@ See Also :doc:`grdmath `, :doc:`grdtrack `, :doc:`mlconverter ` + +References +---------- + +Wessel, P., Matthews, K. J., Müller, R. D., Mazzoni, A., Whittaker, J. M., Myhill, R., Chandler, M. T., +2015, "Semiautomatic fracture zone tracking", *Geochem. Geophys. Geosyst.*, 16 (7), 2462–2472. +https://doi.org/10.1002/2015GC005853. diff --git a/doc/rst/source/supplements/gsfml/fzblender.rst b/doc/rst/source/supplements/gsfml/fzblender.rst index 28ffe954b30..b3c6d3e4371 100644 --- a/doc/rst/source/supplements/gsfml/fzblender.rst +++ b/doc/rst/source/supplements/gsfml/fzblender.rst @@ -17,9 +17,9 @@ Synopsis [ |-F|\ *pfilter* ] [ |-I|\ *FZid* ] [ |-Q|\ *q_min*/*q_max* ] -[ |-S|\ **code**\ [*weight*] ] +[ |-S|\ **b**\|\ **d**\|\ **e**\|\ **t**\|\ **u**\ [*weight*] ] [ |-T|\ *prefix* ] -[ GMT_V_OPT ] +[ |SYN_OPT-V| ] [ |-Z|\ *acut*/*vcut*/*fcut*/*wcut* ] |No-spaces| @@ -27,7 +27,7 @@ Synopsis Description ----------- -**fzblender* is a tool developed as part of the Global Seafloor Fabric +**fzblender** is a tool developed as part of the Global Seafloor Fabric and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It reads an analysis file produced by :doc:`fzanalyzer` and optionally filters those results along track. Then, given the @@ -37,9 +37,9 @@ of the model traces obtained by :doc:`fzanalyzer`. The blend is based on quality indices determined for the model traces: If the quality index is high we favor this track, else we favor the digitized line; in between values leads to a weighted blend. We expect to read the analysis results from the -file *prefix*_analysis.txt produced by :doc:`fzanalyzer`; the blend results -will be written to file *prefix*_blend.txt. Optionally, the intermediate -filtered analysis file can be written to *prefix*_filtered.txt if |-D| is given. +file *prefix*\ _analysis.txt produced by :doc:`fzanalyzer`; the blend results +will be written to file *prefix*\ _blend.txt. Optionally, the intermediate +filtered analysis file can be written to *prefix*\ _filtered.txt if |-D| is given. Optional Arguments ------------------ @@ -47,12 +47,12 @@ Optional Arguments .. _-D: **-D** - Do not remove filtered output but save them to IT(prefix)_filtered.txt. [By default we delete these intermediate files]. + Do not remove filtered output but save them to *prefix*\_filtered.txt. [By default we delete these intermediate files]. .. _-E: **-E**\ *sfilter* - Apply a s\ **E**\ condary filter after the primary required filter has completed. + Apply a secondary filter after the primary required filter has completed. This is sometimes useful if you apply a robust filter first, which may result in short length-scale noise after removing gross outliers. See |-F| for how to specify the filter. @@ -60,7 +60,7 @@ Optional Arguments **-F**\ *pfilter* Sets the along-track primary filter. Choose among convolution and non-convolution filters. - Append the filter directive followed by the full (6-sigma) IT(width). Available convolution filters are: + Append the filter directive followed by the full (6-sigma) *width*. Available convolution filters are: - **b**: Boxcar: All weights are equal. - **c**: Cosine Arch: Weights follow a cosine arch curve. @@ -70,29 +70,29 @@ Optional Arguments - **m**: Median: Returns median value. - **p**: Maximum likelihood probability (a mode estimator): Return modal value. - If more than one mode is found we return their average value. Append - or + to - the filter width if you rather want to return the smallest or largest of the modal + If more than one mode is found we return their average value. Append **+l** or **+u** to + the filter width if you rather want to return the lowermost or uppermost of the modal values. - **l**: Lower: Return the minimum of all values. - **L**: Lower: Return minimum of all positive values only. - **u**: Upper: Return maximum of all values. - **U**: Upper: Return maximum or all negative values only. -In the case of **L**\|\| **U** it is possible that no data passes the initial sign test; in that case -the filter will return 0.0. + In the case of **L**\|\| **U** it is possible that no data passes the initial sign test; + in that case the filter will return 0.0. .. _-I: -**-I**\ *FZ*[/*profile*] +**-I**\ *FZid* By default, we will analyze the cross-profiles generated for all FZs. However, - you can use |-I| to specify a particular FZ *id* id (first *id* is 0). + you can use |-I| to specify a particular *FZid* (first *FZid* is 0). .. _-Q: **-Q**\ *q_min*/*q_max* Sets the range of quality indices that will be used in the blended result. The quality index *q(d)* ranges from *q_min*) (0 or bad) to *q_max* (1 or very good) and varies - continuously with distance IT(d) along the FZ trace. The quality weight assigned to + continuously with distance *d* along the FZ trace. The quality weight assigned to the modeled FZ trace is *w_q(d)* = (*q(d)* - *q_min*)/(*q_max* - *q_min*)), unless *w_q(d)* > *q_max*) (*w_q(d)* = 1) or *w_q(d)* < *q_min*) (*w_q(d)* = 0). You can use the |-Q| option to change this weight assignment. The quality weight assigned to the digitized FZ trace is @@ -100,14 +100,14 @@ the filter will return 0.0. .. _-S: -**-Scode**\ [*weight*] +**-Sb**\|\ **d**\|\ **e**\|\ **t**\|\ **u**\ [*weight*] Specify the model and data traces you wish to blend and the relative custom weights of each [Defaults to 1 for all traces]. Repeat this option for each trace to consider. If you specify more than one model trace then the models are first averaged according to their quality indices and weights before blending with the digitized trace (if specified). Hence, the quality index assigned to the digitized trace is *q_r* = 1 - mean(model quality indices). The final blend is thus a weighted average that takes into account both the quality indices and the custom weights (if specified). - Choose among these traces: + Choose among these directives: - **b**: The trough location for the optimal trough/edge model blend model. This is the best fit obtained to the data using a blend of "Atlantic"-, "Pacific"-, and "Compression"-style synthetic shapes. @@ -122,10 +122,10 @@ the filter will return 0.0. .. _-T: **-T**\ *prefix* - Sets the file name prefix used for all output files [*fztrack*]. + Sets the file name prefix used for all output files [fztrack]. .. |Add_-V| replace:: |Add_-V_links| -.. include:: /explain_-V.rst_ +.. include:: ../../explain_-V.rst_ :start-after: **Syntax** :end-before: **Description** @@ -145,7 +145,7 @@ the filter will return 0.0. to exceed its threshold; (0.25) Poor: Requires the amplitude only to exceed its threshold; and (0) Bad: None of the criteria were met. We compute separate quality indices for the trough and blend models. For the empirical trough model we only have estimates or peak-to-trough - amplitude, IT(A), and trough width, IT(W). Here, we form the ratio (*A*/*a_cut*) over + amplitude, *A*, and trough width, *W*. Here, we form the ratio (*A*/*a_cut*) over (*W*/*w_cut*), take :math:`\tan^{-1}` of this ratio and scale the result to yield the range 0-1 rounded to the nearest multiple of 0.25. @@ -177,7 +177,7 @@ coordinates for the left/right bounds along the FZ. Filtering --------- -Filtering always runs of of data near the FZ end points. We utilize :doc:`filter1d` with its +Filtering always runs of of data near the FZ end points. We utilize :doc:`filter1d ` with its **-E** option to extend the result to the end. Because we are filtering data columns that may contain a strong trend (e.g., longitude versus along-track distance) we first remove such linear trends before filtering, then restore the trends before blending. However, you should @@ -204,7 +204,7 @@ filter of 70 km width followed by a 50-km Gaussian filter, try:: gmt fzblender -Su1 -Sd2 -St1 -Fm70 -Eg50 -TPac To produce a smooth trace of the maximum slope locations along track for the -same file, we try the same filters with the command +same file, we try the same filters with the command:: gmt fzblender -Se -Fm70 -Eg50 -TPac @@ -219,3 +219,10 @@ See Also :doc:`fzprofiler `, :doc:`filter1d `, :doc:`mlconverter ` + +References +---------- + +Wessel, P., Matthews, K. J., Müller, R. D., Mazzoni, A., Whittaker, J. M., Myhill, R., Chandler, M. T., +2015, "Semiautomatic fracture zone tracking", *Geochem. Geophys. Geosyst.*, 16 (7), 2462–2472. +https://doi.org/10.1002/2015GC005853. diff --git a/doc/rst/source/supplements/gsfml/fzinformer.rst b/doc/rst/source/supplements/gsfml/fzinformer.rst index fdb9752cdea..89e1d80169d 100644 --- a/doc/rst/source/supplements/gsfml/fzinformer.rst +++ b/doc/rst/source/supplements/gsfml/fzinformer.rst @@ -12,14 +12,14 @@ Synopsis .. include:: ../../common_SYN_OPTs.rst_ -**zinformer** [ |-D| ] +**fzinformer** [ |-D| ] [ |-F|\ *max* ] [ |-I|\ *profile* ] [ |-N|\ *max* ] [ |-S|\ *max* ] [ |-T|\ *prefix* ] [ |-W|\ *max* ] -[ GMT_V_OPT ] +[ |SYN_OPT-V| ] |No-spaces| @@ -29,7 +29,7 @@ Description **fzinformer** is a script developed as part of the Global Seafloor Fabric and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It make plots of statistical information obtained -by :doc:1fzanalyzer1 as a function of position along a fracture zone (FZ). +by :doc:`fzanalyzer` as a function of position along a fracture zone (FZ). Optional Arguments ------------------ @@ -66,8 +66,8 @@ Optional Arguments **-T**\ *prefix* Sets the file name prefix used when running :doc:`fzanalyzer` and :doc:`fzblender` - [The default is *fztrack*]. The files used here are *prefix*_analysis.txt - (or *prefix*_filtered.txt if |-D| is used) and *prefix*_blend.txt. + [The default is fztrack]. The files used here are *prefix*\ _analysis.txt + (or *prefix*\ _filtered.txt if |-D| is used) and *prefix*\ _blend.txt. .. _-W: @@ -75,7 +75,7 @@ Optional Arguments Sets the maximum range of FZ widths (in km) [50]. .. |Add_-V| replace:: |Add_-V_links| -.. include:: /explain_-V.rst_ +.. include:: ../../explain_-V.rst_ :start-after: **Syntax** :end-before: **Description** @@ -86,8 +86,8 @@ Optional Arguments believe a model fit to be. This assignment relies of four threshold values that need to be determined empirically. Here, *a_cut* is the minimum peak-to-trough amplitude (in Eotvos) of a model for the crossing profile [25], *v_cut* is the minimum - variance reduction offered by the model (in %) [50], *f_cu* is - the minimum F statistic computed for the model [50], and *w_cut* is a typical + variance reduction offered by the model (in %) [50], *f_cut* is + the minimum *F* statistic computed for the model [50], and *w_cut* is a typical FZ trough width (in km) [15]. Currently, the first three quantities are used to arrive at a 5-level quality index (0-1) for fitted models, as follows: (1) Very Good: Requires model parameters to exceed all three thresholds; (0.75) Good: Requires amplitude and @@ -95,7 +95,7 @@ Optional Arguments to exceed its threshold; (0.25) Poor: Requires the amplitude only to exceed its threshold; and (0) Bad: None of the criteria were met. We compute separate quality indices for the trough and blend models. For the empirical trough model we only have estimates or peak-to-trough - amplitude, IT(A), and trough width, IT(W). Here, we form the ratio (*A*/*a_cut*) over + amplitude, |-A|, and trough width, |-W|. Here, we form the ratio (*A*/*a_cut*) over (*W*/*w_cut*), take :math:`\tan^{-1}` of this ratio and scale the result to yield the range 0-1 rounded to the nearest multiple of 0.25. @@ -128,7 +128,7 @@ Panel 4 shows the width of the FZ signal for all three data. Panel 5 presents t Panel 6 shows which side (left is -1, right = +1) is the young side assuming a Pacific edge-anomaly model (it will tend to jump back and forth where the signal is close to symmetric and should only be used when we have clearly asymmetric signals). Finally, panel 7 shows -the compression parameter **C for the blend and trough models, as well as the blend parameter *A* +the compression parameter *C* for the blend and trough models, as well as the blend parameter *A* (black line) for the optimal blend model. Examples @@ -140,7 +140,7 @@ try:: fzinformer -Ttraces -N100 -I5 -The statistical plot will be named *prefix*_stat.pdf. +The statistical plot will be named *prefix*\ _stat.pdf. See Also -------- @@ -152,4 +152,11 @@ See Also :doc:`fzmapper `, :doc:`fzmodeler `, :doc:`fzprofiler `, -:doc:`grdtrack `, +:doc:`grdtrack ` + +References +---------- + +Wessel, P., Matthews, K. J., Müller, R. D., Mazzoni, A., Whittaker, J. M., Myhill, R., Chandler, M. T., +2015, "Semiautomatic fracture zone tracking", *Geochem. Geophys. Geosyst.*, 16 (7), 2462–2472. +https://doi.org/10.1002/2015GC005853. diff --git a/doc/rst/source/supplements/gsfml/fzmapper.rst b/doc/rst/source/supplements/gsfml/fzmapper.rst index c4ca01d03cb..07965fb1ad4 100644 --- a/doc/rst/source/supplements/gsfml/fzmapper.rst +++ b/doc/rst/source/supplements/gsfml/fzmapper.rst @@ -19,8 +19,8 @@ Synopsis [ |-O| ] [ |-S| ] [ |-T|\ *prefix* ] -[ |-W|\ *width*[**c**\|\ **i**\|\ **p**] ] -[ GMT_V_OPT ] +[ |SYN_OPT-V| ] +[ |-W|\ *width*\ [**c**\|\ **i**\|\ **p**] ] |No-spaces| @@ -46,7 +46,7 @@ Optional Arguments .. _-F: **-F**\ *profile* - This is the original digitized FZ traces that was given as input to:doc:`grdtrack`. + This is the original digitized FZ traces that was given as input to:doc:`grdtrack `. .. _-G: @@ -68,10 +68,10 @@ Optional Arguments **-T**\ *prefix* Sets the file name prefix used for all input files as produced by - :doc:`fzanalyzer`. The default is *fztrack*. The files are *prefix*_cross.txt and - *prefix*_par.txt as well as the resampled output from :doc:`grdtrack` which - should be called *prefix*_resampled.txt. When |-S| is set we also look for *prefix*_blend.txt - as produced by :doc:`fzblender`, and with |-A| we also look for *prefix*_analysis.txt. + :doc:`fzanalyzer` [default is fztrack]. The files are *prefix*\ _cross.txt and + *prefix*\ _par.txt as well as the resampled output from :doc:`grdtrack ` which + should be called *prefix*\ _resampled.txt. When |-S| is set we also look for *prefix*\ _blend.txt + as produced by :doc:`fzblender`, and with |-A| we also look for *prefix*\ _analysis.txt. .. _-W: @@ -80,7 +80,7 @@ Optional Arguments unit is assumed to be whatever the GMT default :term:`PROJ_LENGTH_UNIT` is currently set to. .. |Add_-V| replace:: |Add_-V_links| -.. include:: /explain_-V.rst_ +.. include:: ../../explain_-V.rst_ :start-after: **Syntax** :end-before: **Description** @@ -94,7 +94,7 @@ and only label every other profile, try:: fzmapper -Ttraces -W9i -L2 -Fguides.xy -S -V -A where we use the original digitized FZ locations guides.xy, choosing to annotate every -other profile. The final map will be named *prefix*_map.pdf. For cross-section +other profile. The final map will be named *prefix*\ _map.pdf. For cross-section profiles, see :doc:`fzprofiler`. See Also @@ -102,9 +102,16 @@ See Also :doc:`gmt ` :doc:`fzanalyzer `, -:doc:`fzblender ` +:doc:`fzblender `, :doc:`mlconverter `, :doc:`fzinformer `, :doc:`fzmodeler `, :doc:`fzprofiler `, -:doc:`grdtrack `, +:doc:`grdtrack ` + +References +---------- + +Wessel, P., Matthews, K. J., Müller, R. D., Mazzoni, A., Whittaker, J. M., Myhill, R., Chandler, M. T., +2015, "Semiautomatic fracture zone tracking", *Geochem. Geophys. Geosyst.*, 16 (7), 2462–2472. +https://doi.org/10.1002/2015GC005853. diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst index 98a53ae27fe..ec020cb419b 100644 --- a/doc/rst/source/supplements/gsfml/fzmodeler.rst +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -21,7 +21,7 @@ Synopsis [ |-O| ] [ |-P| ] [ |-S|\ *shift* ] -[ GMT_V_OPT ] +[ |SYN_OPT-V| ] [ |-W|\ *width* ] |No-spaces| @@ -90,7 +90,7 @@ Optional Arguments Sets the shift of the FZ location from the origin, in km [0]. .. |Add_-V| replace:: |Add_-V_links| -.. include:: /explain_-V.rst_ +.. include:: ../../explain_-V.rst_ :start-after: **Syntax** :end-before: **Description** @@ -104,6 +104,7 @@ Examples To plot a synthetic profile for the Pacific, using otherwise default arguments, try:: + fzmodeler -C1 -V The final plot will be named *prefix*.pdf, with the model data in *prefix*.txt. @@ -119,3 +120,10 @@ See Also :doc:`fzprofiler `, :doc:`fzmapper `, :doc:`grdtrack ` + +References +---------- + +Wessel, P., Matthews, K. J., Müller, R. D., Mazzoni, A., Whittaker, J. M., Myhill, R., Chandler, M. T., +2015, "Semiautomatic fracture zone tracking", *Geochem. Geophys. Geosyst.*, 16 (7), 2462–2472. +https://doi.org/10.1002/2015GC005853. diff --git a/doc/rst/source/supplements/gsfml/fzprofiler.rst b/doc/rst/source/supplements/gsfml/fzprofiler.rst index d55583f90a8..b882e461383 100644 --- a/doc/rst/source/supplements/gsfml/fzprofiler.rst +++ b/doc/rst/source/supplements/gsfml/fzprofiler.rst @@ -12,13 +12,13 @@ Synopsis .. include:: ../../common_SYN_OPTs.rst_ -**fzprofiler** [ |-H|\ *height*[**c**\|\ **i**\|\ **p**] ] +**fzprofiler** [ |-H|\ *height*\ [**c**\|\ **i**\|\ **p**] ] [ |-I|\ *profile* ] [ |-L|\ *inc* ] [ |-M|\ *ncols* ] [ |-T|\ *prefix* ] -[ GMT_V_OPT ] -[ |-W|\ *width*[**c**\|\ **i**\|\ **p**] ] +[ |SYN_OPT-V| ] +[ |-W|\ *width*\,[**c**\|\ **i**\|\ **p**] ] |No-spaces| @@ -59,24 +59,22 @@ Optional Arguments then all profiles are stacked vertically in one long panel; if *ncols* = 2 then we split the profiles evenly between two columns, etc. -.. _-T: +.. |Add_-V| replace:: |Add_-V_links| +.. include:: ../../explain_-V.rst_ + :start-after: **Syntax** + :end-before: **Description** **-T**\ *prefix* Sets the file name *prefix* used for all input files as produced by - :doc:`fzanalyzer`. The default is fztrack. The files are *prefix*_cross.txt, *prefix*_analysis.txt, - *prefix*_par.txt as well as the resampled output from :doc:`grdtrack` which - should be called *prefix*_resampled.txt. + :doc:`fzanalyzer` [default is fztrack]. The files are *prefix*\ _cross.txt, *prefix*\ _analysis.txt, + *prefix*\ _par.txt as well as the resampled output from :doc:`grdtrack` which + should be called *prefix*\ _resampled.txt. .. _-W: **-W**\ *width*\ [**c**\|\ **i**\|\ **p**] Similarly sets the plot width of an individual profile. For units, see |-H|. -.. |Add_-V| replace:: |Add_-V_links| -.. include:: /explain_-V.rst_ - :start-after: **Syntax** - :end-before: **Description** - Plot Features ------------- @@ -102,7 +100,7 @@ try:: fzprofiler -Ttraces -W6i -H2i -N2 -V -The final plot will be named *prefix*_cross.pdf. To see the same profiles in map +The final plot will be named *prefix*\ _cross.pdf. To see the same profiles in map view, use :doc:`fzmapper`. To plot a synthetic profile, see :doc:`fzmodeler`. See Also @@ -110,9 +108,16 @@ See Also :doc:`gmt ` :doc:`fzanalyzer `, -:doc:`fzblender ` +:doc:`fzblender `, :doc:`mlconverter `, :doc:`fzinformer `, :doc:`fzmodeler `, :doc:`fzmapper `, -:doc:`grdtrack `, +:doc:`grdtrack ` + +References +---------- + +Wessel, P., Matthews, K. J., Müller, R. D., Mazzoni, A., Whittaker, J. M., Myhill, R., Chandler, M. T., +2015, "Semiautomatic fracture zone tracking", *Geochem. Geophys. Geosyst.*, 16 (7), 2462–2472. +https://doi.org/10.1002/2015GC005853. diff --git a/doc/rst/source/supplements/gsfml/mlconverter.rst b/doc/rst/source/supplements/gsfml/mlconverter.rst index 9725dc4dd76..380c2ec8d4a 100644 --- a/doc/rst/source/supplements/gsfml/mlconverter.rst +++ b/doc/rst/source/supplements/gsfml/mlconverter.rst @@ -14,9 +14,9 @@ Synopsis **gmt mlconverter** [ *ML_data* ] [ |-A| ] -[ |-G|\ *s** ] +[ |-G|\ [**s**] ] [ |-I|\ *FZid* ] -[ |-T|\ c**\ |\ **g**\ |\ **o**\ |\ **s** ] +[ |-T|\ **c**\ |\ **g**\ |\ **o**\ |\ **s** ] [ GMT_V_OPT ] |No-spaces| @@ -52,12 +52,11 @@ Optional Arguments .. _-T: **-Tc**\ |\ **g**\ |\ **o**\ |\ **s** - Select the magnetic time scale to use. Choose from **g** (Gee and Kent, 2007), - **o** (Ogg, 2012), **s** (Gradstein, 2004), or **c** (Cande and Kent, 1995) [**g**]. -.TP + Select the magnetic time scale to use. Choose from **c** (Cande and Kent, 1995), + **g** (Gee and Kent, 2007), **o** (Ogg, 2012), or **s** (Gradstein, 2004) [**g**]. .. |Add_-V| replace:: |Add_-V_links| -.. include:: /explain_-V.rst_ +.. include:: ../../explain_-V.rst_ :start-after: **Syntax** :end-before: **Description** @@ -77,7 +76,7 @@ Optional Arguments to exceed its threshold; (0.25) Poor: Requires the amplitude only to exceed its threshold; and (0) Bad: None of the criteria were met. We compute separate quality indices for the trough and blend models. For the empirical trough model we only have estimates or peak-to-trough - amplitude, IT(A), and trough width, IT(W). Here, we form the ratio (*A*/*a_cut*) over + amplitude, *A*, and trough width, *W*. Here, we form the ratio (*A*/*a_cut*) over (*W*/*w_cut*), take :math:`\tan^{-1}` of this ratio and scale the result to yield the range 0-1 rounded to the nearest multiple of 0.25. @@ -108,9 +107,16 @@ See Also :doc:`gmt ` :doc:`fzanalyzer `, -:doc:`fzblender ` +:doc:`fzblender `, :doc:`fzinformer `, :doc:`fzmapper `, :doc:`fzmodeler `, :doc:`fzprofiler `, -:doc:`grdtrack `, +:doc:`grdtrack ` + +References +---------- + +Wessel, P., Matthews, K. J., Müller, R. D., Mazzoni, A., Whittaker, J. M., Myhill, R., Chandler, M. T., +2015, "Semiautomatic fracture zone tracking", *Geochem. Geophys. Geosyst.*, 16 (7), 2462–2472. +https://doi.org/10.1002/2015GC005853. diff --git a/src/gsfml/fzanalyzer.c b/src/gsfml/fzanalyzer.c index 94228a99d73..38da8335a4f 100644 --- a/src/gsfml/fzanalyzer.c +++ b/src/gsfml/fzanalyzer.c @@ -66,7 +66,7 @@ struct FZMODELER_CTRL { int64_t fz; int profile; } I; - struct S { /* -S */ + struct S { /* -S[b|c] */ bool active; int mode; /* 0 = bash/sh, 1 = csh/tcsh syntax */ } S; @@ -534,7 +534,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) { if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); GMT_Usage (API, 0, "usage: %s -F [-C//] " "[-A//] [-D] [-I[/]] " - "-S[c]] [-T] [%s] [-W//] " + "-S[b|c]] [-T] [%s] [-W//] " "%s] [%s] [%s]\n", name, GMT_V_OPT, GMT_colon_OPT, GMT_b_OPT, GMT_i_OPT); if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS); @@ -566,8 +566,8 @@ static int usage (struct GMTAPI_CTRL *API, int level) { GMT_Usage (API, -2, "Specify a particular id (first FZ is 0) to analyze " "[Default analyzes the cross-profiles of all FZs]. " "Optionally, append the id of a particular profile in that FZ."); - GMT_Usage (API, 1, "\n-S[c]"); - GMT_Usage (API, -2, "Write out a parameter file with settings needed for Bourne scripts. " + GMT_Usage (API, 1, "\n-S[b|c]"); + GMT_Usage (API, -2, "Write out a parameter file with settings needed for Bourne scripts [Default, or append b]. " "Append c to use csh/tcsh syntax instead."); GMT_Usage (API, 1, "\n-T"); GMT_Usage (API, -2, "Set file prefix for all output files [fztrack]."); From 488920af1342295844a9bb97107d96a2a5039a6d Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sat, 2 Dec 2023 11:49:58 +0100 Subject: [PATCH 14/20] More polish --- doc/rst/source/pstext.rst | 2 +- .../source/supplements/gsfml/fzanalyzer.rst | 28 +- .../source/supplements/gsfml/fzinformer.rst | 3 +- doc/rst/source/supplements/gsfml/fzmapper.rst | 6 +- .../source/supplements/gsfml/fzmodeler.rst | 19 +- .../source/supplements/gsfml/mlconverter.rst | 7 +- doc/rst/source/text.rst | 7 +- src/gsfml/fzinformer | 168 +++++---- src/gsfml/fzmapper | 122 +++---- src/gsfml/fzmodeler | 81 +++-- src/gsfml/fzprofiler | 326 +++++++++--------- src/pstext.c | 6 +- 12 files changed, 378 insertions(+), 397 deletions(-) diff --git a/doc/rst/source/pstext.rst b/doc/rst/source/pstext.rst index f706ec58d30..4c5eaf08fae 100644 --- a/doc/rst/source/pstext.rst +++ b/doc/rst/source/pstext.rst @@ -17,7 +17,7 @@ Synopsis |SYN_OPT-Rz| [ |-A| ] |SYN_OPT-B| -[ |-C|\ [*dx/dy*][**+to**\|\ **O**\|\ **c**\|\ **C**] ] +[ |-C|\ [*dx*\ [/*dy*]][**+to**\|\ **O**\|\ **c**\|\ **C**] ] [ |-D|\ [**j**\|\ **J**]\ *dx*\ [/*dy*][**+v**\ [*pen*]] ] [ |-F|\ [**+a**\ [*angle*]][**+c**\ [*justify*]][**+f**\ [*font*]][**+j**\ [*justify*]][**+h**\|\ **l**\|\ **r**\ [*first*] \|\ **t**\ *text*\|\ **z**\ [*format*]] ] [ |-G|\ [*fill*][**+n**] ] diff --git a/doc/rst/source/supplements/gsfml/fzanalyzer.rst b/doc/rst/source/supplements/gsfml/fzanalyzer.rst index 3ffabdcce53..9c1a9c453ad 100644 --- a/doc/rst/source/supplements/gsfml/fzanalyzer.rst +++ b/doc/rst/source/supplements/gsfml/fzanalyzer.rst @@ -36,7 +36,7 @@ Description **fzanalyzer** is a tool developed as part of the Global Seafloor Fabric and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It reads processed fracture zone (FZ) traces and cross-profiles as -produced by :doc:`grdtrack`. It then analyzes the trace of each FZ +produced by :doc:`grdtrack `. It then analyzes the trace of each FZ by examining cross-sections orthogonal to the FZ trend and modeling these profiles using a blend model of "Atlantic"-style symmetric troughs and "Pacific"-style asymmetric, dipole-like anomalies, modulated with some peripheral bulges ("compression"). @@ -51,7 +51,7 @@ Required Arguments ------------------ *crossprofiles* - This file is a table with cross-profiles as produced by :doc:`grdtrack` **-C** + This file is a table with cross-profiles as produced by :doc:`grdtrack ` **-C** from an approximate digitized trace (with *lon*, *lat*) of one or more FZs. This is an ASCII (or binary, see **-bi**) file that must contain 7 data columns: *lon, lat, dist, azimuth, vgg, age, fzdist*. @@ -59,9 +59,9 @@ Required Arguments .. _-F: **-F**\ *fzlines* - Here, *fzlines* is a file with resampled track lines obtained by running :doc:`grdtrack` **-D**. + Here, *fzlines* is a file with resampled track lines obtained by running :doc:`grdtrack ` **-D**. As for *crossprofiles* the file must contain the same 7 data columns *lon, lat, dist, azimuth, vgg, age, fzdist*. - See INPUT FILES for more details. + See Input Files for more details. Optional Arguments ------------------ @@ -108,7 +108,7 @@ Optional Arguments .. _-T: **-T**\ *prefix* - Sets the file name prefix used for all output files [*fztrack*]. + Sets the file name prefix used for all output files [fztrack]. .. |Add_-V| replace:: |Add_-V_links| .. include:: ../../explain_-V.rst_ @@ -142,19 +142,19 @@ Optional Arguments Input Files ----------- -The two input files are themselves generated by running :doc:`grdtrack` first. This step +The two input files are themselves generated by running :doc:`grdtrack ` first. This step requires a set of digitized FZ tracks (*lon*, *lat*) and three data grids: (a) a VGG vertical gravity gradient file, (b) a 2 minute crustal age grid, and (c) a grid with distance to the nearest FZ in km, listed in that order. The critical file is the VGG grid. If you don't have or care about ages and distances you can make dummy grids that -are all NaNs. You design your cross-profile layout and resampled FZ trackes using :doc:`grdtrack` -options **-C** and **-D**.. +are all NaNs. You design your cross-profile layout and resampled FZ trackes using :doc:`grdtrack ` +options **-C** and **-D**.. Nearest Fracture Zone Distances ------------------------------- You can use :doc:`grdmath` to create the nearest fracture zone distance grid (in km) required -to prepare the profiles. A typical command suitable for the Nazca plate area might be:: +to prepare the profiles. A typical command suitable for the Nazca plate area might be:: gmt grdmath -R-120/-65/-50/5 -I5m -fg digitize.txt LDIST DEG2KM = dist2fz.nc @@ -173,18 +173,18 @@ then blend these together into a global grid with:: gmt grdblend -Rg -I2 -fg EN.nc WN.nc ES.nc WS.nc -Gdist2FZ.nc -V rm -f WN.nc EN.nc WS.nc ES.nc -To make NaN grids for ages and/or distances for the Nazca area, use +To make NaN grids for ages and/or distances for the Nazca area, use:: gmt grdmath -R-120/-65/-50/5 -I5m -fg 0 0 NaN = ages.nc -**fzanalyzer** can produce up to three output files; these are described below: - Output Files ------------ +**fzanalyzer** can produce up to three output files; these are described below: + #. File *prefix*\ _analysis.txt contains the results of the analysis for each cross profile. There 61 output columns containing the fitted or observed values (see - DETERMINED PARAMETERS). This file is used by :doc:`fzblender` to produce a smooth + Determined Parameters). This file is used by :doc:`fzblender` to produce a smooth and optimal fit to the fracture zone. #. File *prefix*\ _cross.txt contains both observed and predicted best-fitting models for each cross profile. It can be used for plotting and visual analysis of the @@ -194,7 +194,7 @@ Output Files can include this script in custom mapping or analysis scripts and use the variables as you see fit. #. Finally, while not an output file from **fzanalyzer**, you should use the name - *prefix*\ _resampled.txt for the output of :doc:`grdtrack` **-D** as that is what the + *prefix*\ _resampled.txt for the output of :doc:`grdtrack ` **-D** as that is what the scripts for plotting expect. Examples diff --git a/doc/rst/source/supplements/gsfml/fzinformer.rst b/doc/rst/source/supplements/gsfml/fzinformer.rst index 89e1d80169d..fe067ac3a9a 100644 --- a/doc/rst/source/supplements/gsfml/fzinformer.rst +++ b/doc/rst/source/supplements/gsfml/fzinformer.rst @@ -151,8 +151,7 @@ See Also :doc:`mlconverter `, :doc:`fzmapper `, :doc:`fzmodeler `, -:doc:`fzprofiler `, -:doc:`grdtrack ` +:doc:`fzprofiler ` References ---------- diff --git a/doc/rst/source/supplements/gsfml/fzmapper.rst b/doc/rst/source/supplements/gsfml/fzmapper.rst index 07965fb1ad4..f4b56bfaf76 100644 --- a/doc/rst/source/supplements/gsfml/fzmapper.rst +++ b/doc/rst/source/supplements/gsfml/fzmapper.rst @@ -31,7 +31,7 @@ Description and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It make a Mercator map of cross-profiles from the processed fracture zone (FZ) traces and cross-profiles as -produced by :doc:`grdtrack`. Optionally, overlay analysis and blend results. +produced by :doc:`grdtrack `. Optionally, overlay analysis and blend results. Optional Arguments ------------------ @@ -91,9 +91,9 @@ To look at the cross-profiles and the best-fit models and optimal FZ locations i map view, with the prefix used previously as "traces", using a 9 inch wide Mercator, and only label every other profile, try:: - fzmapper -Ttraces -W9i -L2 -Fguides.xy -S -V -A + fzmapper -Ttraces -W9i -L2 -Fguides.txt -S -V -A -where we use the original digitized FZ locations guides.xy, choosing to annotate every +where we use the original digitized FZ locations guides.txt, choosing to annotate every other profile. The final map will be named *prefix*\ _map.pdf. For cross-section profiles, see :doc:`fzprofiler`. diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst index ec020cb419b..cb19c16dd30 100644 --- a/doc/rst/source/supplements/gsfml/fzmodeler.rst +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -15,12 +15,12 @@ Synopsis **fzmodeler** [ |-A|\ *asymmetry* ] [ |-C|\ *compression* ] [ |-D|\ *min*/*max*/*inc* ] -[ |-F|\ *prefix* ] [ |-M| ] [ |-N|\ *amplitude* ] [ |-O| ] [ |-P| ] [ |-S|\ *shift* ] +[ |-T|\ *prefix* ] [ |SYN_OPT-V| ] [ |-W|\ *width* ] @@ -30,7 +30,7 @@ Description ----------- **zmodeler** is a script developed as part of the Global Seafloor Fabric -and Magnetic Lineation Project [see www.soest.hawaii.edu/PT/GSFML for a full +and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It builds a synthetic model cross-profile given the chosen model parameters and optionally images the profile via a PDF plot. @@ -56,12 +56,6 @@ Optional Arguments expected to be in degrees of latitude which *inc* will be decoded as arc minutes [-5/5/2 or -100/100/2, depending on |-M|]. -.. _-F: - -**-F**\ *prefix* - Set the output prefix for the model profile [fzprof]. Give |-F|\ **-** to send - the model profile to stdout. - .. _-M: **-M** @@ -77,7 +71,7 @@ Optional Arguments **-O** Instead of making a stand-alone PDF plot, write a PostScript overlay to stdout, - i.e., make the plot using the GMT **-O -K** options. Requires (or sets) |-P|. + i.e., make the plot using the GMT classic code **-O -K** options. Requires (or sets) |-P|. .. _-P: @@ -89,6 +83,12 @@ Optional Arguments **-S**\ *shift* Sets the shift of the FZ location from the origin, in km [0]. +.. _-T: + +**-T**\ *prefix* + Set the output prefix for the model profile [fzprof]. Give |-T|\ **-** to send + the model profile to stdout. + .. |Add_-V| replace:: |Add_-V_links| .. include:: ../../explain_-V.rst_ :start-after: **Syntax** @@ -119,7 +119,6 @@ See Also :doc:`fzinformer `, :doc:`fzprofiler `, :doc:`fzmapper `, -:doc:`grdtrack ` References ---------- diff --git a/doc/rst/source/supplements/gsfml/mlconverter.rst b/doc/rst/source/supplements/gsfml/mlconverter.rst index 380c2ec8d4a..fcd43510261 100644 --- a/doc/rst/source/supplements/gsfml/mlconverter.rst +++ b/doc/rst/source/supplements/gsfml/mlconverter.rst @@ -27,7 +27,7 @@ Description **mlconverter** is a module developed as part of the Global Seafloor Fabric and Magnetic Lineation Project [[see `GSFML `_ for a full description of the project]. It reads a magnetic pick data file (or stdin) -and converts chron textstrings to ages using a selected magnetic time scale. +and converts chron text-strings to ages using a selected magnetic time scale. The input data must be OGR/GMT data files of the form distributed by the GSFML project. @@ -68,7 +68,7 @@ Optional Arguments that need to be determined empirically. Here, *a_cut* is the minimum peak-to-trough amplitude (in Eotvos) of a model for the crossing profile [25], *v_cut* is the minimum variance reduction offered by the model (in %) [50], *f_cu* is - the minimum F statistic computed for the model [50], and *w_cut* is a typical + the minimum *F* statistic computed for the model [50], and *w_cut* is a typical FZ trough width (in km) [15]. Currently, the first three quantities are used to arrive at a 5-level quality index (0-1) for fitted models, as follows: (1) Very Good: Requires model parameters to exceed all three thresholds; (0.75) Good: Requires amplitude and @@ -111,8 +111,7 @@ See Also :doc:`fzinformer `, :doc:`fzmapper `, :doc:`fzmodeler `, -:doc:`fzprofiler `, -:doc:`grdtrack ` +:doc:`fzprofiler ` References ---------- diff --git a/doc/rst/source/text.rst b/doc/rst/source/text.rst index 3ba4a028255..ddbf5119316 100644 --- a/doc/rst/source/text.rst +++ b/doc/rst/source/text.rst @@ -17,7 +17,7 @@ Synopsis |SYN_OPT-Rz| [ |-A| ] [ |SYN_OPT-B| ] -[ |-C|\ [*dx/dy*][**+to**\|\ **O**\|\ **c**\|\ **C**] ] +[ |-C|\ [*dx*\ [/*dy*]][**+to**\|\ **O**\|\ **c**\|\ **C**] ] [ |-D|\ [**j**\|\ **J**]\ *dx*\ [/*dy*][**+v**\ [*pen*]] ] [ |-F|\ [**+a**\ [*angle*]][**+c**\ [*justify*]][**+f**\ [*font*]][**+j**\ [*justify*]][**+h**\|\ **l**\|\ **r**\ [*first*] \|\ **t**\ *text*\|\ **z**\ [*format*]] ] [ |-G|\ [*fill*][**+n**] ] @@ -148,12 +148,13 @@ Optional Arguments .. _-C: -**-C**\ [*dx/dy*][**+to**\|\ **O**\|\ **c**\|\ **C**] +**-C**\ [*dx*\ [/*dy*]][**+to**\|\ **O**\|\ **c**\|\ **C**] Adjust the clearance between the text and the surrounding box [15%]. Only used if |-W| or |-G| are specified. Append the unit you want (**c**\ m, **i**\ nch, or **p**\ oint; if not given we consult :term:`PROJ_LENGTH_UNIT`) or % for a percentage of the font size. - Optionally, use modifier **+t** to set the shape of the textbox when using |-G| and/or |-W|. + If *dy* is not specified then it is set equal to *dx*. Optionally, + use modifier **+t** to set the shape of the textbox when using |-G| and/or |-W|. Append lower case **o** to get a straight rectangle [Default]. Append upper case **O** to get a rounded rectangle. In paragraph mode (|-M|) you can also append lower case **c** to get a concave diff --git a/src/gsfml/fzinformer b/src/gsfml/fzinformer index 0fd78bb554e..a9218297b09 100755 --- a/src/gsfml/fzinformer +++ b/src/gsfml/fzinformer @@ -80,107 +80,101 @@ while [ ! x"$1" = x ]; do esac done -if [ $filtered -eq 0 ]; then +if [ ${filtered} -eq 0 ]; then AFILE=${prefix}_analysis.txt else AFILE=${prefix}_filtered.txt fi BFILE=${prefix}_blend.txt -PS=${prefix}_stat.ps -PDF=${prefix}_stat.pdf #----------------------------------------- ymargin=1 xmargin=1 spacing=0.175 W=6.3 H=1.2 -xu=`gmt math -Q -0.75 1 $xmargin SUB ADD =` -yu=`gmt math -Q -0.75 1 $ymargin SUB ADD =` +xu=`gmt math -Q -0.75 1 ${xmargin} SUB ADD =` +yu=`gmt math -Q -0.75 1 ${ymargin} SUB ADD =` # Extract our segment */ -gmt convert -Q$P $AFILE > /tmp/t.txt +gmt convert -Q${P} ${AFILE} > /tmp/t.txt # How many points along segment? n_cross=`cat /tmp/t.txt | wc -l | awk '{printf "%d\n", $1-1}'` -yup=`gmt math -Q $H $spacing ADD =` -gmt info $AFILE -C -I1/1/2/10/0.01/1/1/5/5/5/1 > $$.info +yup=`gmt math -Q ${H} ${spacing} ADD =` +gmt info ${AFILE} -C -I1/1/2/10/0.01/1/1/5/5/5/1 > $$.info dmin=`cut -f5 $$.info` dmax=`cut -f6 $$.info` -gmt psbasemap -R$dmin/$dmax/0/1 -JX6i/8.9i -P -U/${xu}i/${yu}i/"$prefix" -K -B+gwhite -X${xmargin}i -Y${ymargin}i > $PS -# Plot blend and u values -x=`fz_col_id DR` -y=`fz_col_id BL` -gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-0.05/1.05 -JX${W}i/${H}i -Bxa500f100+l"Distance along FZ"+u"km" -Bya0.2f0.1 -BWSnE -Y0.25i -O -K -W1p --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i >> $PS -y=`fz_col_id UT` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS -y=`fz_col_id UB` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS -echo "$dmax 1.05 C" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS -echo "$dmin 1.05 A" | gmt pstext -R$dmin/$dmax/-0.05/1.05 -J -O -K -Gwhite -W0.25p -F+jTL+f9p -Dj0.05i/0.05i >> $PS -# Plot directions -y=`fz_col_id OR` -gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-1.1/1.1 -JX${W}i/${H}i -Bxa500f100 -Bya1g5 -BWsnE -O -K -W1p -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i >> $PS -echo "$dmax 0 O" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jBR+f9p -Dj0.05i/0.05i >> $PS -# Plot offsets -y=`fz_col_id SD` -gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-$smax/$smax -JX${W}i/${H}i -Bxa500f100 -Bya5f1g100 -BWsnE -O -K -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS -y=`fz_col_id ST` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS -y=`fz_col_id SB` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS -echo "$dmax $smax @~D@~" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS -# Plot widths -y=`fz_col_id WD` -gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/0/$wmax -JX${W}i/${H}i -Bxa500f100 -Bya10f5 -BWsnE -O -K -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS -y=`fz_col_id WT` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS -y=`fz_col_id WB` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS -echo "$dmax $wmax W" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS -gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS -$dmin 15 -$dmax 15 -EOF -# Plot amplitudes -y=`fz_col_id AD` -gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/0/$amax -JX${W}i/${H}i -Bxa500f100 -Bya50f10g1000 -BWsnE -O -K -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS -y=`fz_col_id AT` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,green >> $PS -y=`fz_col_id AB` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS -echo "$dmax $amax A" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS -gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS -$dmin 25 -$dmax 25 -EOF -# Plot variance reductions -y=`fz_col_id VT` -gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/-5/105 -JX${W}i/${H}i -Bxa500f100 -Bya20f5 -BWsnE -O -K -W1p,green -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS -y=`fz_col_id VB` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS -echo "$dmax 105 V" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS -gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS -$dmin 50 -$dmax 50 -EOF -# Plot F values -y=`fz_col_id FT` -gmt psxy $AFILE -i$x,$y -R$dmin/$dmax/1/$fmax -JX${W}i/${H}il -Bxa500f100 -Bya1pf3 -BWsE -O -K -W1p,green -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 >> $PS -echo "$dmax $fmax F" | gmt pstext -R -J -O -K -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i/0.05i >> $PS -y=`fz_col_id FB` -gmt psxy $AFILE -i$x,$y -R -J -O -K -W1p,blue >> $PS -gmt psxy -R -J -O -K -W0.5p,- << EOF >> $PS -$dmin 50 -$dmax 50 -EOF -#grep -v '^>' $AFILE | cut -f3,11 | gmt psxy -R$dmin/$dmax/0/4 -JX${W}i/${H}i -Bxa500f100 -Bya1f1+l"Q" -BWse -O -K -W1p -Y${yup}i --FONT_ANNOT_PRIMARY=10 >> $PS -gmt psbasemap -R0/$n_cross/0/100 -JX${W}i/${H}i -Bxa20f1+l"FZ ID $P" -By0 -BN -O -K --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i >> $PS -gmt psxy -R -J -O -T >> $PS -gmt psconvert -Tf $PS -if [ $verbose -eq 1 ]; then - echo "fzinformer: Final plot is called $PDF" >&2 -fi -os=`uname -s` -if [ $os = "Darwin" ]; then - open $PDF -fi -rm -f $PS +gmt begin ${prefix}_stat pdf + gmt basemap -R${dmin}/${dmax}/0/1 -JX6i/8.9i -U/${xu}i/${yu}i/"${prefix}" -K -B+gwhite -X${xmargin}i -Y${ymargin}i + # Plot blend and u values + x=`fz_col_id DR` + y=`fz_col_id BL` + gmt plot ${AFILE} -i${x},${y} -R${dmin}/${dmax}/-0.05/1.05 -JX${W}i/${H}i -Bxa500f100+l"Distance along FZ"+u"km" -Bya0.2f0.1 -BWSnE -Y0.25i -W1p --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i + y=`fz_col_id UT` + gmt plot ${AFILE} -i${x},${y} -W1p,green + y=`fz_col_id UB` + gmt plot ${AFILE} -i${x},${y} -W1p,blue + echo "${dmax} 1.05 C" | gmt text-Gwhite -W0.25p -F+jTR+f9p -Dj0.05i + echo "${dmin} 1.05 A" | gmt text -Gwhite -W0.25p -F+jTL+f9p -Dj0.05i + # Plot directions + y=`fz_col_id OR` + gmt plot $AFI{LE -i${x},${y} -R${dmin}/${dmax}/-1.1/1.1 -Bxa500f100 -Bya1g5 -BWsnE -W1p -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i + echo "${dmax} 0 O" | gmt text Gwhite -W0.25p -F+jBR+f9p -Dj0.05i + # Plot offsets + y=`fz_col_id SD` + gmt plot ${AFILE} -i${x},${y} -R${dmin}/${dmax}/-${smax}/${smax} -Bxa500f100 -Bya5f1g100 -BWsnE -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 + y=`fz_col_id ST` + gmt plot ${AFILE} -i${x},${y} -W1p,green + y=`fz_col_id SB` + gmt plot ${AFILE} -i${x},${y} -W1p,blue + echo "$dmax $smax @~D@~" | gmt text -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i + # Plot widths + y=`fz_col_id WD` + gmt plot ${AFILE} -i${x},${y} -R${dmin}/${dmax}/0/${wmax} -Bxa500f100 -Bya10f5 -BWsnE -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 + y=`fz_col_id WT` + gmt plot ${AFILE} -i${x},${y} -W1p,green + y=`fz_col_id WB` + gmt plot ${AFILE} -i${x},${y} -W1p,blue + echo "${dmax} ${wmax} W" | gmt text -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i + gmt plot -W0.5p,- << EOF + ${dmin} 15 + ${dmax} 15 + EOF + # Plot amplitudes + y=`fz_col_id AD` + gmt plot ${AFILE} -i${x},${y} -R${dmin}/${dmax}/0/${amax} -Bxa500f100 -Bya50f10g1000 -BWsnE -W1p,red -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 + y=`fz_col_id AT` + gmt plot ${AFILE} -i${x},${y} -W1p,green + y=`fz_col_id AB` + gmt plot ${AFILE} -i${x},${y}-W1p,blue + echo "${dmax} ${amax} A" | gmt text-Gwhite -W0.25p -F+jTR+f9p -Dj0.05i + gmt plot -W0.5p,- << EOF + ${dmin} 25 + ${dmax} 25 + EOF + # Plot variance reductions + y=`fz_col_id VT` + gmt plot ${AFILE} -i${x},${y} -R${dmin}/${dmax}/-5/105 -JX${W}i/${H}i -Bxa500f100 -Bya20f5 -BWsnE -W1p,green -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 + y=`fz_col_id VB` + gmt plot ${AFILE} -i${x},${y} -W1p,blue + echo "${dmax} 105 V" | gmt text -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i + gmt plot -W0.5p,- << EOF + ${dmin} 50 + ${dmax} 50 + EOF + # Plot F values + y=`fz_col_id FT` + gmt plot ${AFILE} -i${x},${y} -R${dmin}/${dmax}/1/${fmax} -JX${W}i/${H}il -Bxa500f100 -Bya1pf3 -BWsE -W1p,green -Y${yup}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 + echo "${dmax} ${fmax} F" | gmt text -Gwhite -W0.25p -F+jTR+f9p -Dj0.05i + y=`fz_col_id FB` + gmt plot ${AFILE} -i${x},${y} -W1p,blue + gmt plot -W0.5p,- << EOF + ${dmin} 50 + ${dmax} 50 + EOF + #grep -v '^>' ${AFILE} | cut -f3,11 | gmt plot -R${dmin}/${dmax}/0/4 -Bxa500f100 -Bya1f1+l"Q" -BWse -W1p -Y${yup}i --FONT_ANNOT_PRIMARY=10 + gmt basemap -R0/${n_cross}/0/100 -Bxa20f1+l"FZ ID ${P}" -By0 -BN --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 --MAP_LABEL_OFFSET=0.05i + if [ $verbose -eq 1 ]; then + echo "fzinformer: Final plot is called ${prefix}_stat.pdf" >&2 + fi +gmt end show + fz_cleanup 1 diff --git a/src/gsfml/fzmapper b/src/gsfml/fzmapper index 54ec61069f7..85c405d0b66 100755 --- a/src/gsfml/fzmapper +++ b/src/gsfml/fzmapper @@ -73,7 +73,7 @@ while [ ! x"$1" = x ]; do shift;; -L*) N=`fz_get_arg $1`; # Annotate every N'th profile shift;; - -O) OL=1; # Plot as overlay to stdout + -O) OL=1; # Plot as PS overlay to stdout plot=1; shift;; -S) blend=1 # Overlay blend if possible @@ -90,23 +90,23 @@ done # Make sure we convert to inches #----------------------------------------- CFILE=${prefix}_resampled.txt # The resampled tracks from grdtrack -D -if [ ! -f $CFILE ]; then # Cannot do it yet anyway +if [ ! -f ${CFILE} ]; then # Cannot do it yet anyway anal=0 - echo "$0: Resampled file $CFILE not found - cannot make plot" >&2 + echo "$0: Resampled file ${CFILE} not found - cannot make plot" >&2 exit fi XFILE=${prefix}_cross.txt # Crossprofiles from fzmodeler -if [ ! -f $XFILE ]; then # Cannot do it yet anyway +if [ ! -f ${XFILE} ]; then # Cannot do it yet anyway anal=0 - echo "$0: Cross-profile file $XFILE not found - cannot make plot" >&2 + echo "$0: Cross-profile file ${XFILE} not found - cannot make plot" >&2 exit fi TFILE=${prefix}_analysis.txt # The results from fzmodeler -if [ ! -f $TFILE ] && [ $anal -eq 1 ]; then # Cannot do it yet anyway +if [ ! -f ${TFILE} ] && [ ${anal} -eq 1 ]; then # Cannot do it yet anyway anal=0 - echo "$0: Analysis file $TFILE not found - ignored" >&2 + echo "$0: Analysis file ${TFILE} not found - ignored" >&2 fi -if [ $OL -eq 1 ]; then +if [ ${OL} -eq 1 ]; then PS=/tmp/map.ps # PostScript plot file PSargs="-O -K" else @@ -120,23 +120,23 @@ fi # Cross-profiles have lon,lat,dist,azimuth,vgg,age,fzdist columns. # Assign variables and calculate dimensions (inches used throughout) #------------------------------------------------------------------------------------------------------ -ymargin=0.75 # Bottom margin -xmargin=1 # Left margin -gmt set PROJ_ELLIPSOID Sphere # Since we are plotting VGG -n_cross=`gmt convert -L $XFILE | wc -l` # Number of cross-profiles -ndig=`gmt math -Q $n_cross LOG10 FLOOR 1 ADD =` # Number of digits to use for running numbers -gmt info $XFILE -C -I2/2/2/5/10/10/10/10/10 -fg > $$.info # Get clean multiples of min/max for each column -xmin=`cut -f1 $$.info` # West boundary -xmax=`cut -f2 $$.info` # East boundary -ymin=`cut -f3 $$.info` # South boundary -ymax=`cut -f4 $$.info` # North boundary -width2=`gmt math -Q $W 2 $xmargin MUL ADD =` # Width of entire plot including margins -R=-R$xmin/$xmax/$ymin/$ymax # Region -R option -height=`echo $xmax $ymax | gmt mapproject $R -JM${W}i -Di | cut -f2` # Map height -height2=`gmt math -Q $height 2 $ymargin MUL ADD =` # Plot height including margins +ymargin=0.75 # Bottom margin +xmargin=1 # Left margin +gmt set PROJ_ELLIPSOID Sphere # Since we are plotting VGG +n_cross=`gmt convert -L ${XFILE} | wc -l` # Number of cross-profiles +ndig=`gmt math -Q ${n_cross} LOG10 FLOOR 1 ADD =` # Number of digits to use for running numbers +gmt info $XFILE -C -I2/2/2/5/10/10/10/10/10 -fg > $$.info # Get clean multiples of min/max for each column +xmin=`cut -f1 $$.info` # West boundary +xmax=`cut -f2 $$.info` # East boundary +ymin=`cut -f3 $$.info` # South boundary +ymax=`cut -f4 $$.info` # North boundary +width2=`gmt math -Q ${W} 2 ${xmargin} MUL ADD =` # Width of entire plot including margins +R=-R${xmin}/${xmax}/${ymin}/${ymax} # Region -R option +height=`echo ${xmax} ${ymax} | gmt mapproject ${}R -JM${W}i -Di | cut -f2` # Map height +height2=`gmt math -Q ${height} 2 $ymargin MUL ADD =` # Plot height including margins #------------------------------------------------------------------------------------------------------ # Ready for plotting -if [ $verbose -eq 1 ]; then +if [ ${verbose} -eq 1 ]; then echo "fzmapper: Papersize is ${width2}i by ${height2}i" >&2 fi #------------------------------------------------------------------------------------------------------ @@ -146,17 +146,17 @@ else PSargs="-P -K -X${xmargin}i -Y${ymargin}i --PS_MEDIA=${width2}ix${height2}i" fi gmt makecpt -Cgray -T-60/60/5 -Z > $$.cpt # Make basic -60 to + 60 Eotvos grayscale CPT -xu=`gmt math -Q -0.75 1 $xmargin SUB ADD =` # Placement x for -U logo and label -yu=`gmt math -Q -0.75 1 $ymargin SUB ADD =` # Placement y for -U logo and label +xu=`gmt math -Q -0.75 1 ${xmargin} SUB ADD =` # Placement x for -U logo and label +yu=`gmt math -Q -0.75 1 ${ymargin} SUB ADD =` # Placement y for -U logo and label # Lay down VGG image -gmt grdimage ${VGG} -C$$.cpt $R -JX${W}i/${height}i $PSargs >| $PS +gmt grdimage ${VGG} -C$$.cpt ${R} -JM${W}i ${PSargs} >| $PS # Overlay geographic basemap and set -U label -gmt psbasemap $R -JM${W}i -O -B5f1g90 -BWSne -K -U/${xu}i/${yu}i/"${prefix}: Map view" >> $PS +gmt psbasemap ${R} -JM${W}i -O -B5f1g90 -BWSne -K -U/${xu}i/${yu}i/"${prefix}: Map view" >> $PS # Draw resampled FZ tracks as blue solid line -gmt psxy -R -J -O -K $CFILE -W0.5p,blue >> $PS +gmt psxy -R -J -O -K ${CFILE} -W0.5p,blue >> $PS # Plot original digitized points as dark blue squares if [ ! "X${ORIG}" = "X" ]; then - gmt psxy -R -J -O -K $ORIG -Ss0.04i -Gdarkblue >> $PS + gmt psxy -R -J -O -K ${ORIG} -Ss0.04i -Gdarkblue >> $PS fi P=0 # Make color table for quality weights (0-1) @@ -170,71 +170,71 @@ cat << EOF >> $$.cpt2 EOF # Process each crossing profile individually -while [ $P -lt $n_cross ]; do - item=`echo $P $ndig | awk '{printf "%*.*d\n", $2, $2, $1}'` # Format an integer as profile identifier - gmt convert -Q$P $XFILE > $$.raw # Extract the next profile to plot (includes the segment header) +while [ ${P} -lt ${n_cross} ]; do + item=`echo ${P} ${ndig} | awk '{printf "%*.*d\n", $2, $2, $1}'` # Format an integer as profile identifier + gmt convert -Q$P ${XFILE} > $$.raw # Extract the next profile to plot (includes the segment header) grep -v '>' $$.raw > $$.tmp # Get this cross profile without header header=`head -1 $$.raw` # Get this cross profile's header - az=`fz_get_item "$header" az` # Extract the azimuth of this profile + az=`fz_get_item "${header}" az` # Extract the azimuth of this profile tail -1 $$.raw | cut -f1,2 > $$.tail # Place the end coordinates of profile in file $$.tail gmt psxy $$.tmp -R -J -O -K -Wfaint,lightblue >> $PS # Plot cross-profile as faint, lightblue lines - go=`gmt math -Q $P $N MOD 0 EQ =` # Determine when to annotate profiles - if [ $go -eq 1 ]; then # OK, want to place text ID for this cross profile - side=`gmt math -Q $az 180 LT =` # Determine which side to place profile label - if [ $side -eq 1 ]; then - awk '{ printf "%s %s %s LM %s\n", $1, $2, '"$az"', '"$item"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS + go=`gmt math -Q ${P} ${N} MOD 0 EQ =` # Determine when to annotate profiles + if [ ${go} -eq 1 ]; then # OK, want to place text ID for this cross profile + side=`gmt math -Q ${az} 180 LT =` # Determine which side to place profile label + if [ ${side} -eq 1 ]; then + awk '{ printf "%s %s %s LM %s\n", $1, $2, '"${az}"', '"${item}"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS else - awk '{ printf "%s %s %s RM %s\n", $1, $2, '"$az"', '"$item"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS + awk '{ printf "%s %s %s RM %s\n", $1, $2, '"${az}"', '"${item}"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS fi fi - P=`expr $P + 1` # Goto next profile + P=`expr ${P} + 1` # Goto next profile done # Plot resampled digitized line in magenta -gmt psxy -R -J -O -K $CFILE -W0.25p,magenta >> $PS +gmt psxy -R -J -O -K ${CFILE} -W0.25p,magenta >> $PS # Plot empirical trough locations in red x=`fz_col_id XD0` y=`fz_col_id YD0` -if [ $anal -eq 1 ]; then - gmt psxy $TFILE -R -J -O -K -Sc0.02i -Gred -i$x,$y >> $PS +if [ ${anal} -eq 1 ]; then + gmt psxy ${TFILE} -R -J -O -K -Sc0.02i -Gred -i${x},${y} >> $PS # Plot blend trough locations in green x=`fz_col_id XB0` y=`fz_col_id YB0` - gmt psxy $TFILE -R -J -O -K -Sc0.02i -Ggreen3 -i$x,$y >> $PS + gmt psxy ${TFILE} -R -J -O -K -Sc0.02i -Ggreen3 -i${x},${y} >> $PS # Plot edge blend locations in blue x=`fz_col_id XE0` y=`fz_col_id YE0` - gmt psxy $TFILE -R -J -O -K -Sc0.02i -Gblue -i$x,$y >> $PS + gmt psxy ${TFILE} -R -J -O -K -Sc0.02i -Gblue -i${x},${y} >> $PS fi -if [ $blend -eq 1 ]; then +if [ ${blend} -eq 1 ]; then BFILE=${prefix}_blend.txt # Blended solution from fzblender - if [ -f $BFILE ]; then + if [ -f ${BFILE} ]; then # Plot best blend model as cyan line with colored circles reflecting quality - gmt psxy $BFILE -R -J -O -K -W0.5p,cyan >> $PS - gmt psxy $BFILE -R -J -O -K -Sc0.03i -C$$.cpt2 -i0,1,5 >> $PS + gmt psxy ${BFILE} -R -J -O -K -W0.5p,cyan >> $PS + gmt psxy ${BFILE} -R -J -O -K -Sc0.03i -C$$.cpt2 -i0,1,5 >> $PS # Add error bounds as dashed orange lines - gmt psxy $BFILE -R -J -O -K -W0.25p,orange,- -i6,7 >> $PS - gmt psxy $BFILE -R -J -O -K -W0.25p,orange,- -i8,9 >> $PS + gmt psxy ${BFILE} -R -J -O -K -W0.25p,orange,- -i6,7 >> $PS + gmt psxy ${BFILE} -R -J -O -K -W0.25p,orange,- -i8,9 >> $PS else - echo "$0: Blend file $BFILE not found - ignored" >&2 + echo "$0: Blend file ${BFILE} not found - ignored" >&2 fi fi -if [ $OL -eq 1 ]; then - cat $PS +if [ ${OL} -eq 1 ]; then + cat ${PS} else # Finalize plot - gmt psxy -R -J -O -T >> $PS + gmt psxy -R -J -O -T >> ${PS} # Convert the PS to a PDF file - gmt psconvert -Tf $PS + gmt psconvert -Tf ${PS} # Delete temporary files and the PS file os=`uname -s` - if [ $verbose -eq 1 ]; then - echo "fzmapper: Final map is called $PDF" >&2 + if [ ${verbose} -eq 1 ]; then + echo "fzmapper: Final map is called ${PDF}" >&2 fi - if [ $os = "Darwin" ]; then - open $PDF + if [ ${os} = "Darwin" ]; then + open ${PDF} fi fi -rm -f $PS +rm -f ${PS} fz_cleanup 1 diff --git a/src/gsfml/fzmodeler b/src/gsfml/fzmodeler index 338dcae9bc7..fbcfb063fc7 100755 --- a/src/gsfml/fzmodeler +++ b/src/gsfml/fzmodeler @@ -23,17 +23,17 @@ function G0 () { # Gaussian - The Atlantic signal. Expects: x0 x1 dx center width d2km D2KM=$6 - gmt math -T$1/$2/$3 T $D2KM MUL $4 SUB $5 DIV 2 POW NEG EXP = + gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV 2 POW NEG EXP = } function G1 () { # d/dx Gaussian - The Pacific signal. Expects: x0 x1 dx center width d2km D2KM=$6 i_A=`gmt math -Q 2 SQRT -0.5 EXP MUL INV =` # Amplitude scaling - gmt math -T$1/$2/$3 T $D2KM MUL $4 SUB $5 DIV DUP 2 POW NEG EXP MUL $i_A MUL = + gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV DUP 2 POW NEG EXP MUL ${i_A} MUL = } function G2 () { # d2/dx2 Gaussian - The Compression signal. Expects: x0 x1 dx center width d2km D2KM=$6 i_A=`gmt math -Q E =` # Amplitude scaling - gmt math -T$1/$2/$3 T $D2KM MUL $4 SUB $5 DIV 2 POW DUP NEG EXP MUL $i_A MUL = + gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV 2 POW DUP NEG EXP MUL ${i_A} MUL = } function synthFZ () { # Combined signal. Expects: x0 x1 dx center width m u A km? if [ $9 -eq 1 ]; then @@ -43,11 +43,11 @@ function synthFZ () { # Combined signal. Expects: x0 x1 dx center width m u A km fi m=$6 u=$7 - m1=`gmt math -Q 1 $m SUB =` # (1-m) - G0 $1 $2 $3 $4 $5 $D2KM > /tmp/G0 - G1 $1 $2 $3 $4 $5 $D2KM > /tmp/G1 - G2 $1 $2 $3 $4 $5 $D2KM > /tmp/G2 - gmt math /tmp/G2 $u MUL /tmp/G0 SUB $m1 MUL /tmp/G1 $m MUL ADD NORM $8 MUL = + m1=`gmt math -Q 1 ${m} SUB =` # (1-m) + G0 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G0 + G1 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G1 + G2 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G2 + gmt math /tmp/G2 $u MUL /tmp/G0 SUB ${m1} MUL /tmp/G1 ${m} MUL ADD NORM $8 MUL = } . fz_funcs.sh # Load in FZ-specific shell functions @@ -58,20 +58,20 @@ cat << EOF >&2 fzmodeler $version - Make and optionally plot a synthetic FZ profile Usage: fzmodeler [-A] [-C] [-D//] - [-F] [-M] [-N] [-O] [-S] [-W] [-P] + [-M] [-N] [-O] [-S] [-T] [-W] [-P] OPTIONS: -A sets FZ asymmetry between "Pacific" (1) and "Atlantic" (0) [0]. -C sets FZ compression (0-1) [0]. -D sets domain [-5/5/2m or -100/100/2; see -M]. - -F sets output file name prefix [$name]. - Give - to write to stdout. -M means -D is given in degrees/degrees/minutes [km]. -N sets max VGG amplitude [100]. -O Run as GMT overlay (i.e., pass -O -K) and send to stdout. No PDF is made and no datafile is saved. -P plot to fzprof.pdf. -S sets FZ shift from origin in km [0]. + -T sets output file prefix [$name]. + Give - to write to stdout. -V Report on progress [quiet]. -W sets FZ width in km [25]. @@ -100,8 +100,6 @@ while [ ! x"$1" = x ]; do shift;; -D*) domain=`fz_get_arg $1` # min/max/inc domain shift;; - -F*) name=`fz_get_arg $1` # file name - shift;; -M) km=0; # Domain given in degrees shift;; -N*) amp=`fz_get_arg $1` # amplitude @@ -113,6 +111,8 @@ while [ ! x"$1" = x ]; do shift;; -S*) X0=`fz_get_arg $1`; # FZ offset shift;; + -T*) name=`fz_get_arg $1` # file prefix + shift;; -V) verbose=1; # Verbose shift;; -W*) width=`fz_get_arg $1` # FZ width @@ -124,56 +124,53 @@ while [ ! x"$1" = x ]; do esac done #-------------- -if [ "X$domain" = "X" ]; then # Default settings +if [ "X${domain}" = "X" ]; then # Default settings if [ $km -eq 0 ]; then domain=-100/100/2 else domain=-5/5/2 fi fi -if [ "X$name" = "X-" ]; then +if [ "X${name}" = "X-" ]; then out=1 name=/tmp/$$ plot=0 fi -w=`echo $domain |cut -d'/' -f1` -e=`echo $domain |cut -d'/' -f2` -dm=`echo $domain |cut -d'/' -f3` -if [ $km -eq 0 ]; then - dx=`gmt math -Q $dm 60 DIV =` +w=`echo ${domain} |cut -d'/' -f1` +e=`echo ${domain} |cut -d'/' -f2` +dm=`echo ${domain} |cut -d'/' -f3` +if [ ${km} -eq 0 ]; then + dx=`gmt math -Q ${dm} 60 DIV =` tick=2f1 else - dx=$dm + dx=${dm} tick=50f10 fi -(synthFZ $w $e $dx $X0 $width $asym $comp $amp $km > $name.txt) 2> /dev/null -if [ $plot -eq 1 ]; then - if [ $OL -eq 1 ]; then - gmt psxy -R$w/$e/-$amp/$amp -JX$X -Bx${tick}g100 -By50f10g50 -BWSne $name.txt -W2p -O -K - rm -f $name.txt +(synthFZ ${w} ${e} ${dx} ${X0} ${width} ${asym} ${comp} ${amp} ${km} > ${name}.txt) 2> /dev/null +if [ ${plot} -eq 1 ]; then + if [ ${OL} -eq 1 ]; then + gmt psxy -R${w}/${e}/-${amp}/${amp} -JX${X} -Bx${tick}g100 -By50f10g50 -BWSne ${name}.txt -W2p -O -K + rm -f ${name}.txt else - gmt psxy -R$w/$e/-$amp/$amp -JX$X -P -Bx${tick}g100 -By50f10g50 -BWSne $name.txt -W2p > $name.ps - gmt psconvert $name.ps -Tf -P -A - rm -f $name.ps - if [ $os = "Darwin" ]; then - open $name.pdf - fi + gmt begin ${name} pdf + gmt plot -R${w}/${e}/-${amp}/${amp} -JX${X} -Bx${tick}g100 -By50f10g50 -BWSne ${name}.txt -W2p + gmt end show if [ $verbose -eq 1 ]; then - echo "$0: Synthetic FZ profile plotted in file $name.pdf" - echo "$0: Synthetic FZ profile stored in file $name.txt" + echo "$0: Synthetic FZ profile plotted in file ${name}.pdf" + echo "$0: Synthetic FZ profile stored in file ${name}.txt" fi fi -elif [ $verbose -eq 1 ]; then - if [ $out -eq 1 ]; then - cat $name.txt +elif [ ${verbose} -eq 1 ]; then + if [ ${out} -eq 1 ]; then + cat ${name}.txt echo "$0: Synthetic FZ profile written to stdout" - rm -f $name.txt + rm -f ${name}.txt else - echo "$0: Synthetic FZ profile stored in file $name.txt" + echo "$0: Synthetic FZ profile stored in file ${name}.txt" fi fi -if [ $out -eq 1 ]; then - cat $name.txt - rm -f $name.txt +if [ ${out} -eq 1 ]; then + cat ${name}.txt + rm -f ${name}.txt fi diff --git a/src/gsfml/fzprofiler b/src/gsfml/fzprofiler index 6e3f932e0e7..a7d91829e2c 100755 --- a/src/gsfml/fzprofiler +++ b/src/gsfml/fzprofiler @@ -47,7 +47,7 @@ EOF exit fi -trap 'fz_cleanup 1' 1 2 3 15 # Set interrup handling +trap 'fz_cleanup 1' 1 2 3 15 # Set interrupt handling #default values ncols=1 W=6 @@ -79,191 +79,183 @@ while [ ! x"$1" = x ]; do esac done -XFILE=${prefix}_cross.txt # Cross-profiles file -# make sure we convert to inches -PS=${prefix}_cross.ps # Resulting PostScript file -PDF=${prefix}_cross.pdf # Final PDF file for plot -. ${prefix}_par.txt # Read and assign parameters for these profiles +XFILE=${prefix}_cross.txt # Cross-profiles file +# Make sure we convert to inches +. ${prefix}_par.txt # Read and assign parameters for these profiles #------------------------------------------------------------------------------------------------------ # All dimensions are now in inches, regardless of what the user's units are. # Cross-profiles have lon,lat,dist,azimuth,vgg,age,fzdist columns. # Assign variables and calculate dimensions (inches used throughout) #------------------------------------------------------------------------------------------------------ -space=0.50 # Space between columns of panels -ymargin=0.75 # Bottom margin -xmargin=1 # Left margin -zone=`gmt math -Q $CORR_WIDTH 0.5 MUL =` # half-width of central corridor -n_cross=`gmt convert -L $XFILE | wc -l` # Number of cross-profiles -ndig=`gmt math -Q $n_cross LOG10 FLOOR 1 ADD =` # Number of digits to use for running numbers -dmin=`gmt math -Q $CROSS_LENGTH 0.5 MUL NEG =` # Only plot the central 50% of the cross profiles -dmax=`gmt math -Q $CROSS_LENGTH 0.5 MUL =` -gmt info $XFILE -C -I2/2/2/5/10/10/10/10/10 > $$.info # Get clean multiples of min/max for each column -vmin=`cut -f9 $$.info` # Low VGG bounds -vmax=`cut -f10 $$.info` # High VGG bounds -vinc=`gmt math -Q $vmax $vmin SUB 50 DIV CEIL 10 MUL =` # VGG scale bar length is ~1/5 the range, in multiples of 10 -vinc2=`gmt math -Q $vinc 2 DIV =` # +- half vinc -amin=`cut -f11 $$.info` # Low age bounds -amax=`cut -f12 $$.info` # High age bounds -range=`gmt math -Q $vmax $vmin SUB =` # VGG range for this panel -if [ $amin = "NaN" ]; then +space=0.50 # Space between columns of panels +ymargin=0.75 # Bottom margin +xmargin=1 # Left margin +zone=`gmt math -Q ${CORR_WIDTH} 0.5 MUL =` # half-width of central corridor +n_cross=`gmt convert -L ${XFILE} | wc -l` # Number of cross-profiles +ndig=`gmt math -Q ${n_cross} LOG10 FLOOR 1 ADD =` # Number of digits to use for running numbers +dmin=`gmt math -Q ${CROSS_LENGTH} 0.5 MUL NEG =` # Only plot the central 50% of the cross profiles +dmax=`gmt math -Q ${CROSS_LENGTH} 0.5 MUL =` +gmt info ${XFILE} -C -I2/2/2/5/10/10/10/10/10 > $$.info # Get clean multiples of min/max for each column +vmin=`cut -f9 $$.info` # Low VGG bounds +vmax=`cut -f10 $$.info` # High VGG bounds +vinc=`gmt math -Q ${vmax} ${vmin} SUB 50 DIV CEIL 10 MUL =` # VGG scale bar length is ~1/5 the range, in multiples of 10 +vinc2=`gmt math -Q ${vinc} 2 DIV =` # +- half vinc +amin=`cut -f11 $$.info` # Low age bounds +amax=`cut -f12 $$.info` # High age bounds +range=`gmt math -Q ${vmax} ${vmin} SUB =` # VGG range for this panel +if [ ${amin} = "NaN" ]; then got_age=0 else got_age=1 - arange=`gmt math -Q $amax $amin SUB =` # Age range for this panel - am=`gmt math -Q $amin $arange 0.5 MUL ADD =` # Mid-age value - am1=`gmt math -Q $am 5 SUB =` # am1/am2 are 1- Myr apart and will serve as age scale bar - am2=`gmt math -Q $am 5 ADD =` - atxt=" and $arange Myr (dashed orange line)" + arange=`gmt math -Q ${amax} ${amin} SUB =` # Age range for this panel + am=`gmt math -Q ${amin} ${arange} 0.5 MUL ADD =` # Mid-age value + am1=`gmt math -Q ${am} 5 SUB =` # am1/am2 are 1- Myr apart and will serve as age scale bar + am2=`gmt math -Q ${am} 5 ADD =` + atxt=" and ${arange} Myr (dashed orange line)" fi -if [ $P -ge 0 ]; then # Selected to plot a single profile - nrows=1 # Obviously only a single row - single=1 # TRUE for this case - txt=" $P" # Text identifying the profile +if [ $P -ge 0 ]; then # Selected to plot a single profile + nrows=1 # Obviously only a single row + single=1 # TRUE for this case + txt=" $P" # Text identifying the profile else - P=0 # Do all profiles - nrows=`gmt math -Q $n_cross $inc DIV $ncols DIV CEIL =` # The number of rows depends on how many columns we have and how often we plot - single=0 # FALSE for this case - txt="s" # Text identifying all profiles (plural s) + P=0 # Do all profiles + nrows=`gmt math -Q ${n_cross} ${inc} DIV ${ncols} DIV CEIL =` # The number of rows depends on how many columns we have and how often we plot + single=0 # FALSE for this case + txt="s" # Text identifying all profiles (plural s) fi -height=`gmt math -Q $H $nrows MUL =` # Height of all panels -width=`gmt math -Q $W $ncols MUL $ncols 1 SUB $space MUL ADD =` # Width of all plot columns together -width2=`gmt math -Q $width 2 $xmargin MUL ADD =` # PLot width, including margings -height2=`gmt math -Q $height 2 $ymargin MUL ADD =` # Plot height, including margins -xu=`gmt math -Q -0.75 1 $xmargin SUB ADD =` # Placement x for -U logo and label -yu=`gmt math -Q -0.75 1 $ymargin SUB ADD =` # Placement y for -U logo and label -VB=`gmt math -Q $vmax 0.75 MUL =` # VGG-value to use for placement of blend width indicator symbol -VT=`gmt math -Q $vmax 0.50 MUL =` # VGG-value to use for placement of trough width indicator symbol -VD=`gmt math -Q $vmax 0.25 MUL =` # VGG-value to use for placement of data width indicator symbol -#------------------------------------------------------------------------------------------------------ +height=`gmt math -Q ${H} ${nrows} MUL =` # Height of all panels +width=`gmt math -Q ${W} ${ncols} MUL ${ncols} 1 SUB ${space} MUL ADD =` # Width of all plot columns together +width2=`gmt math -Q ${width} 2 ${xmargin} MUL ADD =` # PLot width, including margings +height2=`gmt math -Q ${height} 2 ${ymargin} MUL ADD =` # Plot height, including margins +xu=`gmt math -Q -0.75 1 ${xmargin} SUB ADD =` # Placement x for -U logo and label +yu=`gmt math -Q -0.75 1 ${ymargin} SUB ADD =` # Placement y for -U logo and label +VB=`gmt math -Q ${vmax} 0.75 MUL =` # VGG-value to use for placement of blend width indicator symbol +VT=`gmt math -Q ${vmax} 0.50 MUL =` # VGG-value to use for placement of trough width indicator symbol +VD=`gmt math -Q ${vmax} 0.25 MUL =` # VGG-value to use for placement of data width indicator symbol +#------------------------------------------------------- ----------------------------------------------- # Ready for plotting if [ $verbose -eq 1 ]; then echo "fzprofiler: Papersize is ${width2}i by ${height2}i; vertical range per row panel is $range Eotvos${atxt}." >&2 fi #------------------------------------------------------------------------------------------------------ # Draw the outline of the combined rowsxcols panels; add title and -U label, using a custom paper size tailored to fit the plot -gmt psbasemap -R0/$width/0/$height -Jx1i -P -Xa${xmargin}i -Ya${ymargin}i -B+gwhite -K -U/${xu}i/${yu}i/"${prefix}: Cross profile${txt}" --PS_MEDIA=${width2}ix${height2}i >| $PS -let row=9999 # This will be reset to 1 immediately in the loop below -let col=0 # This will be reset to 1 in the loop. We start from left-most column (1) and work to the right -while [ $P -lt $n_cross ]; do # As long as there are profiles left - if [ $verbose -eq 1 ]; then - echo "fzprofiler: Plotting profile $P" >&2 - fi - let row=row+1 # Go to next row (row = 1 is the first row) - if [ $row -gt $nrows ]; then # Must go to next column - let row=1 # Back to the bottom - let col=col+1 # Move to next column - let frame=1 # Time to plot a basemap again for the entire column - if [ $col -gt 1 ]; then # Draw the central d = 0 line for the entire column - gmt psbasemap -R$dmin/$dmax/0/$height -JX${W}i/${height}i -O -K -Bx0g1000 -By0 -Xa${xpos}i -Ya${ymargin}i >> $PS +gmt begin ${prefix}_cross pdf + gmt basemap -R0/$width/0/$height -Jx1i -Xa${xmargin}i -Ya${ymargin}i -B+gwhite -U/${xu}i/${yu}i/"${prefix}: Cross profile${txt}" + let row=9999 # This will be reset to 1 immediately in the loop below + let col=0 # This will be reset to 1 in the loop. We start from left-most column (1) and work to the right + while [ $P -lt $n_cross ]; do # As long as there are profiles left + if [ $verbose -eq 1 ]; then + echo "fzprofiler: Plotting profile ${P}" >&2 fi - - fi - xpos=`gmt math -Q $col 1 SUB $W $space ADD MUL $xmargin ADD =` # Determines the x position of the current panel's LL corner - ypos=`gmt math -Q $nrows $row SUB $H MUL $ymargin ADD =` # Determines the y position of the current panel's LL corner - xposL=`gmt math -Q $xpos 0.15 SUB =` # We will plot a VGG scale bar 0.15 inches to the left of each panel - xposR=`gmt math -Q $xpos 0.15 ADD =` # We will plot an Age scale bar 0.15 inches to the right of each panel - if [ $frame -eq 1 ]; then # Plot the central corridor in light blue color, annotate the distance axis - gmt psxy -R$dmin/$dmax/0/$height -JX${W}i/${height}i -O -K -Glightblue -Bx20f5 -By0 -BwSne -Xa${xpos}i -Ya${ymargin}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 <<- EOF >> $PS - -${zone} 0 - ${zone} 0 - ${zone} $height - -${zone} $height - EOF - let frame=0 - fi - gmt convert -Q$P $XFILE > $$.raw # Extract the profile to plot (includes the segment header) - header=`head -1 $$.raw` # Get this cross profile's header - # Pull out several parameter values from the segment header, via strings such as WD=25 - - az=`fz_get_item "$header" az` # Extract the azimuth of this profile - mb=`fz_get_item "$header" mb` # Extract the blend parameter for best-fitting model - OB=`fz_get_item "$header" OB` # Extract the offset parameter for best-fitting blend model - WB=`fz_get_item "$header" WB` # Extract the width parameter for best-fitting blend model - UB=`fz_get_item "$header" UB` # Extract the compression parameter for best-fitting blend model - OT=`fz_get_item "$header" OT` # Extract the offset parameter for best-fitting trough model - WT=`fz_get_item "$header" WT` # Extract the width parameter for best-fitting trough model - UT=`fz_get_item "$header" UT` # Extract the compression parameter for best-fitting trough model - OD=`fz_get_item "$header" OD` # Extract trough location parameter for the data - WD=`fz_get_item "$header" WD` # Extract the width estimate of the data trough - OE=`fz_get_item "$header" OE` # Extract the offset parameter for best-fitting edge model - WT2=`gmt math -Q $WT 0.5 MUL =` # Compute half-widths - WB2=`gmt math -Q $WB 0.5 MUL =` - northsouth=`gmt math -Q $az ABS 45 LE =` # Determine if profile is mostly E-W or S-N - if [ $northsouth -eq 1 ]; then # It is mostly S to N - L="S" - R="N" - else # It is mostly E to W - L="W" - R="E" - fi - # Build a polygon the plot as lightcyan the +- 2 sigma uncertainty on the trough location OT - echo $OT $WT $vmin $vmax | awk '{printf "%g\t%s\n%g\t%s\n%g\t%s\n%g\t%s\n", $1-0.5*$2/3, $3, $1+0.5*$2/3, $3, $1+0.5*$2/3, $4, $1-0.5*$2/3, $4}' > $$.w - y=`gmt math -Q $P $H MUL 1 ADD =` - # Plot the uncertainty area on OT as lightcyan - gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -Bx0 -Byf1000g1000 -Bwe -O -K $$.w -Glightcyan -Xa${xpos}i -Ya${ypos}i >> $PS - # Plot the data as red circles connected by a thin dotted red line - gmt psxy $$.raw -i2,4 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Wthinnest,red,. -Xa${xpos}i -Ya${ypos}i >> $PS - gmt psxy $$.raw -i2,4 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Sc0.04i -Gred -Xa${xpos}i -Ya${ypos}i >> $PS - # Plot the trough model as thin solid green3 line - gmt psxy $$.raw -i2,7 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -B0 -Bsn -O -K -Wthin,green3 -Xa${xpos}i -Ya${ypos}i --MAP_FRAME_PEN=faint >> $PS - # Plot the blend model as thin blue line - gmt psxy $$.raw -i2,8 -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Wthin,blue -Xa${xpos}i -Ya${ypos}i >> $PS - if [ $got_age -eq 1 ]; then - # Plot the crustal ages as thin dashed orange line - gmt psxy $$.raw -i2,5 -R$dmin/$dmax/$amin/$amax -JX${W}i/${H}i -O -K -Wthin,orange,- -Xa${xpos}i -Ya${ypos}i >> $PS - fi - # Place width error-bar and trough symbol for the blend model - echo $OB $VB $WB2 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Ex/thin,blue -Gblue -Wthinnest -Si0.075i -Xa${xpos}i -Ya${ypos}i >> $PS - # Place width error-bar and trough symbol for the trough model - echo $OT $VT $WT2 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Ex/thin,green3 -Wthinnest -Si0.075i -Ggreen3 -Xa${xpos}i -Ya${ypos}i >> $PS - # Place width error-bar and max-slope (edge) symbol for the blend model - echo $OE 0.0 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Wthinnest -Sc0.075i -Gblue -Xa${xpos}i -Ya${ypos}i >> $PS - if [ "$WD" = "NaN" ] || [ "$WD" = "nan" ]; then # Cannot do it - echo "WD is NaN - skipped" >&2 - else - WD2=`gmt math -Q $WD 0.5 MUL =` # Compute half-width - echo $OD $VD $WD2 | gmt psxy -R$dmin/$dmax/$vmin/$vmax -JX${W}i/${H}i -O -K -Ex/thin,red -Wthinnest -Si0.075i -Gred -Xa${xpos}i -Ya${ypos}i >> $PS - fi - # Place profile ID in upper-left corner of panel - echo "$dmin $vmax LT $P" | gmt pstext -R$dmin/$dmax/$vmin/$vmax -J -O -K -Dj0.05i/0.05i -C0.01i/0.01i -F+f7p,Helvetica,white+a0+j -Gblack -To -W0.5p -Xa${xpos}i -Ya${ypos}i >> $PS - # Write blend value in upper-right corner of panel - echo "$dmax $vmax RT @;green3;u@-t@- = ${UT}@;; @;blue;u@-b@- = $UB m = ${mb}@;;" | gmt pstext -R -J -O -K -Dj0.05i/0.05i -F+f7p,Helvetica+a0+j -Xa${xpos}i -Ya${ypos}i >> $PS - # Write the W-E or S-N labels on left/right side of the top of the panel - echo "$dmin $vmax LT $L" | gmt pstext -R -J -O -K -Dj0.05i/0.2i -F+f12p,Helvetica-Bold+a0+j -Xa${xpos}i -Ya${ypos}i >> $PS - echo "$dmax $vmax RT $R" | gmt pstext -R -J -O -K -Dj0.05i/0.2i -F+f12p,Helvetica-Bold+a0+j -Xa${xpos}i -Ya${ypos}i >> $PS - # Draw $vinc Eotvos scale bar to the left of the panel - gmt psxy -R -J -O -K -W2p,red -Xa${xposL}i -Ya${ypos}i <<- EOF >> $PS - $dmin -${vinc2} - $dmin ${vinc2} - EOF - # Label the VGG scale bar with "$vinc" - echo $dmin 0 $vinc | gmt pstext -R -J -O -K -F+f6p,Helvetica+a0+jCM -C0.01i/0.01i -Gwhite -To -W0.5p -N -Xa${xposL}i -Ya${ypos}i >> $PS - if [ $got_age -eq 1 ]; then - # Draw 10 Myr scale bar to the right of the panel - gmt psxy -R$dmin/$dmax/$amin/$amax -J -O -K -W2p,orange -Xa${xposR}i -Ya${ypos}i <<- EOF >> $PS - $dmax $am1 - $dmax $am2 + let row=row+1 # Go to next row (row = 1 is the first row) + if [ ${row} -gt ${nrows} ]; then # Must go to next column + let row=1 # Back to the bottom + let col=col+1 # Move to next column + let frame=1 # Time to plot a basemap again for the entire column + if [ ${col} -gt 1 ]; then # Draw the central d = 0 line for the entire column + gmt basemap -R${dmin}/${dmax}/0/${height} -JX${W}i/${height}i -Bx0g1000 -By0 -Xa${xpos}i -Ya${ymargin}i + fi + fi + xpos=`gmt math -Q $col 1 SUB $W $space ADD MUL $xmargin ADD =` # Determines the x position of the current panel's LL corner + ypos=`gmt math -Q $nrows $row SUB $H MUL $ymargin ADD =` # Determines the y position of the current panel's LL corner + xposL=`gmt math -Q $xpos 0.15 SUB =` # We will plot a VGG scale bar 0.15 inches to the left of each panel + xposR=`gmt math -Q $xpos 0.15 ADD =` # We will plot an Age scale bar 0.15 inches to the right of each panel + if [ ${frame} -eq 1 ]; then # Plot the central corridor in light blue color, annotate the distance axis + gmt plot -Glightblue -Bx20f5 -By0 -BwSne -Xa${xpos}i -Ya${ymargin}i --FONT_ANNOT_PRIMARY=10 --FONT_LABEL=14 <<- EOF + -${zone} 0 + ${zone} 0 + ${zone} $height + -${zone} $height + EOF + let frame=0 + fi + gmt convert -Q${P} ${XFILE} > $$.raw # Extract the profile to plot (includes the segment header) + header=`head -1 $$.raw` # Get this cross profile's header + # Pull out several parameter values from the segment header, via strings such as WD=25 + + az=`fz_get_item "${header}" az` # Extract the azimuth of this profile + mb=`fz_get_item "${header}" mb` # Extract the blend parameter for best-fitting model + OB=`fz_get_item "${header}" OB` # Extract the offset parameter for best-fitting blend model + WB=`fz_get_item "${header}" WB` # Extract the width parameter for best-fitting blend model + UB=`fz_get_item "${header}" UB` # Extract the compression parameter for best-fitting blend model + OT=`fz_get_item "${header}" OT` # Extract the offset parameter for best-fitting trough model + WT=`fz_get_item "${header}" WT` # Extract the width parameter for best-fitting trough model + UT=`fz_get_item "${header}" UT` # Extract the compression parameter for best-fitting trough model + OD=`fz_get_item "${header}" OD` # Extract trough location parameter for the data + WD=`fz_get_item "${header}" WD` # Extract the width estimate of the data trough + OE=`fz_get_item "${header}" OE` # Extract the offset parameter for best-fitting edge model + WT2=`gmt math -Q $WT 0.5 MUL =` # Compute half-widths + WB2=`gmt math -Q $WB 0.5 MUL =` + northsouth=`gmt math -Q $az ABS 45 LE =` # Determine if profile is mostly E-W or S-N + if [ ${northsouth} -eq 1 ]; then # It is mostly S to N + L="S" + R="N" + else # It is mostly E to W + L="W" + R="E" + fi + # Build a polygon the plot as lightcyan the +- 2 sigma uncertainty on the trough location OT + echo ${OT} ${WT} ${vmin} ${vmax} | awk '{printf "%g\t%s\n%g\t%s\n%g\t%s\n%g\t%s\n", $1-0.5*$2/3, $3, $1+0.5*$2/3, $3, $1+0.5*$2/3, $4, $1-0.5*$2/3, $4}' > $$.w + y=`gmt math -Q ${P} ${H} MUL 1 ADD =` + # Plot the uncertainty area on OT as lightcyan + gmt plot -R${dmin}/${dmax}/${vmin}/${vmax} -JX${W}i/${H}i -Bx0 -Byf1000g1000 -Bwe $$.w -Glightcyan -Xa${xpos}i -Ya${ypos}i + # Plot the data as red circles connected by a thin dotted red line + gmt plot $$.raw -i2,4 -Wthinnest,red,. -Xa${xpos}i -Ya${ypos}i + gmt plot $$.raw -i2,4 -Sc0.04i -Gred -Xa${xpos}i -Ya${ypos}i + # Plot the trough model as thin solid green3 line + gmt plot $$.raw -i2,7 -B0 -Bsn -Wthin,green3 -Xa${xpos}i -Ya${ypos}i --MAP_FRAME_PEN=faint + # Plot the blend model as thin blue line + gmt plot $$.raw -i2,8 -Wthin,blue -Xa${xpos}i -Ya${ypos}i + if [ ${got_age} -eq 1 ]; then + # Plot the crustal ages as thin dashed orange line + gmt plot $$.raw -i2,5 -R${dmin}/${dmax}/${amin}/${amax} -Wthin,orange,- -Xa${xpos}i -Ya${ypos}i + fi + # Place width error-bar and trough symbol for the blend model + echo ${OB} ${VB} ${WB2} | gmt plot -R${dmin}/${dmax}/${vmin}/${vmax} -Ex+pthin,blue -Gblue -Wthinnest -Si0.075i -Xa${xpos}i -Ya${ypos}i + # Place width error-bar and trough symbol for the trough model + echo ${OT} ${VT} ${WT2} | gmt plot -Ex+pthin,green3 -Wthinnest -Si0.075i -Ggreen3 -Xa${xpos}i -Ya${ypos}i + # Place width error-bar and max-slope (edge) symbol for the blend model + echo ${OE} 0.0 | gmt plot -Wthinnest -Sc0.075i -Gblue -Xa${xpos}i -Ya${ypos}i + if [ "${WD}" = "NaN" ] || [ "${WD}" = "nan" ]; then # Cannot do it + echo "WD is NaN - skipped" >&2 + else + WD2=`gmt math -Q $WD 0.5 MUL =` # Compute half-width + echo ${OD} ${VD} ${WD2} | gmt plot -Ex+pthin,red -Wthinnest -Si0.075i -Gred -Xa${xpos}i -Ya${ypos}i + fi + # Place profile ID in upper-left corner of panel + echo "${dmin} ${vmax} LT ${P}" | gmt text -Dj0.05i -C0.01i -F+f7p,Helvetica,white+a0+j -Gblack -To -W0.5p -Xa${xpos}i -Ya${ypos}i + # Write blend value in upper-right corner of panel + echo "${dmax} ${vmax} RT @;green3;u@-t@- = ${UT}@;; @;blue;u@-b@- = $UB m = ${mb}@;;" | gmt text -Dj0.05i -F+f7p,Helvetica+a0+j -Xa${xpos}i -Ya${ypos}i + # Write the W-E or S-N labels on left/right side of the top of the panel + echo "${dmin} ${vmax} LT ${L}" | gmt text -Dj0.05i/0.2i -F+f12p,Helvetica-Bold+a0+j -Xa${xpos}i -Ya${ypos}i + echo "${dmax} ${vmax} RT ${R}" | gmt text -Dj0.05i/0.2i -F+f12p,Helvetica-Bold+a0+j -Xa${xpos}i -Ya${ypos}i + # Draw $vinc Eotvos scale bar to the left of the panel + gmt plot -W2p,red -Xa${xposL}i -Ya${ypos}i <<- EOF + ${dmin} -${vinc2} + ${dmin} ${vinc2} EOF - # Label the age scale bar with "10" - echo $dmax $am 10 | gmt pstext -R -J -O -K -F+f6p,Helvetica+a0+jCM -C0.01i/0.01i -Gwhite -To -W0.5p -N -Xa${xposR}i -Ya${ypos}i >> $PS - fi - if [ $single -eq 1 ]; then # Set P to last profile so the loop will exit immediately - P=$n_cross - else # March on to the next profile - let P=P+inc - fi -done -# Finalize plot by drawing the d = 0 line for the last panel -gmt psbasemap -R$dmin/$dmax/0/$height -JX${W}i/${height}i -O -Bx0g1000 -By0 -Xa${xpos}i -Ya${ymargin}i >> $PS -# Convert the PS to a PDF file -gmt psconvert -Tf $PS -os=`uname -s` -if [ $verbose -eq 1 ]; then - echo "fzprofiler: Final plot is called $PDF" >&2 -fi -if [ $os = "Darwin" ]; then - open $PDF + # Label the VGG scale bar with "$vinc" + echo ${dmin} 0 ${vinc} | gmt text -F+f6p,Helvetica+a0+jCM -C0.01i -Gwhite -To -W0.5p -N -Xa${xposL}i -Ya${ypos}i + if [ ${got_age} -eq 1 ]; then + # Draw 10 Myr scale bar to the right of the panel + gmt plot -R${dmin}/${dmax}/${amin}/${amax} -W2p,orange -Xa${xposR}i -Ya${ypos}i <<- EOF + ${dmax} ${am1} + ${dmax} ${am2} + EOF + # Label the age scale bar with "10" + echo ${dmax} ${am} 10 | gmt text -F+f6p,Helvetica+a0+jCM -C0.01i -Gwhite -To -W0.5p -N -Xa${xposR}i -Ya${ypos}i + fi + if [ ${single} -eq 1 ]; then # Set P to last profile so the loop will exit immediately + P=${n_cross} + else # March on to the next profile + let P=P+inc + fi + done + # Finalize plot by drawing the d = 0 line for the last panel + gmt basemap -R${dmin}/${dmax}/0/${height} -JX${W}i/${height}i -Bx0g1000 -By0 -Xa${xpos}i -Ya${ymargin}i +gmt end show +if [ ${verbose} -eq 1 ]; then + echo "fzprofiler: Final plot is called ${prefix}_cross.pdf" >&2 fi -rm -f $PS fz_cleanup 1 diff --git a/src/pstext.c b/src/pstext.c index 053abff2467..28e6aa8cb85 100644 --- a/src/pstext.c +++ b/src/pstext.c @@ -292,7 +292,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) { const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE); if (level & PSTEXT_SHOW_FONTS) show_fonts = true, level -= PSTEXT_SHOW_FONTS; /* Deal with the special bitflag for showing the fonts */ if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); - GMT_Usage (API, 0, "usage: %s [] %s %s [-A] [%s] [-C[/][+tc|C|o|O]] [-D[j|J][/][+v[]]] " + GMT_Usage (API, 0, "usage: %s [
] %s %s [-A] [%s] [-C[[/]][+tc|C|o|O]] [-D[j|J][/][+v[]]] " "[-F[+a[]][+c[]][+f[]][+h|l|r[]|+t|+z[]][+j[]]] %s " "[-G[][+n]] [-L] [-M] [-N] %s%s[-Ql|u] [-S[//][]] [%s] [%s] [-W] [%s] [%s] [-Z] " "[%s] %s[%s] [%s] [%s] [-it] [%s] [%s] [%s] [%s] [%s] [%s]\n", @@ -341,9 +341,9 @@ static int usage (struct GMTAPI_CTRL *API, int level) { GMT_Message (API, GMT_TIME_NONE, "\n OPTIONAL ARGUMENTS:\n"); GMT_Usage (API, 1, "\n-A Angles given as azimuths; convert to directions using current projection."); GMT_Option (API, "B-"); - GMT_Usage (API, 1, "\n-C[/][+tc|C|o|O]"); + GMT_Usage (API, 1, "\n-C[[/]][+tc|C|o|O]"); GMT_Usage (API, -2, "Set the clearance between characters and surrounding box. Only used " - "if -W has been set. Append units {%s} or %% of fontsize [%d%%]. " + "if -W has been set. If is not given it equals . Append units {%s} or %% of fontsize [%d%%]. " "Optionally append +t when -G and/or -W is used. Append a shape:", GMT_DIM_UNITS_DISPLAY, GMT_TEXT_CLEARANCE); GMT_Usage (API, 3, "c: Concave rectangle (requires -M)."); GMT_Usage (API, 3, "C: Convex rectangle (requires -M)."); From dd4370f2e6c6fc19e4edcf4ec0be7ddd77f65a43 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sat, 2 Dec 2023 12:39:14 +0100 Subject: [PATCH 15/20] Update mlconverter.rst --- doc/rst/source/supplements/gsfml/mlconverter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rst/source/supplements/gsfml/mlconverter.rst b/doc/rst/source/supplements/gsfml/mlconverter.rst index fcd43510261..b72c1560b59 100644 --- a/doc/rst/source/supplements/gsfml/mlconverter.rst +++ b/doc/rst/source/supplements/gsfml/mlconverter.rst @@ -25,7 +25,7 @@ Description ----------- **mlconverter** is a module developed as part of the Global Seafloor Fabric -and Magnetic Lineation Project [[see `GSFML `_ for a full +and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It reads a magnetic pick data file (or stdin) and converts chron text-strings to ages using a selected magnetic time scale. The input data must be OGR/GMT data files of the form distributed by the From 8637d821c32bae63045677195fadf7bcee8e1bf8 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sun, 3 Dec 2023 12:25:50 +0100 Subject: [PATCH 16/20] Add new -G to fzmodeler --- .../source/supplements/gsfml/fzmodeler.rst | 13 ++++++- src/gsfml/fzmodeler | 37 +++++++++++++------ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst index cb19c16dd30..4bc579ea215 100644 --- a/doc/rst/source/supplements/gsfml/fzmodeler.rst +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -15,6 +15,7 @@ Synopsis **fzmodeler** [ |-A|\ *asymmetry* ] [ |-C|\ *compression* ] [ |-D|\ *min*/*max*/*inc* ] +[ |-G|\ *comp* ] [ |-M| ] [ |-N|\ *amplitude* ] [ |-O| ] @@ -32,7 +33,9 @@ Description **zmodeler** is a script developed as part of the Global Seafloor Fabric and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It builds a synthetic model cross-profile given -the chosen model parameters and optionally images the profile via a PDF plot. +the chosen model parameters and optionally images the profile via a PDF plot. The +model evaluated is :math:`z(x) = A[mG_1 + (1-m)(uG_2 + G0)]`, where *A* is amplitude (|-N|), +*m* is assymetry (|-A|), and *u* is compression (|-C|). Optional Arguments ------------------ @@ -56,6 +59,11 @@ Optional Arguments expected to be in degrees of latitude which *inc* will be decoded as arc minutes [-5/5/2 or -100/100/2, depending on |-M|]. +.. _-G: + +**-G**\ *comp* + Only plot component :math:`G_i(x)`, where i = 0, 1, or 2 + .. _-M: **-M** @@ -108,6 +116,9 @@ try:: fzmodeler -C1 -V The final plot will be named *prefix*.pdf, with the model data in *prefix*.txt. +To just plot normalized component :math:`G_2(x)`, try:: + + fzmodeler -D-30/30/1 -C1 -N1 -W10 -G2 -T- | gmt plot -W1p -B -R-30/30/-1/1 -png G2 See Also -------- diff --git a/src/gsfml/fzmodeler b/src/gsfml/fzmodeler index fbcfb063fc7..ad6e44ed6f0 100755 --- a/src/gsfml/fzmodeler +++ b/src/gsfml/fzmodeler @@ -23,7 +23,7 @@ function G0 () { # Gaussian - The Atlantic signal. Expects: x0 x1 dx center width d2km D2KM=$6 - gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV 2 POW NEG EXP = + gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV 2 POW NEG EXP NEG = } function G1 () { # d/dx Gaussian - The Pacific signal. Expects: x0 x1 dx center width d2km D2KM=$6 @@ -47,23 +47,24 @@ function synthFZ () { # Combined signal. Expects: x0 x1 dx center width m u A km G0 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G0 G1 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G1 G2 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G2 - gmt math /tmp/G2 $u MUL /tmp/G0 SUB ${m1} MUL /tmp/G1 ${m} MUL ADD NORM $8 MUL = + gmt math /tmp/G2 $u MUL /tmp/G0 ADD ${m1} MUL /tmp/G1 ${m} MUL ADD NORM $8 MUL = } . fz_funcs.sh # Load in FZ-specific shell functions name=fzprof if [ $# -eq 0 ]; then - version=`fz_get_version` + version=$(fz_get_version) cat << EOF >&2 - fzmodeler $version - Make and optionally plot a synthetic FZ profile + fzmodeler ${version} - Make and optionally plot a synthetic FZ profile - Usage: fzmodeler [-A] [-C] [-D//] + Usage: fzmodeler [-A] [-C] [-D//] [-G0|1|2] [-M] [-N] [-O] [-S] [-T] [-W] [-P] OPTIONS: -A sets FZ asymmetry between "Pacific" (1) and "Atlantic" (0) [0]. -C sets FZ compression (0-1) [0]. -D sets domain [-5/5/2m or -100/100/2; see -M]. + -G Only plot the specified G_i component, i = 0-2. -M means -D is given in degrees/degrees/minutes [km]. -N sets max VGG amplitude [100]. -O Run as GMT overlay (i.e., pass -O -K) and send to stdout. @@ -79,12 +80,13 @@ EOF exit fi -trap 'fz_cleanup 1' 1 2 3 15 # Set interrup handling +trap $(fz_cleanup 1) 1 2 3 15 # Set interrupt handling # Default values verbose=0 plot=0 asym=0 comp=0 +code=-1 X0=0 amp=100 width=25 @@ -100,6 +102,8 @@ while [ ! x"$1" = x ]; do shift;; -D*) domain=`fz_get_arg $1` # min/max/inc domain shift;; + -G*) code=`fz_get_arg $1` # 0-2 for G_i + shift;; -M) km=0; # Domain given in degrees shift;; -N*) amp=`fz_get_arg $1` # amplitude @@ -131,30 +135,39 @@ if [ "X${domain}" = "X" ]; then # Default settings domain=-5/5/2 fi fi +out=0 if [ "X${name}" = "X-" ]; then out=1 name=/tmp/$$ plot=0 fi -w=`echo ${domain} |cut -d'/' -f1` -e=`echo ${domain} |cut -d'/' -f2` -dm=`echo ${domain} |cut -d'/' -f3` +w=$(echo ${domain} |cut -d'/' -f1) +e=$(echo ${domain} |cut -d'/' -f2) +dm=$(echo ${domain} |cut -d'/' -f3) if [ ${km} -eq 0 ]; then - dx=`gmt math -Q ${dm} 60 DIV =` + dx=$(gmt math -Q ${dm} 60 DIV =) tick=2f1 else dx=${dm} tick=50f10 fi -(synthFZ ${w} ${e} ${dx} ${X0} ${width} ${asym} ${comp} ${amp} ${km} > ${name}.txt) 2> /dev/null +if [ ${code} -eq 0 ]; then # Gaussian - The Atlantic signal + G0 ${w} ${e} ${dx} ${X0} ${width} ${km} ${amp} > ${name}.txt 2> /dev/null +elif [ ${code} -eq 1 ]; then # d/dx Gaussian - The Pacific signal + G1 ${w} ${e} ${dx} ${X0} ${width} ${km} ${amp} > ${name}.txt 2> /dev/null +elif [ ${code} -eq 2 ]; then + G2 ${w} ${e} ${dx} ${X0} ${width} ${km} ${amp} > ${name}.txt 2> /dev/null +else # The blend of all + (synthFZ ${w} ${e} ${dx} ${X0} ${width} ${asym} ${comp} ${amp} ${km} > ${name}.txt) 2> /dev/null +fi if [ ${plot} -eq 1 ]; then if [ ${OL} -eq 1 ]; then gmt psxy -R${w}/${e}/-${amp}/${amp} -JX${X} -Bx${tick}g100 -By50f10g50 -BWSne ${name}.txt -W2p -O -K rm -f ${name}.txt else gmt begin ${name} pdf - gmt plot -R${w}/${e}/-${amp}/${amp} -JX${X} -Bx${tick}g100 -By50f10g50 -BWSne ${name}.txt -W2p + gmt plot -R${w}/${e}/-${amp}/${amp} -JX${X} -Baf -BWSne ${name}.txt -W2p gmt end show if [ $verbose -eq 1 ]; then echo "$0: Synthetic FZ profile plotted in file ${name}.pdf" From f5f4ea864ca6aee8236d8e0a2a4040e61fbba48c Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sun, 3 Dec 2023 12:41:10 +0100 Subject: [PATCH 17/20] Add figure --- doc/rst/source/supplements/gsfml/fzmodeler.rst | 5 +++-- doc/scripts/GMT_gsfml_components.sh | 7 +++++++ src/gsfml/fzmodeler | 9 +++++---- 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100755 doc/scripts/GMT_gsfml_components.sh diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst index 4bc579ea215..3d0cba48827 100644 --- a/doc/rst/source/supplements/gsfml/fzmodeler.rst +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -34,8 +34,9 @@ Description and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It builds a synthetic model cross-profile given the chosen model parameters and optionally images the profile via a PDF plot. The -model evaluated is :math:`z(x) = A[mG_1 + (1-m)(uG_2 + G0)]`, where *A* is amplitude (|-N|), -*m* is assymetry (|-A|), and *u* is compression (|-C|). +model evaluated is :math:`z(x) = A[mG_1 + (1-m)(uG_2 - G0)]`, where *A* is amplitude (|-N|), +*m* is asymmetry (|-A|), and *u* is compression (|-C|). Here :math:`G_0` is the Gaussian +function, while :math:`G_1` and :math:`G_2` are the first two horizontal derivatives. Optional Arguments ------------------ diff --git a/doc/scripts/GMT_gsfml_components.sh b/doc/scripts/GMT_gsfml_components.sh new file mode 100755 index 00000000000..4821f0b0eed --- /dev/null +++ b/doc/scripts/GMT_gsfml_components.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Plot the three building blocks G0, G1, G2 in a normalized way +gmt begin GMT_gsfml_components + fzmodeler -D-30/30/0.1 -N1 -W10 -G0 -T- | gmt plot -W1p,red -Bxafg5 -Byafg1 -R-30/30/-1.25/1.25 -JX15c/-5c -l"-G@-0@-" + fzmodeler -D-30/30/0.1 -N1 -W10 -A1 -G1 -T- | gmt plot -W1p,green -JX15c/5c -l"G@-1@-" + fzmodeler -D-30/30/0.1 -N1 -W10 -C1 -G2 -T- | gmt plot -W1p,blue -l"G@-2@-" +gmt end show diff --git a/src/gsfml/fzmodeler b/src/gsfml/fzmodeler index ad6e44ed6f0..c8aee62c023 100755 --- a/src/gsfml/fzmodeler +++ b/src/gsfml/fzmodeler @@ -23,7 +23,7 @@ function G0 () { # Gaussian - The Atlantic signal. Expects: x0 x1 dx center width d2km D2KM=$6 - gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV 2 POW NEG EXP NEG = + gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV 2 POW NEG EXP = } function G1 () { # d/dx Gaussian - The Pacific signal. Expects: x0 x1 dx center width d2km D2KM=$6 @@ -36,6 +36,7 @@ function G2 () { # d2/dx2 Gaussian - The Compression signal. Expects: x0 x1 dx c gmt math -T$1/$2/$3 T ${D2KM} MUL $4 SUB $5 DIV 2 POW DUP NEG EXP MUL ${i_A} MUL = } function synthFZ () { # Combined signal. Expects: x0 x1 dx center width m u A km? + # Evaluate z(x) = A * [m * G1 + (1 - m) * (u * G2 - G0)] if [ $9 -eq 1 ]; then D2KM=1 else @@ -47,7 +48,7 @@ function synthFZ () { # Combined signal. Expects: x0 x1 dx center width m u A km G0 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G0 G1 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G1 G2 $1 $2 $3 $4 $5 ${D2KM} > /tmp/G2 - gmt math /tmp/G2 $u MUL /tmp/G0 ADD ${m1} MUL /tmp/G1 ${m} MUL ADD NORM $8 MUL = + gmt math /tmp/G2 $u MUL /tmp/G0 SUB ${m1} MUL /tmp/G1 ${m} MUL ADD NORM $8 MUL = } . fz_funcs.sh # Load in FZ-specific shell functions @@ -84,6 +85,7 @@ trap $(fz_cleanup 1) 1 2 3 15 # Set interrupt handling # Default values verbose=0 plot=0 +out=0 asym=0 comp=0 code=-1 @@ -135,7 +137,6 @@ if [ "X${domain}" = "X" ]; then # Default settings domain=-5/5/2 fi fi -out=0 if [ "X${name}" = "X-" ]; then out=1 name=/tmp/$$ @@ -167,7 +168,7 @@ if [ ${plot} -eq 1 ]; then rm -f ${name}.txt else gmt begin ${name} pdf - gmt plot -R${w}/${e}/-${amp}/${amp} -JX${X} -Baf -BWSne ${name}.txt -W2p + gmt plot -R${w}/${e}/-${amp}/${amp} -JX${X} -Bafg -BWSne ${name}.txt -W2p gmt end show if [ $verbose -eq 1 ]; then echo "$0: Synthetic FZ profile plotted in file ${name}.pdf" From 82cd6b3e708cc814fe612545f2ad70fad1f49055 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sun, 3 Dec 2023 12:49:39 +0100 Subject: [PATCH 18/20] Fix to match paper equation --- doc/rst/source/supplements/gsfml/fzmodeler.rst | 3 ++- doc/scripts/GMT_gsfml_components.sh | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst index 3d0cba48827..529ddf3a7fc 100644 --- a/doc/rst/source/supplements/gsfml/fzmodeler.rst +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -34,9 +34,10 @@ Description and Magnetic Lineation Project [see `GSFML `_ for a full description of the project]. It builds a synthetic model cross-profile given the chosen model parameters and optionally images the profile via a PDF plot. The -model evaluated is :math:`z(x) = A[mG_1 + (1-m)(uG_2 - G0)]`, where *A* is amplitude (|-N|), +model evaluated is :math:`z(x) = A[mG_1 + (1-m)(uG_2 - G_0)]`, where *A* is amplitude (|-N|), *m* is asymmetry (|-A|), and *u* is compression (|-C|). Here :math:`G_0` is the Gaussian function, while :math:`G_1` and :math:`G_2` are the first two horizontal derivatives. +**Note**: The blend model subtracts Here :math:`G_0` since for fracture zones we want the negative Gaussian. Optional Arguments ------------------ diff --git a/doc/scripts/GMT_gsfml_components.sh b/doc/scripts/GMT_gsfml_components.sh index 4821f0b0eed..368531bcf1d 100755 --- a/doc/scripts/GMT_gsfml_components.sh +++ b/doc/scripts/GMT_gsfml_components.sh @@ -1,7 +1,7 @@ #!/bin/bash # Plot the three building blocks G0, G1, G2 in a normalized way gmt begin GMT_gsfml_components - fzmodeler -D-30/30/0.1 -N1 -W10 -G0 -T- | gmt plot -W1p,red -Bxafg5 -Byafg1 -R-30/30/-1.25/1.25 -JX15c/-5c -l"-G@-0@-" - fzmodeler -D-30/30/0.1 -N1 -W10 -A1 -G1 -T- | gmt plot -W1p,green -JX15c/5c -l"G@-1@-" + fzmodeler -D-30/30/0.1 -N1 -W10 -G0 -T- | gmt plot -W1p,red -Bxafg5 -Byafg1 -R-30/30/-1.1/1.1 -JX15c/-4c -l"-G@-0@-" + fzmodeler -D-30/30/0.1 -N1 -W10 -A1 -G1 -T- | gmt plot -W1p,green -JX15c/4c -l"G@-1@-" fzmodeler -D-30/30/0.1 -N1 -W10 -C1 -G2 -T- | gmt plot -W1p,blue -l"G@-2@-" gmt end show From b177e81107bfc6ae5137a2308692d113ef3757a8 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sun, 3 Dec 2023 14:45:43 +0100 Subject: [PATCH 19/20] Add figure to fzmodeler --- doc/rst/source/supplements/gsfml/fzmodeler.rst | 9 +++++++++ doc/scripts/images/GMT_gsfml_components.ps.dvc | 5 +++++ 2 files changed, 14 insertions(+) create mode 100644 doc/scripts/images/GMT_gsfml_components.ps.dvc diff --git a/doc/rst/source/supplements/gsfml/fzmodeler.rst b/doc/rst/source/supplements/gsfml/fzmodeler.rst index 529ddf3a7fc..53cd53ccc61 100644 --- a/doc/rst/source/supplements/gsfml/fzmodeler.rst +++ b/doc/rst/source/supplements/gsfml/fzmodeler.rst @@ -39,6 +39,15 @@ model evaluated is :math:`z(x) = A[mG_1 + (1-m)(uG_2 - G_0)]`, where *A* is ampl function, while :math:`G_1` and :math:`G_2` are the first two horizontal derivatives. **Note**: The blend model subtracts Here :math:`G_0` since for fracture zones we want the negative Gaussian. +.. _GFSML_model: + +.. figure:: /_images/GMT_gsfml_components.* + :width: 500 px + :align: center + + Three components (the Gaussian and its two first derivatives) can be used to create a blended + model that matches a FZ-crossing VGG anomaly. Modeling may also require a linear trend. + Optional Arguments ------------------ diff --git a/doc/scripts/images/GMT_gsfml_components.ps.dvc b/doc/scripts/images/GMT_gsfml_components.ps.dvc new file mode 100644 index 00000000000..4bfa26e8f47 --- /dev/null +++ b/doc/scripts/images/GMT_gsfml_components.ps.dvc @@ -0,0 +1,5 @@ +outs: +- md5: 68849a4b9126552a3c4b7296be0dc5fc + size: 27603 + hash: md5 + path: GMT_gsfml_components.ps From 17d5051979f554322004c8f98ed85f4fbeb9726a Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sun, 3 Dec 2023 15:08:34 +0100 Subject: [PATCH 20/20] Update plot --- doc/scripts/images/GMT_gsfml_components.ps.dvc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/scripts/images/GMT_gsfml_components.ps.dvc b/doc/scripts/images/GMT_gsfml_components.ps.dvc index 4bfa26e8f47..e62dd375e64 100644 --- a/doc/scripts/images/GMT_gsfml_components.ps.dvc +++ b/doc/scripts/images/GMT_gsfml_components.ps.dvc @@ -1,5 +1,5 @@ outs: -- md5: 68849a4b9126552a3c4b7296be0dc5fc - size: 27603 +- md5: 93ed456e06d5c1f9d6acc2fc98e49fbf + size: 29551 hash: md5 path: GMT_gsfml_components.ps