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 0e463bb77f376912fcf50604bad9b85d23cd185e
parent 7a18a46e2af2668a2375bf7eb7ffa13955d99aa3
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  9 Jan 2026 15:14:39 +0100

Enable serialization of data loaded by the shtr utility

The -o option defines the file to which the data is written. When
loading lines, the new -z option controls their compression level. The
shtr utility can therefore be used to test the balance between memory
space and compression speed, and as a tool for encoding and compressing
spectroscopic data from HITRAN databases.

Diffstat:
Mdoc/shtr.1 | 34+++++++++++++++++++++++++++++++---
Msrc/shtr_main.c | 69++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/doc/shtr.1 b/doc/shtr.1 @@ -15,19 +15,21 @@ .\" .\" 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 5, 2026 +.Dd January 9, 2026 .Dt SHTR 1 .Os .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh NAME .Nm shtr -.Nd load and print information on HITRAN files +.Nd process spectroscopic data from HITRAN files .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh SYNOPSIS .Nm .Op Fl hv .Op Fl l Ar lines .Op Fl m Ar molparam +.Op Fl o Ar output +.Op Fl z Ar compression_level .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh DESCRIPTION .Nm @@ -37,7 +39,11 @@ The data can be either isotopologue metadata or line-by-line parameters. In fact, .Nm is a utility for analyzing the behavior of the Star-HITRAN library with -regard to the loading and internal structuring of spectroscopic data. +regard to the loading and its internal structuring of spectroscopic +data. +It can also be used to serialize the internal representation of loaded +data, which is much more compact for lines and therefore faster to reload +by the library. .Pp All isotopologue metadata are loaded. However, since the number of lines can be very large, only a subset of @@ -80,6 +86,8 @@ By default, memory usage is displayed in bytes. Files storing line-by-line parameters to be loaded. .It Fl m Ar molparam Files storing isotopologue metadata to be loaded. +.It Fl o Ar output +Files in which to serialize the list of loaded lines. .It Fl v Make .Nm @@ -88,11 +96,31 @@ 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 .Ex -std .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh EXAMPLES +Load a list of lines and serialize the resulting binary representation +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: +.Bd -literal -offset Ds +shtr -l /path/to/CO2_lines.hitemp2010 -o CO2.bin -vvv -h +.Ed +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh SEE ALSO .Rs .%T The HITRAN Database diff --git a/src/shtr_main.c b/src/shtr_main.c @@ -33,11 +33,15 @@ struct args { char* molparam; char* lines; + char* output; int verbose; /* Verbosity level */ + int compression; /* Compression level */ int human_readable; }; -static const struct args ARGS_DEFAULT = {0}; +static const struct args ARGS_DEFAULT = { + NULL, NULL, NULL, 0, SHTR_DEFAULT_COMPRESSION, 0 +}; struct cmd { struct mem_allocator allocator; @@ -53,7 +57,8 @@ static const struct cmd CMD_NULL = {0}; static INLINE void usage(FILE* stream) { - fprintf(stream, "usage: shtr [-hv] [-l lines] [-m molparam]\n"); + fprintf(stream, +"usage: shtr [-hv] [-l lines] [-m molparam] [-o output] [-z compression_level]\n"); } static res_T @@ -66,12 +71,14 @@ args_init(struct args* args, int argc, char** argv) *args = ARGS_DEFAULT; - while((opt = getopt(argc, argv, "hl:m:v")) != -1) { + while((opt = getopt(argc, argv, "hl:m:o:vz:")) != -1) { switch(opt) { case 'h': args->human_readable = 1; break; case 'l': args->lines = optarg; break; case 'm': args->molparam = optarg; break; + case 'o': args->output = optarg; 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) { @@ -143,16 +150,45 @@ load_lines(const struct cmd* cmd, struct shtr_line_list** lines) args.file = stdin; args.filename = "stdin"; } + args.compression_level = cmd->args.compression; return shtr_line_list_load(cmd->shtr, &args, lines); } -static void +static res_T +process_molparam(const struct cmd* cmd, struct shtr_isotope_metadata* molparam) +{ + FILE* fp = NULL; + res_T res = RES_OK; + ASSERT(cmd && molparam); + + if(!cmd->args.output) goto exit; + + fp = fopen(cmd->args.output, "w"); + if(!fp) { + fprintf(stderr, "%s: error opening file -- %s\n", + cmd->args.output, strerror(errno)); + res = RES_IO_ERR; + goto error; + } + + res = shtr_isotope_metadata_write(molparam, fp); + if(res != RES_OK) goto error; + +exit: + if(fp) CHK(fclose(fp) == 0); + return res; +error: + goto exit; +} + +static res_T process_lines(const struct cmd* cmd, 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); - (void)cmd; SHTR(line_list_get_info(list, &info)); @@ -167,6 +203,25 @@ 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; + + fp = fopen(cmd->args.output, "w"); + if(!fp) { + fprintf(stderr, "%s: error opening file -- %s\n", + cmd->args.output, strerror(errno)); + res = RES_IO_ERR; + goto error; + } + + res = shtr_line_list_write(list, fp); + if(res != RES_OK) goto error; + +exit: + if(fp) CHK(fclose(fp) == 0); + return res; +error: + goto exit; } static res_T @@ -181,11 +236,11 @@ cmd_run(const struct cmd* cmd) if(cmd->args.molparam) { if((res = load_molparam(cmd, &molparam)) != RES_OK) goto error; + if((res = process_molparam(cmd, molparam)) != RES_OK) goto error; } if(cmd->args.lines) { if((res = load_lines(cmd, &lines)) != RES_OK) goto error; - - process_lines(cmd, lines); + if((res = process_lines(cmd, lines)) != RES_OK) goto error; } sz = MEM_ALLOCATED_SIZE(&cmd->allocator);