schiff

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

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:
Msrc/schiff_args.c | 153++++++++++++++++++++++++-------------------------------------------------------
Msrc/schiff_geometry.c | 42++++++++++++++++++++++++++----------------
Msrc/schiff_geometry.h | 12+++++-------
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__;