htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

htrdr_atmosphere_args.c (8099B)


      1 /* Copyright (C) 2018-2019, 2022-2025 Centre National de la Recherche Scientifique
      2  * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux
      3  * Copyright (C) 2022-2025 Institut Pierre-Simon Laplace
      4  * Copyright (C) 2022-2025 Institut de Physique du Globe de Paris
      5  * Copyright (C) 2018-2025 |Méso|Star> (contact@meso-star.com)
      6  * Copyright (C) 2022-2025 Observatoire de Paris
      7  * Copyright (C) 2022-2025 Université de Reims Champagne-Ardenne
      8  * Copyright (C) 2022-2025 Université de Versaille Saint-Quentin
      9  * Copyright (C) 2018-2019, 2022-2025 Université Paul Sabatier
     10  *
     11  * This program is free software: you can redistribute it and/or modify
     12  * it under the terms of the GNU General Public License as published by
     13  * the Free Software Foundation, either version 3 of the License, or
     14  * (at your option) any later version.
     15  *
     16  * This program is distributed in the hope that it will be useful,
     17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     19  * GNU General Public License for more details.
     20  *
     21  * You should have received a copy of the GNU General Public License
     22  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     23 
     24 #include "atmosphere/htrdr_atmosphere_args.h"
     25 
     26 #include <rsys/cstr.h>
     27 
     28 #include <getopt.h>
     29 
     30 /*******************************************************************************
     31  * Helper functions
     32  ******************************************************************************/
     33 static void
     34 usage(void)
     35 {
     36   printf("usage: htrdr-atmosphere [-dfhRrv] [-c clouds]\n");
     37   printf("                        [-C persp_camera_opt[:persp_camera_opt ...]]\n");
     38   printf("                        [-D sun_azimuth,sun_elevation] [-g ground]\n");
     39   printf("                        [-i image_opt[:image_opt ...]] [-M materials] [-m mie]\n");
     40   printf("                        [-n sky_mtl] [-O cache] [-o output]\n");
     41   printf("                        [-P ortho_camera_opt[:ortho_camera_opt ...]]\n");
     42   printf("                        [-p flux_sensor_opt[:flux_sensor_opt ...]]\n");
     43   printf("                        [-s spectral_opt[:spectral_opt ...]]\n");
     44   printf("                        [-T optical_thickness] [-t threads_count] [-V x,y,z]\n");
     45   printf("                        -a atmosphere\n");
     46 }
     47 
     48 static res_T
     49 parse_grid_definition(struct htrdr_atmosphere_args* args, const char* str)
     50 {
     51   unsigned def[3];
     52   size_t len;
     53   res_T res = RES_OK;
     54   ASSERT(args && str);
     55 
     56   res = cstr_to_list_uint(str, ',', def, &len, 3);
     57   if(res == RES_OK && len != 3) res = RES_BAD_ARG;
     58   if(res != RES_OK) {
     59     fprintf(stderr, "Invalid grid definition `%s'.\n", str);
     60     goto error;
     61   }
     62 
     63   if(!def[0] || !def[1] || !def[2]) {
     64     fprintf(stderr,
     65       "Invalid null grid definition {%u, %u, %u}.\n", SPLIT3(def));
     66     res = RES_BAD_ARG;
     67     goto error;
     68   }
     69 
     70   args->grid_max_definition[0] = def[0];
     71   args->grid_max_definition[1] = def[1];
     72   args->grid_max_definition[2] = def[2];
     73 
     74 exit:
     75   return res;
     76 error:
     77   goto exit;
     78 }
     79 
     80 static res_T
     81 parse_sun_dir(struct htrdr_atmosphere_args* args, const char* str)
     82 {
     83   double angles[2];
     84   size_t len;
     85   res_T res = RES_OK;
     86   ASSERT(args && str);
     87 
     88   res = cstr_to_list_double(str, ',', angles, &len, 2);
     89   if(res == RES_OK && len != 2) res = RES_BAD_ARG;
     90   if(res != RES_OK) {
     91     fprintf(stderr, "Invalid direction `%s'.\n", str);
     92     goto error;
     93   }
     94 
     95   if(angles[0] < 0 || angles[0] >= 360) {
     96     fprintf(stderr,
     97       "Invalid azimuth angle `%g'. Azimuth must be in [0, 360[ degrees.\n",
     98       angles[0]);
     99     res = RES_BAD_ARG;
    100     goto error;
    101   }
    102 
    103   if(angles[1] < 0 || angles[1] > 90) {
    104     fprintf(stderr,
    105       "Invalid elevation angle `%g'. Elevation must be in [0, 90] degrees.\n",
    106       angles[1]);
    107     res = RES_BAD_ARG;
    108     goto error;
    109   }
    110 
    111   args->sun_azimuth = angles[0];
    112   args->sun_elevation = angles[1];
    113 
    114 exit:
    115   return res;
    116 error:
    117   goto exit;
    118 }
    119 
    120 /*******************************************************************************
    121  * Local functions
    122  ******************************************************************************/
    123 res_T
    124 htrdr_atmosphere_args_init
    125   (struct htrdr_atmosphere_args* args,
    126    int argc,
    127    char** argv)
    128 {
    129   int opt;
    130   res_T res = RES_OK;
    131   ASSERT(args && argc && argv);
    132 
    133   *args = HTRDR_ATMOSPHERE_ARGS_DEFAULT;
    134 
    135   while((opt = getopt(argc, argv, "a:C:c:D:dfg:hi:M:m:n:O:o:P:p:Rrs:T:t:V:v")) != -1) {
    136     switch(opt) {
    137       case 'a': args->filename_gas = optarg; break;
    138       case 'C':
    139         args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE;
    140         args->cam_type = HTRDR_ARGS_CAMERA_PERSPECTIVE;
    141         res = htrdr_args_camera_perspective_parse(&args->cam_persp, optarg);
    142         break;
    143       case 'c': args->filename_les = optarg; break;
    144       case 'D': res = parse_sun_dir(args, optarg); break;
    145       case 'd':
    146         args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_OCTREES;
    147         break;
    148       case 'f': args->force_overwriting = 1; break;
    149       case 'g': args->filename_obj = optarg; break;
    150       case 'h':
    151         usage();
    152         htrdr_atmosphere_args_release(args);
    153         args->quit = 1;
    154         goto exit;
    155       case 'i':
    156         res = htrdr_args_image_parse(&args->image, optarg);
    157         break;
    158       case 'M': args->filename_mtl = optarg; break;
    159       case 'm': args->filename_mie = optarg; break;
    160       case 'n': args->sky_mtl_name = optarg; break;
    161       case 'O': args->filename_cache = optarg; break;
    162       case 'o': args->filename_output = optarg; break;
    163       case 'p':
    164         args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP;;
    165         res = htrdr_args_rectangle_parse(&args->flux_map, optarg);
    166         break;
    167       case 'P':
    168         args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE;
    169         args->cam_type = HTRDR_ARGS_CAMERA_ORTHOGRAPHIC;
    170         res = htrdr_args_camera_orthographic_parse(&args->cam_ortho, optarg);
    171         break;
    172       case 'r': args->repeat_clouds = 1; break;
    173       case 'R': args->repeat_ground = 1; break;
    174       case 's':
    175         res = htrdr_args_spectral_parse(&args->spectral, optarg);
    176         break;
    177       case 'T':
    178         res = cstr_to_double(optarg, &args->optical_thickness);
    179         if(res == RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG;
    180         break;
    181       case 't': /* Submit an hint on the number of threads to use */
    182         res = cstr_to_uint(optarg, &args->nthreads);
    183         if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG;
    184         break;
    185       case 'V': res = parse_grid_definition(args, optarg); break;
    186       case 'v': args->verbose = 1; break;
    187       default: res = RES_BAD_ARG; break;
    188     }
    189     if(res != RES_OK) {
    190       if(optarg) {
    191         fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n",
    192           argv[0], optarg, opt);
    193       }
    194       goto error;
    195     }
    196   }
    197   if(!args->filename_gas) {
    198     fprintf(stderr,
    199       "missing the path of the gas optical properties file -- option '-a'\n");
    200     res = RES_BAD_ARG;
    201     goto error;
    202   }
    203   if(args->filename_obj && !args->filename_mtl) {
    204     fprintf(stderr,
    205       "missing the path of the file listing the ground materials -- option '-M'\n");
    206     res = RES_BAD_ARG;
    207     goto error;
    208   }
    209   if(args->filename_les && !args->filename_mie) {
    210     fprintf(stderr,
    211       "missing the path toward the file of the Mie's data -- option '-m'\n");
    212     res = RES_BAD_ARG;
    213     goto error;
    214   }
    215 
    216   /* Setup default ref temperature if necessary */
    217   if(args->spectral.ref_temperature <= 0) {
    218     switch(args->spectral.spectral_type) {
    219       case HTRDR_SPECTRAL_LW:
    220         args->spectral.ref_temperature = HTRDR_DEFAULT_LW_REF_TEMPERATURE;
    221         break;
    222       case HTRDR_SPECTRAL_SW:
    223         args->spectral.ref_temperature = HTRDR_SUN_TEMPERATURE;
    224         break;
    225       case HTRDR_SPECTRAL_SW_CIE_XYZ:
    226         args->spectral.ref_temperature = -1; /* Unused */
    227         break;
    228       default: FATAL("Unreachable code.\n"); break;
    229     }
    230   }
    231 
    232 exit:
    233   return res;
    234 error:
    235   usage();
    236   htrdr_atmosphere_args_release(args);
    237   goto exit;
    238 }
    239 
    240 void
    241 htrdr_atmosphere_args_release(struct htrdr_atmosphere_args* args)
    242 {
    243   ASSERT(args);
    244   *args = HTRDR_ATMOSPHERE_ARGS_DEFAULT;
    245 }