commit ec9b7c46cfb3f4004566d89aad562e01b230d305
parent f5e69aabf7a56e38e5f7a19fd89efc24ff10d845
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 13 Jan 2021 13:55:38 +0100
Test the load process
Diffstat:
2 files changed, 331 insertions(+), 1 deletion(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -82,7 +82,7 @@ if(NOT NO_TEST)
endfunction()
new_test(test_atrri)
- #new_test(test_atrri_load)
+ new_test(test_atrri_load m)
endif()
################################################################################
diff --git a/src/test_atrri_load.c b/src/test_atrri_load.c
@@ -0,0 +1,330 @@
+/* Copyright (C) 2021 CNRS
+ *
+ * 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 support */
+
+#include "atrri.h"
+
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+
+#include <float.h>
+#include <math.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static INLINE double
+rand_canonic()
+{
+ return (double)rand() / (double)((size_t)RAND_MAX + 1);
+}
+
+static void
+check_desc
+ (const struct atrri_desc* desc,
+ const double refract_ids[],
+ const size_t nrefract_ids)
+{
+ size_t i;
+
+ CHK(desc && refract_ids && nrefract_ids);
+ CHK(desc->nindices == nrefract_ids);
+ FOR_EACH(i, 0, nrefract_ids) {
+ if(i != 0) {
+ CHK(desc->indices[i].wavelength > desc->indices[i-1].wavelength);
+ }
+ CHK(desc->indices[i].wavelength == refract_ids[i*3+0]);
+ CHK(desc->indices[i].n == refract_ids[i*3+1]);
+ CHK(desc->indices[i].kappa == refract_ids[i*3+2]);
+ }
+}
+
+static void
+fetch_refractive_index
+ (const struct atrri_desc* desc,
+ const double wavelength,
+ struct atrri_refractive_index* index)
+{
+ size_t i;
+ CHK(desc && wavelength >= 0 && index);
+
+ /* Naive linear search the first refractive index whose associated wavelength
+ * is greater than or equal to the submitted wavelength */
+ FOR_EACH(i, 0, desc->nindices) {
+ if(desc->indices[i].wavelength >= wavelength) break;
+ }
+
+ if(i >= desc->nindices) {
+ *index = desc->indices[desc->nindices-1];
+ } else if(i == 0) {
+ *index = desc->indices[0];
+ } else {
+ const struct atrri_refractive_index* next = desc->indices + i;
+ const struct atrri_refractive_index* prev = desc->indices + i - 1;
+ const double len = next->wavelength - prev->wavelength;
+ const double u = CLAMP((wavelength - prev->wavelength) / len, 0, 1);
+
+ CHK(wavelength > prev->wavelength);
+ CHK(wavelength <= next->wavelength);
+
+ index->wavelength = wavelength;
+ index->n = u * prev->n + (1.0-u) * next->n;
+ index->kappa = u * prev->kappa + (1.0-u) * next->kappa;
+ }
+}
+
+static void
+test_load(struct atrri* atrri)
+{
+ const double refract_ids[] = { /* Wavelength n kappa */
+ 300.000011921, 1.740000010, 0.469999999,
+ 310.000002384, 1.741990328, 0.469004273,
+ 319.999992847, 1.743917465, 0.468010038,
+ 329.999983311, 1.745785475, 0.467014253,
+ 339.999973774, 1.748130083, 0.465993971,
+ 349.999964237, 1.750000000, 0.464985400,
+ 359.999954700, 1.750000000, 0.463959038,
+ 369.999945164, 1.750000000, 0.462961257,
+ 379.999935627, 1.750000000, 0.461990029,
+ 389.999926090, 1.750000000, 0.460981935,
+ 399.999916553, 1.750000000, 0.459957659,
+ 409.999907017, 1.750000000, 0.458958119,
+ 419.999897480, 1.750000000, 0.457983255,
+ 429.999887943, 1.750000000, 0.456973791,
+ 439.999878407, 1.750000000, 0.455950528,
+ 449.999868870, 1.750000000, 0.454950303,
+ 459.999859333, 1.750000000, 0.453971595,
+ 469.999849796, 1.750000000, 0.452998221,
+ 479.999840260, 1.750000000, 0.451974779,
+ 489.999830723, 1.750000000, 0.450974643,
+ 499.999821186, 1.750000000, 0.449385107,
+ 509.999811649, 1.750000000, 0.447702825,
+ 519.999802113, 1.750000000, 0.445923656,
+ 529.999792576, 1.750000000, 0.443915308,
+ 539.999783039, 1.750000000, 0.441953331,
+ 549.999773502, 1.750000000, 0.440498799,
+ 559.999763966, 1.750000000, 0.439258754,
+ 569.999754429, 1.750000000, 0.438044012,
+ 579.999744892, 1.750000000, 0.437014997,
+ 589.999735355, 1.750000000, 0.436012030,
+ 599.999725819, 1.750000000, 0.435097486,
+ 609.999716282, 1.750000000, 0.435064077,
+ 619.999706745, 1.750000000, 0.435031146,
+ 629.999697208, 1.750000000, 0.434985548,
+ 639.999687672, 1.750000000, 0.434602797,
+ 649.999678135, 1.750000000, 0.434226334,
+ 659.999668598, 1.750000000, 0.433855951,
+ 669.999659061, 1.750000000, 0.432947546,
+ 679.999649525, 1.750000000, 0.431957632,
+ 689.999639988, 1.750000000, 0.430984408,
+ 699.999630451, 1.750000000, 0.430428028,
+ 709.999620914, 1.750000000, 0.430284500,
+ 719.999611378, 1.750000000, 0.430143028,
+ 729.999601841, 1.750000000, 0.430003524,
+ 739.999592304, 1.750000000, 0.430000007,
+ 749.999582767, 1.750000000, 0.430000007,
+ 759.999573231, 1.750000000, 0.430000007,
+ 769.999563694, 1.750000000, 0.430021703,
+ 779.999554157, 1.750000000, 0.430100024,
+ 789.999544621, 1.750000000, 0.430177301,
+ 799.999535084, 1.750000000, 0.430253685
+ };
+ const size_t nrefract_ids = sizeof(refract_ids) / sizeof(double[3]);
+ struct atrri_desc desc = ATRRI_DESC_NULL;
+ struct atrri_refractive_index index = ATRRI_REFRACTIVE_INDEX_NULL;
+ size_t irefract_id = 0;
+ const char* filename = "test_file.atrri";
+ FILE* fp = NULL;
+ double wlen;
+ size_t i;
+
+ fp = fopen(filename, "w+");
+ CHK(fp);
+
+ /* Write the input file */
+ fprintf(fp, "# Wavelength (in nm) n kappa\n");
+ FOR_EACH(irefract_id, 0, nrefract_ids) {
+ fprintf(fp, "%.9f %.9f %.9f\n",
+ refract_ids[irefract_id*3+0],
+ refract_ids[irefract_id*3+1],
+ refract_ids[irefract_id*3+2]);
+ }
+
+ rewind(fp);
+ CHK(atrri_load_stream(NULL, fp, filename) == RES_BAD_ARG);
+ CHK(atrri_load_stream(atrri, NULL, filename) == RES_BAD_ARG);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_OK);
+ CHK(atrri_get_desc(NULL, &desc) == RES_BAD_ARG);
+ CHK(atrri_get_desc(atrri, NULL) == RES_BAD_ARG);
+ CHK(atrri_get_desc(atrri, &desc) == RES_OK);
+ check_desc(&desc, refract_ids, nrefract_ids);
+
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, filename) == RES_OK);
+ check_desc(&desc, refract_ids, nrefract_ids);
+
+ wlen = desc.indices[0].wavelength;
+ CHK(atrri_fetch_refractive_index(NULL, wlen, &index) == RES_BAD_ARG);
+ CHK(atrri_fetch_refractive_index(atrri, -1, &index) == RES_BAD_ARG);
+ CHK(atrri_fetch_refractive_index(atrri, wlen, NULL) == RES_BAD_ARG);
+ CHK(atrri_fetch_refractive_index(atrri, wlen, &index) == RES_OK);
+ CHK(index.wavelength == desc.indices[0].wavelength);
+ CHK(index.n == desc.indices[0].n);
+ CHK(index.kappa == desc.indices[0].kappa);
+
+ /* Test clamp to lower bound */
+ i = 0;
+ wlen = nextafter(wlen, 0);
+ CHK(atrri_fetch_refractive_index(atrri, wlen, &index) == RES_OK);
+ CHK(index.wavelength == desc.indices[i].wavelength);
+ CHK(index.n == desc.indices[i].n);
+ CHK(index.kappa == desc.indices[i].kappa);
+
+ /* Test clamp to upper bound */
+ i = desc.nindices-1;
+ wlen = nextafter(desc.indices[i].wavelength, DBL_MAX);
+ CHK(atrri_fetch_refractive_index(atrri, wlen, &index) == RES_OK);
+ CHK(index.wavelength == desc.indices[i].wavelength);
+ CHK(index.n == desc.indices[i].n);
+ CHK(index.kappa == desc.indices[i].kappa);
+
+ /* Test random fetches */
+ FOR_EACH(i, 0, 10000) {
+ struct atrri_refractive_index index_ref = ATRRI_REFRACTIVE_INDEX_NULL;
+ const double r = rand_canonic();
+ wlen =
+ r * (desc.indices[desc.nindices-1].wavelength - desc.indices[0].wavelength)
+ + desc.indices[0].wavelength;
+
+ CHK(atrri_fetch_refractive_index(atrri, wlen, &index) == RES_OK);
+
+ fetch_refractive_index(&desc, wlen, &index_ref);
+ CHK(index_ref.wavelength == index.wavelength);
+ CHK(eq_eps(index_ref.n, index.n, 1.e-6));
+ CHK(eq_eps(index_ref.kappa, index.kappa, 1.e-6));
+ }
+
+ fclose(fp);
+}
+
+static void
+test_load_failure(struct atrri* atrri)
+{
+ FILE* fp = NULL;
+
+ fp = tmpfile();
+ CHK(fp);
+ fprintf(fp, "# Empty file\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "-1 10 10\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "1 -1 1\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "1 1 -1\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "1 1 1\n");
+ fprintf(fp, "3 3 3\n");
+ fprintf(fp, "2 2 2\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "1, 1 1\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "1 1; 1\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "1 1 1.0.1\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ fp = tmpfile();
+ fprintf(fp, "1 1 1 hello world !\n");
+ rewind(fp);
+ CHK(atrri_load_stream(atrri, fp, NULL) == RES_OK); /* Warning */
+ fclose(fp);
+}
+
+static void
+test_load_files(struct atrri* atrri, int argc, char** argv)
+{
+ int iarg;
+ CHK(atrri);
+ FOR_EACH(iarg, 1, argc) {
+ struct atrri_desc desc = ATRRI_DESC_NULL;
+ size_t i;
+
+ printf("Load %s\n", argv[iarg]);
+ CHK(atrri_load(atrri, argv[iarg]) == RES_OK);
+ CHK(atrri_get_desc(atrri, &desc) == RES_OK);
+ CHK(desc.nindices != 0);
+
+ FOR_EACH(i, 0, desc.nindices) {
+ CHK(desc.indices[i].wavelength == desc.indices[i].wavelength); /* !NaN */
+ CHK(desc.indices[i].n == desc.indices[i].n); /* !NaN */
+ CHK(desc.indices[i].kappa == desc.indices[i].kappa); /* !NaN */
+ CHK(desc.indices[i].wavelength >= 0);
+ CHK(desc.indices[i].n >= 0);
+ CHK(desc.indices[i].kappa >= 0);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ * Main function
+ ******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct atrri* atrri = NULL;
+ (void)argc, (void)argv;
+
+ CHK(atrri_create(NULL, &mem_default_allocator, 1, &atrri) == RES_OK);
+
+ test_load(atrri);
+ test_load_failure(atrri);
+ test_load_files(atrri, argc, argv);
+
+ CHK(atrri_ref_put(atrri) == RES_OK);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}