https://github.com/cmu-ci-lab/mcspeckle
Revision c4ecf78f32558cba5e45ab0c43a0995a20f2c85b authored by igkiou on 05 September 2019, 11:00:35 UTC, committed by igkiou on 05 September 2019, 11:00:35 UTC
1 parent 8572b98
Tip revision: c4ecf78f32558cba5e45ab0c43a0995a20f2c85b authored by igkiou on 05 September 2019, 11:00:35 UTC
first commit
first commit
Tip revision: c4ecf78
scmc.m
function [mulRes] = scmc(targetArea, views, lights, scatter, iterations, varargin)
%SCMC Speckle Covariance Monte-Catlo solver
%
% mulRes = scmc(targetArea,views,lights,scatter,iterations) render
% covariance of given parameters. Return structre with some of
% the possible measurements: configuration struct, covariance,
% single scattering covariance, rendered speckele field.
% * 'targetArea' - define the sample properties and the wavelength.
% see supporting functions: boxArea.
% * 'views' - define far field views directions or near field views
% positions.
% see supporting functions: farFieldSource, nearFieldSource.
% * 'lights' - define far field lights directions or near field lights
% positions.
% see supporting functions: farFieldSource, nearFieldSource.
% * 'scatter' - define the scattering function of each scatterer. The
% scattering function can be isotropic, Henyey-Greenstein
% (HG),and user defined tabulated function.
% see supporting functions: isotropicScatter, HGScatter,
% tabulatedAmplitudeScatter.
% * 'iterations' - number of mc iterations.
%
% mulRes = scmc(targetArea,views,lights,scatter,iterations,varargin) add
% options to scmc, in pair of field name and value, with the following
% options:
% * 'parforIters' - number of iterations using parfor. Thus the total
% iteartions is parforIters * iterations. The default
% is not using parfor.
% * 'rng' - rng number for random number generator (positive scalar). Not
% possible when using parfor. Default is not using rng.
% * 'CBS' - true= evaluat coherent back scattering. Default: true.
% * 'uniformFirstScatter' - true if the first scatterer is sampled
% uniformly in the target area, otherwise it
% is sampled according to an exponentially
% decaying function of the distance from the
% edge of the target. Default: false.
% * 'renderCov' - true for rendering covariance.
% Default: true.
% * 'singleScattering' - true for returning single scattering
% covariance. Default: false.
% * 'multipleScattering' - true for returning multiple scattering
% covariance. Default: true.
% * 'renderField' - true for sampling a field.
% Default: false.
%
% mulRes = scmc(Config) run the algorithm with pre-calculated Config
% struct, which is returned from scmc.m.
%
% Class support for targetArea, views, lights, scatter:
% struct
%
% Class photonsNum:
% float: double
%
% SEE ALSO: boxArea, nearFieldSource, farFieldSource, tabulatedAmplitudeScatter, HGScatter
%
%% Check valid input
if(nargin ~= 1)
narginchk(5,inf);
if(mod(length(varargin),2) ~= 0)
error('Parameters must be in struct of option and value')
end
if(~strcmp(targetArea.type,'targetArea'))
error('Invalid target area input')
end
if(~strcmp(views.type,'source'))
error('Invalid views input')
end
if(~strcmp(lights.type,'source'))
error('Invalid lights input')
end
if(~strcmp(scatter.type,'scatter'))
error('Invalid scatter input')
end
if(~isscalar(iterations) || iterations < 1)
error('Invalid photons number')
end
% measuredFarField must be in 2D
if(strcmp(scatter.function,'measuredFarField') && (targetArea.D == 3))
error('Measured scattering of far field is used only in 2D')
end
% tabulated scattering need to fit to its dimensions
% if(strcmp(scatter.function,'tabulated') && (targetArea.D ~= scatter.D))
% error('Tabulated scattering function is not fit to the area dimensions')
% end
% scattering 2D / 3D ...
if(targetArea.D == 3)
if isfield(views,'directions3D')
views.directions = views.directions3D;
end
if isfield(views,'positions3D')
views.positions = views.positions3D;
end
if isfield(lights,'directions3D')
lights.directions = lights.directions3D;
end
if isfield(lights,'positions3D')
lights.positions = lights.positions3D;
end
end
if(targetArea.D == 2)
if isfield(views,'directions2D')
views.directions = views.directions2D;
end
if isfield(views,'positions2D')
views.positions = views.positions2D;
end
if isfield(lights,'directions2D')
lights.directions = lights.directions2D;
end
if isfield(lights,'positions2D')
lights.positions = lights.positions2D;
end
end
%% Build Config
Config.targetArea = targetArea;
Config.views = views;
Config.lights = lights;
Config.scatter = scatter;
Config.render.iterations = iterations;
%% Default values
Config.parforIters = 1;
Config.rng = -1;
Config.CBS = true;
Config.uniformFirstScatter = false;
Config.render.singleScattering = false;
Config.render.cov = true;
Config.render.singleScattering = false;
Config.render.multipleScattering = true;
Config.render.field = false;
%% Set preffered values
for optNum = 1:2:length(varargin)
optString = char(varargin{optNum});
optVal = varargin{optNum + 1};
if strcmp(optString,'parforIters')
if(~isscalar(optVal) || optVal < 0)
error('invalid parfor iterations number')
end
if(Config.rng ~= -1)
error('rng can not be used while using parfor')
end
Config.parforIters = optVal;
continue;
end
if strcmp(optString,'rng')
if(~isscalar(optVal) || optVal < 0)
error('invalid rng number')
end
if(Config.parforIters ~= 1)
error('rng can not be used while using parfor')
end
Config.rng = optVal;
continue;
end
if strcmp(optString,'CBS')
if(~isscalar(optVal) || ~islogical(optVal))
error('CBS must be logical scalar')
end
Config.CBS = optVal;
continue;
end
if strcmp(optString,'uniformFirstScatter')
if(~isscalar(optVal) || ~islogical(optVal))
error('uniformFirstScatter must be logical scalar')
end
Config.uniformFirstScatter = optVal;
continue;
end
if strcmp(optString,'renderCov')
if(~isscalar(optVal) || ~islogical(optVal))
error('renderCov must be logical scalar')
end
Config.render.cov = optVal;
continue;
end
if strcmp(optString,'singleScattering')
if(~isscalar(optVal) || ~islogical(optVal))
error('Single scattering option must be logical scalar')
end
Config.render.singleScattering = optVal;
continue;
end
if strcmp(optString,'multipleScattering')
if(~isscalar(optVal) || ~islogical(optVal))
error('Multiple scattering option must be logical scalar')
end
Config.render.multipleScattering = optVal;
continue;
end
if strcmp(optString,'renderField')
if(~isscalar(optVal) || ~islogical(optVal))
error('renderField must be logical scalar')
end
Config.render.field = optVal;
continue;
end
error('Invalid option value')
end
else
% in pre-allocated config, the first variable is the config
Config = targetArea;
end
%% run Monte-Carlo
mulRes.Config = Config;
% build the parameters for running the algortihms
sigt = 1./Config.targetArea.MFP;
albedo = Config.scatter.albedo;
if(strcmp(Config.scatter.function,'isotropic'))
sct_type = 1;
ampfunc = 0;
covRendParams = 14;
fieldRenderParams = 14;
end
if(strcmp(Config.scatter.function,'tabulated'))
sct_type = 2;
ampfunc = scatter.ampfunc;
if(isinf(Config.scatter.ampfunc0))
covRendParams = 14;
fieldRenderParams = 14;
else
covRendParams = 15;
fieldRenderParams = 15;
ampfunc0 = Config.scatter.ampfunc0;
end
end
if(strcmp(Config.scatter.function,'HG'))
sct_type = 3;
ampfunc = Config.scatter.g;
if(isinf(Config.scatter.g0))
% default value to g0
covRendParams = 14;
fieldRenderParams = 14;
else
covRendParams = 15;
fieldRenderParams = 15;
ampfunc0 = Config.scatter.g0;
end
end
if(Config.targetArea.D == 3)
box_min = [Config.targetArea.x(1);Config.targetArea.y(1);Config.targetArea.z(1)];
box_max = [Config.targetArea.x(2);Config.targetArea.y(2);Config.targetArea.z(2)];
else
box_min = [Config.targetArea.x(1);Config.targetArea.z(1)];
box_max = [Config.targetArea.x(2);Config.targetArea.z(2)];
end
if(Config.lights.farField == 1)
is_ff_l = 1;
l = Config.lights.directions;
else
is_ff_l = 0;
l = Config.lights.positions;
end
if(Config.views.farField == 1)
is_ff_v = 1;
v = Config.views.directions;
else
is_ff_v = 0;
v = Config.views.positions;
end
maxItr = Config.render.iterations;
lambda = Config.targetArea.wavelength;
doCBS = Config.CBS;
if(Config.uniformFirstScatter)
smpFlg = 1;
else
smpFlg = 2;
end
% run cov rendering
if(Config.render.cov)
if(Config.parforIters == 1)
if(Config.rng ~= -1)
rng(Config.rng);
end
if(covRendParams == 14)
[Ms,Mm] = MCcov( sigt, albedo, box_min, box_max, ...
l, v, is_ff_l, is_ff_v, maxItr, lambda, doCBS, smpFlg, ...
sct_type, ampfunc);
end
if(covRendParams == 15)
[Ms,Mm] = MCcov( sigt, albedo, box_min, box_max, ...
l, v, is_ff_l, is_ff_v, maxItr, lambda, doCBS, smpFlg, ...
sct_type, ampfunc,ampfunc0);
end
else
Ms = zeros(Config.views.count, Config.views.count, ...
Config.lights.count, Config.lights.count, Config.parforIters);
Mm = Ms;
if(covRendParams == 14)
parfor iterNum = 1:1:Config.parforIters
[Ms(:,:,:,:,iterNum),Mm(:,:,:,:,iterNum)] = ...
MCcov( sigt, albedo, box_min, box_max, l, v, ...
is_ff_l, is_ff_v, maxItr, lambda, doCBS, smpFlg, ...
sct_type, ampfunc);
end
end
if(covRendParams == 15)
parfor iterNum = 1:1:Config.parforIters
[Ms(:,:,:,:,iterNum),Mm(:,:,:,:,iterNum)] = ...
MCcov( sigt, albedo, box_min, box_max, l, v, ...
is_ff_l, is_ff_v, maxItr, lambda, doCBS, smpFlg, ...
sct_type, ampfunc, ampfunc0);
end
end
Ms = mean(Ms,5);
Mm = mean(Mm,5);
end
if(Config.render.singleScattering)
mulRes.Csingle = Ms;
end
if(Config.render.multipleScattering)
mulRes.C = Ms + Mm;
end
end
% run field rendering
if(Config.render.field)
if(Config.parforIters == 1)
if(Config.rng ~= -1)
rng(Config.rng);
end
if(fieldRenderParams == 14)
u = MCfield( sigt, albedo, box_min, box_max, l, v, ...
is_ff_l, is_ff_v, maxItr, lambda, doCBS,smpFlg, sct_type, ...
ampfunc);
end
if(fieldRenderParams == 15)
u = MCfield( sigt, albedo, box_min, box_max, l, v, ...
is_ff_l, is_ff_v, maxItr, lambda, doCBS,smpFlg, sct_type, ...
ampfunc, ampfunc0);
end
else
u = zeros(Config.views.count, Config.lights.count, ...
Config.parforIters);
if(fieldRenderParams == 14)
parfor iterNum = 1:1:Config.parforIters
u(:,:,iterNum) = MCfield( sigt, ...
albedo, box_min, box_max, l, v, is_ff_l, is_ff_v, ...
maxItr, lambda, doCBS, smpFlg, sct_type, ampfunc);
end
end
if(fieldRenderParams == 15)
parfor iterNum = 1:1:Config.parforIters
u(:,:,iterNum) = MCfield( sigt, ...
albedo, box_min, box_max, l, v, is_ff_l, is_ff_v, ...
maxItr, lambda, doCBS, smpFlg, sct_type, ampfunc, ampfunc0);
end
end
% normalize
u = u * sqrt(maxItr);
u = sum(u,3);
u = u./sqrt(maxItr * Config.parforIters);
end
mulRes.field = u;
end
end

Computing file changes ...