rnsf

Define and load a phase function data format
git clone git://git.meso-star.fr/rnsf.git
Log | Files | Refs | README | LICENSE

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 }