commit 6bcdc78bd3d4a622aadb501e95808c34c3659493
parent 90e3f632604097d50432ae0ed1d03ea212cdf9ba
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 6 Nov 2015 15:58:52 +0100
Update the super shape distribution
Only the M and N2 parameters are uniformaly distributed. This
drastically simplify the CLI interface.
Diffstat:
3 files changed, 78 insertions(+), 129 deletions(-)
diff --git a/src/schiff_args.c b/src/schiff_args.c
@@ -49,18 +49,19 @@ print_help(const char* binary)
{
printf(
"Usage: %s [OPTIONS] [FILE]\n"
-"Estimate the radiative properties of micro organisms with an \"Approximation\n"
+"Estimate the radiative properties of micro organisms with an \"Approximation\n"
"Method for Short Wavelength or High Energy Scattering\" (L. Schiff, 1956).\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\n"
-"vacuum 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 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"
"of the medium. With no FILE, read optical properties from standard input.\n\n");
+
printf(
-" -c R:S:A[:N] the micro organisms are cylindrical meshes discretized in N\n"
-" slices. By default N is %u. The radius `r' and the height `h'\n"
+" -c R:S:A[:N] the micro organisms are cylindrical meshes discretized in N\n"
+" slices. By default N is %u. The radius `r' and the height `h'\n"
" of the cylinders are distributed as follow:\n"
" y = 1/(ln(S)*x*sqrt(2PI)) * exp(-(ln(x)-ln(R))^2 / (2*ln(S)^2))\n"
" r = y / (3 / (2*A))^1/3\n"
@@ -70,28 +71,36 @@ print_help(const char* binary)
" -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"
+" -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 to\n"
-" OUTPUT or stdout whether the `-o' option is defined or not,\n"
-" respectively. The outputted data followed the Alias Wavefront\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 stdout whether the `-o' option is defined or not,\n"
+" respectively. The outputted data followed the Alias Wavefront\n"
" 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"
" stdout.\n");
printf(
-" -s R:S[:N] the micro organisms are spherical meshes discretized in N\n"
-" slices along 2PI. By default N is %u. Their radius `r' is\n"
+" -s R:S[:N] the micro organisms are spherical meshes discretized in N\n"
+" slices along 2PI. By default N is %u. Their radius `r' is\n"
" distributed with respect to a lognormal distribution:\n"
" r = 1/(ln(S)*x*sqrt(2PI)) * exp(-(ln(x)-ln(R))^2 / (2*ln(S)^2))\n",
SCHIFF_SPHERE_DEFAULT.nslices);
printf(
-" -w A[:B]... list of wavelengths in vacuum (expressed in micron) to\n"
+" -u M_min:M_max:N2_min:N2_max[:N]\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 their M and N2\n"
+" variables are uniformally distributed in [M_min, M_max] and\n"
+" [N2_min, N2_max], respectively.\n",
+ SCHIFF_SUPER_SHAPE_DEFAULT.nslices);
+ printf(
+" -w A[:B]... list of wavelengths in vacuum (expressed in micron) to\n"
" integrate.\n");
}
@@ -188,119 +197,51 @@ error:
}
static res_T
-parse_super_shape(const char* str, double formulas[2][6])
-{
- struct darray_char tmp;
- char* tk;
- char* tk_ctx;
- size_t len;
- res_T res = RES_OK;
- ASSERT(str && formulas);
-
- darray_char_init(&mem_default_allocator, &tmp);
-
- /* Locallly copy the input string */
- res = darray_char_resize(&tmp, strlen(str) + 1 /*NULL char*/);
- if(res != RES_OK) goto error;
- strcpy(darray_char_data_get(&tmp), str);
-
- tk = strtok_r(darray_char_data_get(&tmp), ",", &tk_ctx);
- if(!tk) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- res = cstr_to_list_double(tk, formulas[0], &len, 6);
- if(res != RES_OK) goto error;
- if(len != 6) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- tk = strtok_r(NULL, ",", &tk_ctx);
- if(!tk) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- res = cstr_to_list_double(tk, formulas[1], &len, 6);
- if(res != RES_OK) goto error;
- if(len != 6) {
- res = RES_BAD_ARG;
- goto error;
- }
-
-exit:
- darray_char_release(&tmp);
- return res;
-error:
- goto exit;
-}
-
-static res_T
parse_super_shape_distribution(const char* str, struct schiff_args* args)
{
- struct darray_char tmp;
- struct schiff_super_shape* sshape;
- char* tk;
- char* tk_ctx;
- size_t str_len;
- int i;
+ double list[5];
+ size_t len;
+ unsigned nslices;
res_T res = RES_OK;
+ ASSERT(args && str);
- darray_char_init(&mem_default_allocator, &tmp);
-
+ /* The distribution was already set to a non super_shape distribution. */
if(args->geom.type != SCHIFF_NONE && args->geom.type != SCHIFF_SUPER_SHAPE) {
res = RES_BAD_ARG;
goto error;
- }
- /* Locallly copy the input string */
- str_len = strlen(str);
- res = darray_char_resize(&tmp, str_len + 1 /*NULL char*/);
- if(res != RES_OK) goto error;
- strcpy(darray_char_data_get(&tmp), str);
+ }
+ res = cstr_to_list_double(str, list, &len, 5);
+ if(res != RES_OK) goto error; /* Wrong argument formating */
- /* Parse "lower" super shape */
- tk = strtok_r(darray_char_data_get(&tmp), "#", &tk_ctx);
- if(!tk) {
+ if(len < 4) {/* At least the bounds of the M and N2 params must be provided */
res = RES_BAD_ARG;
goto error;
}
- res = parse_super_shape(tk, args->geom.data.super_shape.lower);
- if(res != RES_OK) goto error;
-
- /* Parse "upper" super shape */
- tk = strtok_r(NULL, "#", &tk_ctx);
- if(!tk) {
+ if(list[0] > list[1] || list[2] > list[3]) {
res = RES_BAD_ARG;
goto error;
}
- res = parse_super_shape(tk, args->geom.data.super_shape.upper);
- if(res != RES_OK) goto error;
- /* Parse the optionnal "nslices" attrib */
- tk = strtok_r(NULL, "#", &tk_ctx);
- if(!tk) {
- args->geom.data.super_shape.nslices = SCHIFF_SUPER_SHAPE_DEFAULT.nslices;
+ if(len == 4) {
+ nslices = SCHIFF_SPHERE_DEFAULT.nslices;
} else {
- res = cstr_to_uint(tk, &args->geom.data.super_shape.nslices);
- if(res != RES_OK) goto error;
- }
-
- args->geom.type = SCHIFF_SUPER_SHAPE;
-
- sshape = &args->geom.data.super_shape;
- FOR_EACH(i, 0, 6) {
- if(sshape->lower[0][i] > sshape->upper[0][i]
- || sshape->lower[1][i] > sshape->upper[1][i]) {
+ nslices = (unsigned)list[4];
+ if((double)nslices != list[4]) { /* The #slices arg is not an integer */
res = RES_BAD_ARG;
goto error;
}
}
+ /* Update the distribution */
+ args->geom.type = SCHIFF_SUPER_SHAPE;
+ args->geom.data.super_shape.lower_M = list[0];
+ args->geom.data.super_shape.upper_M = list[1];
+ args->geom.data.super_shape.lower_N2 = list[2];
+ args->geom.data.super_shape.upper_N2 = list[3];
+ args->geom.data.super_shape.nslices = nslices;
+
exit:
- darray_char_release(&tmp);
return res;
error:
goto exit;
diff --git a/src/schiff_geometry.c b/src/schiff_geometry.c
@@ -65,8 +65,10 @@ struct cylinder_distribution_context {
/* Distribtion context of a super shape geometry */
struct super_shape_distribution_context {
- double lower[2][6];
- double upper[2][6];
+ double lower_M;
+ double upper_M;
+ double lower_N2;
+ double upper_N2;
};
/* 3D context of a generic geometry */
@@ -252,7 +254,6 @@ geometry_sample_super_shape
struct s3d_vertex_data attrib;
const struct super_shape_distribution_context* sshape;
size_t nverts, nprims;
- int i;
ASSERT(rng && mtl && shape && context);
ASSERT(distrib->type == SCHIFF_SUPER_SHAPE);
@@ -260,12 +261,24 @@ geometry_sample_super_shape
geom.mesh = distrib->mesh;
geom.type = SCHIFF_SUPER_SHAPE;
- FOR_EACH(i, 0, 6) {
- geom.data.super_shape.formulas[0][i] = (float)
- ssp_rng_uniform_double(rng, sshape->lower[0][i], sshape->upper[0][i]);
- geom.data.super_shape.formulas[1][i] = (float)
- ssp_rng_uniform_double(rng, sshape->lower[1][i], sshape->upper[1][i]);
- }
+ geom.data.super_shape.formulas[0][A] = 1.0;
+ geom.data.super_shape.formulas[0][B] = 1.0;
+ geom.data.super_shape.formulas[0][N0] = 1.0;
+ geom.data.super_shape.formulas[0][N1] = 1.0;
+
+ geom.data.super_shape.formulas[1][A] = 1.0;
+ geom.data.super_shape.formulas[1][B] = 1.0;
+ geom.data.super_shape.formulas[1][N0] = 1.0;
+ geom.data.super_shape.formulas[1][N1] = 1.0;
+
+ geom.data.super_shape.formulas[0][M] = (float)
+ ssp_rng_uniform_double(rng, sshape->lower_M, sshape->upper_M);
+ geom.data.super_shape.formulas[1][M] = (float)
+ ssp_rng_uniform_double(rng, sshape->lower_M, sshape->upper_M);
+ geom.data.super_shape.formulas[0][N2] = (float)
+ ssp_rng_uniform_double(rng, sshape->lower_M, sshape->upper_N2);
+ geom.data.super_shape.formulas[1][N2] = (float)
+ ssp_rng_uniform_double(rng, sshape->lower_M, sshape->upper_N2);
attrib.usage = S3D_POSITION;
attrib.type = S3D_FLOAT3;
@@ -291,7 +304,6 @@ schiff_geometry_distribution_init
struct schiff_optical_properties* properties)
{
struct geometry_distribution_context* ctx = NULL;
- int i;
res_T res = RES_OK;
ASSERT(distrib && geom);
@@ -330,12 +342,10 @@ schiff_geometry_distribution_init
case SCHIFF_SUPER_SHAPE:
res = schiff_mesh_init_sphere_polar
(&mem_default_allocator, ctx->mesh, geom->data.super_shape.nslices);
- FOR_EACH(i, 0, 6) {
- ctx->data.super_shape.lower[0][i] = geom->data.super_shape.lower[0][i];
- ctx->data.super_shape.lower[1][i] = geom->data.super_shape.lower[1][i];
- ctx->data.super_shape.upper[0][i] = geom->data.super_shape.upper[0][i];
- ctx->data.super_shape.upper[1][i] = geom->data.super_shape.upper[1][i];
- }
+ ctx->data.super_shape.lower_M = geom->data.super_shape.lower_M;
+ ctx->data.super_shape.upper_M = geom->data.super_shape.upper_M;
+ ctx->data.super_shape.lower_N2 = geom->data.super_shape.lower_N2;
+ ctx->data.super_shape.upper_N2 = geom->data.super_shape.upper_N2;
distrib->sample = geometry_sample_super_shape;
break;
default: FATAL("Unreachable code.\n"); break;
diff --git a/src/schiff_geometry.h b/src/schiff_geometry.h
@@ -61,16 +61,14 @@ static const struct schiff_cylinder SCHIFF_CYLINDER_DEFAULT =
enum schiff_super_formula { A, B, M, N0, N1, N2 };
struct schiff_super_shape {
- double lower[2][6]; /* Lower bound of the formula params */
- double upper[2][6]; /* Upper bound of the formula params */
+ double lower_M;
+ double upper_M;
+ double lower_N2;
+ double upper_N2;
unsigned nslices;
};
+#define SCHIFF_SUPER_SHAPE_DEFAULT__ {1.0, 9.0, 1.0, 9.0, 64}
-#define SCHIFF_SUPER_SHAPE_DEFAULT__ { \
- {{ 1, 1, 2, 1, 1, 1 }, { 1, 1, 5, 1, 1, 3 }}, \
- {{ 1, 1, 7, 1, 1, 2 }, { 1, 1, 7, 1, 1, 7 }}, \
- 64 \
-}
static const struct schiff_super_shape SCHIFF_SUPER_SHAPE_DEFAULT =
SCHIFF_SUPER_SHAPE_DEFAULT__;