commit 3a7aba76b8d9036d1e848d83ce7afe5b858f0f95
parent 57c2521bcea370515cbdc686ea17d6ff2d2914ea
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 23 May 2022 14:53:39 +0200
Rename shtr_lines_<list|view> in shtr_line_<list|view>
Diffstat:
9 files changed, 1062 insertions(+), 1062 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -48,11 +48,11 @@ set(SHTR_FILES_SRC
shtr_log.c
shtr_isotope_metadata.c
shtr_param.c
- shtr_lines_list.c
- shtr_lines_view.c)
+ shtr_line_list.c
+ shtr_line_view.c)
set(SHTR_FILES_INC
shtr_c.h
- shtr_lines_list_c.h
+ shtr_line_list_c.h
shtr_log.h
shtr_param.h)
set(SHTR_FILES_INC_API
diff --git a/src/shtr.h b/src/shtr.h
@@ -111,8 +111,8 @@ shtr_line_eq(const struct shtr_line* line0, const struct shtr_line* line1)
/* Forward declarations of opaque data structures */
struct shtr;
struct shtr_isotope_metadata;
-struct shtr_lines_list;
-struct shtr_lines_view;
+struct shtr_line_list;
+struct shtr_line_view;
/*******************************************************************************
* Input arguments for API functions
@@ -139,7 +139,7 @@ struct shtr_isotope_selection {
static const struct shtr_isotope_selection
SHTR_ISOTOPE_SELECTION_NULL = SHTR_ISOTOPE_SELECTION_NULL__;
-struct shtr_lines_view_create_args {
+struct shtr_line_view_create_args {
double wavenumber_range[2]; /* Spectral range */
/* List of molecule be selected */
@@ -148,11 +148,11 @@ struct shtr_lines_view_create_args {
double pressure; /* In atm. Used to compute the line center */
};
-#define SHTR_LINES_VIEW_CREATE_ARGS_NULL__ \
+#define SHTR_LINE_VIEW_CREATE_ARGS_NULL__ \
{{0,0}, {SHTR_ISOTOPE_SELECTION_NULL__}, 0, 0}
-static const struct shtr_lines_view_create_args
-SHTR_LINES_VIEW_CREATE_ARGS_NULL =
- SHTR_LINES_VIEW_CREATE_ARGS_NULL__;
+static const struct shtr_line_view_create_args
+SHTR_LINE_VIEW_CREATE_ARGS_NULL =
+ SHTR_LINE_VIEW_CREATE_ARGS_NULL__;
BEGIN_DECLS
@@ -236,86 +236,86 @@ shtr_isotope_metadata_write
* Lines API
******************************************************************************/
SHTR_API res_T
-shtr_lines_list_load
+shtr_line_list_load
(struct shtr* shtr,
const char* path,
- struct shtr_lines_list** list);
+ struct shtr_line_list** list);
SHTR_API res_T
-shtr_lines_list_load_stream
+shtr_line_list_load_stream
(struct shtr* shtr,
FILE* stream,
const char* stream_name, /* NULL <=> use default stream name */
- struct shtr_lines_list** list);
+ struct shtr_line_list** list);
-/* Load the line list serialized with the "shtr_lines_list_write" function */
+/* Load the line list serialized with the "shtr_line_list_write" function */
SHTR_API res_T
-shtr_lines_list_create_from_stream
+shtr_line_list_create_from_stream
(struct shtr* shtr,
FILE* stream,
- struct shtr_lines_list** list);
+ struct shtr_line_list** list);
SHTR_API res_T
-shtr_lines_list_ref_get
- (struct shtr_lines_list* list);
+shtr_line_list_ref_get
+ (struct shtr_line_list* list);
SHTR_API res_T
-shtr_lines_list_ref_put
- (struct shtr_lines_list* list);
+shtr_line_list_ref_put
+ (struct shtr_line_list* list);
SHTR_API res_T
-shtr_lines_list_get_size
- (const struct shtr_lines_list* list,
+shtr_line_list_get_size
+ (const struct shtr_line_list* list,
size_t* nlines);
SHTR_API res_T
-shtr_lines_list_get
- (const struct shtr_lines_list* list,
+shtr_line_list_get
+ (const struct shtr_line_list* list,
const struct shtr_line* lines[]);
SHTR_API res_T
-shtr_lines_list_write
- (const struct shtr_lines_list* list,
+shtr_line_list_write
+ (const struct shtr_line_list* list,
FILE* stream);
/*******************************************************************************
* Lines view API
******************************************************************************/
SHTR_API res_T
-shtr_lines_view_create
- (struct shtr_lines_list* list,
- const struct shtr_lines_view_create_args* args,
- struct shtr_lines_view** view);
+shtr_line_view_create
+ (struct shtr_line_list* list,
+ const struct shtr_line_view_create_args* args,
+ struct shtr_line_view** view);
-/* Load the line list serialized with the "shtr_lines_view_write" function */
+/* Load the line list serialized with the "shtr_line_view_write" function */
SHTR_API res_T
-shtr_lines_view_create_from_stream
+shtr_line_view_create_from_stream
(struct shtr* shtr,
FILE* stream,
- struct shtr_lines_view** view);
+ struct shtr_line_view** view);
SHTR_API res_T
-shtr_lines_view_ref_get
- (struct shtr_lines_view* view);
+shtr_line_view_ref_get
+ (struct shtr_line_view* view);
SHTR_API res_T
-shtr_lines_view_ref_put
- (struct shtr_lines_view* view);
+shtr_line_view_ref_put
+ (struct shtr_line_view* view);
SHTR_API res_T
-shtr_lines_view_get_size
- (const struct shtr_lines_view* view,
+shtr_line_view_get_size
+ (const struct shtr_line_view* view,
size_t* nlines);
SHTR_API res_T
-shtr_lines_view_get_line
- (const struct shtr_lines_view* view,
+shtr_line_view_get_line
+ (const struct shtr_line_view* view,
const size_t iline,
const struct shtr_line** line);
SHTR_API res_T
-shtr_lines_view_write
- (const struct shtr_lines_view* view,
+shtr_line_view_write
+ (const struct shtr_line_view* view,
FILE* stream);
END_DECLS
diff --git a/src/shtr_line_list.c b/src/shtr_line_list.c
@@ -0,0 +1,420 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "shtr.h"
+#include "shtr_c.h"
+#include "shtr_line_list_c.h"
+#include "shtr_log.h"
+#include "shtr_param.h"
+
+#include <rsys/cstr.h>
+#include <rsys/text_reader.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+create_line_list(struct shtr* shtr, struct shtr_line_list** out_list)
+{
+ struct shtr_line_list* list = NULL;
+ res_T res = RES_OK;
+ ASSERT(shtr && out_list);
+
+ list = MEM_CALLOC(shtr->allocator, 1, sizeof(*list));
+ if(!list) {
+ log_err(shtr, "Could not allocate the list of lines.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&list->ref);
+ SHTR(ref_get(shtr));
+ list->shtr = shtr;
+ darray_line_init(shtr->allocator, &list->lines);
+
+exit:
+ *out_list = list;
+ return res;
+error:
+ if(list) {
+ SHTR(line_list_ref_put(list));
+ list = NULL;
+ }
+ goto exit;
+}
+
+static res_T
+parse_line(struct shtr_line_list* list, struct txtrdr* txtrdr)
+{
+ struct shtr_line ln = SHTR_LINE_NULL;
+ struct param_desc param = PARAM_DESC_NULL;
+ struct shtr* shtr = NULL;
+ char* line = NULL;
+ char* str = NULL;
+ char* end = NULL;
+ char backup;
+ int molecule_id;
+ int isotope_id_local;
+ res_T res = RES_OK;
+
+ ASSERT(list && txtrdr);
+
+ line = txtrdr_get_line(txtrdr);
+ ASSERT(line);
+
+ shtr = list->shtr;
+ param.path = txtrdr_get_name(txtrdr);
+ param.line = txtrdr_get_line_num(txtrdr);
+
+ str = end = line;
+ backup = str[0];
+ #define NEXT(Size) { \
+ *end = backup; \
+ str = end; \
+ end = str+(Size); \
+ backup = *end; \
+ *end = '\0'; \
+ } (void)0
+ #define PARSE(Var, Size, Type, Name, Low, Upp, LowIncl, UppIncl) { \
+ NEXT(Size); \
+ param.name = (Name); \
+ param.low = (Low); \
+ param.upp = (Upp); \
+ param.is_low_incl = (LowIncl); \
+ param.is_upp_incl = (UppIncl); \
+ res = parse_param_##Type(shtr, str, ¶m, Var); \
+ if(res != RES_OK) goto error; \
+ } (void)0
+
+ PARSE(&molecule_id, 2, int, "molecule identifier", 0,99,1,1);
+ ln.molecule_id = (int32_t)molecule_id;
+
+ PARSE(&isotope_id_local, 1, int, "isotope local identifier", 0,9,1,1);
+ ln.isotope_id_local = (int32_t)
+ (isotope_id_local == 0 ? 9 : (isotope_id_local - 1));
+
+ PARSE(&ln.wavenumber, 12, double, "central wavenumber", 0,INF,0,1);
+ PARSE(&ln.intensity, 10, double, "reference intensity", 0,INF,0,1);
+
+ NEXT(10); /* Skip the Enstein coef */
+
+ PARSE(&ln.gamma_air, 5, double, "air broadening half-width", 0,INF,1,1);
+ PARSE(&ln.gamma_self, 5, double, "self broadening half-width", 0,INF,1,1);
+
+ /* Handle unavailable lower state energy */
+ PARSE(&ln.lower_state_energy, 10, double, "lower state energy",-INF,INF,1,1);
+ if(ln.lower_state_energy == -1) {
+ log_warn(shtr,
+ "%s:%lu: the lower state energy is unavailable for this line, so it is "
+ "ignored.\n", txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr));
+ goto exit; /* Skip the line */
+ }
+ /* Check the domain validity */
+ if(ln.lower_state_energy < 0) {
+ log_err(shtr,
+ "%s:%lu: invalid lower state energy %g. It must be in [0, INF].\n",
+ txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr),
+ ln.lower_state_energy);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ PARSE(&ln.n_air, 4, double, "temperature-dependent exponent",-INF,INF,1,1);
+ PARSE(&ln.delta_air, 8, double, "air-pressure wavenumber shift", -INF,INF,1,1);
+
+ /* Skip the remaining values */
+
+ #undef NEXT
+ #undef PARSE
+
+ /* Check the size of the remaining data to ensure that there is at least the
+ * expected number of bytes wrt the HITRAN fileformat */
+ *end = backup;
+ str = end;
+ if(strlen(str) != 93) {
+ log_err(list->shtr, "%s:%lu: missing data after delta air.\n",
+ param.path, (unsigned long)param.line);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(darray_line_size_get(&list->lines)) {
+ const struct shtr_line* last_ln = darray_line_cdata_get(&list->lines)
+ + darray_line_size_get(&list->lines) - 1;
+ if(last_ln->wavenumber > ln.wavenumber) {
+ log_err(list->shtr,
+ "%s:%lu: lines are not sorted in ascending order wrt their wavenumber.\n",
+ txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
+
+ res = darray_line_push_back(&list->lines, &ln);
+ if(res != RES_OK) {
+ log_err(list->shtr,
+ "%s:%lu: error storing the line -- %s.\n",
+ param.path, (unsigned long)param.line, res_to_cstr(res));
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+load_stream
+ (struct shtr* shtr,
+ FILE* stream,
+ const char* name,
+ struct shtr_line_list** out_lines)
+{
+ struct shtr_line_list* list = NULL;
+ struct txtrdr* txtrdr = NULL;
+ res_T res = RES_OK;
+ ASSERT(shtr && stream && name && out_lines);
+
+ res = create_line_list(shtr, &list);
+ if(res != RES_OK) goto error;
+
+ res = txtrdr_stream(list->shtr->allocator, stream, name,
+ 0/*No comment char*/, &txtrdr);
+ if(res != RES_OK) {
+ log_err(shtr, "%s: error creating the text reader -- %s.\n",
+ name, res_to_cstr(res));
+ goto error;
+ }
+
+ for(;;) {
+ res = txtrdr_read_line(txtrdr);
+ if(res != RES_OK) {
+ log_err(shtr, "%s: error reading the line `%lu' -- %s.\n",
+ name, (unsigned long)txtrdr_get_line_num(txtrdr), res_to_cstr(res));
+ goto error;
+ }
+
+ if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */
+ res = parse_line(list, txtrdr);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ if(txtrdr) txtrdr_ref_put(txtrdr);
+ *out_lines = list;
+ return res;
+error:
+ if(list) {
+ SHTR(line_list_ref_put(list));
+ list = NULL;
+ }
+ goto exit;
+}
+
+static void
+release_lines(ref_T * ref)
+{
+ struct shtr* shtr = NULL;
+ struct shtr_line_list* list = CONTAINER_OF
+ (ref, struct shtr_line_list, ref);
+ ASSERT(ref);
+ shtr = list->shtr;
+ darray_line_release(&list->lines);
+ MEM_RM(shtr->allocator, list);
+ SHTR(ref_put(shtr));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+shtr_line_list_load
+ (struct shtr* shtr,
+ const char* path,
+ struct shtr_line_list** list)
+{
+ FILE* file = NULL;
+ res_T res = RES_OK;
+
+ if(!shtr || !path || !list) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ file = fopen(path, "r");
+ if(!file) {
+ log_err(shtr, "%s: error opening file `%s'.\n", FUNC_NAME, path);
+ res = RES_IO_ERR;
+ goto error;
+ }
+
+ res = load_stream(shtr, file, path, list);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(file) fclose(file);
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+shtr_line_list_load_stream
+ (struct shtr* shtr,
+ FILE* stream,
+ const char* stream_name,
+ struct shtr_line_list** list)
+{
+ if(!shtr || !stream || !list) return RES_BAD_ARG;
+ return load_stream
+ (shtr, stream, stream_name ? stream_name : "<stream>", list);
+}
+
+res_T
+shtr_line_list_create_from_stream
+ (struct shtr* shtr,
+ FILE* stream,
+ struct shtr_line_list** out_list)
+{
+ struct shtr_line_list* list = NULL;
+ size_t nlines;
+ int version = 0;
+ res_T res = RES_OK;
+
+ if(!shtr || !out_list || !stream) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = create_line_list(shtr, &list);
+ if(res != RES_OK) goto error;
+
+ #define READ(Var, Nb) { \
+ if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ if(feof(stream)) { \
+ res = RES_BAD_ARG; \
+ } else if(ferror(stream)) { \
+ res = RES_IO_ERR; \
+ } else { \
+ res = RES_UNKNOWN_ERR; \
+ } \
+ log_err(shtr, "%s: error reading isotope metadata -- %s.\n", \
+ FUNC_NAME, res_to_cstr(res)); \
+ goto error; \
+ } \
+ } (void)0
+ READ(&version, 1);
+ if(version != SHTR_LINE_LIST_VERSION) {
+ log_err(shtr,
+ "%s: unexpected line list version %d. "
+ "Expecting a line list in version %d.\n",
+ FUNC_NAME, version, SHTR_LINE_LIST_VERSION);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ READ(&nlines, 1);
+ res = darray_line_resize(&list->lines, nlines);
+ if(res != RES_OK) {
+ log_err(shtr, "%s: error allocating the line list -- %s.\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
+
+ READ(darray_line_data_get(&list->lines), nlines);
+ #undef READ
+
+exit:
+ if(out_list) *out_list = list;
+ return res;
+error:
+ if(list) {
+ SHTR(line_list_ref_put(list));
+ list = NULL;
+ }
+ goto exit;
+}
+
+res_T
+shtr_line_list_ref_get(struct shtr_line_list* list)
+{
+ if(!list) return RES_BAD_ARG;
+ ref_get(&list->ref);
+ return RES_OK;
+}
+
+res_T
+shtr_line_list_ref_put(struct shtr_line_list* list)
+{
+ if(!list) return RES_BAD_ARG;
+ ref_put(&list->ref, release_lines);
+ return RES_OK;
+}
+
+res_T
+shtr_line_list_get_size
+ (const struct shtr_line_list* list,
+ size_t* nlines)
+{
+ if(!list || !nlines) return RES_BAD_ARG;
+ *nlines = darray_line_size_get(&list->lines);
+ return RES_OK;
+}
+
+res_T
+shtr_line_list_get
+ (const struct shtr_line_list* list,
+ const struct shtr_line* line_list[])
+{
+ if(!list || !line_list) return RES_BAD_ARG;
+ *line_list = darray_line_cdata_get(&list->lines);
+ return RES_OK;
+}
+
+res_T
+shtr_line_list_write
+ (const struct shtr_line_list* list,
+ FILE* stream)
+{
+ size_t nlines = 0;
+ res_T res = RES_OK;
+
+ if(!list || !stream) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ nlines = darray_line_size_get(&list->lines);
+
+ #define WRITE(Var, Nb) { \
+ if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ log_err(list->shtr, "%s: error writing line list.\n", FUNC_NAME); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+ WRITE(&SHTR_LINE_LIST_VERSION, 1);
+ WRITE(&nlines, 1);
+ WRITE(darray_line_cdata_get(&list->lines), nlines);
+ #undef WRITE
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/shtr_line_list_c.h b/src/shtr_line_list_c.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SHTR_LINE_LIST_C_H
+#define SHTR_LINE_LIST_C_H
+
+#include <rsys/dynamic_array.h>
+#include <rsys/ref_count.h>
+
+/* Generate the dynamic array of lines */
+#define DARRAY_NAME line
+#define DARRAY_DATA struct shtr_line
+#include <rsys/dynamic_array.h>
+
+struct shtr;
+
+/* Version of the line list. One should increment it and perform a version
+ * management onto serialized data when the line list structure are updated. */
+static const int SHTR_LINE_LIST_VERSION = 0;
+
+struct shtr_line_list {
+ /* Lines sorted in ascending order wrt their wavenumber */
+ struct darray_line lines;
+
+ struct shtr* shtr;
+ ref_T ref;
+};
+
+#endif /* SHTR_LINE_LIST_C_H */
diff --git a/src/shtr_line_view.c b/src/shtr_line_view.c
@@ -0,0 +1,409 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#define _POSIX_C_SOURCE 200112L /* nextafter */
+
+#include "shtr.h"
+#include "shtr_c.h"
+#include "shtr_line_list_c.h"
+#include "shtr_log.h"
+
+#include <rsys/cstr.h>
+#include <rsys/dynamic_array_size_t.h>
+
+#include <math.h>
+
+/* Version of the line view. One should increment it and perform a version
+ * management onto serialized data when the line view structure are updated. */
+static const int SHTR_LINE_VIEW_VERSION = 0;
+
+struct shtr_line_view {
+ struct shtr_line_list* list;
+ struct darray_size_t line_ids; /* Indices of the selected lines */
+ ref_T ref;
+};
+
+struct molecule_selection {
+ /* Map the isotope local identifier to a boolean defining if the isotope is
+ * selected or not */
+ char isotopes[SHTR_MAX_ISOTOPES_COUNT];
+ double cutoff; /* Molecule cutoff */
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+check_shtr_isotope_selection
+ (struct shtr* shtr,
+ const char* caller,
+ const struct shtr_isotope_selection* molecule)
+{
+ size_t i;
+ ASSERT(caller && molecule);
+
+ if((size_t)molecule->id >= SHTR_MAX_MOLECULES_COUNT) {
+ log_err(shtr,
+ "%s: molecule %d: invalid molecule identifier. "
+ "It must be less than %d.\n",
+ caller, molecule->id, SHTR_MAX_MOLECULES_COUNT);
+ return RES_BAD_ARG;
+ }
+
+ if(molecule->cutoff <= 0) {
+ log_err(shtr, "%s: molecule %d: invalid cutoff %g.\n",
+ caller, molecule->id, molecule->cutoff);
+ return RES_BAD_ARG;
+ }
+
+ FOR_EACH(i, 0, molecule->nisotopes) {
+ if(molecule->isotope_ids_local[i] >= SHTR_MAX_ISOTOPES_COUNT) {
+ log_err(shtr,
+ "%s: molecule %d: isotope %d: invalid isotope local identifier. "
+ "It must be less than %d.\n",
+ caller,
+ molecule->id,
+ molecule->isotope_ids_local[i],
+ SHTR_MAX_ISOTOPES_COUNT);
+ return RES_BAD_ARG;
+ }
+ }
+ return RES_OK;
+}
+
+
+static res_T
+check_shtr_line_view_create_args
+ (struct shtr* shtr,
+ const char* caller,
+ const struct shtr_line_view_create_args* args)
+{
+ size_t i;
+ ASSERT(caller);
+
+ if(!args) return RES_BAD_ARG;
+
+ if(args->wavenumber_range[0] > args->wavenumber_range[1]) {
+ log_err(shtr, "%s: invalid line view spectral range [%g, %g].\n",
+ caller, args->wavenumber_range[0], args->wavenumber_range[1]);
+ return RES_BAD_ARG;
+ }
+
+ if(args->pressure < 0) {
+ log_err(shtr, "%s: invalid pressure %g.\n", caller, args->pressure);
+ return RES_BAD_ARG;
+ }
+
+ FOR_EACH(i, 0, args->nmolecules) {
+ const res_T res = check_shtr_isotope_selection
+ (shtr, caller, &args->molecules[i]);
+ if(res != RES_OK) return res;
+
+ }
+ return RES_OK;
+}
+
+static res_T
+create_line_view(struct shtr* shtr, struct shtr_line_view** out_view)
+{
+ struct shtr_line_view* view = NULL;
+ res_T res = RES_OK;
+ ASSERT(shtr && out_view);
+
+ view = MEM_CALLOC(shtr->allocator, 1, sizeof(*view));
+ if(!view) {
+ log_err(shtr, "Could not allocate the line view.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&view->ref);
+ darray_size_t_init(shtr->allocator, &view->line_ids);
+
+exit:
+ *out_view = view;
+ return res;
+error:
+ if(view) {
+ SHTR(line_view_ref_put(view));
+ view = NULL;
+ }
+ goto exit;
+}
+
+static res_T
+select_lines
+ (struct shtr_line_view* view,
+ const char* caller,
+ const struct shtr_line_view_create_args* args)
+{
+ const struct shtr_line* lines;
+ struct molecule_selection selection[SHTR_MAX_MOLECULES_COUNT];
+ size_t imol;
+ size_t iiso;
+ size_t iline;
+ size_t nlines;
+ res_T res = RES_OK;
+ ASSERT(view && caller && args);
+
+ /* Nothing to do */
+ if(args->nmolecules == 0) goto exit;
+
+ /* Setup the selection lookup table that map the isotope of a molecule to a
+ * boolean defining if it is selected */
+ memset(selection, 0, sizeof(selection));
+ FOR_EACH(imol, 0, args->nmolecules) {
+ const int32_t mol_id = args->molecules[imol].id;
+ ASSERT(mol_id < SHTR_MAX_MOLECULES_COUNT);
+ selection[mol_id].cutoff = args->molecules[imol].cutoff;
+
+ if(args->molecules[imol].nisotopes == 0) { /* Select all isotopes */
+ FOR_EACH(iiso, 0, SHTR_MAX_ISOTOPES_COUNT) {
+ selection[mol_id].isotopes[iiso] = 1;
+ }
+
+ } else {
+ FOR_EACH(iiso, 0, args->molecules[imol].nisotopes) {
+ const int32_t iso_id = args->molecules[imol].isotope_ids_local[iiso];
+ ASSERT(iso_id < SHTR_MAX_ISOTOPES_COUNT);
+ selection[mol_id].isotopes[iso_id] = 1;
+ }
+ }
+ }
+
+ lines = darray_line_cdata_get(&view->list->lines);
+ nlines = darray_line_size_get(&view->list->lines);
+
+ /* Iterate through list of lines to find the ones to select based on spectral
+ * range and isotope selection */
+ FOR_EACH(iline, 0, nlines) {
+ const struct shtr_line* line = lines + iline;
+ double nu = 0;
+
+ /* The line is not selected */
+ if(selection[line->molecule_id].isotopes[line->isotope_id_local] == 0) {
+ continue;
+ }
+
+ /* Compute the line center for the submitted pressure */
+ nu = line->wavenumber + line->delta_air * args->pressure;
+
+ /* The line is out of the spectral range */
+ if(nu + selection[line->molecule_id].cutoff < args->wavenumber_range[0]
+ || nu - selection[line->molecule_id].cutoff > args->wavenumber_range[1]) {
+ continue;
+ }
+
+ res = darray_size_t_push_back(&view->line_ids, &iline);
+ if(res != RES_OK) {
+ log_err(view->list->shtr,
+ "%s: could not register the line into the view -- %s.\n",
+ caller, res_to_cstr(res));
+ goto error;
+ }
+ }
+
+exit:
+ return res;
+error:
+ darray_size_t_clear(&view->line_ids);
+ goto exit;
+}
+
+static void
+release_line_view(ref_T* ref)
+{
+ struct shtr_line_view* view = CONTAINER_OF(ref, struct shtr_line_view, ref);
+ struct shtr_line_list* list = view->list;
+ ASSERT(ref);
+ darray_size_t_release(&view->line_ids);
+ MEM_RM(list->shtr->allocator, view);
+ SHTR(line_list_ref_put(list));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+shtr_line_view_create
+ (struct shtr_line_list* list,
+ const struct shtr_line_view_create_args* args,
+ struct shtr_line_view** out_view)
+{
+ struct shtr_line_view* view = NULL;
+ res_T res = RES_OK;
+
+ if(!list || !out_view) { res = RES_BAD_ARG; goto error; }
+
+ res = check_shtr_line_view_create_args(list->shtr, FUNC_NAME, args);
+ if(res != RES_OK) goto error;
+
+ res = create_line_view(list->shtr, &view);
+ if(res != RES_OK) goto error;
+ SHTR(line_list_ref_get(list));
+ view->list = list;
+
+ res = select_lines(view, FUNC_NAME, args);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(out_view) *out_view = view;
+ return res;
+error:
+ if(view) { SHTR(line_view_ref_put(view)); view = NULL; }
+ goto exit;
+}
+
+res_T
+shtr_line_view_create_from_stream
+ (struct shtr* shtr,
+ FILE* stream,
+ struct shtr_line_view** out_view)
+{
+ struct shtr_line_view* view = NULL;
+ size_t nids;
+ int version;
+ res_T res = RES_OK;
+
+ if(!shtr || !stream || !out_view) { res = RES_BAD_ARG; goto error; }
+
+ res = create_line_view(shtr, &view);
+ if(res != RES_OK) goto error;
+
+ #define READ(Var, Nb) { \
+ if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ if(feof(stream)) { \
+ res = RES_BAD_ARG; \
+ } else if(ferror(stream)) { \
+ res = RES_IO_ERR; \
+ } else { \
+ res = RES_UNKNOWN_ERR; \
+ } \
+ log_err(shtr, "%s: error reading isotope metadata -- %s.\n", \
+ FUNC_NAME, res_to_cstr(res)); \
+ goto error; \
+ } \
+ } (void)0
+ READ(&version, 1);
+ if(version != SHTR_LINE_VIEW_VERSION) {
+ log_err(shtr,
+ "%s: unexpected line view version %d. "
+ "Expecting a line view in version %d.\n",
+ FUNC_NAME, version, SHTR_LINE_VIEW_VERSION);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = shtr_line_list_create_from_stream(shtr, stream, &view->list);
+ if(res != RES_OK) goto error;
+
+ READ(&nids, 1);
+ res = darray_size_t_resize(&view->line_ids, nids);
+ if(res != RES_OK) {
+ log_err(shtr, "%s: error allocating the line view -- %s.\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
+
+ READ(darray_size_t_data_get(&view->line_ids), nids);
+ #undef READ
+
+exit:
+ if(out_view) *out_view = view;
+ return res;
+error:
+ if(view) {
+ SHTR(line_view_ref_put(view));
+ view = NULL;
+ }
+ goto exit;
+}
+
+res_T
+shtr_line_view_ref_get(struct shtr_line_view* view)
+{
+ if(!view) return RES_BAD_ARG;
+ ref_get(&view->ref);
+ return RES_OK;
+}
+
+res_T
+shtr_line_view_ref_put(struct shtr_line_view* view)
+{
+ if(!view) return RES_BAD_ARG;
+ ref_put(&view->ref, release_line_view);
+ return RES_OK;
+}
+
+res_T
+shtr_line_view_get_size(const struct shtr_line_view* view, size_t* sz)
+{
+ if(!view || !sz) return RES_BAD_ARG;
+ *sz = darray_size_t_size_get(&view->line_ids);
+ return RES_OK;
+}
+
+res_T
+shtr_line_view_get_line
+ (const struct shtr_line_view* view,
+ const size_t iline,
+ const struct shtr_line** line)
+{
+ size_t i;
+ if(!view || !line || iline >= darray_size_t_size_get(&view->line_ids)) {
+ return RES_BAD_ARG;
+ }
+ i = darray_size_t_cdata_get(&view->line_ids)[iline];
+ *line = darray_line_cdata_get(&view->list->lines) + i;
+ return RES_OK;
+}
+
+res_T
+shtr_line_view_write
+ (const struct shtr_line_view* view,
+ FILE* stream)
+{
+ size_t nids = 0;
+ res_T res = RES_OK;
+
+ if(!view || !stream) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ #define WRITE(Var, Nb) { \
+ if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ log_err(view->list->shtr, "%s: error writing line view.\n", FUNC_NAME); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+ WRITE(&SHTR_LINE_VIEW_VERSION, 1);
+
+ res = shtr_line_list_write(view->list, stream);
+ if(res != RES_OK) goto error;
+
+ nids = darray_size_t_size_get(&view->line_ids);
+ WRITE(&nids, 1);
+ WRITE(darray_size_t_cdata_get(&view->line_ids), nids);
+ #undef WRITE
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/shtr_lines_list.c b/src/shtr_lines_list.c
@@ -1,420 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "shtr.h"
-#include "shtr_c.h"
-#include "shtr_lines_list_c.h"
-#include "shtr_log.h"
-#include "shtr_param.h"
-
-#include <rsys/cstr.h>
-#include <rsys/text_reader.h>
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static res_T
-create_lines_list(struct shtr* shtr, struct shtr_lines_list** out_list)
-{
- struct shtr_lines_list* list = NULL;
- res_T res = RES_OK;
- ASSERT(shtr && out_list);
-
- list = MEM_CALLOC(shtr->allocator, 1, sizeof(*list));
- if(!list) {
- log_err(shtr, "Could not allocate the list of lines.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&list->ref);
- SHTR(ref_get(shtr));
- list->shtr = shtr;
- darray_line_init(shtr->allocator, &list->lines);
-
-exit:
- *out_list = list;
- return res;
-error:
- if(list) {
- SHTR(lines_list_ref_put(list));
- list = NULL;
- }
- goto exit;
-}
-
-static res_T
-parse_line(struct shtr_lines_list* list, struct txtrdr* txtrdr)
-{
- struct shtr_line ln = SHTR_LINE_NULL;
- struct param_desc param = PARAM_DESC_NULL;
- struct shtr* shtr = NULL;
- char* line = NULL;
- char* str = NULL;
- char* end = NULL;
- char backup;
- int molecule_id;
- int isotope_id_local;
- res_T res = RES_OK;
-
- ASSERT(list && txtrdr);
-
- line = txtrdr_get_line(txtrdr);
- ASSERT(line);
-
- shtr = list->shtr;
- param.path = txtrdr_get_name(txtrdr);
- param.line = txtrdr_get_line_num(txtrdr);
-
- str = end = line;
- backup = str[0];
- #define NEXT(Size) { \
- *end = backup; \
- str = end; \
- end = str+(Size); \
- backup = *end; \
- *end = '\0'; \
- } (void)0
- #define PARSE(Var, Size, Type, Name, Low, Upp, LowIncl, UppIncl) { \
- NEXT(Size); \
- param.name = (Name); \
- param.low = (Low); \
- param.upp = (Upp); \
- param.is_low_incl = (LowIncl); \
- param.is_upp_incl = (UppIncl); \
- res = parse_param_##Type(shtr, str, ¶m, Var); \
- if(res != RES_OK) goto error; \
- } (void)0
-
- PARSE(&molecule_id, 2, int, "molecule identifier", 0,99,1,1);
- ln.molecule_id = (int32_t)molecule_id;
-
- PARSE(&isotope_id_local, 1, int, "isotope local identifier", 0,9,1,1);
- ln.isotope_id_local = (int32_t)
- (isotope_id_local == 0 ? 9 : (isotope_id_local - 1));
-
- PARSE(&ln.wavenumber, 12, double, "central wavenumber", 0,INF,0,1);
- PARSE(&ln.intensity, 10, double, "reference intensity", 0,INF,0,1);
-
- NEXT(10); /* Skip the Enstein coef */
-
- PARSE(&ln.gamma_air, 5, double, "air broadening half-width", 0,INF,1,1);
- PARSE(&ln.gamma_self, 5, double, "self broadening half-width", 0,INF,1,1);
-
- /* Handle unavailable lower state energy */
- PARSE(&ln.lower_state_energy, 10, double, "lower state energy",-INF,INF,1,1);
- if(ln.lower_state_energy == -1) {
- log_warn(shtr,
- "%s:%lu: the lower state energy is unavailable for this line, so it is "
- "ignored.\n", txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr));
- goto exit; /* Skip the line */
- }
- /* Check the domain validity */
- if(ln.lower_state_energy < 0) {
- log_err(shtr,
- "%s:%lu: invalid lower state energy %g. It must be in [0, INF].\n",
- txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr),
- ln.lower_state_energy);
- res = RES_BAD_ARG;
- goto error;
- }
-
- PARSE(&ln.n_air, 4, double, "temperature-dependent exponent",-INF,INF,1,1);
- PARSE(&ln.delta_air, 8, double, "air-pressure wavenumber shift", -INF,INF,1,1);
-
- /* Skip the remaining values */
-
- #undef NEXT
- #undef PARSE
-
- /* Check the size of the remaining data to ensure that there is at least the
- * expected number of bytes wrt the HITRAN fileformat */
- *end = backup;
- str = end;
- if(strlen(str) != 93) {
- log_err(list->shtr, "%s:%lu: missing data after delta air.\n",
- param.path, (unsigned long)param.line);
- res = RES_BAD_ARG;
- goto error;
- }
-
- if(darray_line_size_get(&list->lines)) {
- const struct shtr_line* last_ln = darray_line_cdata_get(&list->lines)
- + darray_line_size_get(&list->lines) - 1;
- if(last_ln->wavenumber > ln.wavenumber) {
- log_err(list->shtr,
- "%s:%lu: lines are not sorted in ascending order wrt their wavenumber.\n",
- txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr));
- res = RES_BAD_ARG;
- goto error;
- }
- }
-
- res = darray_line_push_back(&list->lines, &ln);
- if(res != RES_OK) {
- log_err(list->shtr,
- "%s:%lu: error storing the line -- %s.\n",
- param.path, (unsigned long)param.line, res_to_cstr(res));
- goto error;
- }
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static res_T
-load_stream
- (struct shtr* shtr,
- FILE* stream,
- const char* name,
- struct shtr_lines_list** out_lines)
-{
- struct shtr_lines_list* list = NULL;
- struct txtrdr* txtrdr = NULL;
- res_T res = RES_OK;
- ASSERT(shtr && stream && name && out_lines);
-
- res = create_lines_list(shtr, &list);
- if(res != RES_OK) goto error;
-
- res = txtrdr_stream(list->shtr->allocator, stream, name,
- 0/*No comment char*/, &txtrdr);
- if(res != RES_OK) {
- log_err(shtr, "%s: error creating the text reader -- %s.\n",
- name, res_to_cstr(res));
- goto error;
- }
-
- for(;;) {
- res = txtrdr_read_line(txtrdr);
- if(res != RES_OK) {
- log_err(shtr, "%s: error reading the line `%lu' -- %s.\n",
- name, (unsigned long)txtrdr_get_line_num(txtrdr), res_to_cstr(res));
- goto error;
- }
-
- if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */
- res = parse_line(list, txtrdr);
- if(res != RES_OK) goto error;
- }
-
-exit:
- if(txtrdr) txtrdr_ref_put(txtrdr);
- *out_lines = list;
- return res;
-error:
- if(list) {
- SHTR(lines_list_ref_put(list));
- list = NULL;
- }
- goto exit;
-}
-
-static void
-release_lines(ref_T * ref)
-{
- struct shtr* shtr = NULL;
- struct shtr_lines_list* list = CONTAINER_OF
- (ref, struct shtr_lines_list, ref);
- ASSERT(ref);
- shtr = list->shtr;
- darray_line_release(&list->lines);
- MEM_RM(shtr->allocator, list);
- SHTR(ref_put(shtr));
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-shtr_lines_list_load
- (struct shtr* shtr,
- const char* path,
- struct shtr_lines_list** list)
-{
- FILE* file = NULL;
- res_T res = RES_OK;
-
- if(!shtr || !path || !list) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- file = fopen(path, "r");
- if(!file) {
- log_err(shtr, "%s: error opening file `%s'.\n", FUNC_NAME, path);
- res = RES_IO_ERR;
- goto error;
- }
-
- res = load_stream(shtr, file, path, list);
- if(res != RES_OK) goto error;
-
-exit:
- if(file) fclose(file);
- return res;
-error:
- goto exit;
-}
-
-res_T
-shtr_lines_list_load_stream
- (struct shtr* shtr,
- FILE* stream,
- const char* stream_name,
- struct shtr_lines_list** list)
-{
- if(!shtr || !stream || !list) return RES_BAD_ARG;
- return load_stream
- (shtr, stream, stream_name ? stream_name : "<stream>", list);
-}
-
-res_T
-shtr_lines_list_create_from_stream
- (struct shtr* shtr,
- FILE* stream,
- struct shtr_lines_list** out_list)
-{
- struct shtr_lines_list* list = NULL;
- size_t nlines;
- int version = 0;
- res_T res = RES_OK;
-
- if(!shtr || !out_list || !stream) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- res = create_lines_list(shtr, &list);
- if(res != RES_OK) goto error;
-
- #define READ(Var, Nb) { \
- if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
- if(feof(stream)) { \
- res = RES_BAD_ARG; \
- } else if(ferror(stream)) { \
- res = RES_IO_ERR; \
- } else { \
- res = RES_UNKNOWN_ERR; \
- } \
- log_err(shtr, "%s: error reading isotope metadata -- %s.\n", \
- FUNC_NAME, res_to_cstr(res)); \
- goto error; \
- } \
- } (void)0
- READ(&version, 1);
- if(version != SHTR_LINES_LIST_VERSION) {
- log_err(shtr,
- "%s: unexpected line list version %d. "
- "Expecting a line list in version %d.\n",
- FUNC_NAME, version, SHTR_LINES_LIST_VERSION);
- res = RES_BAD_ARG;
- goto error;
- }
-
- READ(&nlines, 1);
- res = darray_line_resize(&list->lines, nlines);
- if(res != RES_OK) {
- log_err(shtr, "%s: error allocating the line list -- %s.\n",
- FUNC_NAME, res_to_cstr(res));
- goto error;
- }
-
- READ(darray_line_data_get(&list->lines), nlines);
- #undef READ
-
-exit:
- if(out_list) *out_list = list;
- return res;
-error:
- if(list) {
- SHTR(lines_list_ref_put(list));
- list = NULL;
- }
- goto exit;
-}
-
-res_T
-shtr_lines_list_ref_get(struct shtr_lines_list* list)
-{
- if(!list) return RES_BAD_ARG;
- ref_get(&list->ref);
- return RES_OK;
-}
-
-res_T
-shtr_lines_list_ref_put(struct shtr_lines_list* list)
-{
- if(!list) return RES_BAD_ARG;
- ref_put(&list->ref, release_lines);
- return RES_OK;
-}
-
-res_T
-shtr_lines_list_get_size
- (const struct shtr_lines_list* list,
- size_t* nlines)
-{
- if(!list || !nlines) return RES_BAD_ARG;
- *nlines = darray_line_size_get(&list->lines);
- return RES_OK;
-}
-
-res_T
-shtr_lines_list_get
- (const struct shtr_lines_list* list,
- const struct shtr_line* lines_list[])
-{
- if(!list || !lines_list) return RES_BAD_ARG;
- *lines_list = darray_line_cdata_get(&list->lines);
- return RES_OK;
-}
-
-res_T
-shtr_lines_list_write
- (const struct shtr_lines_list* list,
- FILE* stream)
-{
- size_t nlines = 0;
- res_T res = RES_OK;
-
- if(!list || !stream) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- nlines = darray_line_size_get(&list->lines);
-
- #define WRITE(Var, Nb) { \
- if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
- log_err(list->shtr, "%s: error writing line list.\n", FUNC_NAME); \
- res = RES_IO_ERR; \
- goto error; \
- } \
- } (void)0
- WRITE(&SHTR_LINES_LIST_VERSION, 1);
- WRITE(&nlines, 1);
- WRITE(darray_line_cdata_get(&list->lines), nlines);
- #undef WRITE
-
-exit:
- return res;
-error:
- goto exit;
-}
diff --git a/src/shtr_lines_list_c.h b/src/shtr_lines_list_c.h
@@ -1,44 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef SHTR_LINES_LIST_C_H
-#define SHTR_LINES_LIST_C_H
-
-#include <rsys/dynamic_array.h>
-#include <rsys/ref_count.h>
-
-/* Generate the dynamic array of lines */
-#define DARRAY_NAME line
-#define DARRAY_DATA struct shtr_line
-#include <rsys/dynamic_array.h>
-
-struct shtr;
-
-/* Version of the line list. One should increment it and perform a version
- * management onto serialized data when the line list structure are updated. */
-static const int SHTR_LINES_LIST_VERSION = 0;
-
-struct shtr_lines_list {
- /* Lines sorted in ascending order wrt their wavenumber */
- struct darray_line lines;
-
- struct shtr* shtr;
- ref_T ref;
-};
-
-#endif /* SHTR_LINES_LIST_C_H */
diff --git a/src/shtr_lines_view.c b/src/shtr_lines_view.c
@@ -1,409 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#define _POSIX_C_SOURCE 200112L /* nextafter */
-
-#include "shtr.h"
-#include "shtr_c.h"
-#include "shtr_lines_list_c.h"
-#include "shtr_log.h"
-
-#include <rsys/cstr.h>
-#include <rsys/dynamic_array_size_t.h>
-
-#include <math.h>
-
-/* Version of the line view. One should increment it and perform a version
- * management onto serialized data when the line view structure are updated. */
-static const int SHTR_LINES_VIEW_VERSION = 0;
-
-struct shtr_lines_view {
- struct shtr_lines_list* list;
- struct darray_size_t line_ids; /* Indices of the selected lines */
- ref_T ref;
-};
-
-struct molecule_selection {
- /* Map the isotope local identifier to a boolean defining if the isotope is
- * selected or not */
- char isotopes[SHTR_MAX_ISOTOPES_COUNT];
- double cutoff; /* Molecule cutoff */
-};
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static res_T
-check_shtr_isotope_selection
- (struct shtr* shtr,
- const char* caller,
- const struct shtr_isotope_selection* molecule)
-{
- size_t i;
- ASSERT(caller && molecule);
-
- if((size_t)molecule->id >= SHTR_MAX_MOLECULES_COUNT) {
- log_err(shtr,
- "%s: molecule %d: invalid molecule identifier. "
- "It must be less than %d.\n",
- caller, molecule->id, SHTR_MAX_MOLECULES_COUNT);
- return RES_BAD_ARG;
- }
-
- if(molecule->cutoff <= 0) {
- log_err(shtr, "%s: molecule %d: invalid cutoff %g.\n",
- caller, molecule->id, molecule->cutoff);
- return RES_BAD_ARG;
- }
-
- FOR_EACH(i, 0, molecule->nisotopes) {
- if(molecule->isotope_ids_local[i] >= SHTR_MAX_ISOTOPES_COUNT) {
- log_err(shtr,
- "%s: molecule %d: isotope %d: invalid isotope local identifier. "
- "It must be less than %d.\n",
- caller,
- molecule->id,
- molecule->isotope_ids_local[i],
- SHTR_MAX_ISOTOPES_COUNT);
- return RES_BAD_ARG;
- }
- }
- return RES_OK;
-}
-
-
-static res_T
-check_shtr_lines_view_create_args
- (struct shtr* shtr,
- const char* caller,
- const struct shtr_lines_view_create_args* args)
-{
- size_t i;
- ASSERT(caller);
-
- if(!args) return RES_BAD_ARG;
-
- if(args->wavenumber_range[0] > args->wavenumber_range[1]) {
- log_err(shtr, "%s: invalid lines view spectral range [%g, %g].\n",
- caller, args->wavenumber_range[0], args->wavenumber_range[1]);
- return RES_BAD_ARG;
- }
-
- if(args->pressure < 0) {
- log_err(shtr, "%s: invalid pressure %g.\n", caller, args->pressure);
- return RES_BAD_ARG;
- }
-
- FOR_EACH(i, 0, args->nmolecules) {
- const res_T res = check_shtr_isotope_selection
- (shtr, caller, &args->molecules[i]);
- if(res != RES_OK) return res;
-
- }
- return RES_OK;
-}
-
-static res_T
-create_lines_view(struct shtr* shtr, struct shtr_lines_view** out_view)
-{
- struct shtr_lines_view* view = NULL;
- res_T res = RES_OK;
- ASSERT(shtr && out_view);
-
- view = MEM_CALLOC(shtr->allocator, 1, sizeof(*view));
- if(!view) {
- log_err(shtr, "Could not allocate the line view.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&view->ref);
- darray_size_t_init(shtr->allocator, &view->line_ids);
-
-exit:
- *out_view = view;
- return res;
-error:
- if(view) {
- SHTR(lines_view_ref_put(view));
- view = NULL;
- }
- goto exit;
-}
-
-static res_T
-select_lines
- (struct shtr_lines_view* view,
- const char* caller,
- const struct shtr_lines_view_create_args* args)
-{
- const struct shtr_line* lines;
- struct molecule_selection selection[SHTR_MAX_MOLECULES_COUNT];
- size_t imol;
- size_t iiso;
- size_t iline;
- size_t nlines;
- res_T res = RES_OK;
- ASSERT(view && caller && args);
-
- /* Nothing to do */
- if(args->nmolecules == 0) goto exit;
-
- /* Setup the selection lookup table that map the isotope of a molecule to a
- * boolean defining if it is selected */
- memset(selection, 0, sizeof(selection));
- FOR_EACH(imol, 0, args->nmolecules) {
- const int32_t mol_id = args->molecules[imol].id;
- ASSERT(mol_id < SHTR_MAX_MOLECULES_COUNT);
- selection[mol_id].cutoff = args->molecules[imol].cutoff;
-
- if(args->molecules[imol].nisotopes == 0) { /* Select all isotopes */
- FOR_EACH(iiso, 0, SHTR_MAX_ISOTOPES_COUNT) {
- selection[mol_id].isotopes[iiso] = 1;
- }
-
- } else {
- FOR_EACH(iiso, 0, args->molecules[imol].nisotopes) {
- const int32_t iso_id = args->molecules[imol].isotope_ids_local[iiso];
- ASSERT(iso_id < SHTR_MAX_ISOTOPES_COUNT);
- selection[mol_id].isotopes[iso_id] = 1;
- }
- }
- }
-
- lines = darray_line_cdata_get(&view->list->lines);
- nlines = darray_line_size_get(&view->list->lines);
-
- /* Iterate through list of lines to find the ones to select based on spectral
- * range and isotope selection */
- FOR_EACH(iline, 0, nlines) {
- const struct shtr_line* line = lines + iline;
- double nu = 0;
-
- /* The line is not selected */
- if(selection[line->molecule_id].isotopes[line->isotope_id_local] == 0) {
- continue;
- }
-
- /* Compute the line center for the submitted pressure */
- nu = line->wavenumber + line->delta_air * args->pressure;
-
- /* The line is out of the spectral range */
- if(nu + selection[line->molecule_id].cutoff < args->wavenumber_range[0]
- || nu - selection[line->molecule_id].cutoff > args->wavenumber_range[1]) {
- continue;
- }
-
- res = darray_size_t_push_back(&view->line_ids, &iline);
- if(res != RES_OK) {
- log_err(view->list->shtr,
- "%s: could not register the line into the view -- %s.\n",
- caller, res_to_cstr(res));
- goto error;
- }
- }
-
-exit:
- return res;
-error:
- darray_size_t_clear(&view->line_ids);
- goto exit;
-}
-
-static void
-release_lines_view(ref_T* ref)
-{
- struct shtr_lines_view* view = CONTAINER_OF(ref, struct shtr_lines_view, ref);
- struct shtr_lines_list* list = view->list;
- ASSERT(ref);
- darray_size_t_release(&view->line_ids);
- MEM_RM(list->shtr->allocator, view);
- SHTR(lines_list_ref_put(list));
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-shtr_lines_view_create
- (struct shtr_lines_list* list,
- const struct shtr_lines_view_create_args* args,
- struct shtr_lines_view** out_view)
-{
- struct shtr_lines_view* view = NULL;
- res_T res = RES_OK;
-
- if(!list || !out_view) { res = RES_BAD_ARG; goto error; }
-
- res = check_shtr_lines_view_create_args(list->shtr, FUNC_NAME, args);
- if(res != RES_OK) goto error;
-
- res = create_lines_view(list->shtr, &view);
- if(res != RES_OK) goto error;
- SHTR(lines_list_ref_get(list));
- view->list = list;
-
- res = select_lines(view, FUNC_NAME, args);
- if(res != RES_OK) goto error;
-
-exit:
- if(out_view) *out_view = view;
- return res;
-error:
- if(view) { SHTR(lines_view_ref_put(view)); view = NULL; }
- goto exit;
-}
-
-res_T
-shtr_lines_view_create_from_stream
- (struct shtr* shtr,
- FILE* stream,
- struct shtr_lines_view** out_view)
-{
- struct shtr_lines_view* view = NULL;
- size_t nids;
- int version;
- res_T res = RES_OK;
-
- if(!shtr || !stream || !out_view) { res = RES_BAD_ARG; goto error; }
-
- res = create_lines_view(shtr, &view);
- if(res != RES_OK) goto error;
-
- #define READ(Var, Nb) { \
- if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
- if(feof(stream)) { \
- res = RES_BAD_ARG; \
- } else if(ferror(stream)) { \
- res = RES_IO_ERR; \
- } else { \
- res = RES_UNKNOWN_ERR; \
- } \
- log_err(shtr, "%s: error reading isotope metadata -- %s.\n", \
- FUNC_NAME, res_to_cstr(res)); \
- goto error; \
- } \
- } (void)0
- READ(&version, 1);
- if(version != SHTR_LINES_VIEW_VERSION) {
- log_err(shtr,
- "%s: unexpected line view version %d. "
- "Expecting a line view in version %d.\n",
- FUNC_NAME, version, SHTR_LINES_VIEW_VERSION);
- res = RES_BAD_ARG;
- goto error;
- }
-
- res = shtr_lines_list_create_from_stream(shtr, stream, &view->list);
- if(res != RES_OK) goto error;
-
- READ(&nids, 1);
- res = darray_size_t_resize(&view->line_ids, nids);
- if(res != RES_OK) {
- log_err(shtr, "%s: error allocating the line view -- %s.\n",
- FUNC_NAME, res_to_cstr(res));
- goto error;
- }
-
- READ(darray_size_t_data_get(&view->line_ids), nids);
- #undef READ
-
-exit:
- if(out_view) *out_view = view;
- return res;
-error:
- if(view) {
- SHTR(lines_view_ref_put(view));
- view = NULL;
- }
- goto exit;
-}
-
-res_T
-shtr_lines_view_ref_get(struct shtr_lines_view* view)
-{
- if(!view) return RES_BAD_ARG;
- ref_get(&view->ref);
- return RES_OK;
-}
-
-res_T
-shtr_lines_view_ref_put(struct shtr_lines_view* view)
-{
- if(!view) return RES_BAD_ARG;
- ref_put(&view->ref, release_lines_view);
- return RES_OK;
-}
-
-res_T
-shtr_lines_view_get_size(const struct shtr_lines_view* view, size_t* sz)
-{
- if(!view || !sz) return RES_BAD_ARG;
- *sz = darray_size_t_size_get(&view->line_ids);
- return RES_OK;
-}
-
-res_T
-shtr_lines_view_get_line
- (const struct shtr_lines_view* view,
- const size_t iline,
- const struct shtr_line** line)
-{
- size_t i;
- if(!view || !line || iline >= darray_size_t_size_get(&view->line_ids)) {
- return RES_BAD_ARG;
- }
- i = darray_size_t_cdata_get(&view->line_ids)[iline];
- *line = darray_line_cdata_get(&view->list->lines) + i;
- return RES_OK;
-}
-
-res_T
-shtr_lines_view_write
- (const struct shtr_lines_view* view,
- FILE* stream)
-{
- size_t nids = 0;
- res_T res = RES_OK;
-
- if(!view || !stream) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- #define WRITE(Var, Nb) { \
- if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
- log_err(view->list->shtr, "%s: error writing line view.\n", FUNC_NAME); \
- res = RES_IO_ERR; \
- goto error; \
- } \
- } (void)0
- WRITE(&SHTR_LINES_VIEW_VERSION, 1);
-
- res = shtr_lines_list_write(view->list, stream);
- if(res != RES_OK) goto error;
-
- nids = darray_size_t_size_get(&view->line_ids);
- WRITE(&nids, 1);
- WRITE(darray_size_t_cdata_get(&view->line_ids), nids);
- #undef WRITE
-
-exit:
- return res;
-error:
- goto exit;
-}
diff --git a/src/test_shtr_lines.c b/src/test_shtr_lines.c
@@ -115,7 +115,7 @@ test_load(struct shtr* shtr)
};
const size_t nlines = sizeof(l) / sizeof(struct shtr_line);
- struct shtr_lines_list* list = NULL;
+ struct shtr_line_list* list = NULL;
const struct shtr_line* lines = NULL;
const char* filename = "test_lines.txt";
FILE* fp = NULL;
@@ -125,57 +125,57 @@ test_load(struct shtr* shtr)
print_lines(fp, l, nlines);
rewind(fp);
- CHK(shtr_lines_list_load_stream(NULL, fp, NULL, &list) == RES_BAD_ARG);
- CHK(shtr_lines_list_load_stream(shtr, NULL, NULL, &list) == RES_BAD_ARG);
- CHK(shtr_lines_list_load_stream(shtr, fp, NULL, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
+ CHK(shtr_line_list_load_stream(NULL, fp, NULL, &list) == RES_BAD_ARG);
+ CHK(shtr_line_list_load_stream(shtr, NULL, NULL, &list) == RES_BAD_ARG);
+ CHK(shtr_line_list_load_stream(shtr, fp, NULL, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
- CHK(shtr_lines_list_get_size(NULL, &n) == RES_BAD_ARG);
- CHK(shtr_lines_list_get_size(list, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_get_size(list, &n) == RES_OK);
+ CHK(shtr_line_list_get_size(NULL, &n) == RES_BAD_ARG);
+ CHK(shtr_line_list_get_size(list, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_get_size(list, &n) == RES_OK);
CHK(n == nlines);
- CHK(shtr_lines_list_get(NULL, &lines) == RES_BAD_ARG);
- CHK(shtr_lines_list_get(list, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_get(list, &lines) == RES_OK);
+ CHK(shtr_line_list_get(NULL, &lines) == RES_BAD_ARG);
+ CHK(shtr_line_list_get(list, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_get(list, &lines) == RES_OK);
FOR_EACH(i, 0, n) CHK(shtr_line_eq(lines+i, l+i));
- CHK(shtr_lines_list_ref_get(NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_ref_get(list) == RES_OK);
- CHK(shtr_lines_list_ref_put(NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_ref_put(list) == RES_OK);
- CHK(shtr_lines_list_ref_put(list) == RES_OK);
+ CHK(shtr_line_list_ref_get(NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_ref_get(list) == RES_OK);
+ CHK(shtr_line_list_ref_put(NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_ref_put(list) == RES_OK);
+ CHK(shtr_line_list_ref_put(list) == RES_OK);
CHK(fclose(fp) == 0);
- CHK(shtr_lines_list_load(NULL, filename, &list) == RES_BAD_ARG);
- CHK(shtr_lines_list_load(shtr, NULL, &list) == RES_BAD_ARG);
- CHK(shtr_lines_list_load(shtr, filename, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_load(shtr, filename, &list) == RES_OK);
+ CHK(shtr_line_list_load(NULL, filename, &list) == RES_BAD_ARG);
+ CHK(shtr_line_list_load(shtr, NULL, &list) == RES_BAD_ARG);
+ CHK(shtr_line_list_load(shtr, filename, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_load(shtr, filename, &list) == RES_OK);
- CHK(shtr_lines_list_get_size(list, &n) == RES_OK);
+ CHK(shtr_line_list_get_size(list, &n) == RES_OK);
CHK(n == nlines);
- CHK(shtr_lines_list_get(list, &lines) == RES_OK);
+ CHK(shtr_line_list_get(list, &lines) == RES_OK);
FOR_EACH(i, 0, n) CHK(shtr_line_eq(lines+i, l+i));
- CHK(shtr_lines_list_ref_put(list) == RES_OK);
+ CHK(shtr_line_list_ref_put(list) == RES_OK);
}
static void
test_line
(struct shtr* shtr, const struct shtr_line* ln, const res_T res)
{
- struct shtr_lines_list* list = NULL;
+ struct shtr_line_list* list = NULL;
FILE* fp = NULL;
CHK(fp = tmpfile());
print_lines(fp, ln, 1);
rewind(fp);
- CHK(shtr_lines_list_load_stream(shtr, fp, NULL, &list) == res);
+ CHK(shtr_line_list_load_stream(shtr, fp, NULL, &list) == res);
CHK(fclose(fp) == 0);
- if(res == RES_OK) CHK(shtr_lines_list_ref_put(list) == RES_OK);
+ if(res == RES_OK) CHK(shtr_line_list_ref_put(list) == RES_OK);
}
static void
@@ -185,7 +185,7 @@ test_load_failures(struct shtr* shtr)
0.000134, 2.672E-38, 0.0533, 0.410, 608.4727, 0.79, 0.000060, 1, 4,
};
struct shtr_line ln;
- struct shtr_lines_list* list = NULL;
+ struct shtr_line_list* list = NULL;
FILE* fp = NULL;
/* Check that the reference line is valid */
@@ -232,14 +232,14 @@ test_load_failures(struct shtr* shtr)
ln.wavenumber -= 1e-4;
print_lines(fp, &ln, 1);
rewind(fp);
- CHK(shtr_lines_list_load_stream(shtr, fp, NULL, &list) == RES_BAD_ARG);
+ CHK(shtr_line_list_load_stream(shtr, fp, NULL, &list) == RES_BAD_ARG);
CHK(fclose(fp) == 0);
}
static void
-check_lines_list_equality
- (const struct shtr_lines_list* list1,
- const struct shtr_lines_list* list2)
+check_line_list_equality
+ (const struct shtr_line_list* list1,
+ const struct shtr_line_list* list2)
{
const struct shtr_line* lines1 = NULL;
const struct shtr_line* lines2 = NULL;
@@ -247,13 +247,13 @@ check_lines_list_equality
size_t iline, nlines;
CHK(list1 && list2);
- CHK(shtr_lines_list_get_size(list1, &n1) == RES_OK);
- CHK(shtr_lines_list_get_size(list2, &n2) == RES_OK);
+ CHK(shtr_line_list_get_size(list1, &n1) == RES_OK);
+ CHK(shtr_line_list_get_size(list2, &n2) == RES_OK);
CHK(n1 == n2);
nlines = n1;
- CHK(shtr_lines_list_get(list1, &lines1) == RES_OK);
- CHK(shtr_lines_list_get(list2, &lines2) == RES_OK);
+ CHK(shtr_line_list_get(list1, &lines1) == RES_OK);
+ CHK(shtr_line_list_get(list2, &lines2) == RES_OK);
FOR_EACH(iline, 0, nlines) {
CHK(shtr_line_eq(lines1+iline, lines2+iline));
}
@@ -271,48 +271,48 @@ test_serialization(struct shtr* shtr)
};
const size_t nlines = sizeof(l) / sizeof(struct shtr_line);
- struct shtr_lines_list* list1 = NULL;
- struct shtr_lines_list* list2 = NULL;
+ struct shtr_line_list* list1 = NULL;
+ struct shtr_line_list* list2 = NULL;
FILE* fp = NULL;
CHK(fp = tmpfile());
print_lines(fp, l, nlines);
rewind(fp);
- CHK(shtr_lines_list_load_stream(shtr, fp, NULL, &list1) == RES_OK);
+ CHK(shtr_line_list_load_stream(shtr, fp, NULL, &list1) == RES_OK);
fclose(fp);
CHK(fp = tmpfile());
- CHK(shtr_lines_list_write(NULL, fp) == RES_BAD_ARG);
- CHK(shtr_lines_list_write(list1, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_write(list1, fp) == RES_OK);
+ CHK(shtr_line_list_write(NULL, fp) == RES_BAD_ARG);
+ CHK(shtr_line_list_write(list1, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_write(list1, fp) == RES_OK);
rewind(fp);
- CHK(shtr_lines_list_create_from_stream(NULL, fp, &list2) == RES_BAD_ARG);
- CHK(shtr_lines_list_create_from_stream(shtr, NULL, &list2) == RES_BAD_ARG);
- CHK(shtr_lines_list_create_from_stream(shtr, fp, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_list_create_from_stream(shtr, fp, &list2) == RES_OK);
+ CHK(shtr_line_list_create_from_stream(NULL, fp, &list2) == RES_BAD_ARG);
+ CHK(shtr_line_list_create_from_stream(shtr, NULL, &list2) == RES_BAD_ARG);
+ CHK(shtr_line_list_create_from_stream(shtr, fp, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_create_from_stream(shtr, fp, &list2) == RES_OK);
fclose(fp);
- check_lines_list_equality(list1, list2);
+ check_line_list_equality(list1, list2);
- CHK(shtr_lines_list_ref_put(list1) == RES_OK);
- CHK(shtr_lines_list_ref_put(list2) == RES_OK);
+ CHK(shtr_line_list_ref_put(list1) == RES_OK);
+ CHK(shtr_line_list_ref_put(list2) == RES_OK);
}
static void
check_view
- (const struct shtr_lines_list* list,
- const struct shtr_lines_view* view,
- const struct shtr_lines_view_create_args* args)
+ (const struct shtr_line_list* list,
+ const struct shtr_line_view* view,
+ const struct shtr_line_view_create_args* args)
{
const struct shtr_line* lines = NULL;
size_t i, n;
size_t nlines_selected = 0;
CHK(list && view && args);
- CHK(shtr_lines_list_get_size(list, &n) == RES_OK);
- CHK(shtr_lines_list_get(list, &lines) == RES_OK);
+ CHK(shtr_line_list_get_size(list, &n) == RES_OK);
+ CHK(shtr_line_list_get(list, &lines) == RES_OK);
FOR_EACH(i, 0, n) {
const struct shtr_line* line = NULL;
double nu = 0;
@@ -346,12 +346,12 @@ check_view
continue; /* Skip the isotope */
}
- CHK(shtr_lines_view_get_line(view, nlines_selected, &line) == RES_OK);
+ CHK(shtr_line_view_get_line(view, nlines_selected, &line) == RES_OK);
CHK(shtr_line_eq(line, lines+i));
nlines_selected += 1;
}
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == nlines_selected);
}
@@ -427,9 +427,9 @@ test_view(struct shtr* shtr)
const double cutoff = 0.01;
- struct shtr_lines_view_create_args args = SHTR_LINES_VIEW_CREATE_ARGS_NULL;
- struct shtr_lines_list* list = NULL;
- struct shtr_lines_view* view = NULL;
+ struct shtr_line_view_create_args args = SHTR_LINE_VIEW_CREATE_ARGS_NULL;
+ struct shtr_line_list* list = NULL;
+ struct shtr_line_view* view = NULL;
const struct shtr_line* line = NULL;
const char* filename = "test_lines.txt";
FILE* fp = NULL;
@@ -439,7 +439,7 @@ test_view(struct shtr* shtr)
print_lines(fp, l, nlines);
rewind(fp);
- CHK(shtr_lines_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
+ CHK(shtr_line_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
args.wavenumber_range[0] = 0;
args.wavenumber_range[1] = INF;
@@ -451,116 +451,116 @@ test_view(struct shtr* shtr)
args.molecules[2].cutoff = cutoff;
args.nmolecules = 3;
args.pressure = 0;
- CHK(shtr_lines_view_create(NULL, &args, &view) == RES_BAD_ARG);
- CHK(shtr_lines_view_create(list, NULL, &view) == RES_BAD_ARG);
- CHK(shtr_lines_view_create(list, &args, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
-
- CHK(shtr_lines_view_get_size(NULL, &n) == RES_BAD_ARG);
- CHK(shtr_lines_view_get_size(view, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(NULL, &args, &view) == RES_BAD_ARG);
+ CHK(shtr_line_view_create(list, NULL, &view) == RES_BAD_ARG);
+ CHK(shtr_line_view_create(list, &args, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+
+ CHK(shtr_line_view_get_size(NULL, &n) == RES_BAD_ARG);
+ CHK(shtr_line_view_get_size(view, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == nlines);
- CHK(shtr_lines_view_get_line(NULL, 0, &line) == RES_BAD_ARG);
- CHK(shtr_lines_view_get_line(view, n, &line) == RES_BAD_ARG);
- CHK(shtr_lines_view_get_line(view, 0, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_view_get_line(NULL, 0, &line) == RES_BAD_ARG);
+ CHK(shtr_line_view_get_line(view, n, &line) == RES_BAD_ARG);
+ CHK(shtr_line_view_get_line(view, 0, NULL) == RES_BAD_ARG);
FOR_EACH(i, 0, n) {
- CHK(shtr_lines_view_get_line(view, i, &line) == RES_OK);
+ CHK(shtr_line_view_get_line(view, i, &line) == RES_OK);
CHK(shtr_line_eq(line, l+i));
}
- CHK(shtr_lines_view_ref_get(NULL) == RES_BAD_ARG);
- CHK(shtr_lines_view_ref_get(view) == RES_OK);
- CHK(shtr_lines_view_ref_put(NULL) == RES_BAD_ARG);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_get(NULL) == RES_BAD_ARG);
+ CHK(shtr_line_view_ref_get(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(NULL) == RES_BAD_ARG);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.wavenumber_range[0] = 1;
args.wavenumber_range[1] = 0;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_BAD_ARG);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_BAD_ARG);
args.wavenumber_range[0] = 0;
args.wavenumber_range[1] = 1;
args.nmolecules = 0;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 0);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.pressure = -1;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_BAD_ARG);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_BAD_ARG);
args.pressure = 0;
args.molecules[0].cutoff = -1;
args.nmolecules = 3;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_BAD_ARG);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_BAD_ARG);
args.molecules[0].cutoff = cutoff;
args.wavenumber_range[0] = nextafter(l[nlines-1].wavenumber, INF) + cutoff;
args.wavenumber_range[1] = INF;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 0);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.wavenumber_range[0] = 0;
args.wavenumber_range[1] = 1.50;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.wavenumber_range[0] = 1.50;
args.wavenumber_range[1] = 1.51603;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.wavenumber_range[0] = 0.29477;
args.wavenumber_range[1] = 0.29477;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 6);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.wavenumber_range[0] = 0.09642;
args.wavenumber_range[1] = 0.21283;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 14);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.molecules[0].id = 2;
args.nmolecules = 1;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 0);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.molecules[1].id = 1;
args.nmolecules = 2;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 4);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.molecules[1].id = 3;
args.nmolecules = 2;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 10);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.wavenumber_range[0] = 0;
args.wavenumber_range[1] = INF;
args.molecules[0].id = 2;
args.nmolecules = 1;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.molecules[0].id = 1;
args.molecules[0].cutoff = 1e-6;
@@ -568,16 +568,16 @@ test_view(struct shtr* shtr)
args.nmolecules = 1;
args.wavenumber_range[0] = 0.1899;
args.wavenumber_range[1] = 0.195;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 1);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.pressure = 1;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 2);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
args.wavenumber_range[0] = 0;
args.wavenumber_range[1] = INF;
@@ -594,35 +594,35 @@ test_view(struct shtr* shtr)
args.molecules[1].isotope_ids_local[1] = 3;
args.molecules[1].nisotopes = 2;
args.nmolecules = 2;
- CHK(shtr_lines_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_lines_view_get_size(view, &n) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
+ CHK(shtr_line_view_get_size(view, &n) == RES_OK);
CHK(n == 35);
check_view(list, view, &args);
- CHK(shtr_lines_view_ref_put(view) == RES_OK);
+ CHK(shtr_line_view_ref_put(view) == RES_OK);
- CHK(shtr_lines_list_ref_put(list) == RES_OK);
+ CHK(shtr_line_list_ref_put(list) == RES_OK);
CHK(fclose(fp) == 0);
}
static void
-check_lines_view_equality
- (const struct shtr_lines_view* view1,
- const struct shtr_lines_view* view2)
+check_line_view_equality
+ (const struct shtr_line_view* view1,
+ const struct shtr_line_view* view2)
{
size_t n1, n2;
size_t iline, nlines;
CHK(view1 && view2);
- CHK(shtr_lines_view_get_size(view1, &n1) == RES_OK);
- CHK(shtr_lines_view_get_size(view2, &n2) == RES_OK);
+ CHK(shtr_line_view_get_size(view1, &n1) == RES_OK);
+ CHK(shtr_line_view_get_size(view2, &n2) == RES_OK);
CHK(n1 == n2);
nlines = n1;
FOR_EACH(iline, 0, nlines) {
const struct shtr_line* line1 = NULL;
const struct shtr_line* line2 = NULL;
- CHK(shtr_lines_view_get_line(view1, iline, &line1) == RES_OK);
- CHK(shtr_lines_view_get_line(view2, iline, &line2) == RES_OK);
+ CHK(shtr_line_view_get_line(view1, iline, &line1) == RES_OK);
+ CHK(shtr_line_view_get_line(view2, iline, &line2) == RES_OK);
CHK(shtr_line_eq(line1, line2));
}
}
@@ -699,17 +699,17 @@ test_view_serialization(struct shtr* shtr)
const double cutoff = 25;
- struct shtr_lines_view_create_args args = SHTR_LINES_VIEW_CREATE_ARGS_NULL;
- struct shtr_lines_list* list = NULL;
- struct shtr_lines_view* view1 = NULL;
- struct shtr_lines_view* view2 = NULL;
+ struct shtr_line_view_create_args args = SHTR_LINE_VIEW_CREATE_ARGS_NULL;
+ struct shtr_line_list* list = NULL;
+ struct shtr_line_view* view1 = NULL;
+ struct shtr_line_view* view2 = NULL;
FILE* fp = NULL;
CHK(fp = tmpfile());
print_lines(fp, l, nlines);
rewind(fp);
- CHK(shtr_lines_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
+ CHK(shtr_line_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
fclose(fp);
args.wavenumber_range[0] = 0;
@@ -722,25 +722,25 @@ test_view_serialization(struct shtr* shtr)
args.molecules[2].cutoff = cutoff;
args.nmolecules = 3;
args.pressure = 0;
- CHK(shtr_lines_view_create(list, &args, &view1) == RES_OK);
- CHK(shtr_lines_list_ref_put(list) == RES_OK);
+ CHK(shtr_line_view_create(list, &args, &view1) == RES_OK);
+ CHK(shtr_line_list_ref_put(list) == RES_OK);
CHK(fp = tmpfile());
- CHK(shtr_lines_view_write(NULL, fp) == RES_BAD_ARG);
- CHK(shtr_lines_view_write(view1, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_view_write(view1, fp) == RES_OK);
+ CHK(shtr_line_view_write(NULL, fp) == RES_BAD_ARG);
+ CHK(shtr_line_view_write(view1, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_view_write(view1, fp) == RES_OK);
rewind(fp);
- CHK(shtr_lines_view_create_from_stream(NULL, fp, &view2) == RES_BAD_ARG);
- CHK(shtr_lines_view_create_from_stream(shtr, NULL, &view2) == RES_BAD_ARG);
- CHK(shtr_lines_view_create_from_stream(shtr, fp, NULL) == RES_BAD_ARG);
- CHK(shtr_lines_view_create_from_stream(shtr, fp, &view2) == RES_OK);
+ CHK(shtr_line_view_create_from_stream(NULL, fp, &view2) == RES_BAD_ARG);
+ CHK(shtr_line_view_create_from_stream(shtr, NULL, &view2) == RES_BAD_ARG);
+ CHK(shtr_line_view_create_from_stream(shtr, fp, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_view_create_from_stream(shtr, fp, &view2) == RES_OK);
fclose(fp);
- check_lines_view_equality(view1, view2);
+ check_line_view_equality(view1, view2);
- CHK(shtr_lines_view_ref_put(view1) == RES_OK);
- CHK(shtr_lines_view_ref_put(view2) == RES_OK);
+ CHK(shtr_line_view_ref_put(view1) == RES_OK);
+ CHK(shtr_line_view_ref_put(view2) == RES_OK);
}
static void
@@ -767,18 +767,18 @@ check_line(const struct shtr_line* ln)
static void
test_load_file(struct shtr* shtr, const char* path)
{
- struct shtr_lines_list* list = NULL;
+ struct shtr_line_list* list = NULL;
const struct shtr_line* lines = NULL;
size_t i, n;
CHK(path);
printf("Loading `%s'.\n", path);
- CHK(shtr_lines_list_load(shtr, path, &list) == RES_OK);
- CHK(shtr_lines_list_get_size(list, &n) == RES_OK);
+ CHK(shtr_line_list_load(shtr, path, &list) == RES_OK);
+ CHK(shtr_line_list_get_size(list, &n) == RES_OK);
printf(" #lines: %lu\n", n);
- CHK(shtr_lines_list_get(list, &lines) == RES_OK);
+ CHK(shtr_line_list_get(list, &lines) == RES_OK);
FOR_EACH(i, 0, n) check_line(lines+i);
- CHK(shtr_lines_list_ref_put(list) == RES_OK);
+ CHK(shtr_line_list_ref_put(list) == RES_OK);
}
int