star-hitran

Load line-by-line data from the HITRAN database
git clone git://git.meso-star.fr/star-hitran.git
Log | Files | Refs | README | LICENSE

commit 52732501a146ed02d7e6dd59639ce858c8c4b26f
parent 15717a07e44b95260b92114d87753a399ace4ee2
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 23 Jan 2026 14:13:52 +0100

shtr: update command line interface

The -h option was used to display the memory size in a user-readable
format. But one would expect the -h option to display the short help
(which was actually missing). Now, the -h option displays the short help
message, as is generally the case in many other tools, and the -H option
activates the “human-readable” flag.

The line information is formatted to make it more readable: fields are
aligned and numbers are displayed in scientific notation, providing
quick information on the order of magnitude of the values.

The compression argument has been removed, as it is no longer supported.

Line information and memory usage are now displayed conditionally,
depending on whether the -i option is set. Thus, when used to serialize
line parameters, the tool can remain silent.

Diffstat:
Mdoc/shtr.1 | 36++++++++++++++----------------------
Msrc/shtr_main.c | 83++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/doc/shtr.1 b/doc/shtr.1 @@ -15,7 +15,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. -.Dd January 12, 2026 +.Dd January 23, 2026 .Dt SHTR 1 .Os .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -25,11 +25,10 @@ .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh SYNOPSIS .Nm -.Op Fl ahsv +.Op Fl aHhisv .Op Fl l Ar lines .Op Fl m Ar molparam .Op Fl o Ar output -.Op Fl z Ar compression_level .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh DESCRIPTION .Nm @@ -66,25 +65,25 @@ Temperature-dependant exponent Air-pressure wavenumber .El .Pp -On output, -.Nm -displays the range of each parameter for all loaded lines, in addition -to their encoding error once loaded, relative to the use of -double-precision floating-point encoding. -The total memory used is finally printed. -.Pp The options are as follows: .Bl -tag -width Ds .It Fl a Measure line access performance. Both linear and random access are tested. -.It Fl h +.It Fl H Use suffixes to make memory usage easier to read: the number of consecutive digits is then three or less, using powers of 2 for sizes .Po KB = 1024, MB = 1048576, etc. .Pc . By default, memory usage is displayed in bytes. +.It Fl h +Display short help and exit. +.It Fl i +Display information about loaded data, such as memory usage. +For lines, the range of their parameters is also displayed, as well as +their encoding error once loaded, relative to the use of +double-precision floating-point encoding. .It Fl l Ar lines Files storing line-by-line parameters to be loaded. .It Fl m Ar molparam @@ -108,14 +107,6 @@ Multiple .Fl v options increase the verbosity. The maximum is 3. -.It Fl z Ar compression_level -Line compression level. -Must be between 0 -.Pq no compression -and 9 -.Pq best compression . -By default, uses an intermediate level that balances speed and -compression. .El .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh EXIT STATUS @@ -127,10 +118,11 @@ to the file .Pa CO2.bin . Make the output of .Nm -as detailed as possible and use suffixes when displaying the size of -memory used to make it easier to read: +as detailed as possible. +Print information about loaded data and use suffixes when displaying the +amount of memory used to make it easier to read: .Bd -literal -offset Ds -shtr -l /path/to/CO2_lines.hitemp2010 -o CO2.bin -vvv -h +shtr -l /path/to/CO2_lines.hitemp2010 -o CO2.bin -vvv -iH .Ed .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh SEE ALSO diff --git a/src/shtr_main.c b/src/shtr_main.c @@ -39,12 +39,11 @@ struct args { int bench_line_access; int internal_format; int verbose; /* Verbosity level */ - int compression; /* Compression level */ + int print_info; int human_readable; + int quit; }; -static const struct args ARGS_DEFAULT = { - NULL, NULL, NULL, 0, 0, 0, SHTR_DEFAULT_COMPRESSION, 0 -}; +static const struct args ARGS_DEFAULT = {0}; struct cmd { struct mem_allocator allocator; @@ -61,7 +60,7 @@ static INLINE void usage(FILE* stream) { fprintf(stream, -"usage: shtr [-ahsv] [-l lines] [-m molparam] [-o output] [-z compression_level]\n"); +"usage: shtr [-aHhisv] [-l lines] [-m molparam] [-o output]\n"); } static res_T @@ -74,16 +73,17 @@ args_init(struct args* args, int argc, char** argv) *args = ARGS_DEFAULT; - while((opt = getopt(argc, argv, "ahl:m:o:svz:")) != -1) { + while((opt = getopt(argc, argv, "aHhil:m:o:sv")) != -1) { switch(opt) { case 'a': args->bench_line_access = 1; break; - case 'h': args->human_readable = 1; break; + case 'H': args->human_readable = 1; break; + case 'h': usage(stdout); args->quit = 1; break; + case 'i': args->print_info = 1; break; case 'l': args->lines = optarg; break; case 'm': args->molparam = optarg; break; case 'o': args->output = optarg; break; case 's': args->internal_format = 1; break; case 'v': args->verbose += (args->verbose < 3); break; - case 'z': res = cstr_to_int(optarg, &args->compression); break; default: res = RES_BAD_ARG; break; } if(res != RES_OK) { @@ -95,6 +95,12 @@ args_init(struct args* args, int argc, char** argv) } } + if(!args->molparam && !args->lines) { + fprintf(stderr, "neither lines nor isotopologues are defined\n"); + res = RES_BAD_ARG; + goto error; + } + exit: return res; error: @@ -188,7 +194,6 @@ load_lines_hitran(const struct cmd* cmd, struct shtr_line_list** lines) args.file = stdin; args.filename = "stdin"; } - args.compression_level = cmd->args.compression; res = shtr_line_list_load(cmd->shtr, &args, lines); if(res != RES_OK) goto error; @@ -210,20 +215,17 @@ load_lines(const struct cmd* cmd, struct shtr_line_list** lines) } } -static res_T -process_lines(const struct cmd* cmd, const struct shtr_line_list* list) +static void +lines_info(const struct shtr_line_list* list) { - FILE* fp = NULL; struct shtr_line_list_info info = SHTR_LINE_LIST_INFO_NULL; - res_T res = RES_OK; - - ASSERT(cmd && list); + ASSERT(list); SHTR(line_list_get_info(list, &info)); #define PRINT(Name) \ - printf(STR(Name)" in [%g, %g]; absolute error: %g\n", \ - SPLIT2(info.Name.range), info.Name.err) + printf("%-18s in [%12.4e,%12.4e]; error: %e\n", \ + STR(Name), SPLIT2(info.Name.range), info.Name.err) PRINT(wavenumber); PRINT(intensity); PRINT(gamma_air); @@ -232,8 +234,30 @@ process_lines(const struct cmd* cmd, const struct shtr_line_list* list) PRINT(n_air); PRINT(delta_air); #undef PRINT +} - if(!cmd->args.output) goto exit; +static void +print_memsz(const struct cmd* cmd) +{ + char buf[128] = {0}; + size_t sz = 0; + ASSERT(cmd); + + sz = MEM_ALLOCATED_SIZE(&cmd->allocator); + if(!cmd->args.human_readable) { + printf("memory usage: %lu byt%s\n", (unsigned long)sz, sz > 0 ? "es" : "e"); + } else { + size_to_cstr(sz, SIZE_ALL, NULL, buf, sizeof(buf)); + printf("memory usage: %s\n", buf); + } +} + +static res_T +write_lines(const struct cmd* cmd, const struct shtr_line_list* list) +{ + FILE* fp = NULL; + res_T res = RES_OK; + ASSERT(cmd && list && cmd->args.output); fp = fopen(cmd->args.output, "w"); if(!fp) { @@ -274,7 +298,7 @@ bench_line_access(struct shtr_line_list* lines) } usec = time_val(time_sub(&t0, time_current(&t1), &t0), TIME_USEC); lines_per_second = 1.e9 * (double)n / (double)usec; - printf("linear access: %g lines per second\n", lines_per_second); + printf("linear access: %e lps\n", lines_per_second); /* Random access */ time_current(&t0); @@ -285,16 +309,14 @@ bench_line_access(struct shtr_line_list* lines) } usec = time_val(time_sub(&t0, time_current(&t1), &t0), TIME_USEC); lines_per_second = 1.e9 * (double)read_count / (double)usec; - printf("random access: %g lines per second\n", lines_per_second); + printf("random access: %e lps\n", lines_per_second); } static res_T cmd_run(const struct cmd* cmd) { - char buf[128] = {0}; struct shtr_isotope_metadata* molparam = NULL; struct shtr_line_list* lines = NULL; - size_t sz = 0; res_T res = RES_OK; ASSERT(cmd); @@ -303,18 +325,14 @@ cmd_run(const struct cmd* cmd) } if(cmd->args.lines) { if((res = load_lines(cmd, &lines)) != RES_OK) goto error; - if((res = process_lines(cmd, lines)) != RES_OK) goto error; + if(cmd->args.print_info) lines_info(lines); if(cmd->args.bench_line_access) bench_line_access(lines); + if(cmd->args.output) { + res = write_lines(cmd, lines); + if(res != RES_OK) goto error; + } } - - sz = MEM_ALLOCATED_SIZE(&cmd->allocator); - - if(!cmd->args.human_readable) { - printf("memory usage: %lu\n", (unsigned long)sz); - } else { - size_to_cstr(sz, SIZE_ALL, NULL, buf, sizeof(buf)); - printf("memory usage: %s\n", buf); - } + if(cmd->args.print_info) print_memsz(cmd); exit: if(molparam) SHTR(isotope_metadata_ref_put(molparam)); @@ -336,6 +354,7 @@ main(int argc, char** argv) res_T res = RES_OK; if((res = args_init(&args, argc, argv)) != RES_OK) goto error; + if(args.quit) goto exit; if((res = cmd_init(&cmd, &args)) != RES_OK) goto error; if((res = cmd_run(&cmd)) != RES_OK) goto error;