star-line

Structure for accelerating line importance sampling
git clone git://git.meso-star.fr/star-line.git
Log | Files | Refs | README | LICENSE

commit 7a82522883aa6fc6bd352cf9b293953a45f6812e
parent bafd3efb0869bb1da4762b89f5b7304831d3b280
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 27 Apr 2022 11:52:19 +0200

Add and test the sln_tree_get_desc function

Diffstat:
Msrc/sln.h | 17+++++++++++++++--
Msrc/sln_tree.c | 39+++++++++++++++++++++++++++++++++++++++
Msrc/sln_tree_c.h | 3+++
Msrc/test_sln_tree.c | 24++++++++++++++++++++----
4 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/src/sln.h b/src/sln.h @@ -104,12 +104,20 @@ struct sln_tree_create_args { enum sln_line_profile line_profile; }; -#define SLN_TREE_CREATE_ARGS_DEFAULT__ \ - {NULL, NULL, {SLN_MOLECULE_NULL__}, 0, {0, DBL_MAX}, 0, 0, 64, \ +#define SLN_TREE_CREATE_ARGS_DEFAULT__ \ + {NULL, NULL, {SLN_MOLECULE_NULL__}, 0, {0, DBL_MAX}, 0, 0, 64, \ SLN_LINE_PROFILE_VOIGT} static const struct sln_tree_create_args SLN_TREE_CREATE_ARGS_DEFAULT = SLN_TREE_CREATE_ARGS_DEFAULT__; +struct sln_tree_desc { + double wavenumber_range[2]; /* Spectral range */ + size_t nlines; /* Number of partitionned lines */ + size_t max_nlines_per_leaf; /* max #lines per leaf */ +}; +#define SLN_TREE_DESC_NULL__ {{0,0}, 0, 0} +static const struct sln_tree_desc SLN_TREE_DESC_NULL = SLN_TREE_DESC_NULL__; + /* Forward declarations of opaque data structures */ struct sln_device; struct sln_tree; @@ -148,6 +156,11 @@ SLN_API res_T sln_tree_ref_put (struct sln_tree* tree); +SLN_API res_T +sln_tree_get_desc + (const struct sln_tree* tree, + struct sln_tree_desc* desc); + SLN_API const struct sln_node* sln_tree_get_root (const struct sln_tree* tree); diff --git a/src/sln_tree.c b/src/sln_tree.c @@ -291,6 +291,20 @@ setup_molecule_params return RES_OK; } +static INLINE res_T +store_input_args + (struct sln_device* sln, + const struct sln_tree_create_args* args, + struct sln_tree* tree) +{ + ASSERT(sln && args && tree); + (void)sln; + tree->wavenumber_range[0] = args->wavenumber_range[0]; + tree->wavenumber_range[1] = args->wavenumber_range[1]; + tree->max_nlines_per_leaf = args->max_nlines_per_leaf; + return RES_OK; +} + static void release_tree(ref_T* ref) { @@ -336,6 +350,8 @@ sln_tree_create if(res != RES_OK) goto error; res = setup_molecule_params(sln, args, tree->molecules_params); if(res != RES_OK) goto error; + res = store_input_args(sln, args, tree); + if(res != RES_OK) goto error; res = tree_build(tree, args); if(res != RES_OK) goto error; @@ -363,6 +379,29 @@ sln_tree_ref_put(struct sln_tree* tree) return RES_OK; } +res_T +sln_tree_get_desc(const struct sln_tree* tree, struct sln_tree_desc* desc) +{ + res_T res = RES_OK; + + if(!tree || !desc) { + res = RES_BAD_ARG; + goto error; + } + + desc->wavenumber_range[0] = tree->wavenumber_range[0]; + desc->wavenumber_range[1] = tree->wavenumber_range[1]; + desc->max_nlines_per_leaf = tree->max_nlines_per_leaf; + + res = shtr_lines_view_get_size(tree->lines_view, &desc->nlines); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + const struct sln_node* sln_tree_get_root(const struct sln_tree* tree) { diff --git a/src/sln_tree_c.h b/src/sln_tree_c.h @@ -55,6 +55,9 @@ struct sln_tree { struct shtr_lines_view* lines_view; /* Set of lines */ struct darray_node nodes; /* Nodes used to partition the lines */ + double wavenumber_range[2]; /* Spectral range */ + size_t max_nlines_per_leaf; + struct sln_device* sln; ref_T ref; }; diff --git a/src/test_sln_tree.c b/src/test_sln_tree.c @@ -245,15 +245,17 @@ find_line } } +/* This test assumes that all the lines contained into the list are + * partitionned in the tree */ static void check_tree (const struct sln_tree* tree, - const size_t nlines_per_leaf, struct shtr_lines_list* lines_list) { #define STACK_SIZE 64 const struct shtr_line* list = NULL; const struct sln_node* stack[STACK_SIZE] = {NULL}; + struct sln_tree_desc desc = SLN_TREE_DESC_NULL; size_t istack = 0; const struct sln_node* node = NULL; @@ -266,10 +268,12 @@ check_tree CHK(found_lines = mem_calloc(lines_list_sz, sizeof(char))); + CHK(sln_tree_get_desc(tree, &desc) == RES_OK); + node = sln_tree_get_root(tree); while(node) { if(!sln_node_is_leaf(node)) { - CHK(sln_node_get_lines_count(node) > nlines_per_leaf); + CHK(sln_node_get_lines_count(node) > desc.max_nlines_per_leaf); ASSERT(istack < STACK_SIZE); stack[istack++] = sln_node_get_child(node, 1); /* Push the child 1 */ @@ -279,7 +283,7 @@ check_tree size_t iline, nlines; nlines = sln_node_get_lines_count(node); - CHK(nlines <= nlines_per_leaf); + CHK(nlines <= desc.max_nlines_per_leaf); FOR_EACH(iline, 0, nlines) { const struct shtr_line* line = NULL; size_t found_iline = 0; @@ -311,9 +315,11 @@ test_tree struct shtr_lines_list* lines_list) { struct sln_tree_create_args tree_args = SLN_TREE_CREATE_ARGS_DEFAULT; + struct sln_tree_desc desc = SLN_TREE_DESC_NULL; struct sln_tree* tree = NULL; const struct sln_node* node = NULL; const struct shtr_line* line = NULL; + size_t nlines = 0; tree_args.metadata = metadata; tree_args.lines = lines_list; @@ -337,6 +343,16 @@ test_tree tree_args.max_nlines_per_leaf = 1; CHK(sln_tree_create(sln, &tree_args, &tree) == RES_OK); + CHK(shtr_lines_list_get_size(lines_list, &nlines) == RES_OK); + + CHK(sln_tree_get_desc(NULL, &desc) == RES_BAD_ARG); + CHK(sln_tree_get_desc(tree, NULL) == RES_BAD_ARG); + CHK(sln_tree_get_desc(tree, &desc) == RES_OK); + CHK(desc.wavenumber_range[0] == tree_args.wavenumber_range[0]); + CHK(desc.wavenumber_range[1] == tree_args.wavenumber_range[1]); + CHK(desc.max_nlines_per_leaf == tree_args.max_nlines_per_leaf); + CHK(desc.nlines == nlines); /* All the lines are taken into the count */ + CHK(node = sln_tree_get_root(tree)); while(!sln_node_is_leaf(node)) { node = sln_node_get_child(node, 0); @@ -349,7 +365,7 @@ test_tree CHK(sln_leaf_get_line(tree, node, 0, NULL) == RES_BAD_ARG); CHK(sln_leaf_get_line(tree, node, 0, &line) == RES_OK); - check_tree(tree, tree_args.max_nlines_per_leaf, lines_list); + check_tree(tree, lines_list); CHK(sln_tree_ref_get(NULL) == RES_BAD_ARG); CHK(sln_tree_ref_get(tree) == RES_OK);