commit 6c750e9e018ea2f4e0ff0acc40ec74d2964cf3d3
parent 40732896b19659f320051f1172d48afa82c1f849
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 19 Dec 2025 16:29:32 +0100
Encode line parameters and remove the line view API
The amount of data to be stored can be enormous, with several million
lines, posing a major challenge in terms of limiting the memory
footprint of each line's data. The HITRAN format encodes this data in
ASCII with a fixed number of characters per data element. The more
characters there are, the more accurate the data must be. Based on
these informations, a new memory representation of a line has been
developed. It no longer stores all line parameters as double-precision
floating-point numbers, but, depending on the desired precision, uses
single precision or even fixed precision with a manually defined number
of bits. The size of the resulting structure is thus reduced by half, to
32 bytes.
For a list of lines, the maximum numerical error induced by the use of a
format other than double precision is calculated for each parameter.
This information is available to the user, who can then assess its
validity. It is likely that, in the mid term, an option will be
available to disable the use of this encoding in order to measure the
impact of numerical error on a calculation. However, this new
representation is currently used all the time to store loaded line data
internally.
Since memory footprint is becoming critical, the lien_view API is no
longer relevant. It was designed to provide a subset of lines from a
list of loaded lines. Since loading the list of lines is already
challenging in terms of memory, using only a subset of these lines is
inappropriate: determining which lines to use should be done before they
are loaded. Now, the list of lines to be loaded is left to the user
before they are loaded by the library, leaving it up to preprocessing
tools to extract the lines to be taken into account.
Diffstat:
| M | Makefile | | | 3 | +-- |
| M | src/shtr.c | | | 73 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/shtr.h | | | 105 | ++++++++++++++++++++++++++++--------------------------------------------------- |
| M | src/shtr_c.h | | | 16 | ++++++++++++++++ |
| M | src/shtr_line_list.c | | | 214 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
| M | src/shtr_line_list_c.h | | | 41 | ++++++++++++++++++++++++++++++++++++++--- |
| D | src/shtr_line_view.c | | | 409 | ------------------------------------------------------------------------------- |
| M | src/test_shtr_lines.c | | | 541 | ++++++++++++------------------------------------------------------------------- |
8 files changed, 421 insertions(+), 981 deletions(-)
diff --git a/Makefile b/Makefile
@@ -35,7 +35,6 @@ SRC = \
src/shtr.c \
src/shtr_isotope_metadata.c \
src/shtr_line_list.c \
- src/shtr_line_view.c \
src/shtr_param.c
OBJ = $(SRC:.c=.o)
DEP = $(SRC:.c=.d)
@@ -146,7 +145,7 @@ uninstall:
clean: clean_test
rm -f $(OBJ) $(DEP) $(LIBNAME)
- rm $(UTIL_OBJ) $(UTIL_DEP) shtr
+ rm -f $(UTIL_OBJ) $(UTIL_DEP) shtr
rm -f .config libshtr.o shtr.pc shtr-local.pc
lint:
diff --git a/src/shtr.c b/src/shtr.c
@@ -38,6 +38,79 @@ release_shtr(ref_T* ref)
}
/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+int64_t
+float2fix
+ (const double fp,
+ const int ipl, /* Length (in bits) of the integer part */
+ const int fpl) /* Length (in bits) of the fractional part */
+{
+ union { double flt; int64_t i64; } fpart; /* Fractional part */
+ int64_t ipart = 0; /* Integer part */
+ double fp_abs = 0; /* Absolute value of fp */
+ int sign = 0; /* 1 if fp is negative, and 0 otherwise */
+
+ ASSERT(ipl + fpl <= 64 && fpl < 51); /* Pre-conditions */
+
+ sign = fp < 0;
+ fp_abs = fabs(fp);
+ ipart = (int64_t)fp_abs & (BIT_I64(ipl)-1);
+
+ /* The IEEE-754 encoding of a double precision floating point number `f'
+ * whose binary representation is `F' is defined as:
+ * f = (-1)^S * 2^(E-1023)
+ * * (1 + For(i in [0..51]) { M & BIT(51-i) ? 2^i : 0 })
+ * with S = F / 2^63; E = F / 2^52 and M = F & (2^52 - 1).
+ *
+ * By adding 1 to the fractional part of the floating point number submitted
+ * as input, its exponent becomes zero (i.e., E = 1023) and its mantissa is
+ * then the binary representation of the fractional part as expected by the
+ * fixed format. In other words, the (fpl-1-i)^th bit of the mantissa then
+ * corresponds to the power of 2 expected in fixed representation, namely
+ * the 'stack pop' procedure. */
+ fpart.flt = 1.0 + (fp_abs - (double)ipart);
+ fpart.i64 &= BIT_I64(52)-1;
+
+ fpart.i64 >>= 52 - fpl; /* Quantification of the fractional part */
+
+ return (((sign << ipl) | ipart) << fpl) | fpart.i64;
+}
+
+double
+fix2float
+ (const int64_t fix,
+ const int ipl, /* Length (in bits) of the integer part */
+ const int fpl) /* Length (in bits) of the fractional part */
+{
+ union { double flt; int64_t i64; } fpart; /* Fractional part */
+ double ipart = 0; /* Integer part */
+ double sign = 0; /* -1 if fix is negative, and 1 otherwise */
+
+ ASSERT(ipl + fpl <= 64 && fpl < 51); /* Pre-conditions */
+
+ sign = (fix & BIT_I64(ipl + fpl)) ? -1.0 : +1.0;
+ ipart = (double)((fix >> fpl) & (BIT_I64(ipl)-1));
+
+ /* The IEEE-754 encoding of a double precision floating point number `f'
+ * whose binary representation is `F' is defined as:
+ * f = (-1)^S * 2^(E-1023)
+ * * (1 + For(i in [0..51]) { M & BIT(51-i) ? 2^i : 0 })
+ * with S = F / 2^63; E = F / 2^52 and M = F & (2^52 - 1).
+ *
+ * Setting a floating-point number to 1 sets its exponent to zero (i.e., E =
+ * 1023). Thus, the mantissa bits and the fractional part of a fixed-point
+ * representation are identical. All you need to do is subtract 1 from the
+ * floating-point representation to retrieve the floating-point encoding of
+ * the fractional part */
+ fpart.flt = 1.0;
+ fpart.i64 |= (fix & (BIT(fpl) - 1)) << (52 - fpl);
+ fpart.flt -= 1.0;
+
+ return sign * (ipart + fpart.flt);
+}
+
+/*******************************************************************************
* Exported functions
******************************************************************************/
res_T
diff --git a/src/shtr.h b/src/shtr.h
@@ -19,6 +19,7 @@
#ifndef SHTR_H
#define SHTR_H
+#include <float.h>
#include <rsys/rsys.h>
/* Library symbol management */
@@ -108,6 +109,36 @@ shtr_line_eq(const struct shtr_line* line0, const struct shtr_line* line1)
&& line0->isotope_id_local == line1->isotope_id_local;
}
+struct shtr_line_param_info {
+ double range[2];
+ double err; /* Encoding error */
+};
+#define SHTR_LINE_PARAM_INFO_NULL__ {{DBL_MAX,-DBL_MAX}, 0}
+static const struct shtr_line_param_info SHTR_LINE_PARAM_INFO_NULL =
+ SHTR_LINE_PARAM_INFO_NULL__;
+
+/* Information on a list of lines */
+struct shtr_line_list_info {
+ struct shtr_line_param_info wavenumber;
+ struct shtr_line_param_info intensity;
+ struct shtr_line_param_info gamma_air;
+ struct shtr_line_param_info gamma_self;
+ struct shtr_line_param_info lower_state_energy;
+ struct shtr_line_param_info n_air;
+ struct shtr_line_param_info delta_air;
+};
+#define SHTR_LINE_LIST_INFO_NULL__ { \
+ SHTR_LINE_PARAM_INFO_NULL__, \
+ SHTR_LINE_PARAM_INFO_NULL__, \
+ SHTR_LINE_PARAM_INFO_NULL__, \
+ SHTR_LINE_PARAM_INFO_NULL__, \
+ SHTR_LINE_PARAM_INFO_NULL__, \
+ SHTR_LINE_PARAM_INFO_NULL__, \
+ SHTR_LINE_PARAM_INFO_NULL__, \
+}
+static const struct shtr_line_list_info SHTR_LINE_LIST_INFO_NULL =
+ SHTR_LINE_LIST_INFO_NULL__;
+
/* Forward declarations of opaque data structures */
struct shtr;
struct shtr_isotope_metadata;
@@ -126,34 +157,6 @@ struct shtr_create_args {
static const struct shtr_create_args SHTR_CREATE_ARGS_DEFAULT =
SHTR_CREATE_ARGS_DEFAULT__;
-struct shtr_isotope_selection {
- /* List of isotopes identifier to consider for this molecule. The listed
- * idenfiers are _local_ to the molecule */
- int32_t isotope_ids_local[SHTR_MAX_ISOTOPES_COUNT];
- size_t nisotopes; /* 0 <=> select all the isotopes */
-
- int32_t id; /* Molecule to which the isotopes belongs */
- double cutoff; /* In cm^-1 */
-};
-#define SHTR_ISOTOPE_SELECTION_NULL__ {{0}, 0, 0, 0}
-static const struct shtr_isotope_selection
-SHTR_ISOTOPE_SELECTION_NULL = SHTR_ISOTOPE_SELECTION_NULL__;
-
-struct shtr_line_view_create_args {
- double wavenumber_range[2]; /* Spectral range */
-
- /* List of molecule be selected */
- struct shtr_isotope_selection molecules[SHTR_MAX_MOLECULES_COUNT];
- size_t nmolecules;
-
- double pressure; /* In atm. Used to compute the line center */
-};
-#define SHTR_LINE_VIEW_CREATE_ARGS_NULL__ \
- {{0,0}, {SHTR_ISOTOPE_SELECTION_NULL__}, 0, 0}
-static const struct shtr_line_view_create_args
-SHTR_LINE_VIEW_CREATE_ARGS_NULL =
- SHTR_LINE_VIEW_CREATE_ARGS_NULL__;
-
BEGIN_DECLS
/*******************************************************************************
@@ -269,54 +272,20 @@ shtr_line_list_get_size
size_t* nlines);
SHTR_API res_T
-shtr_line_list_get
+shtr_line_list_at
(const struct shtr_line_list* list,
- const struct shtr_line* lines[]);
+ const size_t i,
+ struct shtr_line* line);
SHTR_API res_T
shtr_line_list_write
(const struct shtr_line_list* list,
FILE* stream);
-/*******************************************************************************
- * Lines view API
- ******************************************************************************/
-SHTR_API res_T
-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_line_view_write" function */
SHTR_API res_T
-shtr_line_view_create_from_stream
- (struct shtr* shtr,
- FILE* stream,
- struct shtr_line_view** view);
-
-SHTR_API res_T
-shtr_line_view_ref_get
- (struct shtr_line_view* view);
-
-SHTR_API res_T
-shtr_line_view_ref_put
- (struct shtr_line_view* view);
-
-SHTR_API res_T
-shtr_line_view_get_size
- (const struct shtr_line_view* view,
- size_t* nlines);
-
-SHTR_API res_T
-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_line_view_write
- (const struct shtr_line_view* view,
- FILE* stream);
+shtr_line_list_get_info
+ (const struct shtr_line_list* list,
+ struct shtr_line_list_info* info);
END_DECLS
diff --git a/src/shtr_c.h b/src/shtr_c.h
@@ -45,4 +45,20 @@ struct shtr {
ref_T ref;
};
+/* Conversion of a double-precision floating-point representation to a
+ * fixed-point representation */
+extern LOCAL_SYM int64_t
+float2fix
+ (const double fp,
+ const int ipl, /* Length (in bits) of the integer part */
+ const int fpl); /* Length (in bits) of the fractional part */
+
+/* Conversion of a fixed-point representation to a double-precision
+ * floating-point representation */
+extern LOCAL_SYM double
+fix2float
+ (const int64_t fix,
+ const int ipl, /* Length (in bits) of the integer part */
+ const int fpl); /* Length (in bits) of the fractional part */
+
#endif /* SHTR_C_H */
diff --git a/src/shtr_line_list.c b/src/shtr_line_list.c
@@ -44,6 +44,7 @@ create_line_list(struct shtr* shtr, struct shtr_line_list** out_list)
SHTR(ref_get(shtr));
list->shtr = shtr;
darray_line_init(shtr->allocator, &list->lines);
+ list->info = SHTR_LINE_LIST_INFO_NULL;
exit:
*out_list = list;
@@ -56,10 +57,142 @@ error:
goto exit;
}
+static void
+line_encode(const struct shtr_line* line, struct line* line_encoded)
+{
+ union { float flt; int32_t i32; } ucast;
+ ASSERT(line && line_encoded);
+
+ /* Keep the wavenumber and the intensity as it */
+ line_encoded->wavenumber = line->wavenumber;
+ line_encoded->intensity = line->intensity;
+
+ /* Encode the lower state energy and delta air in single precision */
+ line_encoded->lower_state_energy = (float)line->lower_state_energy;
+ line_encoded->delta_air = (float)line->delta_air;
+
+ /* Store gamma_air as an unsigned fixed-point number (0:14), i.e., 0 bit for
+ * the integer part and 14 bits for the fractional part */
+ ASSERT((int64_t)line->gamma_air == 0 && line->gamma_air >= 0);
+ line_encoded->gair14_gself14_isoid4 =
+ ((int32_t)float2fix(line->gamma_air, 0, 14) & (BIT_I32(14)-1)) << 18;
+
+ /* Store gamma_self as an unsigned fixed-point number (0:14), i.e., 0 bit for
+ * the integer part and 14 bits for the fractional part */
+ ASSERT((int64_t)line->gamma_self == 0 && line->gamma_self >= 0);
+ line_encoded->gair14_gself14_isoid4 |=
+ ((int32_t)float2fix(line->gamma_self, 0, 14) & (BIT_I32(14)-1)) << 4;
+
+ /* Store the isotope id on 4 bits */
+ ASSERT(line->isotope_id_local < 16);
+ line_encoded->gair14_gself14_isoid4 |= line->isotope_id_local & (BIT_I32(4)-1);
+
+ /* Encode n_air in single precision with its last 7 bits of matissa disabled
+ * in order to store the molecule identifier */
+ ucast.flt = (float)line->n_air;
+ ucast.i32 &= ~(BIT_I32(7)-1);
+
+ /* Store the molecule id on 7 bits */
+ ASSERT(line->molecule_id < 128);
+ ucast.i32 |= line->molecule_id & (BIT_I32(7)-1);
+ line_encoded->nair25_molid7 = ucast.i32;
+}
+
+static void
+line_decode(const struct line* line_encoded, struct shtr_line* line)
+{
+ union { float flt; int32_t i32; } ucast;
+ int64_t i64 = 0;
+ ASSERT(line && line_encoded);
+
+ line->wavenumber = line_encoded->wavenumber;
+ line->intensity = line_encoded->intensity;
+ line->lower_state_energy = line_encoded->lower_state_energy;
+ line->delta_air = line_encoded->delta_air;
+
+ /* Convert gamma_air and gamma_self from fixed-point numbers (0:14) to
+ * double-precision floating-point numbers */
+ i64 = (line_encoded->gair14_gself14_isoid4 >> 18) & (BIT_I32(14)-1);
+ line->gamma_air = fix2float(i64, 0, 14);
+ i64 = (line_encoded->gair14_gself14_isoid4 >> 4) & (BIT_I32(14)-1);
+ line->gamma_self = fix2float(i64, 0, 14);
+
+ /* Unpack the isotope ID */
+ line->isotope_id_local = line_encoded->gair14_gself14_isoid4 & (BIT_I32(4)-1);
+
+ /* Unpack the molecule ID */
+ ucast.i32 = line_encoded->nair25_molid7;
+ line->molecule_id = ucast.i32 & (BIT_I32(7)-1);
+ ucast.i32 &= ~(BIT_I32(7)-1);
+
+ /* Convert n_air from single precision to double precision */
+ line->n_air = ucast.flt;
+}
+
static res_T
-parse_line(struct shtr_line_list* list, struct txtrdr* txtrdr)
+register_line
+ (struct shtr_line_list* list,
+ const struct txtrdr* txtrdr,
+ const struct shtr_line* line)
{
struct shtr_line ln = SHTR_LINE_NULL;
+ struct line ln_encoded = LINE_NULL;
+ res_T res = RES_OK;
+ ASSERT(list && txtrdr && line); /* Pre-conditions */
+
+ line_encode(line, &ln_encoded);
+
+ if(darray_line_size_get(&list->lines)) {
+ const struct line* last_ln = darray_line_cdata_get(&list->lines)
+ + darray_line_size_get(&list->lines) - 1;
+ if(last_ln->wavenumber > line->wavenumber) {
+ ERROR(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_encoded);
+ if(res != RES_OK) {
+ ERROR(list->shtr,
+ "%s:%lu: error storing the line -- %s.\n",
+ txtrdr_get_name(txtrdr), txtrdr_get_line_num(txtrdr), res_to_cstr(res));
+ goto error;
+ }
+
+ line_decode(&ln_encoded, &ln);
+ ASSERT(ln.molecule_id == line->molecule_id);
+ ASSERT(ln.isotope_id_local == line->isotope_id_local);
+
+ #define UPDATE_INFO(Name) { \
+ const double err = fabs(line->Name - ln.Name); \
+ list->info.Name.range[0] = MMIN(list->info.Name.range[0], ln.Name); \
+ list->info.Name.range[1] = MMAX(list->info.Name.range[1], ln.Name); \
+ list->info.Name.err = MMAX(list->info.Name.err, err); \
+ } (void) 0
+ UPDATE_INFO(wavenumber);
+ UPDATE_INFO(intensity);
+ UPDATE_INFO(gamma_air);
+ UPDATE_INFO(gamma_self);
+ UPDATE_INFO(lower_state_energy);
+ UPDATE_INFO(n_air);
+ UPDATE_INFO(delta_air);
+ #undef UPDATE_INFO
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_line
+ (struct shtr_line_list* list,
+ struct txtrdr* txtrdr,
+ struct shtr_line* ln)
+{
struct param_desc param = PARAM_DESC_NULL;
struct shtr* shtr = NULL;
char* line = NULL;
@@ -70,7 +203,7 @@ parse_line(struct shtr_line_list* list, struct txtrdr* txtrdr)
int isotope_id_local;
res_T res = RES_OK;
- ASSERT(list && txtrdr);
+ ASSERT(list && txtrdr && ln);
line = txtrdr_get_line(txtrdr);
ASSERT(line);
@@ -100,40 +233,40 @@ parse_line(struct shtr_line_list* list, struct txtrdr* txtrdr)
} (void)0
PARSE(&molecule_id, 2, int, "molecule identifier", 0,99,1,1);
- ln.molecule_id = (int32_t)molecule_id;
+ 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)
+ 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);
+ 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);
+ 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) {
+ PARSE(&ln->lower_state_energy, 10, double, "lower state energy",-INF,INF,1,1);
+ if(ln->lower_state_energy == -1) {
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) {
+ if(ln->lower_state_energy < 0) {
ERROR(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);
+ 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);
+ 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 */
@@ -151,26 +284,6 @@ parse_line(struct shtr_line_list* list, struct txtrdr* txtrdr)
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) {
- ERROR(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) {
- ERROR(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:
@@ -201,6 +314,8 @@ load_stream
}
for(;;) {
+ struct shtr_line ln = SHTR_LINE_NULL;
+
res = txtrdr_read_line(txtrdr);
if(res != RES_OK) {
ERROR(shtr, "%s: error reading the line `%lu' -- %s.\n",
@@ -209,7 +324,11 @@ load_stream
}
if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */
- res = parse_line(list, txtrdr);
+
+ res = parse_line(list, txtrdr, &ln);
+ if(res != RES_OK) goto error;
+
+ res = register_line(list, txtrdr, &ln);
if(res != RES_OK) goto error;
}
@@ -376,12 +495,19 @@ shtr_line_list_get_size
}
res_T
-shtr_line_list_get
+shtr_line_list_at
(const struct shtr_line_list* list,
- const struct shtr_line* line_list[])
+ const size_t i,
+ struct shtr_line* line)
{
- if(!list || !line_list) return RES_BAD_ARG;
- *line_list = darray_line_cdata_get(&list->lines);
+ const struct line* ln_encoded = NULL;
+ size_t n = 0;
+
+ if(!list || !line) return RES_BAD_ARG;
+ n = darray_line_size_get(&list->lines);
+ if(i >=n) return RES_BAD_ARG;
+ ln_encoded = darray_line_cdata_get(&list->lines) + i;
+ line_decode(ln_encoded, line);
return RES_OK;
}
@@ -417,3 +543,13 @@ exit:
error:
goto exit;
}
+
+res_T
+shtr_line_list_get_info
+ (const struct shtr_line_list* list,
+ struct shtr_line_list_info* info)
+{
+ if(!list || !info) return RES_BAD_ARG;
+ *info = list->info;
+ return RES_OK;
+}
diff --git a/src/shtr_line_list_c.h b/src/shtr_line_list_c.h
@@ -22,21 +22,56 @@
#include <rsys/dynamic_array.h>
#include <rsys/ref_count.h>
+struct shtr;
+
+#define SET_GAMMA_AIR
+
+struct line {
+ double wavenumber; /* Central wavenumber in vacuum [cm^-1] */
+ double intensity; /* Reference intensity [cm^-1/(molec.cm^2)] */
+ float lower_state_energy; /* [cm^-1] */
+ float delta_air; /* Air-pressure wavenumber shift [cm^-1.atm^-1] */
+
+ /* Packed data on 4 bytes:
+ * - gamma_air in fixed precision (integer: 0; fractional: 14)
+ * - gamma_self in fixed precision (integer: 0; fractional: 14)
+ * - isotope_id_local on 4 bits.
+ *
+ * Note that the The value of the isotopic index is _not_ the value of the
+ * isotopic index read from the HITRAN file. The original value is in [0, 9]
+ * with 0 actually meaning 10. Thus, once decoded, the index is located in [1,
+ * 10]. The next member variable simply stores this index but decremented by
+ * one in order to make it compatible with C indexing. As a result, it can be
+ * used directly to index the 'isotopes' array of a 'shtr_molecule' data
+ * structure loaded from an isotope metadata file */
+ int32_t gair14_gself14_isoid4;
+
+ /* Temperature-dependent exponent. This is actually a floating-point number
+ * with the last 7 bits of the mantissa disabled. They store the molecule
+ * identifier. */
+ int32_t nair25_molid7;
+};
+#define LINE_NULL__ {0}
+static const struct line LINE_NULL = LINE_NULL__;
+
/* Generate the dynamic array of lines */
#define DARRAY_NAME line
-#define DARRAY_DATA struct shtr_line
+#define DARRAY_DATA struct line
#include <rsys/dynamic_array.h>
-struct shtr;
+STATIC_ASSERT(sizeof(struct line)==32, Unexpected_sizeof_struct_line);
/* Version of the line list. One should increment it and perform a version
* management onto serialized data when the line list structure is updated. */
-static const int SHTR_LINE_LIST_VERSION = 0;
+static const int SHTR_LINE_LIST_VERSION = 1;
struct shtr_line_list {
/* Lines sorted in ascending order wrt their wavenumber */
struct darray_line lines;
+ /* Informations on line parameters */
+ struct shtr_line_list_info info;
+
struct shtr* shtr;
ref_T ref;
};
diff --git a/src/shtr_line_view.c b/src/shtr_line_view.c
@@ -1,409 +0,0 @@
-/* Copyright (C) 2022, 2025 |Méso|Star> (contact@meso-star.com)
- * Copyright (C) 2025 Université de Lorraine
- * Copyright (C) 2022 Centre National de la Recherche Scientifique
- * Copyright (C) 2022 Université Paul Sabatier
- *
- * 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 <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 is 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) {
- ERROR(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) {
- ERROR(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) {
- ERROR(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]) {
- ERROR(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) {
- ERROR(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) {
- ERROR(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) {
- ERROR(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; \
- } \
- ERROR(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) {
- ERROR(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) {
- ERROR(shtr,
- "%s: error allocating the line indices of 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)) { \
- ERROR(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/test_shtr_lines.c b/src/test_shtr_lines.c
@@ -104,6 +104,25 @@ test_line_eq(void)
}
static void
+line_eq_eps
+ (const struct shtr_line* ln0,
+ const struct shtr_line* ln1,
+ struct shtr_line_list_info* info)
+{
+ #define EQ_EPS(Name) CHK(eq_eps(ln0->Name, ln1->Name, info->Name.err))
+ EQ_EPS(wavenumber);
+ EQ_EPS(intensity);
+ EQ_EPS(gamma_air);
+ EQ_EPS(gamma_self);
+ EQ_EPS(lower_state_energy);
+ EQ_EPS(n_air);
+ EQ_EPS(delta_air);
+ #undef EQ_EPS
+ CHK(ln0->molecule_id == ln1->molecule_id);
+ CHK(ln0->isotope_id_local == ln1->isotope_id_local);
+}
+
+static void
test_load(struct shtr* shtr)
{
const struct shtr_line l[] = {
@@ -116,7 +135,9 @@ test_load(struct shtr* shtr)
const size_t nlines = sizeof(l) / sizeof(struct shtr_line);
struct shtr_line_list* list = NULL;
- const struct shtr_line* lines = NULL;
+ struct shtr_line_list_info info = SHTR_LINE_LIST_INFO_NULL;
+ struct shtr_line_list_info info_ref = SHTR_LINE_LIST_INFO_NULL;
+ struct shtr_line line = SHTR_LINE_NULL;
const char* filename = "test_lines.txt";
FILE* fp = NULL;
size_t i, n;
@@ -130,15 +151,51 @@ test_load(struct shtr* shtr)
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_line_list_get_info(NULL, &info) == RES_BAD_ARG);
+ CHK(shtr_line_list_get_info(list, NULL) == RES_BAD_ARG);
+ CHK(shtr_line_list_get_info(list, &info) == RES_OK);
+
+ /* Setup the reference information, i.e., from the original list of lines */
+ FOR_EACH(i, 0, nlines) {
+ #define UPDATE_INFO(Name) { \
+ info_ref.Name.range[0] = MMIN(l[i].Name, info_ref.Name.range[0]); \
+ info_ref.Name.range[1] = MMAX(l[i].Name, info_ref.Name.range[1]); \
+ } (void)0
+ UPDATE_INFO(wavenumber);
+ UPDATE_INFO(intensity);
+ UPDATE_INFO(gamma_air);
+ UPDATE_INFO(gamma_self);
+ UPDATE_INFO(lower_state_energy);
+ UPDATE_INFO(n_air);
+ UPDATE_INFO(delta_air);
+ #undef UPDATE_INFO
+ }
+
+ #define CHK_INFO(Name) { \
+ CHK(eq_eps(info.Name.range[0], info_ref.Name.range[0], info.Name.err)); \
+ CHK(eq_eps(info.Name.range[1], info_ref.Name.range[1], info.Name.err)); \
+ } (void)0
+ CHK_INFO(wavenumber);
+ CHK_INFO(intensity);
+ CHK_INFO(gamma_air);
+ CHK_INFO(gamma_self);
+ CHK_INFO(lower_state_energy);
+ CHK_INFO(n_air);
+ CHK_INFO(delta_air);
+ #undef CHK_INFO
+
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_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_line_list_at(NULL, 0, &line) == RES_BAD_ARG);
+ CHK(shtr_line_list_at(list, nlines, &line) == RES_BAD_ARG);
+ CHK(shtr_line_list_at(list, 0, NULL) == RES_BAD_ARG);
+ FOR_EACH(i, 0, n) {
+ CHK(shtr_line_list_at(list, i, &line) == RES_OK);
+ line_eq_eps(&line, l+i, &info);
+ }
CHK(shtr_line_list_ref_get(NULL) == RES_BAD_ARG);
CHK(shtr_line_list_ref_get(list) == RES_OK);
@@ -153,11 +210,15 @@ test_load(struct shtr* shtr)
CHK(shtr_line_list_load(shtr, filename, NULL) == RES_BAD_ARG);
CHK(shtr_line_list_load(shtr, filename, &list) == RES_OK);
+ CHK(shtr_line_list_get_info(list, &info) == RES_OK);
+
CHK(shtr_line_list_get_size(list, &n) == RES_OK);
CHK(n == nlines);
- CHK(shtr_line_list_get(list, &lines) == RES_OK);
- FOR_EACH(i, 0, n) CHK(shtr_line_eq(lines+i, l+i));
+ FOR_EACH(i, 0, n) {
+ CHK(shtr_line_list_at(list, i, &line) == RES_OK);
+ line_eq_eps(&line, l+i, &info);
+ }
CHK(shtr_line_list_ref_put(list) == RES_OK);
}
@@ -241,8 +302,6 @@ 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;
size_t n1, n2;
size_t iline, nlines;
CHK(list1 && list2);
@@ -252,10 +311,14 @@ check_line_list_equality
CHK(n1 == n2);
nlines = n1;
- 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));
+ struct shtr_line lines1 = SHTR_LINE_NULL;
+ struct shtr_line lines2 = SHTR_LINE_NULL;
+
+ CHK(shtr_line_list_at(list1, iline, &lines1) == RES_OK);
+ CHK(shtr_line_list_at(list2, iline, &lines2) == RES_OK);
+
+ CHK(shtr_line_eq(&lines1, &lines2));
}
}
@@ -301,449 +364,6 @@ test_serialization(struct shtr* shtr)
}
static void
-check_view
- (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_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;
- size_t imolecule;
-
- /* Discard lines that does not belongs to a listed molecule */
- FOR_EACH(imolecule, 0, args->nmolecules) {
- if(lines[i].molecule_id == args->molecules[imolecule].id) break;
- }
- if(imolecule >= args->nmolecules)
- continue; /* Skip the molecule */
-
- /* Compute the line center for the given pressure */
- nu = lines[i].wavenumber + lines[i].delta_air * args->pressure;
-
- /* Discard lines that are out of ranges */
- if(nu + args->molecules[imolecule].cutoff < args->wavenumber_range[0])
- continue;
- if(nu - args->molecules[imolecule].cutoff > args->wavenumber_range[1])
- continue;
-
- /* nisotope == 0 <=> All isotopes must be selected */
- if(args->molecules[imolecule].nisotopes) {
- size_t iisotope;
- FOR_EACH(iisotope, 0, args->molecules[imolecule].nisotopes) {
- if(lines[i].isotope_id_local
- == args->molecules[imolecule].isotope_ids_local[iisotope])
- break;
- }
- if(iisotope >= args->molecules[imolecule].nisotopes)
- continue; /* Skip the isotope */
- }
-
- CHK(shtr_line_view_get_line(view, nlines_selected, &line) == RES_OK);
- CHK(shtr_line_eq(line, lines+i));
- nlines_selected += 1;
- }
-
- CHK(shtr_line_view_get_size(view, &n) == RES_OK);
- CHK(n == nlines_selected);
-}
-
-static void
-test_view(struct shtr* shtr)
-{
- const struct shtr_line l[] = {
- {0.00156, 2.685e-36, 0.0695, 0.428, 399.7263, 0.79, 0.000240, 1, 5},
- {0.03406, 5.898e-37, 0.0883, 0.410, 1711.6192, 0.79, 0.000000, 1, 5},
- {0.03445, 5.263e-33, 0.0504, 0.329, 1570.0616, 0.79, 0.001940, 1, 3},
- {0.03628, 9.296e-29, 0.0704, 0.095, 522.5576, 0.81, 0.000000, 3, 0},
- {0.03671, 2.555e-37, 0.0389, 0.304, 2337.5190, 0.79, 0.002660, 1, 4},
- {0.08403, 8.190e-33, 0.0753, 0.394, 568.0017, 0.79, 0.002180, 1, 4},
- {0.08653, 5.376e-29, 0.0691, 0.083, 1061.6864, 0.76, 0.000000, 3, 0},
- {0.09642, 6.675e-37, 0.0570, 0.351, 2516.3150, 0.79, 0.000000, 1, 4},
- {0.16772, 2.456e-28, 0.0823, 0.105, 751.2922, 0.77, 0.000000, 3, 0},
- {0.18582, 5.338e-32, 0.0925, 0.428, 1717.3356, 0.79, 0.004100, 1, 3},
- {0.19368, 2.553e-32, 0.0901, 0.428, 293.8010, 0.79, 0.001260, 1, 5},
- {0.19688, 1.447e-31, 0.0901, 0.428, 292.3093, 0.79, 0.001260, 1, 4},
- {0.19757, 6.063e-29, 0.0681, 0.078, 1401.6146, 0.76, 0.000000, 3, 0},
- {0.21281, 8.238e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21282, 5.999e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21283, 7.737e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21283, 6.394e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21284, 7.260e-31, 0.0780, 0.103, 127.4732, 0.78, 0.000000, 3, 4},
- {0.21284, 6.813e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21728, 5.928e-29, 0.0823, 0.105, 1153.4099, 0.77, 0.000000, 3, 0},
- {0.25818, 3.110e-32, 0.0539, 0.311, 1958.1248, 0.79, 0.008600, 1, 3},
- {0.26618, 1.468e-32, 0.0801, 0.378, 2118.9452, 0.79, 0.003100, 1, 3},
- {0.27091, 1.362e-35, 0.0539, 0.311, 1949.2032, 0.79, 0.008600, 1, 5},
- {0.28910, 2.058e-30, 0.0878, 0.106, 7.8611, 0.76, 0.000000, 3, 3},
- {0.29412, 8.666e-33, 0.0795, 0.378, 679.8760, 0.79, 0.004170, 1, 5},
- {0.29477, 1.457e-30, 0.0660, 0.340, 1238.7943, 0.79, 0.007260, 1, 3},
- {0.29673, 1.609e-30, 0.0773, 0.103, 138.7916, 0.78, 0.000000, 3, 3},
- {0.29673, 1.195e-30, 0.0773, 0.103, 138.7916, 0.78, 0.000000, 3, 3},
- {0.29676, 1.268e-30, 0.0773, 0.103, 138.7916, 0.78, 0.000000, 3, 3},
- {1.46280, 7.205e-26, 0.0696, 0.090, 702.3167, 0.82, 0.000000, 3, 0},
- {1.46899, 7.847e-28, 0.0704, 0.095, 1557.6290, 0.81, 0.000000, 3, 0},
- {1.47237, 1.700e-34, 0.0633, 0.297, 2389.2994, 0.79, 0.013980, 1, 4},
- {1.47273, 1.131e-32, 0.0903, 0.123, 0.7753, 0.69, 0.000814, 2, 2},
- {1.47863, 5.318e-33, 0.0925, 0.428, 2877.6872, 0.79, 0.006200, 1, 3},
- {1.48860, 1.058e-27, 0.0760, 0.102, 163.7760, 0.78, 0.000000, 3, 1},
- {1.49043, 4.787e-31, 0.0773, 0.103, 139.7879, 0.78, 0.000000, 3, 4},
- {1.49044, 3.139e-29, 0.0773, 0.103, 139.7879, 0.78, 0.000000, 3, 4},
- {1.49044, 3.332e-29, 0.0773, 0.103, 139.7880, 0.78, 0.000000, 3, 4},
- {1.49045, 2.785e-29, 0.0773, 0.103, 139.7880, 0.78, 0.000000, 3, 4},
- {1.49045, 2.625e-29, 0.0773, 0.103, 139.7880, 0.78, 0.000000, 3, 4},
- {1.49057, 5.941e-27, 0.0909, 0.106, 703.4398, 0.76, 0.000000, 3, 0},
- {1.49110, 1.537e-29, 0.0714, 0.098, 381.8992, 0.80, 0.000000, 3, 3},
- {1.49111, 1.828e-29, 0.0714, 0.098, 381.8992, 0.80, 0.000000, 3, 3},
- {1.49111, 1.648e-29, 0.0714, 0.098, 381.8992, 0.80, 0.000000, 3, 3},
- {1.49111, 1.766e-29, 0.0714, 0.098, 381.8991, 0.80, 0.000000, 3, 3},
- {1.49111, 1.706e-29, 0.0714, 0.098, 381.8991, 0.80, 0.000000, 3, 3},
- {1.49674, 1.208e-25, 0.0719, 0.102, 190.2125, 0.79, 0.000000, 3, 0},
- {1.50216, 4.971e-28, 0.0696, 0.090, 1734.9796, 0.82, 0.000000, 3, 0},
- {1.51178, 3.047e-27, 0.0766, 0.103, 1195.5580, 0.78, 0.000000, 3, 0},
- {1.51399, 1.986e-27, 0.0765, 0.104, 1129.0675, 0.77, 0.000000, 3, 0},
- {1.51442, 2.601e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51443, 3.981e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51443, 6.637e-35, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51444, 3.902e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51445, 1.394e-33, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51446, 7.166e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51446, 2.787e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51446, 5.096e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51448, 1.672e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51597, 4.443e-30, 0.0704, 0.097, 463.6953, 0.81, 0.000000, 3, 3},
- {1.51600, 5.172e-30, 0.0704, 0.097, 463.6952, 0.81, 0.000000, 3, 3},
- {1.51603, 4.580e-30, 0.0704, 0.097, 463.6952, 0.81, 0.000000, 3, 3},
- {1.51605, 5.019e-30, 0.0704, 0.097, 463.6951, 0.81, 0.000000, 3, 3}
- };
- const size_t nlines = sizeof(l) / sizeof(struct shtr_line);
-
- const double cutoff = 0.01;
-
- 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;
- size_t i, n;
-
- CHK(fp = fopen(filename, "w+"));
- print_lines(fp, l, nlines);
- rewind(fp);
-
- CHK(shtr_line_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
-
- args.wavenumber_range[0] = 0;
- args.wavenumber_range[1] = INF;
- args.molecules[0].id = 1;
- args.molecules[1].id = 2;
- args.molecules[2].id = 3;
- args.molecules[0].cutoff = cutoff;
- args.molecules[1].cutoff = cutoff;
- args.molecules[2].cutoff = cutoff;
- args.nmolecules = 3;
- args.pressure = 0;
- 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_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_line_view_get_line(view, i, &line) == RES_OK);
- CHK(shtr_line_eq(line, l+i));
- }
-
- 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_line_view_create(list, &args, &view) == RES_BAD_ARG);
-
- args.wavenumber_range[0] = 0;
- args.wavenumber_range[1] = 1;
- args.nmolecules = 0;
- 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_line_view_ref_put(view) == RES_OK);
-
- args.pressure = -1;
- CHK(shtr_line_view_create(list, &args, &view) == RES_BAD_ARG);
- args.pressure = 0;
- args.molecules[0].cutoff = -1;
- args.nmolecules = 3;
- 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_line_view_create(list, &args, &view) == RES_OK);
- CHK(shtr_line_view_get_size(view, &n) == RES_OK);
- CHK(n == 0);
- CHK(shtr_line_view_ref_put(view) == RES_OK);
-
- args.wavenumber_range[0] = 0;
- args.wavenumber_range[1] = 1.50;
- CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
- check_view(list, view, &args);
- CHK(shtr_line_view_ref_put(view) == RES_OK);
-
- args.wavenumber_range[0] = 1.50;
- args.wavenumber_range[1] = 1.51603;
- CHK(shtr_line_view_create(list, &args, &view) == RES_OK);
- check_view(list, view, &args);
- CHK(shtr_line_view_ref_put(view) == RES_OK);
-
- args.wavenumber_range[0] = 0.29477;
- args.wavenumber_range[1] = 0.29477;
- 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_line_view_ref_put(view) == RES_OK);
-
- args.wavenumber_range[0] = 0.09642;
- args.wavenumber_range[1] = 0.21283;
- 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_line_view_ref_put(view) == RES_OK);
-
- args.molecules[0].id = 2;
- args.nmolecules = 1;
- 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_line_view_ref_put(view) == RES_OK);
-
- args.molecules[1].id = 1;
- args.nmolecules = 2;
- 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_line_view_ref_put(view) == RES_OK);
-
- args.molecules[1].id = 3;
- args.nmolecules = 2;
- 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_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_line_view_create(list, &args, &view) == RES_OK);
- check_view(list, view, &args);
- CHK(shtr_line_view_ref_put(view) == RES_OK);
-
- args.molecules[0].id = 1;
- args.molecules[0].cutoff = 1e-6;
- args.molecules[0].nisotopes = 0;
- args.nmolecules = 1;
- args.wavenumber_range[0] = 0.1899;
- args.wavenumber_range[1] = 0.195;
- 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_line_view_ref_put(view) == RES_OK);
- args.pressure = 1;
- 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_line_view_ref_put(view) == RES_OK);
-
- args.wavenumber_range[0] = 0;
- args.wavenumber_range[1] = INF;
- args.molecules[0].id = 3;
- args.molecules[0].cutoff = cutoff;
- args.molecules[0].isotope_ids_local[0] = 4;
- args.molecules[0].isotope_ids_local[1] = 1;
- args.molecules[0].isotope_ids_local[2] = 2;
- args.molecules[0].isotope_ids_local[3] = 0;
- args.molecules[0].nisotopes = 4;
- args.molecules[1].id = 1;
- args.molecules[0].cutoff = cutoff;
- args.molecules[1].isotope_ids_local[0] = 4;
- args.molecules[1].isotope_ids_local[1] = 3;
- args.molecules[1].nisotopes = 2;
- args.nmolecules = 2;
- 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_line_view_ref_put(view) == RES_OK);
-
- CHK(shtr_line_list_ref_put(list) == RES_OK);
- CHK(fclose(fp) == 0);
-}
-
-static void
-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_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_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));
- }
-}
-
-static void
-test_view_serialization(struct shtr* shtr)
-{
- const struct shtr_line l[] = {
- {0.00156, 2.685e-36, 0.0695, 0.428, 399.7263, 0.79, 0.000240, 1, 5},
- {0.03406, 5.898e-37, 0.0883, 0.410, 1711.6192, 0.79, 0.000000, 1, 5},
- {0.03445, 5.263e-33, 0.0504, 0.329, 1570.0616, 0.79, 0.001940, 1, 3},
- {0.03628, 9.296e-29, 0.0704, 0.095, 522.5576, 0.81, 0.000000, 3, 0},
- {0.03671, 2.555e-37, 0.0389, 0.304, 2337.5190, 0.79, 0.002660, 1, 4},
- {0.08403, 8.190e-33, 0.0753, 0.394, 568.0017, 0.79, 0.002180, 1, 4},
- {0.08653, 5.376e-29, 0.0691, 0.083, 1061.6864, 0.76, 0.000000, 3, 0},
- {0.09642, 6.675e-37, 0.0570, 0.351, 2516.3150, 0.79, 0.000000, 1, 4},
- {0.16772, 2.456e-28, 0.0823, 0.105, 751.2922, 0.77, 0.000000, 3, 0},
- {0.18582, 5.338e-32, 0.0925, 0.428, 1717.3356, 0.79, 0.004100, 1, 3},
- {0.19368, 2.553e-32, 0.0901, 0.428, 293.8010, 0.79, 0.001260, 1, 5},
- {0.19688, 1.447e-31, 0.0901, 0.428, 292.3093, 0.79, 0.001260, 1, 4},
- {0.19757, 6.063e-29, 0.0681, 0.078, 1401.6146, 0.76, 0.000000, 3, 0},
- {0.21281, 8.238e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21282, 5.999e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21283, 7.737e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21283, 6.394e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21284, 7.260e-31, 0.0780, 0.103, 127.4732, 0.78, 0.000000, 3, 4},
- {0.21284, 6.813e-31, 0.0780, 0.103, 127.4733, 0.78, 0.000000, 3, 4},
- {0.21728, 5.928e-29, 0.0823, 0.105, 1153.4099, 0.77, 0.000000, 3, 0},
- {0.25818, 3.110e-32, 0.0539, 0.311, 1958.1248, 0.79, 0.008600, 1, 3},
- {0.26618, 1.468e-32, 0.0801, 0.378, 2118.9452, 0.79, 0.003100, 1, 3},
- {0.27091, 1.362e-35, 0.0539, 0.311, 1949.2032, 0.79, 0.008600, 1, 5},
- {0.28910, 2.058e-30, 0.0878, 0.106, 7.8611, 0.76, 0.000000, 3, 3},
- {0.29412, 8.666e-33, 0.0795, 0.378, 679.8760, 0.79, 0.004170, 1, 5},
- {0.29477, 1.457e-30, 0.0660, 0.340, 1238.7943, 0.79, 0.007260, 1, 3},
- {0.29673, 1.609e-30, 0.0773, 0.103, 138.7916, 0.78, 0.000000, 3, 3},
- {0.29673, 1.195e-30, 0.0773, 0.103, 138.7916, 0.78, 0.000000, 3, 3},
- {0.29676, 1.268e-30, 0.0773, 0.103, 138.7916, 0.78, 0.000000, 3, 3},
- {1.46280, 7.205e-26, 0.0696, 0.090, 702.3167, 0.82, 0.000000, 3, 0},
- {1.46899, 7.847e-28, 0.0704, 0.095, 1557.6290, 0.81, 0.000000, 3, 0},
- {1.47237, 1.700e-34, 0.0633, 0.297, 2389.2994, 0.79, 0.013980, 1, 4},
- {1.47273, 1.131e-32, 0.0903, 0.123, 0.7753, 0.69, 0.000814, 2, 2},
- {1.47863, 5.318e-33, 0.0925, 0.428, 2877.6872, 0.79, 0.006200, 1, 3},
- {1.48860, 1.058e-27, 0.0760, 0.102, 163.7760, 0.78, 0.000000, 3, 1},
- {1.49043, 4.787e-31, 0.0773, 0.103, 139.7879, 0.78, 0.000000, 3, 4},
- {1.49044, 3.139e-29, 0.0773, 0.103, 139.7879, 0.78, 0.000000, 3, 4},
- {1.49044, 3.332e-29, 0.0773, 0.103, 139.7880, 0.78, 0.000000, 3, 4},
- {1.49045, 2.785e-29, 0.0773, 0.103, 139.7880, 0.78, 0.000000, 3, 4},
- {1.49045, 2.625e-29, 0.0773, 0.103, 139.7880, 0.78, 0.000000, 3, 4},
- {1.49057, 5.941e-27, 0.0909, 0.106, 703.4398, 0.76, 0.000000, 3, 0},
- {1.49110, 1.537e-29, 0.0714, 0.098, 381.8992, 0.80, 0.000000, 3, 3},
- {1.49111, 1.828e-29, 0.0714, 0.098, 381.8992, 0.80, 0.000000, 3, 3},
- {1.49111, 1.648e-29, 0.0714, 0.098, 381.8992, 0.80, 0.000000, 3, 3},
- {1.49111, 1.766e-29, 0.0714, 0.098, 381.8991, 0.80, 0.000000, 3, 3},
- {1.49111, 1.706e-29, 0.0714, 0.098, 381.8991, 0.80, 0.000000, 3, 3},
- {1.49674, 1.208e-25, 0.0719, 0.102, 190.2125, 0.79, 0.000000, 3, 0},
- {1.50216, 4.971e-28, 0.0696, 0.090, 1734.9796, 0.82, 0.000000, 3, 0},
- {1.51178, 3.047e-27, 0.0766, 0.103, 1195.5580, 0.78, 0.000000, 3, 0},
- {1.51399, 1.986e-27, 0.0765, 0.104, 1129.0675, 0.77, 0.000000, 3, 0},
- {1.51442, 2.601e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51443, 3.981e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51443, 6.637e-35, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51444, 3.902e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51445, 1.394e-33, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51446, 7.166e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51446, 2.787e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51446, 5.096e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51448, 1.672e-34, 0.0903, 0.123, 0.7572, 0.69, 0.000814, 2, 3},
- {1.51597, 4.443e-30, 0.0704, 0.097, 463.6953, 0.81, 0.000000, 3, 3},
- {1.51600, 5.172e-30, 0.0704, 0.097, 463.6952, 0.81, 0.000000, 3, 3},
- {1.51603, 4.580e-30, 0.0704, 0.097, 463.6952, 0.81, 0.000000, 3, 3},
- {1.51605, 5.019e-30, 0.0704, 0.097, 463.6951, 0.81, 0.000000, 3, 3}
- };
- const size_t nlines = sizeof(l) / sizeof(struct shtr_line);
-
- const double cutoff = 25;
-
- 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_line_list_load_stream(shtr, fp, NULL, &list) == RES_OK);
- fclose(fp);
-
- args.wavenumber_range[0] = 0;
- args.wavenumber_range[1] = INF;
- args.molecules[0].id = 1;
- args.molecules[1].id = 2;
- args.molecules[2].id = 3;
- args.molecules[0].cutoff = cutoff;
- args.molecules[1].cutoff = cutoff;
- args.molecules[2].cutoff = cutoff;
- args.nmolecules = 3;
- args.pressure = 0;
- CHK(shtr_line_view_create(list, &args, &view1) == RES_OK);
- CHK(shtr_line_list_ref_put(list) == RES_OK);
-
- CHK(fp = tmpfile());
- 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_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_line_view_equality(view1, view2);
-
- CHK(shtr_line_view_ref_put(view1) == RES_OK);
- CHK(shtr_line_view_ref_put(view2) == RES_OK);
-}
-
-static void
check_line(const struct shtr_line* ln)
{
/* Check NaN */
@@ -768,7 +388,6 @@ static void
test_load_file(struct shtr* shtr, const char* path)
{
struct shtr_line_list* list = NULL;
- const struct shtr_line* lines = NULL;
size_t i, n;
CHK(path);
printf("Loading `%s'.\n", path);
@@ -776,8 +395,12 @@ test_load_file(struct shtr* shtr, const char* path)
CHK(shtr_line_list_get_size(list, &n) == RES_OK);
printf(" #lines: %lu\n", n);
- CHK(shtr_line_list_get(list, &lines) == RES_OK);
- FOR_EACH(i, 0, n) check_line(lines+i);
+ FOR_EACH(i, 0, n) {
+ struct shtr_line line = SHTR_LINE_NULL;
+ CHK(shtr_line_list_at(list, i, &line) == RES_OK);
+ check_line(&line);
+ }
+
CHK(shtr_line_list_ref_put(list) == RES_OK);
}
@@ -796,8 +419,6 @@ main(int argc, char** argv)
test_load(shtr);
test_load_failures(shtr);
test_serialization(shtr);
- test_view(shtr);
- test_view_serialization(shtr);
FOR_EACH(i, 1, argc) {
char buf[64];