commit a8a4758faba933a862174961dbf099a285cebe00
parent 1256fc4d8ccc8da17f660b4be7844b35c4622e2a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 16 Oct 2023 15:42:29 +0200
Add the sars_validate function
It checks the validity of the loaded radiative coefficients. This check
is not mandatory, in order to speed up the loading step and avoid
loading these data when using memory mapping. However, it is always a
good idea to allow the caller to check that his input data is valid.
Diffstat:
3 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/src/sars.c b/src/sars.c
@@ -564,6 +564,52 @@ sars_load_stream(struct sars* sars, const struct sars_load_stream_args* args)
return load_stream(sars, args);
}
+res_T
+sars_validate(const struct sars* sars)
+{
+ size_t iband;
+ size_t nbands;
+ if(!sars) return RES_BAD_ARG;
+
+ nbands = sars_get_bands_count(sars);
+ FOR_EACH(iband, 0, nbands) {
+ struct sars_band band = SARS_BAND_NULL;
+ size_t inode;
+ size_t nnodes;
+
+ SARS(get_band(sars, iband, &band));
+
+ /* Check band limits */
+ if(band.lower != band.lower /* NaN? */
+ || band.upper != band.upper) { /* NaN? */
+ log_err(sars,
+ "%s: invalid limits for band %lu: [%g, %g[\n",
+ sars_get_name(sars), (unsigned long)iband, band.lower, band.upper);
+ return RES_BAD_ARG;
+ }
+
+ /* Check radiative coefficients */
+ nnodes = sars_get_nodes_count(sars);
+ FOR_EACH(inode, 0, nnodes) {
+ const float ka = sars_band_get_ka(&band, inode);
+ const float ks = sars_band_get_ks(&band, inode);
+ if(ka != ka /* NaN? */ || ka < 0) {
+ log_err(sars,
+ "%s: invalid absorption coefficient for band %lu at node %lu: %g\n",
+ sars_get_name(sars), (unsigned long)iband, (unsigned long)inode, ka);
+ return RES_BAD_ARG;
+ }
+ if(ks != ks /* NaN? */ || ks < 0) {
+ log_err(sars,
+ "%s: invalid scattering coefficient for band %lu at node %lu: %g\n",
+ sars_get_name(sars), (unsigned long)iband, (unsigned long)inode, ka);
+ return RES_BAD_ARG;
+ }
+ }
+ }
+ return RES_OK;
+}
+
size_t
sars_get_bands_count(const struct sars* sars)
{
diff --git a/src/sars.h b/src/sars.h
@@ -109,6 +109,17 @@ sars_load_stream
(struct sars* sars,
const struct sars_load_stream_args* args);
+/* Validates radiative coefficients. Data checks have already been carried out
+ * during loading, notably on spectral bands, but this function performs longer
+ * and more thorough tests. It reviews all scattering and absorption
+ * coefficients to check their validity, i.e. whether they are positive or zero.
+ * Note that checking radiative coefficients is not mandatory, in order to speed
+ * up the loading step and avoid loading/unloading them when using memory
+ * mapping. */
+SARS_API res_T
+sars_validate
+ (const struct sars* sars);
+
SARS_API size_t
sars_get_bands_count
(const struct sars* sars);
diff --git a/src/test_sars_load.c b/src/test_sars_load.c
@@ -308,25 +308,14 @@ test_load_files(struct sars* sars, int argc, char** argv)
FOR_EACH(iband, 0, nbands) {
struct sars_band band = SARS_BAND_NULL;
- size_t inode;
CHK(sars_get_band(sars, iband, &band) == RES_OK);
printf("band %lu in [%g, %g[ nm\n",
(unsigned long)band.id,
band.lower, band.upper);
-
- CHK(band.lower == band.lower); /* !NaN */
- CHK(band.upper == band.upper); /* !NaN */
- CHK(band.lower < band.upper);
-
- FOR_EACH(inode, 0, nnodes) {
- const float ka = sars_band_get_ka(&band, inode);
- const float ks = sars_band_get_ks(&band, inode);
- CHK(ka == ka); /* !NaN */
- CHK(ks == ks); /* !NaN */
- }
}
+ CHK(sars_validate(sars) == RES_OK);
CHK(sars_compute_hash(sars, hash) == RES_OK);
}
}