test_rnsf_bands.c (12417B)
1 /* Copyright (C) 2022, 2023 Centre National de la Recherche Scientifique 2 * Copyright (C) 2022, 2023 Institut Pierre-Simon Laplace 3 * Copyright (C) 2022, 2023 Institut de Physique du Globe de Paris 4 * Copyright (C) 2022, 2023 |Méso|Star> (contact@meso-star.com) 5 * Copyright (C) 2022, 2023 Observatoire de Paris 6 * Copyright (C) 2022, 2023 Université de Reims Champagne-Ardenne 7 * Copyright (C) 2022, 2023 Université de Versaille Saint-Quentin 8 * Copyright (C) 2022, 2023 Université Paul Sabatier 9 * 10 * This program is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation, either version 3 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 22 23 #include "rnsf.h" 24 25 #include <rsys/math.h> 26 #include <rsys/mem_allocator.h> 27 28 #include <stdio.h> 29 30 static void 31 test_load1(struct rnsf* rnsf) 32 { 33 FILE* fp = NULL; 34 const char* filename = "test_file_bands.rnsf"; 35 const struct rnsf_phase_fn* phase = NULL; 36 struct rnsf_phase_fn_hg hg = RNSF_PHASE_FN_HG_NULL; 37 38 CHK(fp = fopen(filename, "w+")); 39 fprintf(fp, "# Comment\n"); 40 fprintf(fp, "bands 1\n"); 41 fprintf(fp, "\n"); 42 fprintf(fp, "200.1 280.3 HG 0\n"); 43 rewind(fp); 44 45 CHK(rnsf_load_stream(NULL, fp, filename) == RES_BAD_ARG); 46 CHK(rnsf_load_stream(rnsf, NULL, filename) == RES_BAD_ARG); 47 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 48 49 rewind(fp); 50 CHK(rnsf_load_stream(rnsf, fp, filename) == RES_OK); 51 52 CHK(rnsf_load(NULL, filename) == RES_BAD_ARG); 53 CHK(rnsf_load(rnsf, NULL) == RES_BAD_ARG); 54 CHK(rnsf_load(rnsf, "invalid") == RES_IO_ERR); 55 CHK(rnsf_load(rnsf, filename) == RES_OK); 56 57 CHK(rnsf_get_phase_fn_count(rnsf) == 1); 58 CHK(phase = rnsf_get_phase_fn(rnsf, 0)); 59 CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG); 60 61 CHK(rnsf_phase_fn_get_hg(NULL, &hg) == RES_BAD_ARG); 62 CHK(rnsf_phase_fn_get_hg(phase, NULL) == RES_BAD_ARG); 63 CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK); 64 CHK(hg.wavelengths[0] == 200.1); 65 CHK(hg.wavelengths[1] == 280.3); 66 CHK(hg.g == 0); 67 CHK(fclose(fp) == 0); 68 } 69 70 static void 71 test_load2(struct rnsf* rnsf) 72 { 73 struct rnsf_phase_fn_discrete discrete = RNSF_PHASE_FN_DISCRETE_NULL; 74 struct rnsf_phase_fn_hg hg = RNSF_PHASE_FN_HG_NULL; 75 FILE* fp = NULL; 76 const struct rnsf_phase_fn* phase = NULL; 77 78 CHK(fp = tmpfile()); 79 fprintf(fp, "bands 0\n"); 80 rewind(fp); 81 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 82 CHK(rnsf_get_phase_fn_count(rnsf) == 0); 83 CHK(fclose(fp) == 0); 84 85 CHK(fp = tmpfile()); 86 fprintf(fp, "bands 5\n"); 87 fprintf(fp, "100 200 HG -0.3\n"); 88 fprintf(fp, "200 300 HG 0.4\n"); 89 fprintf(fp, "300 400 HG 0.5\n"); 90 fprintf(fp, "850 875.123 discrete 5\n"); 91 fprintf(fp, " 0 0.3\n"); 92 fprintf(fp, " %.9g 0.3\n", PI/4.0); 93 fprintf(fp, " %.9g 0.3\n", PI/2.0); 94 fprintf(fp, " %.9g 0.3\n", 3*PI/4.0); 95 fprintf(fp, " 3.14159 0.3\n"); 96 fprintf(fp, "900 900 HG -0.1\n"); 97 rewind(fp); 98 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 99 100 CHK(rnsf_get_phase_fn_count(rnsf) == 5); 101 102 CHK(phase = rnsf_get_phase_fn(rnsf, 0)); 103 CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG); 104 CHK(rnsf_phase_fn_get_discrete(phase, &discrete) == RES_BAD_ARG); 105 CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK); 106 CHK(hg.wavelengths[0] == 100 && hg.wavelengths[1] == 200); 107 CHK(hg.g == -0.3); 108 109 CHK(phase = rnsf_get_phase_fn(rnsf, 1)); 110 CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG); 111 CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK); 112 CHK(hg.wavelengths[0] == 200 && hg.wavelengths[1] == 300); 113 CHK(hg.g == 0.4); 114 115 CHK(phase = rnsf_get_phase_fn(rnsf, 2)); 116 CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG); 117 CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK); 118 CHK(hg.wavelengths[0] == 300 && hg.wavelengths[1] == 400); 119 CHK(hg.g == 0.5); 120 121 CHK(phase = rnsf_get_phase_fn(rnsf, 3)); 122 CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_DISCRETE); 123 CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_BAD_ARG); 124 CHK(rnsf_phase_fn_get_discrete(NULL, &discrete) == RES_BAD_ARG); 125 CHK(rnsf_phase_fn_get_discrete(phase, NULL) == RES_BAD_ARG); 126 CHK(rnsf_phase_fn_get_discrete(phase, &discrete) == RES_OK); 127 CHK(discrete.wavelengths[0] == 850); 128 CHK(discrete.wavelengths[1] == 875.123); 129 CHK(discrete.nitems == 5); 130 CHK(discrete.items[0].theta == 0); 131 CHK(eq_eps(discrete.items[1].theta, PI/4.0, 1.e-6)); 132 CHK(eq_eps(discrete.items[2].theta, PI/2.0, 1.e-6)); 133 CHK(eq_eps(discrete.items[3].theta, 3*PI/4.0, 1.e-6)); 134 CHK(eq_eps(discrete.items[4].theta, PI, 1.e-6)); 135 /* Check normalization */ 136 CHK(eq_eps(discrete.items[0].value, 1.0/(4*PI), 1.e-6)); 137 CHK(eq_eps(discrete.items[1].value, 1.0/(4*PI), 1.e-6)); 138 CHK(eq_eps(discrete.items[2].value, 1.0/(4*PI), 1.e-6)); 139 CHK(eq_eps(discrete.items[3].value, 1.0/(4*PI), 1.e-6)); 140 141 CHK(phase = rnsf_get_phase_fn(rnsf, 4)); 142 CHK(rnsf_phase_fn_get_type(phase) == RNSF_PHASE_FN_HG); 143 CHK(rnsf_phase_fn_get_hg(phase, &hg) == RES_OK); 144 CHK(hg.wavelengths[0] == 900 && hg.wavelengths[1] == 900); 145 CHK(hg.g == -0.1); 146 147 CHK(fclose(fp) == 0); 148 } 149 150 static void 151 test_fetch(struct rnsf* rnsf) 152 { 153 FILE* fp = NULL; 154 size_t iphase_fn = 0; 155 156 CHK(fp = tmpfile()); 157 fprintf(fp, "bands 0\n"); 158 rewind(fp); 159 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 160 CHK(fclose(fp) == 0); 161 162 CHK(rnsf_fetch_phase_fn(NULL, 400, 0.5, &iphase_fn) == RES_BAD_ARG); 163 CHK(rnsf_fetch_phase_fn(rnsf, -1, 0.5, &iphase_fn) == RES_BAD_ARG); 164 CHK(rnsf_fetch_phase_fn(rnsf, 400, -0.1, &iphase_fn) == RES_BAD_ARG); 165 CHK(rnsf_fetch_phase_fn(rnsf, 400, 1, &iphase_fn) == RES_BAD_ARG); 166 CHK(rnsf_fetch_phase_fn(rnsf, 400, 0.5, NULL) == RES_BAD_ARG); 167 CHK(rnsf_fetch_phase_fn(rnsf, 400, 0.5, &iphase_fn) == RES_OK); 168 CHK(iphase_fn >= rnsf_get_phase_fn_count(rnsf)); 169 170 CHK(fp = tmpfile()); 171 fprintf(fp, "bands 2\n"); 172 fprintf(fp, "200 300 HG 0.0\n"); 173 fprintf(fp, "300 400 HG 0.1\n"); 174 rewind(fp); 175 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 176 CHK(fclose(fp) == 0); 177 178 CHK(rnsf_fetch_phase_fn(rnsf, 100, 0, &iphase_fn) == RES_OK); 179 CHK(iphase_fn == 0); 180 CHK(rnsf_fetch_phase_fn(rnsf, 450, 0, &iphase_fn) == RES_OK); 181 CHK(iphase_fn == 1); 182 CHK(rnsf_fetch_phase_fn(rnsf, 300, 0, &iphase_fn) == RES_OK); 183 CHK(iphase_fn == 0); 184 CHK(rnsf_fetch_phase_fn(rnsf, 300.1, 0, &iphase_fn) == RES_OK); 185 CHK(iphase_fn == 1); 186 187 CHK(fp = tmpfile()); 188 fprintf(fp, "bands 4\n"); 189 fprintf(fp, "100 150 HG 0\n"); 190 fprintf(fp, "200 200 HG 1\n"); 191 fprintf(fp, "300 400 HG -1\n"); 192 fprintf(fp, "400 401 discrete 4\n"); 193 fprintf(fp, " 0 1\n"); 194 fprintf(fp, " 0.5 1\n"); 195 fprintf(fp, " 1.57 1\n"); 196 fprintf(fp, " 3.14159 1\n"); 197 rewind(fp); 198 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 199 CHK(fclose(fp) == 0); 200 201 CHK(rnsf_fetch_phase_fn(rnsf, 160, 0, &iphase_fn) == RES_OK); 202 CHK(iphase_fn == 0); 203 CHK(rnsf_fetch_phase_fn(rnsf, 160, 0.5, &iphase_fn) == RES_OK); 204 CHK(iphase_fn == 0); 205 CHK(rnsf_fetch_phase_fn(rnsf, 160, 0.8, &iphase_fn) == RES_OK); 206 CHK(iphase_fn == 1); 207 CHK(rnsf_fetch_phase_fn(rnsf, 200, 0, &iphase_fn) == RES_OK); 208 CHK(iphase_fn == 1); 209 CHK(rnsf_fetch_phase_fn(rnsf, 250, 0.49, &iphase_fn) == RES_OK); 210 CHK(iphase_fn == 1); 211 CHK(rnsf_fetch_phase_fn(rnsf, 250, 0.5, &iphase_fn) == RES_OK); 212 CHK(iphase_fn == 2); 213 CHK(rnsf_fetch_phase_fn(rnsf, 400.1, 0, &iphase_fn) == RES_OK); 214 CHK(iphase_fn == 3); 215 } 216 217 static void 218 test_load_fail(struct rnsf* rnsf) 219 { 220 FILE* fp = NULL; 221 222 /* Invalid keyword */ 223 CHK(fp = tmpfile()); 224 fprintf(fp, "bandes 1\n"); 225 fprintf(fp, "380 780 HG 0.5\n"); 226 rewind(fp); 227 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 228 CHK(fclose(fp) == 0); 229 230 /* No band count */ 231 CHK(fp = tmpfile()); 232 fprintf(fp, "bands\n"); 233 fprintf(fp, "380 780 HG 0.5\n"); 234 rewind(fp); 235 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 236 CHK(fclose(fp) == 0); 237 238 /* Missing a band definition */ 239 CHK(fp = tmpfile()); 240 fprintf(fp, "bands 2\n"); 241 fprintf(fp, "380 780 HG 0.5\n"); 242 rewind(fp); 243 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 244 CHK(fclose(fp) == 0); 245 246 /* Invalid wavelengths */ 247 CHK(fp = tmpfile()); 248 fprintf(fp, "bands 1\n"); 249 fprintf(fp, "-380 780 HG 0.5\n"); 250 rewind(fp); 251 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 252 CHK(fclose(fp) == 0); 253 254 /* Missing a band boundary */ 255 CHK(fp = tmpfile()); 256 fprintf(fp, "bands 1\n"); 257 fprintf(fp, "380 HG 0.5\n"); 258 rewind(fp); 259 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 260 CHK(fclose(fp) == 0); 261 262 /* Invalid phase function type */ 263 CHK(fp = tmpfile()); 264 fprintf(fp, "bands 1\n"); 265 fprintf(fp, "380 780 Henyey-Greenstein 0.5\n"); 266 rewind(fp); 267 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 268 CHK(fclose(fp) == 0); 269 270 /* Invalid asymmetric param */ 271 CHK(fp = tmpfile()); 272 fprintf(fp, "bands 1\n"); 273 fprintf(fp, "380 780 HG 1.01\n"); 274 rewind(fp); 275 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 276 CHK(fclose(fp) == 0); 277 278 /* Additional parameters. Print a warning */ 279 CHK(fp = tmpfile()); 280 fprintf(fp, "bands 1 additional_text\n"); 281 fprintf(fp, "380 780 HG 1.0\n"); 282 rewind(fp); 283 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 284 CHK(fclose(fp) == 0); 285 286 /* Unsorted phase functions */ 287 CHK(fp = tmpfile()); 288 fprintf(fp, "bands 2\n"); 289 fprintf(fp, "380 400 HG 1.0\n"); 290 fprintf(fp, "280 300 HG 0.0\n"); 291 rewind(fp); 292 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 293 CHK(fclose(fp) == 0); 294 295 /* Phase functions overlap */ 296 CHK(fp = tmpfile()); 297 fprintf(fp, "bands 2\n"); 298 fprintf(fp, "280 400 HG 1.0\n"); 299 fprintf(fp, "300 480 HG 0.0\n"); 300 rewind(fp); 301 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 302 CHK(fclose(fp) == 0); 303 304 /* Phase functions overlap */ 305 CHK(fp = tmpfile()); 306 fprintf(fp, "bands 2\n"); 307 fprintf(fp, "280 280 HG 1.0\n"); 308 fprintf(fp, "280 280 HG 0.0\n"); 309 rewind(fp); 310 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 311 CHK(fclose(fp) == 0); 312 313 /* Invalid #angles */ 314 CHK(fp = tmpfile()); 315 fprintf(fp, "bands 1\n"); 316 fprintf(fp, "380 780 discrete 1\n"); 317 fprintf(fp, " 0 1\n"); 318 rewind(fp); 319 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 320 CHK(fclose(fp) == 0); 321 322 /* Invalid last angle */ 323 CHK(fp = tmpfile()); 324 fprintf(fp, "bands 1\n"); 325 fprintf(fp, "380 780 discrete 2\n"); 326 fprintf(fp, " 0 1\n"); 327 fprintf(fp, " 3.14 1\n"); 328 rewind(fp); 329 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 330 CHK(fclose(fp) == 0); 331 332 /* Missing an angle */ 333 CHK(fp = tmpfile()); 334 fprintf(fp, "bands 1\n"); 335 fprintf(fp, "380 780 discrete 2\n"); 336 fprintf(fp, " 0 1\n"); 337 rewind(fp); 338 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 339 CHK(fclose(fp) == 0); 340 341 /* Invalid angle */ 342 CHK(fp = tmpfile()); 343 fprintf(fp, "bands 1\n"); 344 fprintf(fp, "380 780 discrete 3\n"); 345 fprintf(fp, " 0 1\n"); 346 fprintf(fp, " 3.14159 1\n"); 347 fprintf(fp, " 4 1\n"); 348 rewind(fp); 349 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 350 CHK(fclose(fp) == 0); 351 352 /* Unsorted angles */ 353 CHK(fp = tmpfile()); 354 fprintf(fp, "bands 1\n"); 355 fprintf(fp, "380 780 discrete 5\n"); 356 fprintf(fp, " 0 1\n"); 357 fprintf(fp, " 0.1 1\n"); 358 fprintf(fp, " 0.2 1\n"); 359 fprintf(fp, " 0.15 1\n"); 360 fprintf(fp, " 3.14159 1\n"); 361 rewind(fp); 362 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_BAD_ARG); 363 CHK(fclose(fp) == 0); 364 365 /* Additional text. Print a warning */ 366 CHK(fp = tmpfile()); 367 fprintf(fp, "bands 1\n"); 368 fprintf(fp, "380 780 discrete 4\n"); 369 fprintf(fp, " 0 1\n"); 370 fprintf(fp, " 0.1 1\n"); 371 fprintf(fp, " 0.15 1 additional_text\n"); 372 fprintf(fp, " 3.1416 1\n"); 373 rewind(fp); 374 CHK(rnsf_load_stream(rnsf, fp, NULL) == RES_OK); 375 CHK(fclose(fp) == 0); 376 } 377 378 int 379 main(int argc, char** argv) 380 { 381 struct rnsf_create_args args = RNSF_CREATE_ARGS_DEFAULT; 382 struct rnsf* rnsf = NULL; 383 (void)argc, (void)argv; 384 385 args.verbose = 1; 386 CHK(rnsf_create(&args, &rnsf) == RES_OK); 387 CHK(rnsf_get_phase_fn_count(rnsf) == 0); 388 389 test_load1(rnsf); 390 test_load2(rnsf); 391 test_fetch(rnsf); 392 test_load_fail(rnsf); 393 394 CHK(rnsf_ref_put(rnsf) == RES_OK); 395 CHK(mem_allocated_size() == 0); 396 return 0; 397 }