schiff

Estimate the radiative properties of soft particless
git clone git://git.meso-star.com/schiff.git
Log | Files | Refs | README | LICENSE

commit 2e58e37060b0623813c7e6242ecddf1393e4ff8b
parent 690b15153d71fbdb34ceb436df39563ab749506a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 29 Oct 2015 12:06:38 +0100

Refactor the parsing of the command line arguments

Refactor the parsing of the -w and -s options.

Diffstat:
Msrc/schiff_args.c | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/schiff_args.h | 30+++++++++++++++++++++++++++---
Msrc/schiff_sphere.c | 12+++++++-----
3 files changed, 118 insertions(+), 48 deletions(-)

diff --git a/src/schiff_args.c b/src/schiff_args.c @@ -54,7 +54,7 @@ print_help(const char* binary) printf( "FILE lists the per wavelength optical properties of the micro organisms.\n" "Each line must be formatted as \"W Nr Kr Ne\" where \"W\" is the wavelength\n" -"in meter, \"Nr\" and \"Kr\" are the real and imaginary parts, respectively, of\n" +"in micron, \"Nr\" and \"Kr\" are the real and imaginary parts, respectively, of\n" "the relative refractive index, and \"Ne\" the refractive index of the medium.\n" "With no FILE, read optical properties from standard input.\n\n"); printf( @@ -68,17 +68,95 @@ print_help(const char* binary) " -o OUTPUT write results to OUTPUT. If not defined, write results to\n" " stdout.\n"); printf( -" -s R:S[:N] the micro organisms are spherical meshes discretised in N\n" +" -s R:S[:N] the micro organisms are spherical meshes discretized in N\n" " slices along 2PI. Their radius is distributed with respect to a\n" " lognormal distribution:\n" " 1/(ln(S)*x*sqrt(2PI)) * exp(-(ln(x)-ln(R))^2 / (2*ln(S)^2))\n" " By default N is %u.\n", - SCHIFF_DISTRIBUTION_SPHERE_DEFAULT.nthetas); + SCHIFF_DISTRIBUTION_SPHERE_DEFAULT.nslices); printf( -" -w A[:B]... list of wavelengths to integrate in meter. At least one\n" +" -w A[:B]... list of wavelengths (in micron) to integrate. At least one\n" " wavelength must be provided.\n"); } +static res_T +parse_sphere_distribution(const char* str, struct schiff_args* args) +{ + double list[3]; + size_t len; + unsigned nslices; + res_T res = RES_OK; + ASSERT(args && str); + + /* The distribution was already set to a non sphere distribution. */ + if(args->distrib_type != SCHIFF_NONE && args->distrib_type != SCHIFF_SPHERE) { + res = RES_BAD_ARG; + goto error; + + } + res = cstr_to_list_double(str, list, &len, 3); + if(res != RES_OK) goto error; /* Wrong argument formating */ + + if(len < 2) {/* At least the radius and the sigma argument must be provided */ + res = RES_BAD_ARG; + goto error; + } + + if(len == 2) { + nslices = SCHIFF_DISTRIBUTION_SPHERE_DEFAULT.nslices; + } else { + nslices = (unsigned)list[2]; + if((double)nslices != list[2]) { /* The #slices arg is not an integer */ + res = RES_BAD_ARG; + goto error; + } + } + + /* Update the distribution */ + args->distrib_type = SCHIFF_SPHERE; + args->distrib.sphere.radius = list[0]; + args->distrib.sphere.sigma = list[1]; + args->distrib.sphere.nslices = nslices; + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_wavelengths(const char* str, struct schiff_args* args) +{ + size_t len; + size_t i; + res_T res = RES_OK; + ASSERT(args && str); + + /* How many wavelengths are submitted */ + res = cstr_to_list_double(str, NULL, &len, 0); + if(res != RES_OK) goto error; + + /* Reserve the wavelengths memory space */ + sa_clear(args->wavelengths); + args->wavelengths = sa_add(args->wavelengths, len); + + /* Read the wavelengths */ + res = cstr_to_list_double(optarg, args->wavelengths, NULL, len); + if(res != RES_OK) goto error; + + /* Check the validity of read wavelengths */ + FOR_EACH(i, 0, len) { + if(args->wavelengths[i] < 0.0) { + res = RES_BAD_ARG; + goto error; + } + } +exit: + return res; +error: + goto exit; +} + static int cmp_properties(const void* op0, const void* op1) { @@ -96,8 +174,6 @@ schiff_args_init const int argc, char** argv) { - size_t len; - double list[3]; int opt; res_T res = RES_OK; ASSERT(argc && argv && args); @@ -113,40 +189,8 @@ schiff_args_init schiff_args_release(args); return RES_OK; case 'o': args->output_filename = optarg; break; - case 's': - res = cstr_to_list_double(optarg, list, &len, 3); - if(res == RES_OK) { - if(len < 2) { - res = RES_BAD_ARG; - } else { - args->distribution.sphere = SCHIFF_DISTRIBUTION_SPHERE_DEFAULT; - args->distribution.sphere.radius = list[0]; - args->distribution.sphere.sigma = list[1]; - if(len > 2) { - args->distribution.sphere.nthetas = (unsigned)list[2]; - if((double)args->distribution.sphere.nthetas != list[2]) - res = RES_BAD_ARG; - } - } - } - break; - case 'w': - sa_clear(args->wavelengths); - res = cstr_to_list_double(optarg, NULL, &len, 0); - if(res == RES_OK) { - args->wavelengths = sa_add(args->wavelengths, len); - res = cstr_to_list_double(optarg, args->wavelengths, NULL, len); - if(res == RES_OK) { - size_t i; - FOR_EACH(i, 0, len) { - if(args->wavelengths[i] < 0.0) { - res = RES_BAD_ARG; - break; - } - } - } - } - break; + case 's': res = parse_sphere_distribution(optarg, args); break; + case 'w': res = parse_wavelengths(optarg, args); break; default: res = RES_BAD_ARG; break; } if(res != RES_OK) { diff --git a/src/schiff_args.h b/src/schiff_args.h @@ -31,17 +31,39 @@ #include <rsys/rsys.h> +/* List of supported distribution */ +enum schiff_distribution_type { + SCHIFF_CYLINDER, + SCHIFF_SPHERE, + SCHIFF_NONE +}; + +/* Sphere distribution */ struct schiff_distribution_sphere { double radius; double sigma; - unsigned nthetas; + unsigned nslices; }; + #define SCHIFF_DISTRIBUTION_SPHERE_DEFAULT__ {1.0, 1.0, 64} static const struct schiff_distribution_sphere SCHIFF_DISTRIBUTION_SPHERE_DEFAULT = SCHIFF_DISTRIBUTION_SPHERE_DEFAULT__; +/* Cylinder distribution */ +struct schiff_distribution_cylinder { + double radius; + double aspect_ratio; + unsigned nslices; +}; + +#define SCHIFF_DISTRIBUTION_CYLINDER_DEFAULT__ {1.0, 1.0, 64} +static const struct schiff_distribution_cylinder +SCHIFF_DISTRIBUTION_CYLINDER_DEFAULT = SCHIFF_DISTRIBUTION_SPHERE_DEFAULT__; + +/* Generic distribution */ union schiff_distribution { struct schiff_distribution_sphere sphere; + struct schiff_distribution_cylinder cylinder; }; #define SCHIFF_DISTRIBUTION_DEFAULT__ {SCHIFF_DISTRIBUTION_SPHERE_DEFAULT__} @@ -50,7 +72,8 @@ struct schiff_args { const char* output_filename; struct schiff_optical_properties* properties; double* wavelengths; - union schiff_distribution distribution; + enum schiff_distribution_type distrib_type; + union schiff_distribution distrib; unsigned ngeoms; unsigned ndirs; }; @@ -59,7 +82,8 @@ static const struct schiff_args SCHIFF_ARGS_NULL = { NULL, /* Output filename */ NULL, /* List of optical properties */ NULL, /* List of wavelength to integrate */ - SCHIFF_DISTRIBUTION_DEFAULT__, + SCHIFF_NONE, + { SCHIFF_DISTRIBUTION_SPHERE_DEFAULT__ }, 1000, /* # Sampled geometries */ 100, /* # Sampled directions per gemetry */ }; diff --git a/src/schiff_sphere.c b/src/schiff_sphere.c @@ -153,8 +153,10 @@ schiff_sphere_sample_geometry /******************************************************************************* * Local functions ******************************************************************************/ + res_T -schiff_run_sphere(const struct schiff_args* args) +schiff_run_sphere + (const struct schiff_args* args) { FILE* fp = stdout; struct sschiff_geometry_distribution distrib = SSCHIFF_NULL_GEOMETRY_DISTRIBUTION; @@ -180,11 +182,11 @@ schiff_run_sphere(const struct schiff_args* args) /* Generate the spherical mesh */ res = schiff_mesh_init_sphere - (&mem_default_allocator, &mesh, args->distribution.sphere.nthetas); + (&mem_default_allocator, &mesh, args->distrib.sphere.nslices); if(res != RES_OK) { fprintf(stderr, "Couldn't create the sphere mesh discretised in %u steps along 2PI\n", - args->distribution.sphere.nthetas); + args->distrib.sphere.nslices); goto error; } @@ -204,8 +206,8 @@ schiff_run_sphere(const struct schiff_args* args) /* Setup the geometry distribution context */ ctx.mesh = &mesh; ctx.properties = args->properties; - ctx.log_mean_radius = log(args->distribution.sphere.radius); - ctx.log_sigma = log(args->distribution.sphere.sigma); + ctx.log_mean_radius = log(args->distrib.sphere.radius); + ctx.log_sigma = log(args->distrib.sphere.sigma); /* Setup the geometry distribution */ distrib.sample = schiff_sphere_sample_geometry;