commit ac25ce9e4c2a482bad8eec78acd616263d27490f
parent 4e2d6a0d2e499884a3fb25d97afd8fa85def6282
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 20 Nov 2015 14:25:53 +0100
Add the "cylinder as sphere" distribution
Cylinders have a constant aspect ratio and their size is defined by a
sphere whose radius is controlled by a user defined distribution.
Improve the command documentation: document the parameter distribution
and add examples.
Diffstat:
2 files changed, 152 insertions(+), 37 deletions(-)
diff --git a/src/schiff_args.c b/src/schiff_args.c
@@ -50,67 +50,119 @@ print_help(const char* binary)
{
printf(
"Usage: %s [OPTIONS] [FILE]\n"
-"Estimate the radiative properties of soft particles with an \"Approximation\n"
-"Method for Short Wavelength or High Energy Scattering\" (L. Schiff, 1956).\n"
+"Estimate the radiative properties of soft particles with an \"Approximation\n"
+"Method for Short Wavelength or High Energy Scattering\" (L. Schiff, 1956).\n"
"Assume a small contrast on the relative refractive index of the particles.\n\n",
binary);
printf(
-"FILE lists the per wavelength optical properties of the micro organisms. Each\n"
-"line must be formatted as \"W Nr Kr Ne\" where \"W\" is the wavelength in vacuum\n"
-"expressed in micron, \"Nr\" and \"Kr\" are the real and imaginary parts,\n"
-"respectively, of the relative refractive index, and \"Ne\" the refractive index\n"
+"FILE lists the per wavelength optical properties of the soft particles. Each\n"
+"line must be formatted as \"W Nr Kr Ne\" where \"W\" is the wavelength in vacuum\n"
+"expressed in micron, \"Nr\" and \"Kr\" are the real and imaginary parts,\n"
+"respectively, of the relative refractive index, and \"Ne\" the refractive index\n"
"of the medium. With no FILE, read optical properties from standard input.\n\n");
printf(
-"The estimated results are written to OUTPUT or to standard output whether the\n"
-"\"-o\" option is defined or not, respectively. ");
-printf(
-"The line format of the outputed\n"
-"results is \"W E E' A A' S S' P P'\" with \"W\" the wavelength in vacuum (expressed\n"
-"in micron), \"E\", \"A\" and \"S\" the estimation of the extinction, absorption and\n"
-"scattering cross section, respectively, and \"P\" the estimated average projected\n"
-"area. The \"E'\", \"A'\", \"S'\" and \"P'\" values are the standard error of the\n"
+"The estimated results are written to OUTPUT or to standard output whether the\n"
+"\"-o\" option is defined or not, respectively. The line format of the outputed\n"
+"results is \"W E E' A A' S S' P P'\" with \"W\" the wavelength in vacuum (expressed\n"
+"in micron), \"E\", \"A\" and \"S\" the estimation of the extinction, absorption and\n"
+"scattering cross section, respectively, and \"P\" the estimated average projected\n"
+"area. The \"E'\", \"A'\", \"S'\" and \"P'\" values are the standard error of the\n"
"aforementioned estimations.\n\n");
printf(
-" -c RADIUS,HEIGHT[,N]\n"
-" the micro organisms are cylindrical meshes discretized in N\n"
-" slices. By default N is %u. RADIUS and HEIGHT are the\n"
-" distributions of, respectively, the radius and the height\n"
+"The shapes of the soft particles are controlled by a geometric distribution\n"
+"whose parameters are distributed according to an user defined distribution. The\n"
+"available distributions of the parameters and the syntax to control them are\n"
+"described below:\n\n");
+ printf(
+" c=VAL parameter is the constant VAL.\n");
+ printf(
+" h=HISTOGRAM parameter follows the distribution whose the normalized\n"
+" histogram is described by the HISTOGRAM file. Each line of the\n"
+" HISTOGRAM file must be formatted as \"VAL PROBA\", where PROBA is\n"
+" the probability of the VAL value.\n");
+ printf(
+" l=ZETA:SIGMA parameter is distributed with respect to the lognormal\n"
+" distribution:\n"
+" P(x) dx = 1/(log(SIGMA)*x*sqrt(2*PI))\n"
+" * exp(-(ln(x)-log(ZETA))^2 / (2*log(SIGMA)^2)) dx\n\n");
+ printf(
+"Options:\n\n");
+ printf(
+" -c RDISTRIB,HDISTRIB[,N]\n"
+" the soft particles are cylindrical meshes discretized in N\n"
+" slices. By default N is %u. RDISTRIB and HDISTRIB ar the\n"
+" distributions of, respectively, the radius and the height\n"
" parameters of the cylinder.\n",
SCHIFF_CYLINDER_DEFAULT.nslices);
printf(
+" -C ASPECT_RATIO,RDISTRIB[,N]\n"
+" the soft particles are cylindrical meshes discretized in N\n"
+" slices. By default N is %u. The ratio between their height\n"
+" and their radius is fixed by the ASPECT_RATIO floating point\n"
+" parameter. Their volume is defined according to the volume of\n"
+" a sphere whose radius is distributed with respect to the\n"
+" RDISTRIB distribution.\n",
+ SCHIFF_CYLINDER_DEFAULT.nslices);
+ printf(
" -d DIRS number of sampled directions for each geometry. Default is %u.\n",
SCHIFF_ARGS_NULL.ndirs);
printf(
-" -g GOEMS number of sampled geometries. This is actually the number of\n"
-" realisations. Default is %u.\n",
+" -g GOEMS number of sampled geometries. This is actually the number of\n"
+" realisations. Default is %u.\n",
SCHIFF_ARGS_NULL.ngeoms);
printf(
-" -G NUM sampled `NUM' geometries with respect to the defined\n"
-" distribution, dump their data and exit. The data are written\n"
-" to OUTPUT or the standard output whether the `-o' option is\n"
-" defined or not, respectively. The outputted data followed the\n"
+" -G NUM sampled `NUM' geometries with respect to the defined\n"
+" distribution, dump their data and exit. The data are written\n"
+" to OUTPUT or the standard output whether the `-o' option is\n"
+" defined or not, respectively. The outputted data followed the\n"
" Alias Wavefront obj file format.\n");
printf(
" -h display this help and exit.\n");
printf(
-" -o OUTPUT write results to OUTPUT. If not defined, write results to\n"
+" -o OUTPUT write results to OUTPUT. If not defined, write results to\n"
" standard output.\n");
printf(
" -q do not print the helper message when no FILE is submitted.\n");
printf(
-" -s RADIUS[,N] the micro organisms are spherical meshes discretized in N\n"
-" slices along 2PI. By default N is %u. Their radius parameter\n"
-" is distributed with respect to the distribution RADIUS.\n",
+" -s RDISTRIB[,N]\n"
+" the soft particles are spherical meshes discretized in N slices\n"
+" along 2PI. By default N is %u. Their radius parameter is\n"
+" distributed with respect to the RDISTRIB distribution.\n",
SCHIFF_SPHERE_DEFAULT.nslices);
printf(
-" -u M,N2[,N] the micro organisms are 3D super shapes discretized in N slices\n"
-" along 2PI. By default N is %u. The A, B, N0 and N1 parameters\n"
-" of the super formulas are fixed to 1 while the M and N2 control\n"
-" de distribution of the remaining parameters.",
+" -u MDISTRIB,N2DISTRIB[,N]\n"
+" the soft particles are 3D super shapes discretized in N slices\n"
+" along 2PI. By default N is %u. The A, B, N0 and N1 parameters\n"
+" of the super formulas are fixed to 1 while the MDISTRIBG and\n"
+" the N2DISTRIB control de distribution of the M, and N2\n"
+" supershape parameters, respectively.\n",
SCHIFF_SUPER_SHAPE_DEFAULT.nslices);
printf(
-" -w A[:B]... list of wavelengths in vacuum (expressed in micron) to\n"
-" integrate.\n");
+" -w A[:B]... list of wavelengths in vacuum (expressed in micron) to\n"
+" integrate.\n\n");
+ printf(
+"Examples:\n\n");
+ printf(
+" Spheric soft particles whose radius is distributed according to a lognormal\n"
+" distribution and their optical properties are defined in the \"optical_props\"\n"
+" file. The estimation is evaluated for the wavelength 0.6 micron:\n"
+" %s -s l=1:1.18 -w 0.6 optical_props\n\n",
+ binary);
+ printf(
+" Soft particles are cylinders discretized in 128 slices. Their radius is a\n"
+" constant and their height follows the distribution described in the \"histo\"\n"
+" file. Optical properties are read from standard input. Estimation is\n"
+" performed for the wavelengths 0.5, 0.6 and 0.65 micron:\n"
+" %s -c c=4.1e-3,h=hist,128 -w 0.5:0.6:0.65\n\n",
+ binary);
+ printf(
+" Cylindrical soft particles whith a fixed aspect ratio of 1.33. Their volume\n"
+" is defined with respect to a sphere whose radius is distributed according to\n"
+" a lognormal distribution. Optical properties are read from standard input.\n"
+" The estimation is evaluated for the wavelength 0.6 micron and is stored in\n"
+" the \"output\" file:\n"
+" %s -C 1.33,l=1.2:1.834 -w 0.6 -o output\n",
+ binary);
}
static res_T
@@ -195,16 +247,19 @@ parse_cylinder_distribution(const char* str, struct schiff_args* args)
goto error;
}
+ /* Distribution of the cylinder radius */
tk = strtok_r(str_get(&buf), ",", &tk_ctx);
res = parse_param_distribution(tk, &args->geom.data.cylinder.radius);
if(res != RES_OK) goto error;
+ /* Distribution of the cylinder height */
tk = strtok_r(NULL, ",", &tk_ctx);
res = parse_param_distribution(tk, &args->geom.data.cylinder.height);
if(res != RES_OK) goto error;
+ /* Cylinder discretisation */
tk = strtok_r(NULL, "\0", &tk_ctx);
- if(tk) {
+ if(!tk) {
args->geom.data.cylinder.nslices = SCHIFF_CYLINDER_DEFAULT.nslices;
} else {
res = cstr_to_uint(tk, &args->geom.data.cylinder.nslices);
@@ -220,6 +275,59 @@ error:
}
static res_T
+parse_cylinder_as_sphere_distribution(const char* str, struct schiff_args* args)
+{
+ struct str buf;
+ char* tk;
+ char* tk_ctx;
+ res_T res = RES_OK;
+ ASSERT(args && str);
+
+ str_init(&mem_default_allocator, &buf);
+
+ /* The distribution was already set to a non sphere distribution. */
+ if(args->geom.type != SCHIFF_NONE && args->geom.type != SCHIFF_CYLINDER) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = str_set(&buf, str);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Not enough memory. Couldn't parse the cylinder distribution `%s'.\n",
+ str);
+ goto error;
+ }
+
+ /* Cylinder aspect ratio */
+ tk = strtok_r(str_get(&buf), ",", &tk_ctx);
+ res = cstr_to_double(tk, &args->geom.data.cylinder.aspect_ratio);
+ if(res != RES_OK) goto error;
+
+ /* Distribution of the radius of the equivalent sphere */
+ tk = strtok_r(NULL, ",", &tk_ctx);
+ res = parse_param_distribution(tk, &args->geom.data.cylinder.radius);
+ if(res != RES_OK) goto error;
+
+ /* Cylinder discretisation */
+ tk = strtok_r(NULL, "\0", &tk_ctx);
+ if(!tk) {
+ args->geom.data.cylinder.nslices = SCHIFF_CYLINDER_DEFAULT.nslices;
+ } else {
+ res = cstr_to_uint(tk, &args->geom.data.cylinder.nslices);
+ if(res != RES_OK) goto error;
+ }
+ args->geom.type = SCHIFF_CYLINDER_AS_SPHERE;
+
+exit:
+ str_release(&buf);
+ return res;
+error:
+ goto exit;
+}
+
+
+static res_T
parse_sphere_distribution(const char* str, struct schiff_args* args)
{
struct str buf;
@@ -244,10 +352,12 @@ parse_sphere_distribution(const char* str, struct schiff_args* args)
goto error;
}
+ /* Distribution of the sphere radius */
tk = strtok_r(str_get(&buf), ",", &tk_ctx);
res = parse_param_distribution(tk, &args->geom.data.sphere.radius);
if(res != RES_OK) goto error;
+ /* Sphere discretisation */
tk = strtok_r(NULL, "\0", &tk_ctx);
if(!tk) {
args->geom.data.sphere.nslices = SCHIFF_SPHERE_DEFAULT.nslices;
@@ -289,16 +399,19 @@ parse_super_shape_distribution(const char* str, struct schiff_args* args)
goto error;
}
+ /* Distribution of the M parameters */
tk = strtok_r(str_get(&buf), ",", &tk_ctx);
res = parse_param_distribution(tk, &args->geom.data.super_shape.M);
if(res != RES_OK) goto error;
+ /* Distribution of N2 parameters */
tk = strtok_r(NULL, ",", &tk_ctx);
res = parse_param_distribution(tk, &args->geom.data.super_shape.N2);
if(res != RES_OK) goto error;
+ /* Super shape discretisation */
tk = strtok_r(NULL, "\0", &tk_ctx);
- if(tk) {
+ if(!tk) {
args->geom.data.super_shape.nslices = SCHIFF_SUPER_SHAPE_DEFAULT.nslices;
} else {
res = cstr_to_uint(tk, &args->geom.data.super_shape.nslices);
@@ -361,9 +474,10 @@ schiff_args_init
ASSERT(argc && argv && args);
*args = SCHIFF_ARGS_NULL;
- while((opt = getopt(argc, argv, "c:d:g:G:ho:qs:u:w:")) != -1) {
+ while((opt = getopt(argc, argv, "c:C:d:g:G:ho:qs:u:w:")) != -1) {
switch(opt) {
case 'c': res = parse_cylinder_distribution(optarg, args); break;
+ case 'C': res = parse_cylinder_as_sphere_distribution(optarg, args); break;
case 'd': res = cstr_to_uint(optarg, &args->ndirs); break;
case 'g': res = cstr_to_uint(optarg, &args->ngeoms); break;
case 'G': res = cstr_to_uint(optarg, &args->ngeoms_dump); break;
diff --git a/src/schiff_histogram.c b/src/schiff_histogram.c
@@ -76,6 +76,7 @@ parse_schiff_hentry
if(tk) {
fprintf(stderr, "%s:%lu: wrong histogram entry `%s'.\n",
filename, (unsigned long)iline, str);
+ return RES_BAD_ARG;
}
entry->value = tmp[0];
entry->cdf = tmp[1];