Skip to content

Commit

Permalink
compact implementation of ring source, close #181
Browse files Browse the repository at this point in the history
  • Loading branch information
fangq committed Sep 3, 2023
1 parent b0bad9f commit ad6ff4c
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 16 deletions.
4 changes: 3 additions & 1 deletion mcxcloud/frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,9 @@ <h3>Backend</h3>
"zgaussian",
"line",
"slit",
"pencilarray"
"pencilarray",
"hyperboloid",
"ring"
]
},
"Pos": {
Expand Down
54 changes: 54 additions & 0 deletions mcxlab/examples/demo_mcxlab_srctype.m
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,62 @@
axis equal; colorbar
title('a gaussian beam source');


%% test group 5

clear cfg;
figure;
cfg.nphoton=1e6;
cfg.vol=uint8(ones(60,60,60));
cfg.gpuid=1;
cfg.autopilot=1;
cfg.prop=[0 0 1 1;0.005 1 0.8 1.37];
cfg.tstart=0;
cfg.seed=99999;
cfg.tend=5e-11;
cfg.tstep=5e-11;

% a ring beam
cfg.srctype='ring';
cfg.srcpos=[30 30 -10];
cfg.srcdir=[0 0 1];
cfg.srcparam1=[15 10 0 0];
cfg.srcparam2=[0 0 0 0];
flux=mcxlab(cfg);
fcw=flux.data*cfg.tstep;
subplot(221);
imagesc(log10(abs(squeeze(fcw(:,:,1)))))
axis equal; colorbar
title('a ring beam');

% a diverging ring sector beam
cfg.srctype='ring';
cfg.srcpos=[30 30 -10];
cfg.srcdir=[0 0 1 -20];
cfg.srcparam1=[15 10 0 2*pi/3];
cfg.srcparam2=[0 0 0 0];
flux=mcxlab(cfg);
fcw=flux.data*cfg.tstep;
subplot(222);
imagesc(log10(abs(squeeze(fcw(:,:,1)))))
axis equal; colorbar
title('a ring-sector beam');

% a ring beam
cfg.srctype='pencilarray';
cfg.srcpos=[10 10 0];
cfg.srcdir=[0 0 1];
cfg.srcparam1=[40 0 0 4];
cfg.srcparam2=[0 40 0 5];
flux=mcxlab(cfg);
fcw=flux.data*cfg.tstep;
subplot(223);
imagesc(log10(abs(squeeze(fcw(:,:,1)))))
axis equal; colorbar
title('a pencil beam array)');

%% test group 6

%debug flag to retrieve/test build-in RNG
cfg.vol=uint8(ones(100,100,100));
cfg.debuglevel='R';
Expand Down
2 changes: 2 additions & 0 deletions mcxstudio/mcxsource.lfm
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ object fmSource: TfmSource
'line'
'slit'
'pencilarray'
'hyperboloid'
'ring'
)
OnEditingDone = edSourceEditingDone
ParentFont = False
Expand Down
2 changes: 1 addition & 1 deletion pymcx
4 changes: 3 additions & 1 deletion schema/mcxinput.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@
"zgaussian",
"line",
"slit",
"pencilarray"
"pencilarray",
"hyperboloid",
"ring"
]
},
"Pos": {
Expand Down
1 change: 1 addition & 0 deletions src/mcx_const.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
#define MCX_SRC_PENCILARRAY 14 /**< a rectangular array of pencil beams */
#define MCX_SRC_PATTERN3D 15 /**< a 3D pattern source, starting from srcpos, srcparam1.{x,y,z} define the x/y/z dimensions */
#define MCX_SRC_HYPERBOLOID_GAUSSIAN 16 /**< Gaussian-beam with spot focus, scrparam1.{x,y,z} define beam waist, distance from source to focus, rayleigh range */
#define MCX_SRC_RING 17 /**< ring/ring-sector source, scrparam1.{x,y} defines the outer/inner radius, srcparam1.{z,w} defines start/end angle*/

#define SAVE_DETID(a) ((a) & 0x1) /**< mask to save detector ID*/
#define SAVE_NSCAT(a) ((a)>>1 & 0x1) /**< output partial scattering counts */
Expand Down
19 changes: 12 additions & 7 deletions src/mcx_core.cu
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ __device__ inline void updatestokes(Stokes* s, float theta, float phi, float3* u
temp = (u2->z > -1.f && u2->z < 1.f) ? rsqrtf((1.f - costheta * costheta) * (1.f - u2->z * u2->z)) : 0.f;

cosi = (temp == 0.f) ? 0.f : (((phi > ONE_PI && phi < TWO_PI) ? 1.f : -1.f) * (u2->z * costheta - u->z) * temp);
cosi = fmax(-1.f, fmin(cosi, 1.f));
cosi = fmaxf(-1.f, fminf(cosi, 1.f));

sini = sqrtf(1.f - cosi * cosi);
cos22 = 2.f * cosi * cosi - 1.f;
Expand Down Expand Up @@ -1240,15 +1240,20 @@ __device__ inline int launchnewphoton(MCXpos* p, MCXdir* v, Stokes* s, MCXtime*
}

case (MCX_SRC_DISK):
case (MCX_SRC_RING):
case (MCX_SRC_GAUSSIAN): { // uniform disk distribution or collimated Gaussian-beam
// Uniform disk point picking
// http://mathworld.wolfram.com/DiskPointPicking.html
float sphi, cphi;
float phi = TWO_PI * rand_uniform01(t);
float phi, sphi, cphi, r;

if (gcfg->srctype == MCX_SRC_RING && (gcfg->srcparam1.z > 0.f || gcfg->srcparam1.w > 0.f)) {
phi = fabsf(gcfg->srcparam1.z - gcfg->srcparam1.w) * rand_uniform01(t) + fminf(gcfg->srcparam1.z, gcfg->srcparam1.w);
} else {
phi = TWO_PI * rand_uniform01(t);
}
sincosf(phi, &sphi, &cphi);
float r;

if (gcfg->srctype == MCX_SRC_DISK) {
if (gcfg->srctype == MCX_SRC_DISK || gcfg->srctype == MCX_SRC_RING) {
r = sqrtf(rand_uniform01(t) * fabsf(gcfg->srcparam1.x * gcfg->srcparam1.x - gcfg->srcparam1.y * gcfg->srcparam1.y) + gcfg->srcparam1.y * gcfg->srcparam1.y);
} else if (fabsf(gcfg->c0.w) < 1e-5f || fabsf(gcfg->srcparam1.y) < 1e-5f) {
r = sqrtf(0.5f * rand_next_scatlen(t)) * gcfg->srcparam1.x;
Expand Down Expand Up @@ -1724,7 +1729,7 @@ __global__ void mcx_main_loop(uint media[], OutputType field[], float genergy[],

// in early CUDA, when ran=1, CUDA gives 1.000002 for tmp0 which produces nan later
// detected by Ocelot,thanks to Greg Diamos,see http://bit.ly/cR2NMP
tmp0 = fmax(-1.f, fmin(1.f, tmp0));
tmp0 = fmaxf(-1.f, fminf(1.f, tmp0));

theta = acosf(tmp0);
stheta = sinf(theta);
Expand Down Expand Up @@ -1854,7 +1859,7 @@ __global__ void mcx_main_loop(uint media[], OutputType field[], float genergy[],
GPUDEBUG(("p=[%f %f %f] -> <%f %f %f>*%f -> hit=[%d %d %d] flip=%d\n", p.x, p.y, p.z, v.x, v.y, v.z, len, flipdir[0], flipdir[1], flipdir[2], flipdir[3]));

/** if the consumed unitless scat length is less than what's left in f.pscat, keep moving; otherwise, stop in this voxel */
slen = fmin(slen, f.pscat);
slen = fminf(slen, f.pscat);

/** final length that the photon moves - either the length to move to the next voxel, or the remaining scattering length */
len = ((prop.mus == 0.f) ? len : (slen / prop.mus * (v.nscat + 1.f > gcfg->gscatter ? (1.f - prop.g) : 1.f)));
Expand Down
2 changes: 1 addition & 1 deletion src/mcx_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ const char boundarydetflag[] = {'0', '1', '\0'};

const char* srctypeid[] = {"pencil", "isotropic", "cone", "gaussian", "planar",
"pattern", "fourier", "arcsine", "disk", "fourierx", "fourierx2d", "zgaussian",
"line", "slit", "pencilarray", "pattern3d", "hyperboloid", ""
"line", "slit", "pencilarray", "pattern3d", "hyperboloid", "ring", ""
};


Expand Down
3 changes: 2 additions & 1 deletion src/mcx_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ typedef struct MCXConfig {
char internalsrc; /**<1 all photons launch positions are inside non-zero voxels, 0 let mcx search entry point*/
int zipid; /**<data zip method "zlib","gzip","base64","lzip","lzma","lz4","lz4hc"*/
char srctype; /**<0:pencil,1:isotropic,2:cone,3:gaussian,4:planar,5:pattern,\
6:fourier,7:arcsine,8:disk,9:fourierx,10:fourierx2d,11:zgaussian,12:line,13:slit*/
6:fourier,7:arcsine,8:disk,9:fourierx,10:fourierx2d,11:zgaussian,\
12:line,13:slit,14:pencilarray,15:pattern3d,16:hyperboloid,17:ring*/
char outputtype; /**<'X' output is flux, 'F' output is fluence, 'E' energy deposit*/
char outputformat; /**<'mc2' output is text, 'nii': binary, 'img': regular json, 'ubj': universal binary json*/
char faststep; /**<1 use tMCimg-like approximated photon stepping (obsolete) */
Expand Down
2 changes: 1 addition & 1 deletion src/mcxlab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ void mcx_set_field(const mxArray* root, const mxArray* item, int idx, Config* cf
int len = mxGetNumberOfElements(item);
const char* srctypeid[] = {"pencil", "isotropic", "cone", "gaussian", "planar",
"pattern", "fourier", "arcsine", "disk", "fourierx", "fourierx2d", "zgaussian",
"line", "slit", "pencilarray", "pattern3d", "hyperboloid", ""
"line", "slit", "pencilarray", "pattern3d", "hyperboloid", "ring", ""
};
char strtypestr[MAX_SESSION_LENGTH] = {'\0'};

Expand Down
2 changes: 1 addition & 1 deletion src/pmcx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ void parse_config(const py::dict& user_cfg, Config& mcx_config) {
std::string src_type = py::str(user_cfg["srctype"]);
const char* srctypeid[] = {"pencil", "isotropic", "cone", "gaussian", "planar",
"pattern", "fourier", "arcsine", "disk", "fourierx", "fourierx2d", "zgaussian",
"line", "slit", "pencilarray", "pattern3d", "hyperboloid", ""
"line", "slit", "pencilarray", "pattern3d", "hyperboloid", "ring", ""
};
char strtypestr[MAX_SESSION_LENGTH] = {'\0'};

Expand Down
2 changes: 1 addition & 1 deletion src/pybind11
Submodule pybind11 updated 79 files
+61 −65 .clang-tidy
+3 −5 .github/CONTRIBUTING.md
+4 −0 .github/dependabot.yml
+23 −40 .github/workflows/ci.yml
+1 −1 .github/workflows/configure.yml
+4 −6 .github/workflows/format.yml
+5 −7 .github/workflows/pip.yml
+3 −3 .github/workflows/upstream.yml
+11 −14 .pre-commit-config.yaml
+0 −13 CMakeLists.txt
+0 −3 docs/_static/css/custom.css
+11 −0 docs/_static/theme_overrides.css
+2 −2 docs/advanced/cast/custom.rst
+3 −3 docs/advanced/cast/stl.rst
+2 −2 docs/advanced/classes.rst
+2 −2 docs/advanced/pycpp/numpy.rst
+1 −1 docs/advanced/smart_ptrs.rst
+12 −160 docs/changelog.rst
+1 −1 docs/classes.rst
+17 −6 docs/conf.py
+ docs/pybind11-logo.png
+3 −4 docs/requirements.txt
+3 −5 include/pybind11/attr.h
+5 −5 include/pybind11/cast.h
+30 −23 include/pybind11/detail/class.h
+2 −21 include/pybind11/detail/common.h
+1 −1 include/pybind11/detail/init.h
+0 −1 include/pybind11/detail/internals.h
+66 −0 include/pybind11/detail/type_caster_base.h
+3 −9 include/pybind11/detail/typeid.h
+6 −17 include/pybind11/eigen.h
+32 −56 include/pybind11/embed.h
+2 −2 include/pybind11/functional.h
+1 −1 include/pybind11/iostream.h
+8 −19 include/pybind11/numpy.h
+26 −44 include/pybind11/pybind11.h
+64 −338 include/pybind11/pytypes.h
+6 −6 include/pybind11/stl.h
+6 −16 noxfile.py
+1 −2 pybind11/__init__.py
+1 −8 pybind11/__main__.py
+1 −1 pybind11/_version.py
+0 −12 pybind11/commands.py
+1 −2 setup.cfg
+0 −1 setup.py
+0 −1 tests/CMakeLists.txt
+1 −14 tests/conftest.py
+0 −51 tests/cross_module_interleaved_error_already_set.cpp
+58 −68 tests/extra_python_package/test_files.py
+0 −25 tests/pybind11_tests.cpp
+1 −1 tests/requirements.txt
+2 −8 tests/test_builtin_casters.cpp
+2 −2 tests/test_constants_and_functions.cpp
+7 −7 tests/test_custom_type_casters.cpp
+2 −5 tests/test_eigen.cpp
+0 −7 tests/test_eigen.py
+1 −1 tests/test_embed/CMakeLists.txt
+2 −47 tests/test_exceptions.cpp
+3 −99 tests/test_exceptions.py
+1 −10 tests/test_kwargs_and_defaults.cpp
+9 −21 tests/test_methods_and_attributes.py
+0 −2 tests/test_modules.cpp
+0 −30 tests/test_modules.py
+1 −1 tests/test_numpy_array.cpp
+1 −1 tests/test_numpy_dtypes.cpp
+1 −1 tests/test_numpy_vectorize.cpp
+0 −183 tests/test_pytypes.cpp
+0 −129 tests/test_pytypes.py
+2 −2 tests/test_smart_ptr.cpp
+8 −15 tests/test_stl.cpp
+2 −2 tests/test_tagbased_polymorphic.cpp
+3 −2 tests/test_virtual_functions.cpp
+11 −21 tools/FindPythonLibsNew.cmake
+0 −23 tools/JoinPaths.cmake
+0 −7 tools/pybind11.pc.in
+1 −3 tools/pybind11NewTools.cmake
+11 −32 tools/pybind11Tools.cmake
+0 −2 tools/setup_global.py.in
+0 −2 tools/setup_main.py.in
6 changes: 5 additions & 1 deletion utils/mcxpreview.m
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,16 @@
% rendering area-source aperature
hsrcarea=[];
if(isfield(cfg(i),'srctype'))
if(strcmp(cfg(i).srctype,'disk') || strcmp(cfg(i).srctype,'gaussian') || strcmp(cfg(i).srctype,'zgaussian'))
if(strcmp(cfg(i).srctype,'disk') || strcmp(cfg(i).srctype,'gaussian') || strcmp(cfg(i).srctype,'zgaussian') || strcmp(cfg(i).srctype,'ring'))
if(~isfield(cfg(i),'srcparam1'))
error('cfg.srcparam1 is missing');
end
[ncyl,fcyl]=meshacylinder(srcpos,srcpos+cfg(i).srcdir(1:3)*1e-5,cfg(i).srcparam1(1)*voxelsize,0,0);
hsrcarea=plotmesh(ncyl,fcyl{end-1},'facecolor','r','linestyle','none');
if(cfg(1).srcparam1(2) > 0)
[ncyl,fcyl]=meshacylinder(srcpos,srcpos+cfg(i).srcdir(1:3)*1e-5,cfg(i).srcparam1(2)*voxelsize,0,0);
hsrcarea=plotmesh(ncyl,fcyl{end-1},'facecolor','k','linestyle','none');
end
elseif(strcmp(cfg(i).srctype,'planar') || strcmp(cfg(i).srctype,'pattern') || strcmp(cfg(i).srctype,'fourier') || ...
strcmp(cfg(i).srctype,'fourierx') || strcmp(cfg(i).srctype,'fourierx2d') || strcmp(cfg(i).srctype,'pencilarray'))
if(~isfield(cfg(i),'srcparam1') || ~isfield(cfg(i),'srcparam2'))
Expand Down

0 comments on commit ad6ff4c

Please sign in to comment.