commit 31809f4f63f8bc681abe7eef910cabf44f6a96f3
parent 701b894144e64bafece998abf9d6c886d99cb8d5
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 8 Mar 2022 16:02:15 +0100
Rename 'transition' in 'line'
Diffstat:
6 files changed, 608 insertions(+), 614 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -48,7 +48,7 @@ set(SHTR_FILES_SRC
shtr_log.c
shtr_isotope_metadata.c
shtr_param.c
- shtr_transitions_list.c)
+ shtr_lines_list.c)
set(SHTR_FILES_INC
shtr_c.h
shtr_log.h
@@ -91,7 +91,7 @@ if(NOT NO_TEST)
new_test(test_shtr)
new_test(test_shtr_isotope_metadata)
- new_test(test_shtr_transitions)
+ new_test(test_shtr_lines)
endif()
################################################################################
diff --git a/src/shtr.h b/src/shtr.h
@@ -30,9 +30,9 @@
#define SHTR_API extern IMPORT_SYM
#endif
-/* Helper macro that asserts if the invocation of the sth function `Func'
- * returns an error. One should use this macro on sth function calls for
- * which no explicit error checking is performed */
+/* Helper macro that asserts if the invocation of the shtr function `Func'
+ * returns an error. One should use this macro on shtr function calls for which
+ * no explicit error checking is performed */
#ifndef NDEBUG
#define SHTR(Func) ASSERT(shtr_ ## Func == RES_OK)
#else
@@ -76,7 +76,7 @@ static const struct shtr_molecule SHTR_MOLECULE_NULL =
#define SHTR_MOLECULE_IS_NULL(Molecule) \
((Molecule)->id == SHTR_MOLECULE_NULL.id)
-struct shtr_transition {
+struct shtr_line {
double wavenumber; /* Central wavenumber in vacuum [cm^-1] */
double intensity; /* Reference intensity [cm^-1/(molec.cm^2)] */
double gamma_air; /* Air broadening half-width [cm^-1.atm^-1] */
@@ -96,14 +96,13 @@ struct shtr_transition {
* data structure loaded from an isotope metadata file */
int32_t isotope_id_local;
};
-#define SHTR_TRANSITION_NULL__ {0,0,0,0,0,0,0,-1,-1}
-static const struct shtr_transition SHTR_TRANSITION_NULL =
- SHTR_TRANSITION_NULL__;
+#define SHTR_LINE_NULL__ {0,0,0,0,0,0,0,-1,-1}
+static const struct shtr_line SHTR_LINE_NULL = SHTR_LINE_NULL__;
/* Forward declarations of opaque data structures */
struct shtr;
struct shtr_isotope_metadata;
-struct shtr_transitions_list;
+struct shtr_lines_list;
BEGIN_DECLS
@@ -174,35 +173,35 @@ shtr_isotope_metadata_find_molecule
* Transitions API
******************************************************************************/
SHTR_API res_T
-shtr_transitions_list_load
+shtr_lines_list_load
(struct shtr* shtr,
const char* path,
- struct shtr_transitions_list** trlst);
+ struct shtr_lines_list** trlst);
SHTR_API res_T
-shtr_transitions_list_load_stream
+shtr_lines_list_load_stream
(struct shtr* shtr,
FILE* stream,
const char* stream_name, /* NULL <=> use default stream name */
- struct shtr_transitions_list** trlst);
+ struct shtr_lines_list** trlst);
SHTR_API res_T
-shtr_transitions_list_ref_get
- (struct shtr_transitions_list* trlst);
+shtr_lines_list_ref_get
+ (struct shtr_lines_list* trlst);
SHTR_API res_T
-shtr_transitions_list_ref_put
- (struct shtr_transitions_list* trlst);
+shtr_lines_list_ref_put
+ (struct shtr_lines_list* trlst);
SHTR_API res_T
-shtr_transitions_list_get_size
- (const struct shtr_transitions_list* trlst,
- size_t* ntransitions);
+shtr_lines_list_get_size
+ (const struct shtr_lines_list* trlst,
+ size_t* nlines);
SHTR_API res_T
-shtr_transitions_list_get
- (const struct shtr_transitions_list* trlst,
- const struct shtr_transition* transitions[]);
+shtr_lines_list_get
+ (const struct shtr_lines_list* trlst,
+ const struct shtr_line* lines[]);
END_DECLS
diff --git a/src/shtr_lines_list.c b/src/shtr_lines_list.c
@@ -0,0 +1,320 @@
+/* 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_log.h"
+#include "shtr_param.h"
+
+#include <rsys/cstr.h>
+#include <rsys/dynamic_array.h>
+#include <rsys/text_reader.h>
+
+/* Generate the dynamic array of trlst */
+#define DARRAY_NAME line
+#define DARRAY_DATA struct shtr_line
+#include <rsys/dynamic_array.h>
+
+struct shtr_lines_list {
+ /* List of trlst */
+ struct darray_line lines;
+
+ struct shtr* shtr;
+ ref_T ref;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+create_lines_list
+ (struct shtr* shtr,
+ struct shtr_lines_list** out_lines)
+{
+ struct shtr_lines_list* trlst = NULL;
+ res_T res = RES_OK;
+ ASSERT(shtr && out_lines);
+
+ trlst = MEM_CALLOC(shtr->allocator, 1, sizeof(*trlst));
+ if(!trlst) {
+ log_err(shtr, "Could not allocate the trlst data structure.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&trlst->ref);
+ SHTR(ref_get(shtr));
+ trlst->shtr = shtr;
+ darray_line_init(shtr->allocator, &trlst->lines);
+
+exit:
+ *out_lines = trlst;
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_line(struct shtr_lines_list* trlst, struct txtrdr* txtrdr)
+{
+ struct shtr_line tr = 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(trlst && txtrdr);
+
+ line = txtrdr_get_line(txtrdr);
+ ASSERT(line);
+
+ shtr = trlst->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);
+ tr.molecule_id = (int32_t)molecule_id;
+
+ PARSE(&isotope_id_local, 1, int, "isotope local identifier", 0,9,1,1);
+ tr.isotope_id_local = (int32_t)
+ (isotope_id_local == 0 ? 9 : (isotope_id_local - 1));
+
+ PARSE(&tr.wavenumber, 12, double, "central wavenumber", 0,INF,0,1);
+ PARSE(&tr.intensity, 10, double, "reference intensity", 0,INF,0,1);
+
+ NEXT(10); /* Skip the Enstein coef */
+
+ PARSE(&tr.gamma_air, 5, double, "air broadening half-width", 0,INF,1,1);
+ PARSE(&tr.gamma_self, 5, double, "self broadening half-width", 0,INF,1,1);
+
+ /* Handle unavailable lower state energy */
+ PARSE(&tr.lower_state_energy, 10, double, "lower state energy",-INF,INF,1,1);
+ if(tr.lower_state_energy == -1) {
+ log_warn(shtr,
+ "%s:%lu: the lower state energy is unavailable for this line, so it is "
+ "ignored.\n", param.path, param.line);
+ goto exit; /* Skip the line */
+ }
+ /* Check the domain validity */
+ if(tr.lower_state_energy < 0) {
+ log_err(shtr,
+ "%s:%lu: invalid lower state energy %g. It must be in [0, INF].\n",
+ param.path, param.line, tr.lower_state_energy);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ PARSE(&tr.n_air, 4, double, "temperature-dependent exponent",-INF,INF,1,1);
+ PARSE(&tr.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(trlst->shtr, "%s:%lu: missing data after delta air.\n",
+ param.path, (unsigned long)param.line);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = darray_line_push_back(&trlst->lines, &tr);
+ if(res != RES_OK) {
+ log_err(trlst->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* trlst = NULL;
+ struct txtrdr* txtrdr = NULL;
+ res_T res = RES_OK;
+ ASSERT(shtr && stream && name && out_lines);
+
+ res = create_lines_list(shtr, &trlst);
+ if(res != RES_OK) goto error;
+
+ res = txtrdr_stream(trlst->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(trlst, txtrdr);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ if(txtrdr) txtrdr_ref_put(txtrdr);
+ *out_lines = trlst;
+ return res;
+error:
+ if(trlst) {
+ SHTR(lines_list_ref_put(trlst));
+ trlst = NULL;
+ }
+ goto exit;
+}
+
+static void
+release_lines(ref_T * ref)
+{
+ struct shtr* shtr = NULL;
+ struct shtr_lines_list* trlst = CONTAINER_OF
+ (ref, struct shtr_lines_list, ref);
+ ASSERT(ref);
+ shtr = trlst->shtr;
+ darray_line_release(&trlst->lines);
+ MEM_RM(shtr->allocator, trlst);
+ SHTR(ref_put(shtr));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+shtr_lines_list_load
+ (struct shtr* shtr,
+ const char* path,
+ struct shtr_lines_list** trlst)
+{
+ FILE* file = NULL;
+ res_T res = RES_OK;
+
+ if(!shtr || !path || !trlst) {
+ 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, trlst);
+ 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** trlst)
+{
+ if(!shtr || !stream || !trlst) return RES_BAD_ARG;
+ return load_stream
+ (shtr, stream, stream_name ? stream_name : "<stream>", trlst);
+}
+
+res_T
+shtr_lines_list_ref_get(struct shtr_lines_list* trlst)
+{
+ if(!trlst) return RES_BAD_ARG;
+ ref_get(&trlst->ref);
+ return RES_OK;
+}
+
+res_T
+shtr_lines_list_ref_put(struct shtr_lines_list* trlst)
+{
+ if(!trlst) return RES_BAD_ARG;
+ ref_put(&trlst->ref, release_lines);
+ return RES_OK;
+}
+
+res_T
+shtr_lines_list_get_size
+ (const struct shtr_lines_list* trlst,
+ size_t* nlines)
+{
+ if(!trlst || !nlines) return RES_BAD_ARG;
+ *nlines = darray_line_size_get(&trlst->lines);
+ return RES_OK;
+}
+
+res_T
+shtr_lines_list_get
+ (const struct shtr_lines_list* trlst,
+ const struct shtr_line* lines_list[])
+{
+ if(!trlst || !lines_list) return RES_BAD_ARG;
+ *lines_list = darray_line_cdata_get(&trlst->lines);
+ return RES_OK;
+}
diff --git a/src/shtr_transitions_list.c b/src/shtr_transitions_list.c
@@ -1,325 +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_TRANSITIONS_H
-#define SHTR_TRANSITIONS_H
-
-#include "shtr.h"
-#include "shtr_c.h"
-#include "shtr_log.h"
-#include "shtr_param.h"
-
-#include <rsys/cstr.h>
-#include <rsys/dynamic_array.h>
-#include <rsys/text_reader.h>
-
-/* Generate the dynamic array of trlst */
-#define DARRAY_NAME transition
-#define DARRAY_DATA struct shtr_transition
-#include <rsys/dynamic_array.h>
-
-struct shtr_transitions_list {
- /* List of trlst */
- struct darray_transition transitions;
-
- struct shtr* shtr;
- ref_T ref;
-};
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static res_T
-create_transitions_list
- (struct shtr* shtr,
- struct shtr_transitions_list** out_transitions)
-{
- struct shtr_transitions_list* trlst = NULL;
- res_T res = RES_OK;
- ASSERT(shtr && out_transitions);
-
- trlst = MEM_CALLOC(shtr->allocator, 1, sizeof(*trlst));
- if(!trlst) {
- log_err(shtr, "Could not allocate the trlst data structure.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&trlst->ref);
- SHTR(ref_get(shtr));
- trlst->shtr = shtr;
- darray_transition_init(shtr->allocator, &trlst->transitions);
-
-exit:
- *out_transitions = trlst;
- return res;
-error:
- goto exit;
-}
-
-static res_T
-parse_transition(struct shtr_transitions_list* trlst, struct txtrdr* txtrdr)
-{
- struct shtr_transition tr = SHTR_TRANSITION_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(trlst && txtrdr);
-
- line = txtrdr_get_line(txtrdr);
- ASSERT(line);
-
- shtr = trlst->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);
- tr.molecule_id = (int32_t)molecule_id;
-
- PARSE(&isotope_id_local, 1, int, "isotope local identifier", 0,9,1,1);
- tr.isotope_id_local = (int32_t)
- (isotope_id_local == 0 ? 9 : (isotope_id_local - 1));
-
- PARSE(&tr.wavenumber, 12, double, "central wavenumber", 0,INF,0,1);
- PARSE(&tr.intensity, 10, double, "reference intensity", 0,INF,0,1);
-
- NEXT(10); /* Skip the Enstein coef */
-
- PARSE(&tr.gamma_air, 5, double, "air broadening half-width", 0,INF,1,1);
- PARSE(&tr.gamma_self, 5, double, "self broadening half-width", 0,INF,1,1);
-
- /* Handle unavailable lower state energy */
- PARSE(&tr.lower_state_energy, 10, double, "lower state energy",-INF,INF,1,1);
- if(tr.lower_state_energy == -1) {
- log_warn(shtr,
- "%s:%lu: the lower state energy is unavailable for this line, so it is "
- "ignored.\n", param.path, param.line);
- goto exit; /* Skip the transition */
- }
- /* Check the domain validity */
- if(tr.lower_state_energy < 0) {
- log_err(shtr,
- "%s:%lu: invalid lower state energy %g. It must be in [0, INF].\n",
- param.path, param.line, tr.lower_state_energy);
- res = RES_BAD_ARG;
- goto error;
- }
-
- PARSE(&tr.n_air, 4, double, "temperature-dependent exponent",-INF,INF,1,1);
- PARSE(&tr.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(trlst->shtr, "%s:%lu: missing data after delta air.\n",
- param.path, (unsigned long)param.line);
- res = RES_BAD_ARG;
- goto error;
- }
-
- res = darray_transition_push_back(&trlst->transitions, &tr);
- if(res != RES_OK) {
- log_err(trlst->shtr,
- "%s:%lu: error storing the transition -- %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_transitions_list** out_transitions)
-{
- struct shtr_transitions_list* trlst = NULL;
- struct txtrdr* txtrdr = NULL;
- res_T res = RES_OK;
- ASSERT(shtr && stream && name && out_transitions);
-
- res = create_transitions_list(shtr, &trlst);
- if(res != RES_OK) goto error;
-
- res = txtrdr_stream(trlst->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_transition(trlst, txtrdr);
- if(res != RES_OK) goto error;
- }
-
-exit:
- if(txtrdr) txtrdr_ref_put(txtrdr);
- *out_transitions = trlst;
- return res;
-error:
- if(trlst) {
- SHTR(transitions_list_ref_put(trlst));
- trlst = NULL;
- }
- goto exit;
-}
-
-static void
-release_transitions(ref_T * ref)
-{
- struct shtr* shtr = NULL;
- struct shtr_transitions_list* trlst = CONTAINER_OF
- (ref, struct shtr_transitions_list, ref);
- ASSERT(ref);
- shtr = trlst->shtr;
- darray_transition_release(&trlst->transitions);
- MEM_RM(shtr->allocator, trlst);
- SHTR(ref_put(shtr));
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-shtr_transitions_list_load
- (struct shtr* shtr,
- const char* path,
- struct shtr_transitions_list** trlst)
-{
- FILE* file = NULL;
- res_T res = RES_OK;
-
- if(!shtr || !path || !trlst) {
- 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, trlst);
- if(res != RES_OK) goto error;
-
-exit:
- if(file) fclose(file);
- return res;
-error:
- goto exit;
-}
-
-res_T
-shtr_transitions_list_load_stream
- (struct shtr* shtr,
- FILE* stream,
- const char* stream_name,
- struct shtr_transitions_list** trlst)
-{
- if(!shtr || !stream || !trlst) return RES_BAD_ARG;
- return load_stream
- (shtr, stream, stream_name ? stream_name : "<stream>", trlst);
-}
-
-res_T
-shtr_transitions_list_ref_get(struct shtr_transitions_list* trlst)
-{
- if(!trlst) return RES_BAD_ARG;
- ref_get(&trlst->ref);
- return RES_OK;
-}
-
-res_T
-shtr_transitions_list_ref_put(struct shtr_transitions_list* trlst)
-{
- if(!trlst) return RES_BAD_ARG;
- ref_put(&trlst->ref, release_transitions);
- return RES_OK;
-}
-
-res_T
-shtr_transitions_list_get_size
- (const struct shtr_transitions_list* trlst,
- size_t* ntransitions)
-{
- if(!trlst || !ntransitions) return RES_BAD_ARG;
- *ntransitions = darray_transition_size_get(&trlst->transitions);
- return RES_OK;
-}
-
-res_T
-shtr_transitions_list_get
- (const struct shtr_transitions_list* trlst,
- const struct shtr_transition* transitions_list[])
-{
- if(!trlst || !transitions_list) return RES_BAD_ARG;
- *transitions_list = darray_transition_cdata_get(&trlst->transitions);
- return RES_OK;
-}
-
-#endif /* SHTR_TRANSITIONS_H */
diff --git a/src/test_shtr_lines.c b/src/test_shtr_lines.c
@@ -0,0 +1,265 @@
+/* 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 <rsys/clock_time.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/math.h>
+
+#include <string.h>
+
+static void
+print_lines
+ (FILE* fp,
+ const struct shtr_line* lines,
+ const size_t nlines)
+{
+ size_t i;
+
+ CHK(fp && (!nlines || lines));
+ FOR_EACH(i, 0, nlines) {
+ fprintf(fp,
+ "%2d%1d%12.6f%10.3e 0.000E-00.%04d%5.3f%10.4f%4.2f%8.6f"
+ " 0 0 0" /* Global upper quanta */
+ " 0 0 0" /* Global upper quanta */
+ " 5 5 0 " /* Local upper quanta */
+ " 5 5 1 " /* Local lower quanta */
+ "562220" /* Error indices */
+ "5041 7833348" /* References */
+ " " /* Line mixing flag */
+ " 66.0" /* g' */
+ " 66.0" /* g'' */
+ "\n",
+ lines[i].molecule_id,
+ lines[i].isotope_id_local == 9 ? 0 : lines[i].isotope_id_local+1,
+ lines[i].wavenumber,
+ lines[i].intensity,
+ (int)(lines[i].gamma_air*10000+0.5/*round*/),
+ lines[i].gamma_self,
+ lines[i].lower_state_energy,
+ lines[i].n_air,
+ lines[i].delta_air);
+ }
+}
+
+static int
+line_eq
+ (const struct shtr_line* tr0,
+ const struct shtr_line* tr1)
+{
+ CHK(tr0 && tr1);
+ return tr0->wavenumber == tr1->wavenumber
+ && tr0->intensity == tr1->intensity
+ && tr0->gamma_air == tr1->gamma_air
+ && tr0->gamma_self == tr1->gamma_self
+ && tr0->lower_state_energy == tr1->lower_state_energy
+ && tr0->n_air == tr1->n_air
+ && tr0->delta_air == tr1->delta_air
+ && tr0->molecule_id == tr1->molecule_id
+ && tr0->isotope_id_local == tr1->isotope_id_local;
+}
+
+static void
+test_load(struct shtr* shtr)
+{
+ const struct shtr_line lines[] = {
+ {0.000134, 2.672E-38, 0.0533, 0.410, 608.4727, 0.79, 0.000060, 1, 4},
+ {0.000379, 1.055E-39, 0.0418, 0.329,1747.9686, 0.79, 0.000110, 1, 5},
+ {0.000448, 5.560E-38, 0.0490, 0.364,1093.0269, 0.79, 0.000060, 1, 4},
+ {0.000686, 1.633E-36, 0.0578, 0.394, 701.1162, 0.79, 0.000180, 1, 4},
+ {0.000726, 6.613E-33, 0.0695, 0.428, 402.3295, 0.79, 0.000240, 1, 3}
+ };
+ const size_t nlines =
+ sizeof(lines) / sizeof(struct shtr_line);
+
+ struct shtr_lines_list* trs = NULL;
+ const struct shtr_line* trs_list = NULL;
+ const char* filename = "test_lines.txt";
+ FILE* fp = NULL;
+ size_t i, n;
+
+ CHK(fp = fopen(filename, "w+"));
+ print_lines(fp, lines, nlines);
+ rewind(fp);
+
+ CHK(shtr_lines_list_load_stream(NULL, fp, NULL, &trs) == RES_BAD_ARG);
+ CHK(shtr_lines_list_load_stream(shtr, NULL, NULL, &trs) == 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, &trs) == RES_OK);
+
+ CHK(shtr_lines_list_get_size(NULL, &n) == RES_BAD_ARG);
+ CHK(shtr_lines_list_get_size(trs, NULL) == RES_BAD_ARG);
+ CHK(shtr_lines_list_get_size(trs, &n) == RES_OK);
+ CHK(n == nlines);
+
+ CHK(shtr_lines_list_get(NULL, &trs_list) == RES_BAD_ARG);
+ CHK(shtr_lines_list_get(trs, NULL) == RES_BAD_ARG);
+ CHK(shtr_lines_list_get(trs, &trs_list) == RES_OK);
+ FOR_EACH(i, 0, n) CHK(line_eq(trs_list+i, lines+i));
+
+ CHK(shtr_lines_list_ref_get(NULL) == RES_BAD_ARG);
+ CHK(shtr_lines_list_ref_get(trs) == RES_OK);
+ CHK(shtr_lines_list_ref_put(NULL) == RES_BAD_ARG);
+ CHK(shtr_lines_list_ref_put(trs) == RES_OK);
+ CHK(shtr_lines_list_ref_put(trs) == RES_OK);
+
+ CHK(fclose(fp) == 0);
+
+ CHK(shtr_lines_list_load(NULL, filename, &trs) == RES_BAD_ARG);
+ CHK(shtr_lines_list_load(shtr, NULL, &trs) == RES_BAD_ARG);
+ CHK(shtr_lines_list_load(shtr, filename, NULL) == RES_BAD_ARG);
+ CHK(shtr_lines_list_load(shtr, filename, &trs) == RES_OK);
+
+ CHK(shtr_lines_list_get_size(trs, &n) == RES_OK);
+ CHK(n == nlines);
+
+ CHK(shtr_lines_list_get(trs, &trs_list) == RES_OK);
+ FOR_EACH(i, 0, n) CHK(line_eq(trs_list+i, lines+i));
+
+ CHK(shtr_lines_list_ref_put(trs) == RES_OK);
+}
+
+static void
+test_line
+ (struct shtr* shtr, const struct shtr_line* ln, const res_T res)
+{
+ struct shtr_lines_list* trs = NULL;
+ FILE* fp = NULL;
+
+ CHK(fp = tmpfile());
+ print_lines(fp, ln, 1);
+ rewind(fp);
+ CHK(shtr_lines_list_load_stream(shtr, fp, NULL, &trs) == res);
+ CHK(fclose(fp) == 0);
+
+ if(res == RES_OK) CHK(shtr_lines_list_ref_put(trs) == RES_OK);
+}
+
+static void
+test_load_failures(struct shtr* shtr)
+{
+ const struct shtr_line tr_ref = {
+ 0.000134, 2.672E-38, 0.0533, 0.410, 608.4727, 0.79, 0.000060, 1, 4,
+ };
+ struct shtr_line ln;
+
+ /* Check that the reference line is valid */
+ test_line(shtr, &tr_ref, RES_OK);
+
+ /* Invalid wavenumber */
+ ln = tr_ref; ln.wavenumber = 0;
+ test_line(shtr, &ln, RES_BAD_ARG);
+
+ /* Invalid intensity */
+ ln = tr_ref; ln.intensity = 0;
+ test_line(shtr, &ln, RES_BAD_ARG);
+
+ /* Invalid gamma air */
+ ln = tr_ref; ln.gamma_air = -1;
+ test_line(shtr, &ln, RES_BAD_ARG);
+
+ /* Invalid gamma self */
+ ln = tr_ref; ln.gamma_self = -1;
+ test_line(shtr, &ln, RES_BAD_ARG);
+
+ /* Unavailable lower state energy */
+ ln = tr_ref; ln.lower_state_energy = -1;
+ test_line(shtr, &ln, RES_OK);
+
+ /* Invalid lower state energy */
+ ln = tr_ref; ln.lower_state_energy = -2;
+ test_line(shtr, &ln, RES_BAD_ARG);
+
+ /* Invalid molecule id */
+ ln = tr_ref; ln.molecule_id = -1;
+ test_line(shtr, &ln, RES_BAD_ARG);
+
+ /* Bad file formatting */
+ ln = tr_ref; ln.molecule_id = 100;
+ test_line(shtr, &ln, RES_BAD_ARG);
+ ln = tr_ref; ln.isotope_id_local = 10;
+ test_line(shtr, &ln, RES_BAD_ARG);
+}
+
+static void
+check_line(const struct shtr_line* ln)
+{
+ /* Check NaN */
+ CHK(ln->wavenumber == ln->wavenumber);
+ CHK(ln->intensity == ln->intensity);
+ CHK(ln->gamma_air == ln->gamma_air);
+ CHK(ln->gamma_self == ln->gamma_self);
+ CHK(ln->lower_state_energy == ln->lower_state_energy);
+ CHK(ln->n_air == ln->n_air);
+ CHK(ln->delta_air == ln->delta_air);
+
+ CHK(ln->wavenumber > 0);
+ CHK(ln->intensity > 0);
+ CHK(ln->gamma_air >= 0);
+ CHK(ln->gamma_self >= 0);
+ CHK(ln->lower_state_energy >= 0);
+ CHK(ln->molecule_id >= 0 && ln->molecule_id < 100);
+ CHK(ln->isotope_id_local >= 0 && ln->isotope_id_local <= 9);
+}
+
+static void
+test_load_file(struct shtr* shtr, const char* path)
+{
+ struct shtr_lines_list* trs = NULL;
+ const struct shtr_line* trs_list = NULL;
+ size_t i, n;
+ CHK(path);
+ printf("Loading `%s'.\n", path);
+ CHK(shtr_lines_list_load(shtr, path, &trs) == RES_OK);
+ CHK(shtr_lines_list_get_size(trs, &n) == RES_OK);
+ printf(" #lines: %lu\n", n);
+
+ CHK(shtr_lines_list_get(trs, &trs_list) == RES_OK);
+ FOR_EACH(i, 0, n) check_line(trs_list+i);
+ CHK(shtr_lines_list_ref_put(trs) == RES_OK);
+}
+
+int
+main(int argc, char** argv)
+{
+ struct shtr_create_args args = SHTR_CREATE_ARGS_DEFAULT;
+ struct shtr* shtr = NULL;
+ int i;
+ (void)argc, (void)argv;
+
+ args.verbose = 1;
+ CHK(shtr_create(&args, &shtr) == RES_OK);
+
+ test_load(shtr);
+ test_load_failures(shtr);
+ FOR_EACH(i, 1, argc) {
+ char buf[64];
+ struct time t0, t1;
+
+ time_current(&t0);
+ test_load_file(shtr, argv[i]);
+ time_sub(&t0, time_current(&t1), &t0);
+ time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf));
+ printf("%s loaded in %s\n", argv[i], buf);
+ }
+
+ CHK(shtr_ref_put(shtr) == RES_OK);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_shtr_transitions.c b/src/test_shtr_transitions.c
@@ -1,265 +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 <rsys/clock_time.h>
-#include <rsys/mem_allocator.h>
-#include <rsys/math.h>
-
-#include <string.h>
-
-static void
-print_transitions
- (FILE* fp,
- const struct shtr_transition* transitions,
- const size_t ntransitions)
-{
- size_t i;
-
- CHK(fp && (!ntransitions || transitions));
- FOR_EACH(i, 0, ntransitions) {
- fprintf(fp,
- "%2d%1d%12.6f%10.3e 0.000E-00.%04d%5.3f%10.4f%4.2f%8.6f"
- " 0 0 0" /* Global upper quanta */
- " 0 0 0" /* Global upper quanta */
- " 5 5 0 " /* Local upper quanta */
- " 5 5 1 " /* Local lower quanta */
- "562220" /* Error indices */
- "5041 7833348" /* References */
- " " /* Line mixing flag */
- " 66.0" /* g' */
- " 66.0" /* g'' */
- "\n",
- transitions[i].molecule_id,
- transitions[i].isotope_id_local == 9 ? 0 : transitions[i].isotope_id_local+1,
- transitions[i].wavenumber,
- transitions[i].intensity,
- (int)(transitions[i].gamma_air*10000+0.5/*round*/),
- transitions[i].gamma_self,
- transitions[i].lower_state_energy,
- transitions[i].n_air,
- transitions[i].delta_air);
- }
-}
-
-static int
-transition_eq
- (const struct shtr_transition* tr0,
- const struct shtr_transition* tr1)
-{
- CHK(tr0 && tr1);
- return tr0->wavenumber == tr1->wavenumber
- && tr0->intensity == tr1->intensity
- && tr0->gamma_air == tr1->gamma_air
- && tr0->gamma_self == tr1->gamma_self
- && tr0->lower_state_energy == tr1->lower_state_energy
- && tr0->n_air == tr1->n_air
- && tr0->delta_air == tr1->delta_air
- && tr0->molecule_id == tr1->molecule_id
- && tr0->isotope_id_local == tr1->isotope_id_local;
-}
-
-static void
-test_load(struct shtr* shtr)
-{
- const struct shtr_transition transitions[] = {
- {0.000134, 2.672E-38, 0.0533, 0.410, 608.4727, 0.79, 0.000060, 1, 4},
- {0.000379, 1.055E-39, 0.0418, 0.329,1747.9686, 0.79, 0.000110, 1, 5},
- {0.000448, 5.560E-38, 0.0490, 0.364,1093.0269, 0.79, 0.000060, 1, 4},
- {0.000686, 1.633E-36, 0.0578, 0.394, 701.1162, 0.79, 0.000180, 1, 4},
- {0.000726, 6.613E-33, 0.0695, 0.428, 402.3295, 0.79, 0.000240, 1, 3}
- };
- const size_t ntransitions =
- sizeof(transitions) / sizeof(struct shtr_transition);
-
- struct shtr_transitions_list* trs = NULL;
- const struct shtr_transition* trs_list = NULL;
- const char* filename = "test_transitions.txt";
- FILE* fp = NULL;
- size_t i, n;
-
- CHK(fp = fopen(filename, "w+"));
- print_transitions(fp, transitions, ntransitions);
- rewind(fp);
-
- CHK(shtr_transitions_list_load_stream(NULL, fp, NULL, &trs) == RES_BAD_ARG);
- CHK(shtr_transitions_list_load_stream(shtr, NULL, NULL, &trs) == RES_BAD_ARG);
- CHK(shtr_transitions_list_load_stream(shtr, fp, NULL, NULL) == RES_BAD_ARG);
- CHK(shtr_transitions_list_load_stream(shtr, fp, NULL, &trs) == RES_OK);
-
- CHK(shtr_transitions_list_get_size(NULL, &n) == RES_BAD_ARG);
- CHK(shtr_transitions_list_get_size(trs, NULL) == RES_BAD_ARG);
- CHK(shtr_transitions_list_get_size(trs, &n) == RES_OK);
- CHK(n == ntransitions);
-
- CHK(shtr_transitions_list_get(NULL, &trs_list) == RES_BAD_ARG);
- CHK(shtr_transitions_list_get(trs, NULL) == RES_BAD_ARG);
- CHK(shtr_transitions_list_get(trs, &trs_list) == RES_OK);
- FOR_EACH(i, 0, n) CHK(transition_eq(trs_list+i, transitions+i));
-
- CHK(shtr_transitions_list_ref_get(NULL) == RES_BAD_ARG);
- CHK(shtr_transitions_list_ref_get(trs) == RES_OK);
- CHK(shtr_transitions_list_ref_put(NULL) == RES_BAD_ARG);
- CHK(shtr_transitions_list_ref_put(trs) == RES_OK);
- CHK(shtr_transitions_list_ref_put(trs) == RES_OK);
-
- CHK(fclose(fp) == 0);
-
- CHK(shtr_transitions_list_load(NULL, filename, &trs) == RES_BAD_ARG);
- CHK(shtr_transitions_list_load(shtr, NULL, &trs) == RES_BAD_ARG);
- CHK(shtr_transitions_list_load(shtr, filename, NULL) == RES_BAD_ARG);
- CHK(shtr_transitions_list_load(shtr, filename, &trs) == RES_OK);
-
- CHK(shtr_transitions_list_get_size(trs, &n) == RES_OK);
- CHK(n == ntransitions);
-
- CHK(shtr_transitions_list_get(trs, &trs_list) == RES_OK);
- FOR_EACH(i, 0, n) CHK(transition_eq(trs_list+i, transitions+i));
-
- CHK(shtr_transitions_list_ref_put(trs) == RES_OK);
-}
-
-static void
-test_transition
- (struct shtr* shtr, const struct shtr_transition* tr, const res_T res)
-{
- struct shtr_transitions_list* trs = NULL;
- FILE* fp = NULL;
-
- CHK(fp = tmpfile());
- print_transitions(fp, tr, 1);
- rewind(fp);
- CHK(shtr_transitions_list_load_stream(shtr, fp, NULL, &trs) == res);
- CHK(fclose(fp) == 0);
-
- if(res == RES_OK) CHK(shtr_transitions_list_ref_put(trs) == RES_OK);
-}
-
-static void
-test_load_failures(struct shtr* shtr)
-{
- const struct shtr_transition tr_ref = {
- 0.000134, 2.672E-38, 0.0533, 0.410, 608.4727, 0.79, 0.000060, 1, 4,
- };
- struct shtr_transition tr;
-
- /* Check that the reference transition is valid */
- test_transition(shtr, &tr_ref, RES_OK);
-
- /* Invalid wavenumber */
- tr = tr_ref; tr.wavenumber = 0;
- test_transition(shtr, &tr, RES_BAD_ARG);
-
- /* Invalid intensity */
- tr = tr_ref; tr.intensity = 0;
- test_transition(shtr, &tr, RES_BAD_ARG);
-
- /* Invalid gamma air */
- tr = tr_ref; tr.gamma_air = -1;
- test_transition(shtr, &tr, RES_BAD_ARG);
-
- /* Invalid gamma self */
- tr = tr_ref; tr.gamma_self = -1;
- test_transition(shtr, &tr, RES_BAD_ARG);
-
- /* Unavailable lower state energy */
- tr = tr_ref; tr.lower_state_energy = -1;
- test_transition(shtr, &tr, RES_OK);
-
- /* Invalid lower state energy */
- tr = tr_ref; tr.lower_state_energy = -2;
- test_transition(shtr, &tr, RES_BAD_ARG);
-
- /* Invalid molecule id */
- tr = tr_ref; tr.molecule_id = -1;
- test_transition(shtr, &tr, RES_BAD_ARG);
-
- /* Bad file formatting */
- tr = tr_ref; tr.molecule_id = 100;
- test_transition(shtr, &tr, RES_BAD_ARG);
- tr = tr_ref; tr.isotope_id_local = 10;
- test_transition(shtr, &tr, RES_BAD_ARG);
-}
-
-static void
-check_transition(const struct shtr_transition* tr)
-{
- /* Check NaN */
- CHK(tr->wavenumber == tr->wavenumber);
- CHK(tr->intensity == tr->intensity);
- CHK(tr->gamma_air == tr->gamma_air);
- CHK(tr->gamma_self == tr->gamma_self);
- CHK(tr->lower_state_energy == tr->lower_state_energy);
- CHK(tr->n_air == tr->n_air);
- CHK(tr->delta_air == tr->delta_air);
-
- CHK(tr->wavenumber > 0);
- CHK(tr->intensity > 0);
- CHK(tr->gamma_air >= 0);
- CHK(tr->gamma_self >= 0);
- CHK(tr->lower_state_energy >= 0);
- CHK(tr->molecule_id >= 0 && tr->molecule_id < 100);
- CHK(tr->isotope_id_local >= 0 && tr->isotope_id_local <= 9);
-}
-
-static void
-test_load_file(struct shtr* shtr, const char* path)
-{
- struct shtr_transitions_list* trs = NULL;
- const struct shtr_transition* trs_list = NULL;
- size_t i, n;
- CHK(path);
- printf("Loading `%s'.\n", path);
- CHK(shtr_transitions_list_load(shtr, path, &trs) == RES_OK);
- CHK(shtr_transitions_list_get_size(trs, &n) == RES_OK);
- printf(" #transitions: %lu\n", n);
-
- CHK(shtr_transitions_list_get(trs, &trs_list) == RES_OK);
- FOR_EACH(i, 0, n) check_transition(trs_list+i);
- CHK(shtr_transitions_list_ref_put(trs) == RES_OK);
-}
-
-int
-main(int argc, char** argv)
-{
- struct shtr_create_args args = SHTR_CREATE_ARGS_DEFAULT;
- struct shtr* shtr = NULL;
- int i;
- (void)argc, (void)argv;
-
- args.verbose = 1;
- CHK(shtr_create(&args, &shtr) == RES_OK);
-
- test_load(shtr);
- test_load_failures(shtr);
- FOR_EACH(i, 1, argc) {
- char buf[64];
- struct time t0, t1;
-
- time_current(&t0);
- test_load_file(shtr, argv[i]);
- time_sub(&t0, time_current(&t1), &t0);
- time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf));
- printf("%s loaded in %s\n", argv[i], buf);
- }
-
- CHK(shtr_ref_put(shtr) == RES_OK);
- CHK(mem_allocated_size() == 0);
- return 0;
-}