commit 44411bd98ca7faf0a3c3bce0040a7b47884ac745
parent 16fc032a3f487568352803984b2ab6e7d201fb7d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 26 Oct 2022 11:50:13 +0200
htrdr-planeto: parse source arguments
Diffstat:
2 files changed, 139 insertions(+), 13 deletions(-)
diff --git a/src/planeto/htrdr_planeto_args.c b/src/planeto/htrdr_planeto_args.c
@@ -73,6 +73,27 @@ check_ground_args(const struct htrdr_planeto_ground_args* args)
}
static INLINE res_T
+check_source_args(const struct htrdr_planeto_source_args* args)
+{
+ if(!args) return RES_BAD_ARG;
+
+ /* Invalid position */
+ if(args->latitude <-90
+ || args->latitude > 90
+ || args->longitude <-180
+ || args->longitude > 180
+ || args->distance < 0)
+ return RES_BAD_ARG;
+
+ /* Miscellaneous parameters */
+ if(args->radius < 0
+ || args->temperature < 0)
+ return RES_BAD_ARG;
+
+ return RES_OK;
+}
+
+static INLINE res_T
check_spectral_args(const struct htrdr_args_spectral* spectral_domain)
{
if(!spectral_domain) return RES_BAD_ARG;
@@ -108,7 +129,7 @@ print_help(const char* cmd)
"Usage: %s [-dfhv] [-s spectral_domain] [-t threads]\n"
" [-T optical_thickness] [-V octree_definition]\n"
" [-O octrees_storage] [-o output]\n"
-" [-a aerosol]... -g gas -G ground\n", cmd);
+" [-a aerosol]... -g gas -G ground -S source\n", cmd);
printf(
"Simulate radiative transfer in heterogeneous 3D planetary atmosphere.\n"
"See htrdr-planeto(1) man page for details\n\n");
@@ -132,6 +153,8 @@ print_help(const char* cmd)
" -o output file where the result is written. If not defined,\n"
" the result is written to standard output\n");
printf(
+" -S source define the source\n");
+ printf(
" -s spectral_domain\n"
" define the spectral domain of integration\n");
printf(
@@ -379,6 +402,87 @@ error:
goto exit;
}
+static res_T
+parse_source_parameters(const char* str, void* ptr)
+{
+ enum {LAT, LON, DST, RADIUS, TEMP} iparam;
+ char buf[BUFSIZ];
+ struct htrdr_planeto_args* args = ptr;
+ struct htrdr_planeto_source_args* src = NULL;
+ char* key;
+ char* val;
+ char* tk_ctx;
+ res_T res = RES_OK;
+ ASSERT(str && ptr);
+
+ src = &args->source;
+
+ if(strlen(str) >= sizeof(buf) -1/*NULL char*/) {
+ fprintf(stderr, "Could not duplicate the source parameter `%s'\n", str);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ strncpy(buf, str, sizeof(buf));
+
+ key = strtok_r(buf, "=", &tk_ctx);
+ val = strtok_r(NULL, "", &tk_ctx);
+
+ if(!strcmp(key, "lat")) iparam = LAT;
+ else if(!strcmp(key, "lon")) iparam = LON;
+ else if(!strcmp(key, "dst")) iparam = DST;
+ else if(!strcmp(key, "radius")) iparam = RADIUS;
+ else if(!strcmp(key, "temp")) iparam = TEMP;
+ else {
+ fprintf(stderr, "Invalid source parameter `%s'\n", key);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(!val) {
+ fprintf(stderr, "Invalid null value for the source parameter`%s'\n", key);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ switch(iparam) {
+ case LAT:
+ res = cstr_to_double(val, &src->latitude);
+ if(res == RES_OK && (src->latitude < -90 || src->latitude > 90)) {
+ res = RES_BAD_ARG;
+ }
+ break;
+ case LON:
+ res = cstr_to_double(val, &src->longitude);
+ if(res == RES_OK && (src->longitude < -180 || src->longitude > 180)) {
+ res = RES_BAD_ARG;
+ }
+ break;
+ case DST:
+ res = cstr_to_double(val, &src->distance);
+ if(res == RES_OK && src->distance < 0) res = RES_BAD_ARG;
+ break;
+ case RADIUS:
+ res = cstr_to_double(val, &src->radius);
+ if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG;
+ break;
+ case TEMP:
+ res = cstr_to_double(val, &src->temperature);
+ if(res == RES_OK && src->temperature < 0) res = RES_BAD_ARG;
+ break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+ if(res != RES_OK) {
+ fprintf(stderr, "Unable to parse the source parameter `%s' -- %s\n",
+ str, res_to_cstr(res));
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -391,7 +495,7 @@ htrdr_planeto_args_init(struct htrdr_planeto_args* args, int argc, char** argv)
*args = HTRDR_PLANETO_ARGS_DEFAULT;
- while((opt = getopt(argc, argv, "a:dfG:g:hO:o:s:T:t:V:v")) != -1) {
+ while((opt = getopt(argc, argv, "a:dfG:g:hO:o:S:s:T:t:V:v")) != -1) {
switch(opt) {
case 'a':
sa_add(args->aerosols, 1);
@@ -427,6 +531,9 @@ htrdr_planeto_args_init(struct htrdr_planeto_args* args, int argc, char** argv)
goto exit;
case 'O': args->octrees_storage = optarg; break;
case 'o': args->output = optarg; break;
+ case 'S':
+ res = cstr_parse_list(optarg, ':', parse_source_parameters, args);
+ break;
case 's':
res = htrdr_args_spectral_parse(&args->spectral_domain, optarg);
break;
@@ -457,12 +564,17 @@ htrdr_planeto_args_init(struct htrdr_planeto_args* args, int argc, char** argv)
res = check_gas_args(&args->gas);
if(res != RES_OK) {
- fprintf(stderr, "missing gas definition -- option '-a'\n");
+ fprintf(stderr, "Missing gas definition -- option '-a'\n");
goto error;
}
res = check_ground_args(&args->ground);
if(res != RES_OK) {
- fprintf(stderr, "missing ground definition -- option '-G'\n");
+ fprintf(stderr, "Missing ground definition -- option '-G'\n");
+ goto error;
+ }
+ res = check_source_args(&args->source);
+ if(res != RES_OK) {
+ fprintf(stderr, "Missing source definition -- option '-S'\n");
goto error;
}
@@ -508,29 +620,33 @@ htrdr_planeto_args_check(const struct htrdr_planeto_args* args)
if(!args) return RES_BAD_ARG;
- /* Invalid gas */
+ /* Check the gas */
res = check_gas_args(&args->gas);
if(res != RES_OK) return res;
- /* Invalid aerosols */
+ /* Check the aerosols */
FOR_EACH(i, 0, args->naerosols) {
res = check_aerosol_args(args->aerosols+i);
if(res != RES_OK) return res;
}
- /* Invalid ground */
+ /* Check the ground */
res = check_ground_args(&args->ground);
if(res != RES_OK) return res;
- /* Invalid octree parameters */
+ /* Check the octree parameters */
if(args->octree_definition_hint == 0
|| args->optical_thickness < 0)
return RES_BAD_ARG;
- /* Invalid spectral domain */
+ /* Check the spectral domain */
res = check_spectral_args(&args->spectral_domain);
if(res != RES_OK) return res;
+ /* Check the source */
+ res = check_source_args(&args->source);
+ if(res != RES_OK) return res;
+
/* Check miscalleneous parameters */
if(args->nthreads == 0
|| (unsigned)args->output_type >= HTRDR_PLANETO_ARGS_OUTPUT_TYPES_COUNT__)
diff --git a/src/planeto/htrdr_planeto_args.h b/src/planeto/htrdr_planeto_args.h
@@ -31,6 +31,17 @@ enum htrdr_planeto_args_output_type {
HTRDR_PLANETO_ARGS_OUTPUT_TYPES_COUNT__
};
+struct htrdr_planeto_source_args {
+ double longitude; /* In [-180, 180] degrees */
+ double latitude; /* In [-90, 90] degrees */
+ double distance; /* In km */
+ double radius; /* In km */
+ double temperature; /* In Kelvin */
+};
+#define HTRDR_PLANETO_SOURCE_ARGS_NULL__ {0,0,0,-1,-1}
+static const struct htrdr_planeto_source_args HTRDR_PLANETO_SOURCE_ARGS_NULL =
+ HTRDR_PLANETO_SOURCE_ARGS_NULL__;
+
struct htrdr_planeto_ground_args {
char* smsh_filename; /* The Star-Mesh geometry */
char* props_filename; /* Per triangle physical properties */
@@ -56,9 +67,8 @@ struct htrdr_planeto_args {
double optical_thickness; /* Threshold used during octree building */
char* output; /* File where the result is written */
-
- /* Integration spectral domain */
- struct htrdr_args_spectral spectral_domain;
+ struct htrdr_args_spectral spectral_domain; /* Integration spectral domain */
+ struct htrdr_planeto_source_args source;
/* Miscellaneous arguments */
unsigned nthreads; /* Hint on the nimber of threads to use */
@@ -79,8 +89,8 @@ struct htrdr_planeto_args {
10, /* Optical thickness criteria */ \
\
NULL, /* Ouput file */ \
- \
HTRDR_ARGS_SPECTRAL_DEFAULT__, /* Spectral domain */ \
+ HTRDR_PLANETO_SOURCE_ARGS_NULL__, /* Source */ \
\
UINT_MAX, /* Number of threads */ \
HTRDR_PLANETO_ARGS_OUTPUT_TYPES_COUNT__, \