commit a65b8be7dbf522634e8a16563d767e5c940fdca7
parent c15774ccdb473d30b51fdfdfa5ae12706c352286
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 21 Jun 2022 16:16:36 +0200
Test the loading of phase functions per band
Diffstat:
2 files changed, 324 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -92,6 +92,7 @@ if(NOT NO_TEST)
endfunction()
new_test(test_rnsf)
+ new_test(test_rnsf_bands)
endif()
################################################################################
diff --git a/src/test_rnsf_bands.c b/src/test_rnsf_bands.c
@@ -0,0 +1,323 @@
+/* Copyright (C) 2022 GSMA - Université de Reims Champgne-Ardenne, CNRS
+ * Copyright (C) 2022 IPGP, Université Paris Cité, CNRS
+ * Copyright (C) 2022 LAPLACE - Université de Toulouse, CNRS, INPT, UPS
+ * Copyright (C) 2022 LATMOS/IPSL - UVSQ, Université Paris-Saclay,
+ * Sorbonne Université, CNRS
+ * Copyright (C) 2022 LESIA - Observatoire de Paris, Université PSL,
+ * Sorbonne Université, Université Paris Cité
+ * Copyright (C) 2022 LMD/IPSL - Sorbonne Université, Université PSL,
+ * Ecole Polytechnique, Institut Polytechnique de Paris,
+ * CNRS
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * 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 "rnsf.h"
+
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+
+static void
+test_load1(struct rnsf* rnsf)
+{
+ FILE* fp = NULL;
+ const char* filename = "test_file_bands.rnsf";
+ const struct rnsf_phase_fn* phase = NULL;
+ struct rnsf_phase_fn_hg hg = RNSF_PHASE_FN_HG_NULL;
+
+ CHK(fp = fopen(filename, "w+"));
+ fprintf(fp, "# Comment\n");
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "200.1 280.3 hg 0\n");
+ rewind(fp);
+
+ CHK(rnsf_load_stream(NULL, fp, filename) == RES_BAD_ARG);
+ CHK(rnsf_load_stream(rnsf, NULL, filename) == RES_BAD_ARG);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK);
+
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, filename) == RES_OK);
+
+ CHK(rnsf_load(NULL, filename) == RES_BAD_ARG);
+ CHK(rnsf_load(rnsf, NULL) == RES_BAD_ARG);
+ CHK(rnsf_load(rnsf, "invalid") == RES_IO_ERR);
+ CHK(rnsf_load(rnsf, filename) == RES_OK);
+
+ CHK(rnsf_get_phase_fn_count(rnsf) == 1);
+ CHK(phase = rnsf_get_phase_fn(rnsf, 0));
+ CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG);
+
+ CHK(rnsf_phase_fn_get_hg(NULL, &hg) == RES_BAD_ARG);
+ CHK(rnsf_phase_fn_get_hg(phase, NULL) == RES_BAD_ARG);
+ CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK);
+ CHK(hg.wavelengths[0] == 200.1);
+ CHK(hg.wavelengths[1] == 280.3);
+ CHK(hg.g == 0);
+ CHK(fclose(fp) == 0);
+}
+
+static void
+test_load2(struct rnsf* rnsf)
+{
+ struct rnsf_phase_fn_discrete discrete = RNSF_PHASE_FN_DISCRETE_NULL;
+ struct rnsf_phase_fn_hg hg = RNSF_PHASE_FN_HG_NULL;
+ FILE* fp = NULL;
+ const struct rnsf_phase_fn* phase = NULL;
+
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 5\n");
+ fprintf(fp, "100 200 hg -0.3\n");
+ fprintf(fp, "200 300 hg 0.4\n");
+ fprintf(fp, "300 400 hg 0.5\n");
+ fprintf(fp, "850 875.123 discrete 5\n");
+ fprintf(fp, " 0 0.3\n");
+ fprintf(fp, " %.9g 0.3\n", PI/4.0);
+ fprintf(fp, " %.9g 0.3\n", PI/2.0);
+ fprintf(fp, " %.9g 0.3\n", 3*PI/4.0);
+ fprintf(fp, " PI 0.3\n");
+ fprintf(fp, "900 1000 hg -0.1\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK);
+
+ CHK(rnsf_get_phase_fn_count(rnsf) == 5);
+
+ CHK(phase = rnsf_get_phase_fn(rnsf, 0));
+ CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG);
+ CHK(rnsf_phase_fn_get_discrete(phase, &discrete) == RES_BAD_ARG);
+ CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK);
+ CHK(hg.wavelengths[0] == 100 && hg.wavelengths[1] == 200);
+ CHK(hg.g == -0.3);
+
+ CHK(phase = rnsf_get_phase_fn(rnsf, 1));
+ CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG);
+ CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK);
+ CHK(hg.wavelengths[0] == 200 && hg.wavelengths[1] == 300);
+ CHK(hg.g == 0.4);
+
+ CHK(phase = rnsf_get_phase_fn(rnsf, 2));
+ CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG);
+ CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK);
+ CHK(hg.wavelengths[0] == 300 && hg.wavelengths[1] == 400);
+ CHK(hg.g == 0.5);
+
+ CHK(phase = rnsf_get_phase_fn(rnsf, 3));
+ CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_DISCRETE);
+ CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_BAD_ARG);
+ CHK(rnsf_phase_fn_get_discrete(NULL, &discrete) == RES_BAD_ARG);
+ CHK(rnsf_phase_fn_get_discrete(phase, NULL) == RES_BAD_ARG);
+ CHK(rnsf_phase_fn_get_discrete(phase, &discrete) == RES_OK);
+ CHK(discrete.wavelengths[0] == 850);
+ CHK(discrete.wavelengths[1] == 875.123);
+ CHK(discrete.nitems == 5);
+ CHK(discrete.items[0].theta == 0);
+ CHK(eq_eps(discrete.items[1].theta, PI/4.0, 1.e-6));
+ CHK(eq_eps(discrete.items[2].theta, PI/2.0, 1.e-6));
+ CHK(eq_eps(discrete.items[3].theta, 3*PI/4.0, 1.e-6));
+ CHK(eq_eps(discrete.items[4].theta, PI, 1.e-6));
+ /* Check normalization */
+ CHK(eq_eps(discrete.items[0].value, 1.0/(4*PI), 1.e-6));
+ CHK(eq_eps(discrete.items[1].value, 1.0/(4*PI), 1.e-6));
+ CHK(eq_eps(discrete.items[2].value, 1.0/(4*PI), 1.e-6));
+ CHK(eq_eps(discrete.items[3].value, 1.0/(4*PI), 1.e-6));
+
+ CHK(phase = rnsf_get_phase_fn(rnsf, 4));
+ CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG);
+ CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK);
+ CHK(hg.wavelengths[0] == 900 && hg.wavelengths[1] == 1000);
+ CHK(hg.g == -0.1);
+
+ CHK(fclose(fp) == 0);
+}
+
+static void
+test_load_fail(struct rnsf* rnsf)
+{
+ FILE* fp = NULL;
+
+ /* Invalid keyword */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bandes 1\n");
+ fprintf(fp, "380 780 hg 0.5\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* No bands count */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands\n");
+ fprintf(fp, "380 780 hg 0.5\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Missing a band definition */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 2\n");
+ fprintf(fp, "380 780 hg 0.5\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Invalid wavelengths */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "-380 780 hg 0.5\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Missing a band boundary */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 hg 0.5\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Invalid phase function type */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 Henyey-Greenstein 0.5\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Invalid asymmetric param */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 hg 1.01\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Additional parameters. Print a warning */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1 additional_text\n");
+ fprintf(fp, "380 780 hg 1.0\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK);
+ CHK(fclose(fp) == 0);
+
+ /* Unsorted phase functions */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 2\n");
+ fprintf(fp, "380 400 hg 1.0\n");
+ fprintf(fp, "280 300 hg 0.0\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Phase functions overlap */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 2\n");
+ fprintf(fp, "280 400 hg 1.0\n");
+ fprintf(fp, "300 480 hg 0.0\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Phase functions overlap */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 2\n");
+ fprintf(fp, "280 280 hg 1.0\n");
+ fprintf(fp, "280 280 hg 0.0\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Invalid #angles */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 discrete 1\n");
+ fprintf(fp, " 0 1\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Invalid last angle */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 discrete 2\n");
+ fprintf(fp, " 0 1\n");
+ fprintf(fp, " 3.14 1\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Missing an angle */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 discrete 2\n");
+ fprintf(fp, " 0 1\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Invalid angle */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 discrete 3\n");
+ fprintf(fp, " 0 1\n");
+ fprintf(fp, " PI 1\n");
+ fprintf(fp, " 4 1\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Unsorted angles */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 discrete 5\n");
+ fprintf(fp, " 0 1\n");
+ fprintf(fp, " 0.1 1\n");
+ fprintf(fp, " 0.2 1\n");
+ fprintf(fp, " 0.15 1\n");
+ fprintf(fp, " PI 1\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG);
+ CHK(fclose(fp) == 0);
+
+ /* Additional text. Print a warning */
+ CHK(fp = tmpfile());
+ fprintf(fp, "bands 1\n");
+ fprintf(fp, "380 780 discrete 4\n");
+ fprintf(fp, " 0 1\n");
+ fprintf(fp, " 0.1 1\n");
+ fprintf(fp, " 0.15 1 additional_text\n");
+ fprintf(fp, " PI 1\n");
+ rewind(fp);
+ CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK);
+ CHK(fclose(fp) == 0);
+}
+
+int
+main(int argc, char** argv)
+{
+ struct rnsf_create_args args = RNSF_CREATE_ARGS_DEFAULT;
+ struct rnsf* rnsf = NULL;
+ (void)argc, (void)argv;
+
+ args.verbose = 1;
+ CHK(rnsf_create(&args, &rnsf) == RES_OK);
+ CHK(rnsf_get_phase_fn_count(rnsf) == 0);
+
+ test_load1(rnsf);
+ test_load2(rnsf);
+ test_load_fail(rnsf);
+
+ CHK(rnsf_ref_put(rnsf) == RES_OK);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}