schiff

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

commit a2d8927486f97b3a6c9cba491701776c18b7e47a
parent 4c97784d48b341ca409e1c12892b4b8b742daa5f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 14 Mar 2016 14:31:27 +0100

Improve the geometry distribution YAML file format

A single YAML mapping node can be used to declare a single geometry
distribution.

Diffstat:
Msrc/schiff_args.c | 114++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 72 insertions(+), 42 deletions(-)

diff --git a/src/schiff_args.c b/src/schiff_args.c @@ -721,6 +721,42 @@ parse_yaml_sphere } static res_T +parse_yaml_geom_distrib + (const char* filename, + yaml_document_t* doc, + yaml_node_t* node, + struct schiff_geometry* geom, + double* proba) +{ + res_T res; + yaml_node_t *key, *val; + ASSERT(filename && doc && node && geom && proba); + + if(node->type != YAML_MAPPING_NODE + || node->data.mapping.pairs.top - node->data.mapping.pairs.start > 1) { + log_err(filename, node, + "expecting a mapping of the geometry distribution to its parameters\n"); + return RES_BAD_ARG; + } + + key = yaml_document_get_node(doc, node->data.mapping.pairs.start[0].key); + val = yaml_document_get_node(doc, node->data.mapping.pairs.start[0].value); + ASSERT(key->type == YAML_SCALAR_NODE); + + if(!strcmp((char*)key->data.scalar.value, "cylinder")) { + res = parse_yaml_cylinder(filename, doc, val, geom, proba); + } else if(!strcmp((char*)key->data.scalar.value, "sphere")) { + res = parse_yaml_sphere(filename, doc, val, geom, proba); + } else { + log_err(filename, key, "unknown distribution `%s'.\n", + key->data.scalar.value); + return RES_BAD_ARG; + } + if(res != RES_OK) return res; + return RES_OK; +} + +static res_T parse_yaml (const char* filename, struct schiff_geometry** out_geoms, @@ -733,9 +769,9 @@ parse_yaml size_t idistrib; struct schiff_geometry* geoms = NULL; double* probas = NULL; - double accum_proba = 0; struct ssp_ran_discrete* ran = NULL; FILE* file = NULL; + int doc_is_init = 0; res_T res = RES_OK; ASSERT(filename && out_geoms && out_ran); @@ -763,18 +799,26 @@ parse_yaml res = RES_IO_ERR; goto error; } + doc_is_init = 1; root = yaml_document_get_root_node(&doc); - if(root->type != YAML_SEQUENCE_NODE) { - fprintf(stderr, "Expecting YAML sequence.\n"); + if(root->type == YAML_MAPPING_NODE) { + ndistribs = (size_t) + (root->data.mapping.pairs.top - root->data.mapping.pairs.start); + } else if(root->type == YAML_SEQUENCE_NODE) { + /* Define the number of submitted distributions */ + ndistribs = (size_t) + (root->data.sequence.items.top - root->data.sequence.items.start); + } + + if((root->type == YAML_MAPPING_NODE && ndistribs > 1) + || (root->type != YAML_MAPPING_NODE && root->type != YAML_SEQUENCE_NODE)) { + fprintf(stderr, + "Expecting either one or a list of geometry distributions.\n"); res = RES_BAD_ARG; goto error; } - /* Define the number of submitted distributions */ - ndistribs = (size_t) - (root->data.sequence.items.top - root->data.sequence.items.start); - /* Allocate the list geometry distributions */ if(!sa_add(geoms, ndistribs)) { log_err(filename, root, @@ -802,46 +846,32 @@ parse_yaml goto error; } - /* Parse the geometry distributions */ - accum_proba = 0; - FOR_EACH(idistrib, 0, ndistribs) { - yaml_node_t* distrib, *key, *val; + /* Only one distribution */ + if(root->type == YAML_MAPPING_NODE) { + res = parse_yaml_geom_distrib(filename, &doc, root, &geoms[0], &probas[0]); + if(res != RES_OK) goto error; - distrib = yaml_document_get_node - (&doc, root->data.sequence.items.start[idistrib]); - if(distrib->type != YAML_MAPPING_NODE - || distrib->data.mapping.pairs.top - distrib->data.mapping.pairs.start > 1) { - log_err(filename, distrib, - "expecting a mapping of the geometry distribution to its parameters\n"); - res = RES_BAD_ARG; - goto error; - } + /* List of geometry distributions */ + } else { + double accum_proba = 0; + ASSERT(root->type == YAML_SEQUENCE_NODE); - key = yaml_document_get_node(&doc, distrib->data.mapping.pairs.start[0].key); - val = yaml_document_get_node(&doc, distrib->data.mapping.pairs.start[0].value); - ASSERT(key->type == YAML_SCALAR_NODE); + FOR_EACH(idistrib, 0, ndistribs) { + yaml_node_t* distrib; - if(!strcmp((char*)key->data.scalar.value, "cylinder")) { - res = parse_yaml_cylinder - (filename, &doc, val, &geoms[idistrib], &probas[idistrib]); - } else if(!strcmp((char*)key->data.scalar.value, "sphere")) { - res = parse_yaml_sphere - (filename, &doc, val, &geoms[idistrib], &probas[idistrib]); - } else { - log_err(filename, key, "unknown distribution `%s'.\n", - key->data.scalar.value); - res = RES_BAD_ARG; - goto error; + distrib = yaml_document_get_node + (&doc, root->data.sequence.items.start[idistrib]); + res = parse_yaml_geom_distrib + (filename, &doc, distrib, &geoms[idistrib], &probas[idistrib]); + if(res != RES_OK) goto error; + + accum_proba += probas[idistrib]; } - if(res != RES_OK) goto error; - accum_proba += probas[idistrib]; + /* Normalized the geometry distribution probabilities */ + FOR_EACH(idistrib, 0, ndistribs-1) probas[idistrib] /= accum_proba; + probas[ndistribs-1] = 1.f; /* Handle precision issues */ } - /* Normalized the geometry distribution probabilities */ - FOR_EACH(idistrib, 0, ndistribs-1) - probas[idistrib] /= accum_proba; - probas[ndistribs-1] = 1.f; /* Handle precision issues */ - /* Setup the geometry distributions random variate */ res = ssp_ran_discrete_setup(ran, probas, ndistribs); if(res != RES_OK) { @@ -852,7 +882,7 @@ parse_yaml exit: yaml_parser_delete(&parser); - yaml_document_delete(&doc); + if(doc_is_init) yaml_document_delete(&doc); if(file) fclose(file); if(probas) sa_release(probas); *out_geoms = geoms;