function cfg=mcxcreate(benchname,varargin)
%
% Format:
%    list=mcxcreate
%    cfg=mcxcreate(benchname)
%    cfg=mcxcreate(benchname,'param1',value1,'param2',value2,...)
%
% Create MCX simulation from built-in benchmarks (similar to "mcx --bench")
%
% Author: Qianqian Fang <q.fang at neu.edu>
%
% Input:
%    benchname (optional): a string to specify the name of the benchmark
%         
% Output:
%    cfg: a struct defining the parameters associated with a simulation. If
%         no input, this function returns a list of supported benchmarks.
%
% Example:
%    list=mcxcreate;
%    cfg=mcxcreate('cube60b');
%    cfg=mcxcreate('cube60','srctype','isotropic','srcpos',[30 30 30])
%
% This function is part of Monte Carlo eXtreme (MCX) URL: http://mcx.space
%
% License: GNU General Public License version 3, please read LICENSE.txt for details
%

mcxbench.cube60=struct(...
    'nphoton',1e6,...
    'vol',uint8(ones(60,60,60)),...
    'srctype','pencil','srcpos',[29 29 0],'srcdir',[0 0 1],...
    'prop',[0 0 1 1;0.005 1 0.01 1.37],...
    'tstart',0,'tend',5e-9,'tstep',5e-9,....
    'isreflect',0,'seed',1648335518,'issrcfrom0',1,...
    'detpos',[29,19,0,1;29,39,0,1;19,29,0,1;39,29,0,1]);

mcxbench.cube60b=mcxbench.cube60;
mcxbench.cube60b.isreflect=1;

mcxbench.cube60planar=mcxbench.cube60b;
mcxbench.cube60planar.srctype='planar';
mcxbench.cube60planar.srcpos=[10.0, 10.0, -10.0];
mcxbench.cube60planar.srcparam1=[40.0, 0.0, 0.0, 0.0];
mcxbench.cube60planar.srcparam2=[0.0, 40.0, 0.0, 0.0];

mcxbench.skinvessel=struct(...
    'nphoton',1e6,...
    'vol',uint8(ones(200,200,200)),...
    'srctype','disk','srcpos',[100 100 20],'srcdir',[0 0 1],...
    'srcparam1',[60 0 0 0],'unitinmm',0.005,...
    'prop',[0 0 1 1;3.564e-05 1 1 1.37;...
      23.05426549 9.398496241 0.9 1.37;...
      0.04584957865 35.65405549 0.9 1.37;...
      1.657237447 37.59398496 0.9 1.37],...
    'tstart',0,'tend',5e-8,'tstep',5e-8,....
    'isreflect',0,'seed',1648335518,'issrcfrom0',1);
mcxbench.skinvessel.shapes=['{"Shapes":[{"ZLayers":[[1,20,1],[21,32,4],[33,200,3]]},' ...
    '{"Cylinder": {"Tag":2, "C0": [0,100.5,100.5], "C1": [200,100.5,100.5], "R": 20}}]}'];

mcxbench.sphshell=struct(...
    'nphoton',1e6,...
    'vol',uint8(ones(60,60,60)),...
    'srctype','pencil','srcpos',[30 30.1 0],'srcdir',[0 0 1],...
    'prop',[0 0 1 1;...
      0.02 7 0.89 1.37;...
      0.004 0.009 0.89 1.37;...
      0.02 9.0 0.89 1.37;...
      0.05 0.0 1.00 1.37],...
    'tstart',0,'tend',5e-9,'tstep',5e-9,....
    'isreflect',1,'seed',1648335518,'issrcfrom0',1);
mcxbench.sphshell.shapes=['{"Shapes":[{"Grid":{"Tag":1,"Size":[60,60,60]}},'...
    '{"Sphere":{"Tag":2,"O":[30,30,30],"R":25}},'...
    '{"Sphere":{"Tag":3,"O":[30,30,30],"R":23}},'...
    '{"Sphere":{"Tag":4,"O":[30,30,30],"R":10}}]}'];
mcxbench.sphshell.detpos=mcxbench.cube60.detpos;

mcxbench.spherebox=struct(...
    'nphoton',1e6,...
    'vol',uint8(ones(60,60,60)),...
    'srcpos',[29.5, 29.5 0],'srcdir',[0 0 1],...
    'prop',[0 0 1 1;...
      0.002 1 0.01 1.37;...
      0.05 5 0.9 1.37],...
    'tstart',0,'tend',5e-9,'tstep',1e-10,....
    'isreflect',0,'seed',1648335518,'issrcfrom0',1);
mcxbench.spherebox.shapes=['{"Shapes":[{"Grid":{"Tag":1,"Size":[60,60,60]}},'...
    '{"Sphere":{"Tag":2,"O":[30,30,30],"R":10}}]}'];

if(nargin==0)
    cfg=fieldnames(mcxbench);
    return;
end

if(isfield(mcxbench,benchname))
    cfg=mcxbench.(benchname);
    if(~isempty(varargin))
        for i=1:2:length(varargin)
            if(ischar(varargin{i}) && i+1<=length(varargin))
                cfg.(lower(varargin{i}))=varargin{i+1};
            else
                error('input must be in the form of ...,''name'',value,... pairs or structs');
            end
        end
    end
else
    error('benchmark name is not supported');
end