star-schiff

Library for estimating radiative properties
git clone git://git.meso-star.com/star-schiff.git
Log | Files | Refs | README | LICENSE

commit f519ed6cab752075a1749e6656a2a75e59743deb
parent 66fa585aff034ac42504b3b92ab3ea0058291f30
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 16 Feb 2016 13:31:52 +0100

Update the schiff API to handle scattering angle distributions

Refactor the estimator to prepare the integration of phase functions.

Diffstat:
Mcmake/CMakeLists.txt | 5++++-
Msrc/sschiff.h | 16++++++++++++++--
Msrc/sschiff_estimator.c | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Asrc/sschiff_scattering_angles_distributions.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_sschiff_estimator_cylinder.c | 7++++---
Msrc/test_sschiff_estimator_sphere.c | 142+++++++++++++++++++++++++++++++++++++++++--------------------------------------
6 files changed, 232 insertions(+), 116 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -59,7 +59,10 @@ set(VERSION_MINOR 3) set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) -set(SSCHIFF_FILES_SRC sschiff_device.c sschiff_estimator.c) +set(SSCHIFF_FILES_SRC + sschiff_device.c + sschiff_estimator.c + sschiff_scattering_angles_distributions.c) set(SSCHIFF_FILES_INC_API sschiff.h) set(SSCHIFF_FILES_INC sschiff_device.h) set(SSCHIFF_FILES_DOC COPYING.en COPYING.fr README.md) diff --git a/src/sschiff.h b/src/sschiff.h @@ -110,14 +110,25 @@ struct sschiff_estimator_state { } values[SSCHIFF_DATA_COUNT__]; }; +/* Type of the function use to distribute the scattering angles in [0, PI]. + * nangles is assumed to be greater than or equal to 2 and the angles is + * ensured to have `nangles' entries. */ +typedef void (*sschiff_scattering_angles_distribution_T) + (double angles[], const size_t nangles); + /* Opaque types */ struct sschiff_device; struct sschiff_estimator; +BEGIN_DECLS + +/* Built-in uniform distribution of scattering angles */ +SSCHIFF_API const sschiff_scattering_angles_distribution_T +sschiff_uniform_scattering_angles; + /******************************************************************************* * Star Schiff API ******************************************************************************/ -BEGIN_DECLS SSCHIFF_API res_T sschiff_device_create @@ -143,7 +154,8 @@ sschiff_integrate struct sschiff_geometry_distribution* distribution, const double* wavelengths, /* list of wavelengths to estimate in micron */ const size_t wavelengths_count, /* # wavelengths to estimate */ - const size_t scattering_angles_count, /* # of scattering angles to handle */ + const sschiff_scattering_angles_distribution_T angles, /* angles distrib */ + const size_t scattering_angles_count, /* # scattering angles. Must be >= 2 */ const size_t sampled_geometries_count, /* # geometries to sample */ const size_t sampled_directions_count, /* # directions to sample per geometry */ struct sschiff_estimator** estimator); diff --git a/src/sschiff_estimator.c b/src/sschiff_estimator.c @@ -264,6 +264,48 @@ compute_path_length return RES_OK; } +static FINLINE void +accum_cross_section + (const struct sschiff_material_properties* props, + const double* wavelengths, + const size_t nwavelengths, + const double rcp_pdf, + const double path_length, + struct accum* accums) +{ + size_t iwlen; + ASSERT(props && wavelengths && nwavelengths && rcp_pdf>0 && path_length>0); + + FOR_EACH(iwlen, 0, nwavelengths) { + double n_r, k_r; + double n_e, k_e, lambda_e; + double w_extinction, w_absorption, w_scattering; + + n_e = props[iwlen].medium_refractive_index; + n_r = props[iwlen].relative_real_refractive_index; + k_r = props[iwlen].relative_imaginary_refractive_index; + + lambda_e = wavelengths[iwlen] / n_e; + k_e = 2.0 * PI / lambda_e; + + /* Extinction cross section */ + w_extinction = 2.0 * rcp_pdf * + (1.0 - exp(-k_e*k_r*path_length) * cos(k_e*(n_r - 1.0)*path_length)); + accums[iwlen].weights[SSCHIFF_EXTINCTION_CROSS_SECTION] += w_extinction; + + /* Absorption cross section */ + w_absorption = rcp_pdf * (1.0 - exp(-2.0*k_e*k_r*path_length)); + accums[iwlen].weights[SSCHIFF_ABSORPTION_CROSS_SECTION] += w_absorption; + + /* Scattering cross section */ + w_scattering = w_extinction - w_absorption; + accums[iwlen].weights[SSCHIFF_SCATTERING_CROSS_SECTION] += w_scattering; + + /* Average projected area */ + accums[iwlen].weights[SSCHIFF_AVERAGE_PROJECTED_AREA] += rcp_pdf; + } +} + static res_T accum_monte_carlo_weight (struct sschiff_device* dev, @@ -272,6 +314,8 @@ accum_monte_carlo_weight const struct sschiff_material_properties* props, const double* wavelengths, /* In micron */ const size_t nwavelengths, + const double* angles, /* Scattering angles */ + const size_t nangles, const float basis[9], /* World space basis of the RT volume */ const float pos[3], /* World space centroid of the RT volume */ const float lower[3], /* Lower boundary of the RT volume */ @@ -289,8 +333,8 @@ accum_monte_carlo_weight float x[3], y[3]; float rcp_pdf; res_T res = RES_OK; - ASSERT(scn && rng && props && wavelengths && accums && basis && pos); - ASSERT(lower && upper); + ASSERT(scn && rng && props && wavelengths && nwavelengths && angles && nangles); + ASSERT(accums && basis && pos && lower && upper); f2_sub(plane_size, upper, lower); /* In micron */ rcp_pdf = plane_size[0] * plane_size[1]; @@ -304,6 +348,8 @@ accum_monte_carlo_weight f3_add(org, pos, f3_mulf(org, axis_z, lower[2])); do { + double path_length; + /* Uniformly sample a position onto the projection plane and use it as the * origin of the ray to trace */ sample[0] = ssp_rng_uniform_double(rng, -1.0, 1.0); @@ -314,45 +360,21 @@ accum_monte_carlo_weight S3D(scene_trace_ray(scn, ray_org, axis_z, range, &hit)); - if(!S3D_HIT_NONE(&hit)) { - double path_length; - size_t iwlen; + if(S3D_HIT_NONE(&hit)) /* NULL cross section and phase function weight */ + break; - res = compute_path_length(dev, scn, &hit, ray_org, axis_z, &path_length); - if(res != RES_OK) { /* Handle numerical/geometry issues */ - ++nfailures; - continue; - } - - FOR_EACH(iwlen, 0, nwavelengths) { - double n_r, k_r; - double n_e, k_e, lambda_e; - double w_extinction, w_absorption, w_scattering; - - n_e = props[iwlen].medium_refractive_index; - n_r = props[iwlen].relative_real_refractive_index; - k_r = props[iwlen].relative_imaginary_refractive_index; - - lambda_e = wavelengths[iwlen] / n_e; - k_e = 2.0 * PI / lambda_e; - - /* Extinction cross section */ - w_extinction = 2.0 * rcp_pdf * - (1.0 - exp(-k_e*k_r*path_length) * cos(k_e*(n_r - 1.0)*path_length)); - accums[iwlen].weights[SSCHIFF_EXTINCTION_CROSS_SECTION] += w_extinction; - /* Absorption cross section */ - w_absorption = rcp_pdf * (1.0 - exp(-2.0*k_e*k_r*path_length)); - accums[iwlen].weights[SSCHIFF_ABSORPTION_CROSS_SECTION] += w_absorption; + res = compute_path_length(dev, scn, &hit, ray_org, axis_z, &path_length); + if(res != RES_OK) { /* Handle numerical/geometry issues */ + ++nfailures; + continue; + } + accum_cross_section + (props, wavelengths, nwavelengths, rcp_pdf, path_length, accums); - /* Scattering cross section */ - w_scattering = w_extinction - w_absorption; - accums[iwlen].weights[SSCHIFF_SCATTERING_CROSS_SECTION] += w_scattering; + /* TODO phase function integration */ + (void)angles, (void)nangles; - /* Average projected area */ - accums[iwlen].weights[SSCHIFF_AVERAGE_PROJECTED_AREA] += rcp_pdf; - } - } } while(res != RES_OK && nfailures < MAX_FAILURES); if(res != RES_OK) { @@ -370,6 +392,8 @@ radiative_properties const int istep, const double* wavelengths, /* Sorted in ascending order */ const size_t nwavelengths, + const double* angles, /* Sorted in ascending order in [0, PI] */ + const size_t nangles, const size_t ndirs, struct s3d_scene* scene, const struct sschiff_material_properties* props, @@ -434,7 +458,7 @@ radiative_properties } res = accum_monte_carlo_weight(dev, scene, rng, props, wavelengths, - nwavelengths, basis, centroid, lower, upper, accums); + nwavelengths, angles, nangles, basis, centroid, lower, upper, accums); if(res != RES_OK) goto error; #if 0 @@ -550,6 +574,7 @@ sschiff_integrate struct sschiff_geometry_distribution* distrib, const double* wavelengths, const size_t nwavelengths, + const sschiff_scattering_angles_distribution_T angles_distrib, const size_t nangles, const size_t ngeoms, const size_t ndirs, @@ -563,13 +588,15 @@ sschiff_integrate struct s3d_scene** scenes = NULL; struct ssp_rng** rngs = NULL; struct ssp_rng_proxy* rng_proxy = NULL; + double* angles = NULL; size_t i; int igeom; ATOMIC res = (ATOMIC)RES_OK; (void)nangles; - if(!dev || !rng || !distrib || !wavelengths || !nwavelengths || !nangles - || !ngeoms || !ndirs || !out_estimator || !check_distribution(distrib)) { + if(!dev || !rng || !distrib || !wavelengths || !nwavelengths + || !angles_distrib || nangles < 2 || !ngeoms || !ndirs || !out_estimator + || !check_distribution(distrib)) { return RES_BAD_ARG; } @@ -583,6 +610,24 @@ sschiff_integrate log_error(dev, "Couldn't create the proxy allocator\n"); goto error; } + + /* Setup the scattering angles */ + angles = sa_add(angles, nangles); + if(!angles) { + log_error(dev, + "Not enough memory: couldn't allocate the list of scattering angles.\n"); + res = RES_MEM_ERR; + goto error; + } + angles_distrib(angles, nangles); + if(angles[0] != 0.f && !eq_eps(angles[1], PI, 1.e-6)) { + log_error(dev, +"Invalid scattering angles distribution. The first and the last angles must be\n" +"0 and PI, respectively\n"); + res = RES_BAD_ARG; + goto error; + } + /* Create the containers of per thread data structures */ if(!sa_add(mtls, dev->nthreads)) { log_error(dev, @@ -707,8 +752,8 @@ sschiff_integrate /* Schiff Estimation */ res_local = radiative_properties(dev, rngs[ithread], igeom, wlengths, - nwavelengths, ndirs, scenes[ithread], mtls[ithread], mc_accums[ithread], - accums[ithread]); + nwavelengths, angles, nangles, ndirs, scenes[ithread], mtls[ithread], + mc_accums[ithread], accums[ithread]); if(res != RES_OK) ATOMIC_SET(&res, res_local); S3D(scene_end_session(scenes[ithread])); @@ -731,6 +776,7 @@ sschiff_integrate exit: if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy)); + if(angles) sa_release(angles); /* Release per thread data */ if(mtls) { FOR_EACH(i, 0, dev->nthreads) if(mtls[i]) sa_release(mtls[i]); diff --git a/src/sschiff_scattering_angles_distributions.c b/src/sschiff_scattering_angles_distributions.c @@ -0,0 +1,48 @@ +/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com) + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. */ + +#include "sschiff.h" +#include <rsys/math.h> + +static void +uniform(double* angles, const size_t nangles) +{ + size_t iangle; + const double step = PI / (double)(nangles - 1); + ASSERT(nangles >= 2); + + angles[0] = 0.0; + FOR_EACH(iangle, 1, nangles-1) { + angles[iangle] = angles[iangle-1] + step; + } + angles[nangles-1] = PI; +} + +const sschiff_scattering_angles_distribution_T +sschiff_uniform_scattering_angles = uniform; + diff --git a/src/test_sschiff_estimator_cylinder.c b/src/test_sschiff_estimator_cylinder.c @@ -559,7 +559,7 @@ main(int argc, char** argv) 2.010619438e+2, 2.018997018e+2, 2.027374599e+2 }; const size_t nx = sizeof(x)/sizeof(double); - const size_t nscatt_angles = 1; + const size_t nscatt_angles = 2; const size_t ngeoms = 100; const size_t ndirs = 10; size_t i; @@ -587,8 +587,9 @@ main(int argc, char** argv) distrib.context = &sampler_ctx; time_current(&t0); - CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1, nscatt_angles, - ngeoms, ndirs, &estimator), RES_OK); + CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1, + sschiff_uniform_scattering_angles, nscatt_angles, ngeoms, ndirs, + &estimator), RES_OK); time_current(&t1); time_sub(&t0, &t1, &t0); time_dump(&t0, TIME_MIN|TIME_SEC|TIME_MSEC, NULL, buf, sizeof(buf)); diff --git a/src/test_sschiff_estimator_sphere.c b/src/test_sschiff_estimator_sphere.c @@ -246,7 +246,7 @@ check_schiff_estimation struct time t0, t1; size_t i; - const size_t nscatt_angles = 1; + const size_t nscatt_angles = 2; const size_t ngeoms = 100; const size_t ndirs = 100; const double wavelength = sampler_ctx->wavelength; @@ -271,8 +271,8 @@ check_schiff_estimation sampler_ctx->mean_radius = results[i].mean_radius; time_current(&t0); - CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1, nscatt_angles, - ngeoms, ndirs, &estimator), RES_OK); + CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1, + sschiff_uniform_scattering_angles, nscatt_angles, ngeoms, ndirs, &estimator), RES_OK); time_current(&t1); time_sub(&t0, &t1, &t0); time_dump(&t0, TIME_MIN|TIME_SEC|TIME_MSEC, NULL, buf, sizeof(buf)); @@ -365,70 +365,75 @@ main(int argc, char** argv) distrib.sample = sample_sphere; distrib.context = &sampler_ctx; - CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_OK); + CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG); + + CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, + sschiff_uniform_scattering_angles, 1, 1, 1, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, + sschiff_uniform_scattering_angles, 2, 1, 1, &estimator), RES_OK); CHECK(sschiff_estimator_get_wavelengths_count(NULL, NULL), RES_BAD_ARG); CHECK(sschiff_estimator_get_wavelengths_count(estimator, NULL), RES_BAD_ARG); @@ -458,7 +463,8 @@ main(int argc, char** argv) CHECK(sschiff_estimator_ref_put(estimator), RES_OK); CHECK(sschiff_estimator_ref_put(estimator), RES_OK); - CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, 1, 10, 1, &estimator), RES_OK); + CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, + sschiff_uniform_scattering_angles, 2, 10, 1, &estimator), RES_OK); CHECK(sschiff_estimator_get_realisations_count(estimator, &count), RES_OK); CHECK(count, 10); CHECK(sschiff_estimator_ref_put(estimator), RES_OK);