├── .git_filters ├── rcs-keywords.clean └── rcs-keywords.smudge ├── .gitattributes ├── .github └── workflows │ └── build_all.yml ├── .travis.yml ├── AUTHORS.txt ├── ChangeLog.txt ├── LICENSE.txt ├── README.md ├── README.txt ├── Reference.txt ├── commons └── Makefile_common.mk ├── deploy └── buildmmc.sh ├── examples ├── README.txt ├── colin27 │ ├── README.txt │ ├── brain.inp │ ├── createmesh.m │ ├── prop_brain.dat │ └── run_test.sh ├── dcs │ ├── README.txt │ ├── createmesh.m │ ├── dcs.inp │ ├── dcs_example.m │ ├── dcs_g1_Db.m │ ├── dcs_g1_Db_fms.m │ ├── dcs_g2_Db.m │ ├── dcs_g2_Db_fms.m │ ├── prop_dcs.dat │ └── run_test.sh ├── mcxsph │ ├── benchbox.sh │ ├── box.inp │ ├── createmcxbin.m │ ├── runspherebox.sh │ └── spherebox.inp ├── meshtest │ ├── README.txt │ ├── createmesh.m │ ├── mesh0.inp │ ├── mesh0.json │ ├── mesh1.inp │ ├── mesh1.json │ ├── mesh2.inp │ ├── mesh2.json │ ├── plotmmcsph.m │ ├── prop_mesh0.dat │ ├── prop_mesh1.dat │ ├── prop_mesh2.dat │ ├── run_test.sh │ └── sphdiffsemiinf.mat ├── misctest │ └── bary_external.m ├── mmclbench │ └── run_bench.sh ├── onecube │ ├── README.txt │ ├── createmesh.m │ ├── elem_onecube.dat │ ├── facenb_onecube.dat │ ├── node_onecube.dat │ ├── onecube.inp │ ├── onecube.json │ ├── onecube_isotropic.json │ ├── plotmmcdebug.m │ ├── prop_onecube.dat │ ├── run_test.sh │ ├── velem_onecube.dat │ └── vnode_onecube.dat ├── planar │ ├── README.txt │ ├── addsource_digimouse.m │ ├── planar.inp │ ├── plotresult.m │ ├── pointsrc.inp │ ├── prop_digimouse.dat │ └── run_test.sh ├── reftest │ ├── README.txt │ ├── createmesh.m │ ├── elem_onecube.dat │ ├── facenb_onecube.dat │ ├── node_onecube.dat │ ├── onecube.inp │ ├── plotmmcdebug.m │ ├── prop_onecube.dat │ ├── run_test.sh │ └── velem_onecube.dat ├── regression │ └── exitangle │ │ ├── phantom.m │ │ ├── prop_tank.dat │ │ ├── run_test_planar.sh │ │ ├── tank_planar.inp │ │ └── testexitdir.m ├── replay │ ├── createmesh.m │ ├── plotjacobian.m │ ├── prop_replaytest.dat │ ├── replaytest.inp │ └── run_test.sh ├── replaywide │ ├── createmesh.m │ ├── createpattern.m │ ├── init_MC.inp │ ├── plotresults.m │ ├── prop_replaywide.dat │ ├── replay1.inp │ ├── replay2.inp │ ├── replay3.inp │ └── run_test.sh ├── rngtest │ ├── Makefile │ ├── makefile_logistic │ ├── makefile_sfmt │ └── rngtest.c ├── sfdi2layer │ ├── README.txt │ ├── createmesh.m │ ├── plot_result.m │ ├── prop_sfdi.dat │ ├── run_test.sh │ └── sfdi.inp ├── sharing │ ├── README.txt │ ├── createmesh.m │ ├── createpattern.m │ ├── plotresults.m │ ├── prop_sharing.dat │ ├── run_test.sh │ └── sharing.inp ├── skinvessel │ ├── createsession.m │ ├── dmmc_skinvessel.json │ ├── elem_dmmc_skinvessel.dat │ ├── face_dmmc_skinvessel.dat │ ├── facenb_dmmc_skinvessel.dat │ ├── node_dmmc_skinvessel.dat │ ├── prop_dmmc_skinvessel.dat │ ├── run_dmmc.sh │ ├── run_mmc.sh │ ├── skinvessel.json │ └── velem_dmmc_skinvessel.dat ├── sphere │ ├── README.txt │ ├── addsource_sphere.m │ ├── planar.inp │ ├── plotresults.m │ ├── prop_sphere.dat │ └── run_test.sh ├── sphshells │ ├── createsession.m │ ├── dmmc_sphshells.json │ ├── elem_dmmc_sphshells.dat │ ├── face_dmmc_sphshells.dat │ ├── facenb_dmmc_sphshells.dat │ ├── node_dmmc_sphshells.dat │ ├── prop_dmmc_sphshells.dat │ ├── run_dmmc.sh │ ├── run_mmc.sh │ └── velem_dmmc_sphshells.dat ├── ssehmin │ └── ssehmin_test.c ├── statnoise │ ├── README.txt │ ├── createmesh.m │ ├── prop_cube20.dat │ ├── run_test.sh │ ├── vartest.inp │ └── vartest.json ├── validation │ ├── README.txt │ ├── benchspeed.sh │ ├── createmesh.m │ ├── cube.inp │ ├── cube.json │ ├── cube2.inp │ ├── cube2.json │ ├── elem_cube2.dat │ ├── facenb_cube2.dat │ ├── node_cube2.dat │ ├── plotcuberes.m │ ├── prop_cube.dat │ ├── prop_cube2.dat │ ├── run_tess.sh │ ├── run_test.sh │ ├── tessmesh.m │ └── velem_cube2.dat └── widedet │ ├── README.txt │ ├── createmesh.m │ ├── plot_results.m │ ├── prop_widedet.dat │ ├── run_test.sh │ └── widedet.inp ├── matlab ├── README_spherediffusion.txt ├── besselhprime.m ├── besseljprime.m ├── besselyprime.m ├── cart2sphorigin.m ├── genT5mesh.m ├── genT6mesh.m ├── generate_g1.m ├── load_mc_prop.m ├── loadmch.m ├── mmcadddet.m ├── mmcaddsrc.m ├── mmcdettime.m ├── mmcdettpsf.m ├── mmcdetweight.m ├── mmcjacobian.m ├── mmcjmua.m ├── mmcjmus.m ├── mmcmeanpath.m ├── mmcmeanscat.m ├── mmcraytrace.m ├── mmcsrcdomain.m ├── readmmcelem.m ├── readmmcface.m ├── readmmcmesh.m ├── readmmcnode.m ├── savemmcmesh.m ├── spbesselh.m ├── spbesselhprime.m ├── spbesselj.m ├── spbesseljprime.m ├── spbessely.m ├── spbesselyprime.m ├── spharmonic.m ├── sphdiffAcoeff.m ├── sphdiffBcoeff.m ├── sphdiffCcoeff.m ├── sphdiffexterior.m ├── sphdiffincident.m ├── sphdiffinterior.m ├── sphdiffscatter.m ├── sphdiffusion.m ├── sphdiffusioninfinite.m ├── sphdiffusionscatteronly.m ├── sphdiffusionsemi.m └── sphdiffusionslab.m ├── mmclab ├── LICENSE.txt ├── PKG_ADD ├── README.txt ├── example │ ├── demo_compare_mmc_mcx.m │ ├── demo_dmmc_sphshells.m │ ├── demo_dualmesh_output.m │ ├── demo_example_meshtest.m │ ├── demo_example_onecube.m │ ├── demo_example_replay.m │ ├── demo_example_validation.m │ ├── demo_head_atlas.m │ ├── demo_immc_basic.m │ ├── demo_immc_vessel.m │ ├── demo_mcxyz_skinvessel.m │ ├── demo_mmcl_b1_b1d.m │ ├── demo_mmcl_b2_b2d.m │ ├── demo_mmcl_b3.m │ ├── demo_mmcl_b4.m │ ├── demo_mmclab_basic.m │ ├── demo_mmclab_slit.m │ ├── demo_photon_sharing.m │ ├── demo_sfdi_2layer.m │ ├── demo_wide_det.m │ ├── head_atlas.mat │ ├── mmclab_selftest_input.m │ ├── test_albedo.m │ └── vessel.mat ├── mmc2json.m └── mmclab.m ├── src ├── CMakeLists.txt ├── Makefile ├── SFMT │ ├── LICENSE.txt │ ├── SFMT-params.h │ ├── SFMT-params19937.h │ ├── SFMT-sse2.h │ ├── SFMT.c │ └── SFMT.h ├── buildmmc.m ├── cjson │ ├── LICENSE │ ├── README │ ├── cJSON.c │ ├── cJSON.h │ └── test.c ├── makefile_logistic ├── makefile_sfmt ├── makefile_xorshift ├── mexopts_cygwin64_gcc.bat ├── mexopts_maci64_gcc.xml ├── mexopts_msys2_gcc.xml ├── mingw64 │ └── include │ │ ├── CL │ │ ├── cl.h │ │ ├── cl_d3d10.h │ │ ├── cl_d3d11.h │ │ ├── cl_dx9_media_sharing.h │ │ ├── cl_dx9_media_sharing_intel.h │ │ ├── cl_egl.h │ │ ├── cl_ext.h │ │ ├── cl_ext_intel.h │ │ ├── cl_gl.h │ │ ├── cl_gl_ext.h │ │ ├── cl_platform.h │ │ ├── cl_va_api_media_sharing_intel.h │ │ └── opencl.h │ │ ├── _ansi.h │ │ ├── features.h │ │ ├── ieee754.h │ │ └── sys │ │ ├── ioctl.h │ │ └── termios.h ├── mmc.c ├── mmc_bench.c ├── mmc_bench.h ├── mmc_cl_host.c ├── mmc_cl_host.h ├── mmc_cl_utils.c ├── mmc_cl_utils.h ├── mmc_const.h ├── mmc_core.cl ├── mmc_core.cu ├── mmc_cu_host.cu ├── mmc_cu_host.h ├── mmc_doxygen.cfg ├── mmc_fastmath.h ├── mmc_highorder.cpp ├── mmc_highorder.h ├── mmc_host.c ├── mmc_host.h ├── mmc_mesh.c ├── mmc_mesh.h ├── mmc_neurojson.cpp ├── mmc_neurojson.h ├── mmc_rand_common.h ├── mmc_rand_drand48.c ├── mmc_rand_drand48.h ├── mmc_rand_logistic.c ├── mmc_rand_logistic.h ├── mmc_rand_posix.c ├── mmc_rand_posix.h ├── mmc_rand_sfmt.c ├── mmc_rand_sfmt.h ├── mmc_rand_xorshift128p.c ├── mmc_rand_xorshift128p.h ├── mmc_raytrace.c ├── mmc_raytrace.h ├── mmc_tictoc.c ├── mmc_tictoc.h ├── mmc_utils.c ├── mmc_utils.h ├── mmclab.cpp ├── nifti1.h ├── sse_math │ └── sse_math.h ├── ubj │ ├── CMakeLists.txt │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── ubj.h │ ├── ubj_internal.h │ ├── ubjr.c │ ├── ubjrw.c │ └── ubjw.c ├── vector_types.h └── zmat │ ├── CMakeLists.txt │ ├── Makefile │ ├── easylzma │ ├── Makefile │ ├── README │ ├── common_internal.c │ ├── common_internal.h │ ├── compress.c │ ├── decompress.c │ ├── easylzma │ │ ├── common.h │ │ ├── compress.h │ │ └── decompress.h │ ├── lzip_header.c │ ├── lzip_header.h │ ├── lzma_header.c │ ├── lzma_header.h │ └── pavlov │ │ ├── 7zBuf.c │ │ ├── 7zBuf.h │ │ ├── 7zBuf2.c │ │ ├── 7zCrc.c │ │ ├── 7zCrc.h │ │ ├── 7zFile.c │ │ ├── 7zFile.h │ │ ├── 7zStream.c │ │ ├── 7zVersion.h │ │ ├── Alloc.c │ │ ├── Alloc.h │ │ ├── Bcj2.c │ │ ├── Bcj2.h │ │ ├── Bra.c │ │ ├── Bra.h │ │ ├── Bra86.c │ │ ├── BraIA64.c │ │ ├── CpuArch.h │ │ ├── LzFind.c │ │ ├── LzFind.h │ │ ├── LzHash.h │ │ ├── LzmaDec.c │ │ ├── LzmaDec.h │ │ ├── LzmaEnc.c │ │ ├── LzmaEnc.h │ │ ├── LzmaLib.c │ │ ├── LzmaLib.h │ │ └── Types.h │ ├── lz4 │ ├── lz4.c │ ├── lz4.h │ ├── lz4hc.c │ └── lz4hc.h │ ├── miniz │ ├── ChangeLog.md │ ├── LICENSE │ ├── miniz.c │ ├── miniz.h │ ├── readme.md │ └── zlib.h │ ├── zmat.cpp │ ├── zmatlib.c │ └── zmatlib.h ├── webmmc ├── Makefile ├── make.bat ├── webmmc.cc ├── webmmc.html └── webmmc.nmf └── win32 └── cbuilder ├── mmc.cbproj └── mmcbcc.h /.git_filters/rcs-keywords.clean: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -p 2 | # 3 | # @brief Git filter to implement rcs keyword expansion as seen in cvs and svn. 4 | # @author Martin Turon 5 | # 6 | # Copyright (c) 2009-2011 Turon Technologies, Inc. All rights reserved. 7 | 8 | s/(\$Id)((::)*)([^\$]*)\$/TR($1,$4,$2)/eo; 9 | s/(\$Date)((::)*)([^\$]*)\$/TR($1,$4,$2)/eo; 10 | s/(\$Author)((::)*)([^\$]*)\$/TR($1,$4,$2)/eo; 11 | s/(\$Source)((::)*)([^\$]*)\$/TR($1,$4,$2)/eo; 12 | s/(\$File)((::)*)([^\$]*)\$/TR($1,$4,$2)/eo; 13 | s/(\$Rev)((::)*)([^\$]*)\$/TR($1,$4,$2)/eo; 14 | s/(\$Revision)((::)*)([^\$]*)\$/TR($1,$4,$2)/eo; 15 | 16 | sub TR{ 17 | my ($pre,$from,$fix)=@_; 18 | return $pre.$fix.(" " x length($from)).'$'; 19 | } 20 | -------------------------------------------------------------------------------- /.git_filters/rcs-keywords.smudge: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # 3 | # @brief Git filter to implement rcs keyword expansion as seen in cvs and svn. 4 | # @author Martin Turon 5 | # 6 | # Usage: 7 | # .git_filter/rcs-keywords.smudge file_path < file_contents 8 | # 9 | # To add keyword expansion: 10 | # /.gitattributes - *.c filter=rcs-keywords 11 | # /.git_filters/rcs-keywords.smudge - copy this file to project 12 | # /.git_filters/rcs-keywords.clean - copy companion to project 13 | # ~/.gitconfig - add [filter] lines below 14 | # 15 | # [filter "rcs-keywords"] 16 | # clean = .git_filters/rcs-keywords.clean 17 | # smudge = .git_filters/rcs-keywords.smudge %f 18 | # 19 | # Copyright (c) 2009-2011 Turon Technologies, Inc. All rights reserved. 20 | 21 | $path = shift; 22 | $path =~ /.*\/(.*)/; 23 | $filename = $1; 24 | 25 | if (0 == length($filename)) { 26 | $filename = $path; 27 | } 28 | 29 | # Need to grab filename and to use git log for this to be accurate. 30 | $rev = `git log --date=iso -- | head -n 3`; 31 | $rev =~ /^Author:\s*(.*)\s*$/m; 32 | $author = $1; 33 | $author =~ /\s*(.*)\s*<.*/; 34 | $name = $1; 35 | $rev =~ /^Date:\s*(.*)\s*$/m; 36 | $date = $1; 37 | $rev =~ /^commit (.*)$/m; 38 | $ident = $1; 39 | $shortident = substr($ident,0, 6); 40 | 41 | while () { 42 | s/\$Date(((::)*)[^\$]*)\$/TR("\$Date",$1,$date,$2,"\$")/eo; 43 | s/\$Author(((::)*)[^\$]*)\$/TR("\$Author",$1,$author,$2,"\$")/eo; 44 | s/\$Id(((::)*)[^\$]*)\$/TR("\$Id",$1,"$filename | $date | $name",$2,"\$")/eo; 45 | s/\$File(((::)*)[^\$]*)\$/TR("\$File",$1,$filename,$2,"\$")/eo; 46 | s/\$Source(((::)*)[^\$]*)\$/TR("\$Source",$1,$path,$2,"\$")/eo; 47 | s/\$Rev(((::)*)[^\$]*)\$/TR("\$Rev",$1,$shortident,$2,"\$")/eo; 48 | s/\$Revision(((::)*)[^\$]*)\$/TR("\$Revision",$1,$ident,$2,"\$")/eo; 49 | } continue { 50 | print or die "-p destination: $!\n"; 51 | } 52 | 53 | sub TR{ 54 | my ($pre,$from,$to,$fix,$post)=@_; 55 | return $pre.$to.$post if($fix eq ''); 56 | 57 | $pre.=$fix; 58 | if(length($from) mov.txt 4 | ../../bin/mmc -n 20 -f onecube.inp -s onecube -G -1 -D MA | grep '^[A-Z]' | sed -e 's/^[A-Z] //g' | sed '$d' > ad.txt 5 | -------------------------------------------------------------------------------- /examples/onecube/velem_onecube.dat: -------------------------------------------------------------------------------- 1 | 1 6 2 | 1 1.666667e+02 3 | 2 1.666667e+02 4 | 3 1.666667e+02 5 | 4 1.666667e+02 6 | 5 1.666667e+02 7 | 6 1.666667e+02 8 | -------------------------------------------------------------------------------- /examples/onecube/vnode_onecube.dat: -------------------------------------------------------------------------------- 1 | 1 8 2 | 1 2.500000e+02 3 | 2 8.333333e+01 4 | 3 8.333333e+01 5 | 4 8.333333e+01 6 | 5 8.333333e+01 7 | 6 8.333333e+01 8 | 7 8.333333e+01 9 | 8 2.500000e+02 10 | -------------------------------------------------------------------------------- /examples/planar/README.txt: -------------------------------------------------------------------------------- 1 | = Validation of uniform planar source = 2 | 3 | == Introduction == 4 | 5 | In this example, we test a simple widefield source -- uniform planar on a digimouse mesh model. 6 | Three corners of the 3D quadrilateral are specified by srcpos, srcpos+srcparam1(0:2), srcpos+srcparam2(0:2). 7 | The original mesh is re-tessellated after adding source nodes in addsource.m . 8 | The digimouse mesh model can be downloaded at http://mcx.sourceforge.net/cgi-bin/index.cgi?MMC/DigimouseMesh 9 | -------------------------------------------------------------------------------- /examples/planar/addsource_digimouse.m: -------------------------------------------------------------------------------- 1 | if (~exist('Digimouse_Mesh_1L.mat', 'file')) 2 | if (~exist('digimouse_mesh_version_1L.tar.gz', 'file')) 3 | websave('digimouse_mesh_version_1L.tar.gz', 'http://downloads.sourceforge.net/project/mcx/mmc/Digimouse%20FEM%20Mesh/Version%201/digimouse_mesh_version_1L.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fmcx%2Ffiles%2Fmmc%2FDigimouse%2520FEM%2520Mesh%2FVersion%25201%2F&ts=1450931781&use_mirror=skylineservers'); 4 | end 5 | if (~exist('digimouse_mesh_version_1L.tar', 'file')) 6 | gunzip('digimouse_mesh_version_1L.tar.gz'); 7 | end 8 | if (~exist('digimouse_mesh/Digimouse_Mesh_1L.mat', 'file')) 9 | untar('digimouse_mesh_version_1L.tar'); 10 | movefile('digimouse_mesh/Digimouse_Mesh_1L.mat', './Digimouse_Mesh_1L.mat'); 11 | end 12 | end 13 | load Digimouse_Mesh_1L; 14 | elem(:, 5) = 1; 15 | 16 | cfg = struct('srctype', 'planar', 'srcpos', [15 50 25], 'srcdir', [0 0 -1], ... 17 | 'srcparam1', [10 0 0 0], 'srcparam2', [0 10 0 0]); 18 | 19 | [newnode, newelem] = mmcaddsrc(node, elem, cfg); 20 | savemmcmesh('digimouse', newnode, newelem); 21 | -------------------------------------------------------------------------------- /examples/planar/planar.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon counts (normally not used) 2 | 1648335518 # RNG seed, negative to generate 3 | 15.0 50.0 25.0 # source position in mm (corner 1) 4 | 0.0 0.0 -1.0 # initial directional vector 5 | 0 5e-09 1e-10 # time-gates(s): start, end, step 6 | digimouse # volume ('uchar' format) 7 | -1 # eid (not actually used) 8 | 5 2.0 # total number of detectors and radius 9 | 15.0 50.0 0.0 # detector 1 position (mm) 10 | 15.0 60.0 0.0 11 | 25.0 50.0 0.0 12 | 25.0 60.0 0.0 13 | 20.0 55.0 0.0 14 | planar # source type 15 | 10.0 0.0 0.0 0.0 # parameters set 1 16 | 0.0 10.0 0.0 0.0 # parameters set 2 17 | -------------------------------------------------------------------------------- /examples/planar/plotresult.m: -------------------------------------------------------------------------------- 1 | figure; 2 | load enterpos.txt; 3 | subplot(121); 4 | plotmesh(enterpos(:, 1:3), '.'); 5 | load exitpos.txt; 6 | subplot(122); 7 | plotmesh(exitpos(:, 1:3), '.'); 8 | -------------------------------------------------------------------------------- /examples/planar/pointsrc.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon counts (normally not used) 2 | 1648335518 # RNG seed, negative to generate 3 | 21.576111 52.056393 25.0 # source position in mm (corner 1) 4 | 0.0 0.0 -1.0 # initial directional vector 5 | 0 5e-09 1e-10 # time-gates(s): start, end, step 6 | digimouse # volume ('uchar' format) 7 | 252886 # eid (not actually used) 8 | 5 2.0 # total number of detectors and radius 9 | 15.0 50.0 0.0 # detector 1 position (mm) 10 | 15.0 60.0 0.0 11 | 25.0 50.0 0.0 12 | 25.0 60.0 0.0 13 | 20.0 55.0 0.0 14 | pencil # source type 15 | 0.0 0.0 0.0 0.0 # parameters set 1 16 | 0.0 0.0 0.0 0.0 # parameters set 2 17 | -------------------------------------------------------------------------------- /examples/planar/prop_digimouse.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.03 15 0.9 1.37 3 | 4 | -------------------------------------------------------------------------------- /examples/planar/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -n 100000 -f planar.inp -s planar -b 1 -x 1 -D E > debug.txt 4 | grep '^x ' debug.txt | sed -e 's/^x //g'> exitpos.txt 5 | grep '^e ' debug.txt | sed -e 's/^e //g'> enterpos.txt 6 | 7 | #../../bin/mmc -n 1 -f planar.inp -s planar -b 1 -x 1 -D M | sed -e 's/^M/1/g' -e 's/^B/0/g' -e 's/P/2/g'| sed '$d' > mov.txt 8 | #../../bin/mmc -n 1 -f planar.inp -s planar -b 1 -x 1 -D MA | sed -e 's/^[A-Z] //g' | sed '$d' > ad.txt 9 | 10 | #../../bin/mmc -n 1000000 -f planar.inp -s planar -b 1 -x 1 -D TP 11 | -------------------------------------------------------------------------------- /examples/reftest/README.txt: -------------------------------------------------------------------------------- 1 | = Visual debugging of photon migration in a simple mesh = 2 | 3 | == Introduction == 4 | 5 | In this example, we run photon migration in a toy-problem to show 6 | the basic steps and behaviors of the simulation code. 7 | The mesh used in this case is a simple cube, splitted into 8 | 6 tetrahedra. The edge length of the cube is 10mm. 9 | A total of 20 photons are simulated starting 10 | from a source position [2,8,0] along an incident 11 | vector [0 0 1]. We run the simulation and print out 12 | the moving trajectories of the photon, and the exit and 13 | accumulation sites. Using a matlab script, one can visualize 14 | the photon moving from the output of the simulation. 15 | 16 | == Steps == 17 | 18 | 1. The mesh files for this example has already been generated. 19 | if you want to regenerate the mesh files, please open matlab 20 | or octave and run "createmesh" 21 | 22 | 2. Run the simulation by typing 23 | ./run_test.sh 24 | 25 | 3. Start matlab, run "plotmmcdebug" to see the photon trajectory plot 26 | -------------------------------------------------------------------------------- /examples/reftest/createmesh.m: -------------------------------------------------------------------------------- 1 | sessionid = 'onecube'; 2 | 3 | addpath('../../matlab/'); 4 | [node, elem] = genT6mesh(0:1, 0:1, 0:1); 5 | elem = sortrows(elem); 6 | elem(:, 1:4) = meshreorient(node, elem(:, 1:4)); 7 | elem(:, 5) = 1; 8 | 9 | node = node * 10; 10 | 11 | srcpos = [2, 8, 0]; 12 | eid = tsearchn(node, elem(:, 1:4), srcpos); 13 | elem(eid, 5) = 2; 14 | savemmcmesh(sessionid, node, elem, []); 15 | -------------------------------------------------------------------------------- /examples/reftest/elem_onecube.dat: -------------------------------------------------------------------------------- 1 | 1 6 2 | 1 1 2 8 4 1 3 | 2 1 2 6 8 1 4 | 3 1 3 4 8 2 5 | 4 1 3 8 7 1 6 | 5 1 5 8 6 1 7 | 6 1 5 7 8 1 8 | -------------------------------------------------------------------------------- /examples/reftest/facenb_onecube.dat: -------------------------------------------------------------------------------- 1 | 1 6 2 | 2 0 3 0 3 | 0 1 5 0 4 | 0 4 1 0 5 | 3 0 6 0 6 | 6 0 2 0 7 | 0 5 4 0 8 | -------------------------------------------------------------------------------- /examples/reftest/node_onecube.dat: -------------------------------------------------------------------------------- 1 | 1 8 2 | 1 0.00000000e+00 0.00000000e+00 0.00000000e+00 3 | 2 1.00000000e+01 0.00000000e+00 0.00000000e+00 4 | 3 0.00000000e+00 1.00000000e+01 0.00000000e+00 5 | 4 1.00000000e+01 1.00000000e+01 0.00000000e+00 6 | 5 0.00000000e+00 0.00000000e+00 1.00000000e+01 7 | 6 1.00000000e+01 0.00000000e+00 1.00000000e+01 8 | 7 0.00000000e+00 1.00000000e+01 1.00000000e+01 9 | 8 1.00000000e+01 1.00000000e+01 1.00000000e+01 10 | -------------------------------------------------------------------------------- /examples/reftest/onecube.inp: -------------------------------------------------------------------------------- 1 | 100 # total photon 2 | 17182818 # RNG seed, negative to generate 3 | 2 8 0.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.e+00 5.e-09 5e-10 # time-gates(s): start, end, step 6 | onecube # volume ('uchar' format) 7 | 3 8 | 4 1 # detector number and radius (mm) 9 | 30.0 20.0 1.0 # detector 1 position (mm) 10 | 30.0 40.0 1.0 # ... 11 | 20.0 30.0 1.0 12 | 40.0 30.0 1.0 13 | -------------------------------------------------------------------------------- /examples/reftest/plotmmcdebug.m: -------------------------------------------------------------------------------- 1 | addpath('../../matlab/'); 2 | node = readmmcnode('node_onecube.dat'); 3 | elem = readmmcelem('elem_onecube.dat'); 4 | 5 | load ad.txt; 6 | load mov.txt; 7 | 8 | figure; 9 | hh = tetramesh(elem, node); 10 | set(hh, 'facealpha', 0.1); 11 | hold on; 12 | photonnum = max(mov(:, end - 1)); 13 | for i = 0:photonnum 14 | idx = find(mov(:, end - 1) == i); 15 | plot3(mov(idx, 2), mov(idx, 3), mov(idx, 4), '.-'); 16 | end 17 | idx = find(mov(:, 1) == 0); 18 | plot3(mov(idx, 2), mov(idx, 3), mov(idx, 4), 'co'); 19 | 20 | idx = find(mov(:, 1) == 2); 21 | plot3(mov(idx, 2), mov(idx, 3), mov(idx, 4), '+'); 22 | 23 | idx = find(mov(:, 1) == 3); 24 | plot3(mov(idx, 2), mov(idx, 3), mov(idx, 4), 'co'); 25 | 26 | plot3(ad(:, 1), ad(:, 2), ad(:, 3), 'r.'); 27 | -------------------------------------------------------------------------------- /examples/reftest/prop_onecube.dat: -------------------------------------------------------------------------------- 1 | 1 2 2 | 1 0.005 1.0101010101 0.01 1.0 3 | 2 0.005 1.0101010101 0.01 1.37 4 | -------------------------------------------------------------------------------- /examples/reftest/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -n 20 -f onecube.inp -s onecube -b 1 -D M | sed -e 's/^M/1/g' -e 's/^B/0/g' -e 's/P/2/g' -e 's/T/3/g'| sed '$d' > mov.txt 4 | ../../bin/mmc -n 20 -f onecube.inp -s onecube -b 1 -D MA | sed -e 's/^[A-Z] //g' | sed '$d' > ad.txt 5 | -------------------------------------------------------------------------------- /examples/reftest/velem_onecube.dat: -------------------------------------------------------------------------------- 1 | 1 6 2 | 1 1.666667e+02 3 | 2 1.666667e+02 4 | 3 1.666667e+02 5 | 4 1.666667e+02 6 | 5 1.666667e+02 7 | 6 1.666667e+02 8 | -------------------------------------------------------------------------------- /examples/regression/exitangle/phantom.m: -------------------------------------------------------------------------------- 1 | clear; 2 | phantom_l = 50; 3 | phantom_w = 40; 4 | phantom_h = 21; 5 | bar_dis = 16.8; 6 | bar_h = 11; 7 | bar_c1 = [(phantom_l - bar_dis) / 2, bar_h]; 8 | bar_c2 = [(phantom_l + bar_dis) / 2, bar_h]; 9 | 10 | %% old mesh 11 | 12 | [node, face, elem] = meshabox([0 0 0], [phantom_l phantom_w phantom_h], 1.2, 10); 13 | elem(:, 1:4) = meshreorient(node(:, 1:3), elem(:, 1:4)); 14 | elem(:, 5) = 1; 15 | plotmesh(node, elem); 16 | 17 | % savemmcmesh('tank',node,elem); 18 | 19 | %% add source 20 | 21 | source = [5 5 23]; 22 | source_dir = [0 0 -1]; 23 | param1 = [40 0 0 0]; 24 | param2 = [0 30 0 0]; 25 | cfg = struct('srctype', 'planar', 'srcpos', source, 'srcdir', source_dir, 'srcparam1', param1, 'srcparam2', param2); 26 | source_domain = mmcsrcdomain(cfg, [min(node); max(node)]); 27 | 28 | [newnode, newelem] = mmcaddsrc(node, elem, source_domain); 29 | plotmesh(newnode, newelem); 30 | 31 | savemmcmesh('tank', newnode, newelem); 32 | -------------------------------------------------------------------------------- /examples/regression/exitangle/prop_tank.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.002 7 0.9 1.35 3 | 4 | -------------------------------------------------------------------------------- /examples/regression/exitangle/run_test_planar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | date 3 | 4 | ../../../bin/mmc -n 1000000 -f tank_planar.inp -s tank_planar -b 1 -x 1 -U 0 -D TP 5 | 6 | date 7 | -------------------------------------------------------------------------------- /examples/regression/exitangle/testexitdir.m: -------------------------------------------------------------------------------- 1 | dat = loadmch('tank_planar.mch'); 2 | dd = dat(:, 7:9); 3 | dl = sqrt(sum(dd .* dd, 2)); 4 | % plot(dl) 5 | 6 | find(sum(dd(:, 1:2) .* dd(:, 1:2), 2) < 1e-5); 7 | -------------------------------------------------------------------------------- /examples/replay/createmesh.m: -------------------------------------------------------------------------------- 1 | % you may also use meshgrid5 in iso2mesh 1.7.9 or newer 2 | % it is identical to genT5mesh 3 | 4 | srcpos = [30.1 30.2 0.0]; 5 | [node, elem] = genT6mesh(0:2:60, 0:2:60, 0:2:60); 6 | e0 = tsearchn(node, elem, srcpos); 7 | savemmcmesh('replaytest', node, elem); 8 | -------------------------------------------------------------------------------- /examples/replay/plotjacobian.m: -------------------------------------------------------------------------------- 1 | % verify the replay outcome and plot the Jacobian profile 2 | 3 | % the photons detected in the original run 4 | [data1, header1] = loadmch('step1.mch'); 5 | header1; 6 | 7 | % the photons detected in the wl replay phase 8 | [data2, header2] = loadmch('step2.mch'); 9 | header2; 10 | 11 | % the photons detected in the wp replay phase 12 | [data3, header3] = loadmch('step3.mch'); 13 | header3; 14 | 15 | data1 = data1(data1(:, 1) == 1, :); 16 | 17 | % the two sets of captured photons should be identical 18 | if (all(ismember(round(data1 * 1e10) * 1e-10, round(data2 * 1e10) * 1e-10, 'rows'))) 19 | disp('replay is successful :-)'); 20 | else 21 | disp('replay failed :-('); 22 | end 23 | 24 | % plot the wl profile 25 | 26 | load step2.dat; 27 | [no, el] = readmmcmesh('replaytest'); 28 | 29 | figure; 30 | plotmesh([no, log10(step2(:, 2))], el(:, 1:4), 'z=0.2', 'linestyle', 'none'); 31 | hold on; 32 | plotmesh([no, log10(step2(:, 2))], el(:, 1:4), 'x=30', 'linestyle', 'none'); 33 | view(3); 34 | set(gca, 'xlim', [0 60]); 35 | set(gca, 'ylim', [0 60]); 36 | set(gca, 'zlim', [0 60]); 37 | shading interp; 38 | 39 | % plot the wp profile 40 | 41 | load step3.dat; 42 | [no, el] = readmmcmesh('replaytest'); 43 | 44 | figure; 45 | plotmesh([no, log10(step3(:, 2))], el(:, 1:4), 'z=0.2', 'linestyle', 'none'); 46 | hold on; 47 | plotmesh([no, log10(step3(:, 2))], el(:, 1:4), 'x=30', 'linestyle', 'none'); 48 | view(3); 49 | set(gca, 'xlim', [0 60]); 50 | set(gca, 'ylim', [0 60]); 51 | set(gca, 'zlim', [0 60]); 52 | shading interp; 53 | -------------------------------------------------------------------------------- /examples/replay/prop_replaytest.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.005 1. 0.01 1.0 3 | 4 | -------------------------------------------------------------------------------- /examples/replay/replaytest.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon 2 | 1648335518 # RNG seed, negative to generate 3 | 30.1 30.2 0.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.0 5e-9 5e-9 # time-gates(s): start, end, step 6 | replaytest # volume ('uchar' format) 7 | 27466 8 | 4 1 # detector number and radius (mm) 9 | 30.0 20.0 0.0 # detector 1 position (mm) 10 | 20.0 30.0 0.0 # ... 11 | 30.0 40.0 0.0 12 | 40.0 30.0 0.0 13 | isotropic 14 | 0 0 0 0 15 | 0 0 0 0 16 | -------------------------------------------------------------------------------- /examples/replay/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # first run to get the seeds for each detected photon (-q 1) 4 | ../../bin/mmc -f replaytest.inp -s step1 -n 3e6 -b 0 -q 1 -x 1 -d 1 -D TP $@ 5 | 6 | # replay the detected photons (-E *.mch) detected by detector#1 (-P 1) without normalization (-U 0) 7 | ../../bin/mmc -f replaytest.inp -E step1.mch -s step2 -P 1 -b 0 -q 1 -x 1 -d 1 -O L -D TP $@ 8 | 9 | # replay the detected photons (-E *.mch) detected by detector#1 (-P 1) without normalization (-U 0) 10 | ../../bin/mmc -f replaytest.inp -E step1.mch -s step3 -P 1 -b 0 -q 1 -x 1 -d 1 -O P -D TP $@ 11 | 12 | -------------------------------------------------------------------------------- /examples/replaywide/createmesh.m: -------------------------------------------------------------------------------- 1 | %% original mesh 2 | 3 | [node, face, elem] = meshabox([0 0 0], [60 60 20], 2, 2); 4 | elem(:, 5) = 1; 5 | 6 | figure(1); 7 | plotmesh(node, elem); 8 | 9 | %% extended source domain 10 | 11 | srcdef = struct('srctype', 'planar', 'srcpos', [10, 10, -2], 'srcdir', [0 0 1], ... 12 | 'srcparam1', [40 0 0 40], 'srcparam2', [0 40 0 40]); 13 | 14 | [newnode, newelem] = mmcaddsrc(node, elem, srcdef); 15 | 16 | figure(2); 17 | plotmesh(newnode, newelem); 18 | 19 | %% extended detector domain 20 | 21 | detdef = struct('srctype', 'planar', 'srcpos', [10, 10, 20.1], 'srcdir', [0 0 -1], ... 22 | 'srcparam1', [40 0 0 40], 'srcparam2', [0 40 0 40]); 23 | 24 | [newnode2, newelem2] = mmcadddet(newnode, newelem, detdef); 25 | 26 | figure(3); 27 | plotmesh(newnode2, newelem2); 28 | 29 | savemmcmesh('replaywide', newnode2, newelem2); 30 | -------------------------------------------------------------------------------- /examples/replaywide/createpattern.m: -------------------------------------------------------------------------------- 1 | % full field illumination pattern 2 | pat0 = ones(40); 3 | 4 | % pattern with left half dark 5 | pat1 = pat0; 6 | pat1(1:20, :) = 0; 7 | 8 | % pattern with top half dark 9 | pat2 = pat0; 10 | pat2(:, 1:20) = 0; 11 | 12 | fid = fopen('pattern0.pat', 'wb', 'ieee-le'); 13 | fwrite(fid, pat0', 'float'); 14 | fclose(fid); 15 | 16 | fid = fopen('pattern1.pat', 'wb', 'ieee-le'); 17 | fwrite(fid, pat1', 'float'); 18 | fclose(fid); 19 | 20 | fid = fopen('pattern2.pat', 'wb', 'ieee-le'); 21 | fwrite(fid, pat2', 'float'); 22 | fclose(fid); 23 | -------------------------------------------------------------------------------- /examples/replaywide/init_MC.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon, not used 2 | 12345678 # RNG seed, negative to generate 3 | 10.0 10.0 -2.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.0 2e-9 2e-9 # time-gates(s): start, end, step 6 | replaywide # volume ('uchar' format) 7 | -1 # initial eid 8 | 1 0 # detector number and radius (mm) 9 | 10.0 10.0 20.1 0.0 # detector 1 position (mm) 10 | pattern 11 | 40.0 0.0 0.0 40 # source param1 12 | 0.0 40.0 0.0 40 # source param2 13 | pattern0.pat # pattern file name 14 | 40.0 0.0 0.0 40 # detector param1 15 | 0.0 40.0 0.0 40 # detector param2 16 | -------------------------------------------------------------------------------- /examples/replaywide/plotresults.m: -------------------------------------------------------------------------------- 1 | [node, face, elem] = meshabox([0 0 0], [60 60 20], 2, 2); 2 | 3 | data1 = load('replay1.dat'); 4 | data2 = load('replay2.dat'); 5 | data3 = load('replay3.dat'); 6 | 7 | figure(1); 8 | plotmesh([node, log(data1(1:end - 7, 2))], elem); 9 | 10 | figure(2); 11 | plotmesh([node, log(data2(1:end - 7, 2))], elem); 12 | 13 | figure(3); 14 | plotmesh([node, log(data3(1:end - 7, 2))], elem); 15 | -------------------------------------------------------------------------------- /examples/replaywide/prop_replaywide.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.01 1.0 0.01 1.37 3 | -------------------------------------------------------------------------------- /examples/replaywide/replay1.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon, not used 2 | 12345678 # RNG seed, negative to generate 3 | 10.0 10.0 -2.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.0 2e-9 2e-9 # time-gates(s): start, end, step 6 | replaywide # volume ('uchar' format) 7 | -1 # initial eid 8 | 1 0 # detector number and radius (mm) 9 | 10.0 10.0 20.1 0.0 # detector 1 position (mm) 10 | pattern 11 | 40.0 0.0 0.0 40 # source param1 12 | 0.0 40.0 0.0 40 # source param2 13 | pattern0.pat # source pattern 14 | 40.0 0.0 0.0 40 # detector param1 15 | 0.0 40.0 0.0 40 # detector param2 16 | pattern1.pat # detector pattern 17 | -------------------------------------------------------------------------------- /examples/replaywide/replay2.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon, not used 2 | 12345678 # RNG seed, negative to generate 3 | 10.0 10.0 -2.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.0 2e-9 2e-9 # time-gates(s): start, end, step 6 | replaywide # volume ('uchar' format) 7 | -1 # initial eid 8 | 1 0 # detector number and radius (mm) 9 | 10.0 10.0 20.1 0.0 # detector 1 position (mm) 10 | pattern 11 | 40.0 0.0 0.0 40 # source param1 12 | 0.0 40.0 0.0 40 # source param2 13 | pattern2.pat # source pattern 14 | 40.0 0.0 0.0 40 # detector param1 15 | 0.0 40.0 0.0 40 # detector param2 16 | pattern0.pat # detector pattern 17 | -------------------------------------------------------------------------------- /examples/replaywide/replay3.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon, not used 2 | 12345678 # RNG seed, negative to generate 3 | 10.0 10.0 -2.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.0 2e-9 2e-9 # time-gates(s): start, end, step 6 | replaywide # volume ('uchar' format) 7 | -1 # initial eid 8 | 1 0 # detector number and radius (mm) 9 | 10.0 10.0 20.1 0.0 # detector 1 position (mm) 10 | pattern 11 | 40.0 0.0 0.0 40 # source param1 12 | 0.0 40.0 0.0 40 # source param2 13 | pattern1.pat # source pattern 14 | 40.0 0.0 0.0 40 # detector param1 15 | 0.0 40.0 0.0 40 # detector param2 16 | pattern2.pat # detector pattern 17 | -------------------------------------------------------------------------------- /examples/replaywide/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # first run to get the seeds for each detected photon (-q 1) 4 | ../../bin/mmc -f init_MC.inp -s init -n 3e7 -b 1 -q 1 -x 1 -D TP 5 | 6 | # replay the detected photons (-E *.mch) for full illumination & half detection (-P 0) under wl mode 7 | ../../bin/mmc -f replay1.inp -E init.mch -s replay1 -P 0 -b 1 -O L -D TP 8 | 9 | # replay the detected photons (-E *.mch) for half illumination & full detection (-P 0) under wp mode 10 | ../../bin/mmc -f replay2.inp -E init.mch -s replay2 -P 0 -b 1 -O L -D TP 11 | 12 | # replay the detected photons (-E *.mch) for half illumination & half detection (-P 0) under wl mode 13 | ../../bin/mmc -f replay3.inp -E init.mch -s replay3 -P 0 -b 1 -O L -D TP -------------------------------------------------------------------------------- /examples/rngtest/Makefile: -------------------------------------------------------------------------------- 1 | ROOTDIR = ../.. 2 | BINARY=rngtest 3 | 4 | FILES=$(ROOTDIR)/src/posix_randr rngtest 5 | USERCCFLAGS=-I$(ROOTDIR)/src -O3 6 | 7 | include $(ROOTDIR)/commons/Makefile_common.mk 8 | 9 | -------------------------------------------------------------------------------- /examples/rngtest/makefile_logistic: -------------------------------------------------------------------------------- 1 | ROOTDIR = ../.. 2 | BINARY=rngtest_log 3 | 4 | FILES=$(ROOTDIR)/src/logistic_rand rngtest 5 | USERCCFLAGS=-DMMC_LOGISTIC -I$(ROOTDIR)/src -O3 6 | 7 | include $(ROOTDIR)/commons/Makefile_common.mk 8 | 9 | -------------------------------------------------------------------------------- /examples/rngtest/makefile_sfmt: -------------------------------------------------------------------------------- 1 | ROOTDIR = ../.. 2 | BINARY=rngtest_sfmt 3 | 4 | FILES=$(ROOTDIR)/src/sfmt_rand $(ROOTDIR)/src/SFMT/SFMT rngtest 5 | USERCCFLAGS=-DMMC_SFMT -DMEXP=19937 -I$(ROOTDIR)/src -O3 6 | 7 | include $(ROOTDIR)/commons/Makefile_common.mk 8 | 9 | -------------------------------------------------------------------------------- /examples/rngtest/rngtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef _OPENMP 6 | #include 7 | #endif 8 | 9 | #ifdef MMC_LOGISTIC 10 | #include "logistic_rand.c" 11 | #elif defined MMC_SFMT 12 | #include "sfmt_rand.c" 13 | #else 14 | #include "posix_randr.c" 15 | #endif 16 | 17 | void usage(char *exename){ 18 | printf("usage:\n\t%s \n",exename); 19 | } 20 | void genrand(int threadid, int id, RandType ran[],RandType ran0[]){ 21 | rand_need_more(ran,ran0); 22 | printf("%d\t%d\t%e\t%e\t%e\n",threadid,id,rand_next_scatlen(ran),rand_next_aangle(ran),rand_next_zangle(ran)); 23 | } 24 | int main(int argc, char**argv){ 25 | unsigned int seed=19650218, count=100000,threadid=0,i; 26 | RandType ran0[RAND_BUF_LEN] __attribute__ ((aligned(16))); 27 | RandType ran1[RAND_BUF_LEN] __attribute__ ((aligned(16))); 28 | 29 | if(argc>=2) 30 | count=atoi(argv[1]); 31 | if(argc>=3) 32 | seed=atoi(argv[2]); 33 | 34 | if(count==0 || seed==0 || argc==1){ /*when atoi returned error*/ 35 | usage(argv[0]); 36 | exit(0); 37 | } 38 | 39 | if(seed<0) seed=time(NULL); 40 | 41 | #pragma omp parallel private(ran0,ran1,threadid) 42 | { 43 | #ifdef _OPENMP 44 | threadid=omp_get_thread_num(); 45 | #endif 46 | rng_init(ran0,ran1,(unsigned int *)&seed,threadid); 47 | 48 | #pragma omp for 49 | for(i=0;i 0, 1:4), cfg.node, log10(layercw), 'y=30', 'linestyle', 'none'); 14 | view(3); 15 | qmeshcut(cfg.elem(cfg.elemprop > 0, 1:4), cfg.node, log10(layercw), 'z=27', 'linestyle', 'none'); 16 | box on; 17 | axis equal; 18 | view(-56, 22); 19 | -------------------------------------------------------------------------------- /examples/sfdi2layer/prop_sfdi.dat: -------------------------------------------------------------------------------- 1 | 1 2 2 | 1 0.02 9.0 0.89 1.37 3 | 2 0.019 7.8 0.89 1.37 4 | 5 | -------------------------------------------------------------------------------- /examples/sfdi2layer/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -n 3000000 -f sfdi.inp -s sfdi -b 0 -k 0 -D TP -M S $@ 4 | -------------------------------------------------------------------------------- /examples/sfdi2layer/sfdi.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon counts (normally not used) 2 | 1648335518 # RNG seed, negative to generate 3 | 10.0 10.0 35.0 # source position in mm (corner 1) 4 | 0.0 0.0 -1.0 # initial directional vector 5 | 0 5e-09 1e-10 # time-gates(s): start, end, step 6 | sfdi # volume ('uchar' format) 7 | -1 # eid (not actually used) 8 | 1 2.0 # total number of detectors and radius 9 | 30.0 30.0 0.0 # detector 1 position (mm) 10 | fourier # source type 11 | 40.0 0.0 0.0 3.0 # parameters set 1 12 | 0.0 40.0 0.0 0.0 # parameters set 2 13 | -------------------------------------------------------------------------------- /examples/sharing/README.txt: -------------------------------------------------------------------------------- 1 | = Simulate multiple wide-field illumination patterns through "photon sharing" = 2 | 3 | == Introduction == 4 | 5 | In this example, we again use a two-layer cubic model. 6 | Mesh retessellation is performed based on the origin model 7 | to accomodate for the wide-feild configuration 8 | 9 | Five illumination patterns of 40 by 40 mm2 are simulated 10 | 11 | The optical properties mimic that of the skull and CSF 12 | of a human brain model, and can be found at 13 | 14 | http://mcx.sourceforge.net/cgi-bin/index.cgi?MMC/Colin27AtlasMesh#Tissue_optical_properties. 15 | 16 | Run "createmesh.m" first to generate mesh (before/after retessellation), 17 | then run "run_test.sh" to perform the simulation. Finally, run "plot_result.m" 18 | to see the continuous wave (CW) fluence distribution of five source patterns. 19 | -------------------------------------------------------------------------------- /examples/sharing/createmesh.m: -------------------------------------------------------------------------------- 1 | %% original mesh 2 | 3 | [node, face, elem] = meshabox([0 0 0], [60 60 20], 2, 2); 4 | elem(:, 5) = 1; 5 | 6 | figure(1); 7 | plotmesh(node, elem); 8 | 9 | %% extended source domain 10 | 11 | srcdef = struct('srctype', 'planar', 'srcpos', [10, 10, -2], 'srcdir', [0 0 1], ... 12 | 'srcparam1', [40 0 0 40], 'srcparam2', [0 40 0 40]); 13 | 14 | [newnode, newelem] = mmcaddsrc(node, elem, srcdef); 15 | 16 | figure(2); 17 | plotmesh(newnode, newelem); 18 | 19 | savemmcmesh('sharing', newnode, newelem); 20 | -------------------------------------------------------------------------------- /examples/sharing/createpattern.m: -------------------------------------------------------------------------------- 1 | % full field illumination pattern 2 | pat0 = ones(40); 3 | 4 | % pattern with left half bright 5 | pat1 = zeros(40); 6 | pat1(1:20, :) = 1; 7 | 8 | % pattern with top half bright 9 | pat2 = zeros(40); 10 | pat2(:, 1:20) = 1; 11 | 12 | % pattern with bright square in the middle 13 | pat3 = zeros(40); 14 | pat3(11:30, 11:30) = 1; 15 | 16 | % pattern with a bright cross 17 | pat4 = zeros(40); 18 | pat4(16:25, :) = 1; 19 | pat4(:, 16:25) = 1; 20 | 21 | fid = fopen('patterns.pat', 'wb', 'ieee-le'); 22 | fwrite(fid, pat0', 'float'); 23 | fwrite(fid, pat1', 'float'); 24 | fwrite(fid, pat2', 'float'); 25 | fwrite(fid, pat3', 'float'); 26 | fwrite(fid, pat4', 'float'); 27 | fclose(fid); 28 | -------------------------------------------------------------------------------- /examples/sharing/plotresults.m: -------------------------------------------------------------------------------- 1 | % [node,face,elem]=meshabox([0 0 0],[60 60 20],2, 2); 2 | nTG = 50; 3 | npat = 5; 4 | 5 | rawdata = load('sharing.dat'); 6 | data = reshape(rawdata(:, end), npat, [], nTG); 7 | cwdata = squeeze(sum(data, 3)); 8 | cwdata = cwdata(:, 1:end - 3); 9 | 10 | %% plot results 11 | 12 | figure(); 13 | 14 | subplot(1, 3, 1); 15 | title('pattern 1'); 16 | plotmesh([node, (cwdata(1, :))'], elem, 'linestyle', 'none'); 17 | shading interp; 18 | axis off; 19 | view([0, 0, -1]); 20 | 21 | subplot(2, 3, 2); 22 | title('pattern 2'); 23 | plotmesh([node, (cwdata(2, :))'], elem, 'linestyle', 'none'); 24 | shading interp; 25 | axis off; 26 | view([0, 0, -1]); 27 | 28 | subplot(2, 3, 3); 29 | title('pattern 3'); 30 | plotmesh([node, (cwdata(3, :))'], elem, 'linestyle', 'none'); 31 | shading interp; 32 | axis off; 33 | view([0, 0, -1]); 34 | 35 | subplot(2, 3, 5); 36 | title('pattern 4'); 37 | plotmesh([node, (cwdata(4, :))'], elem, 'linestyle', 'none'); 38 | shading interp; 39 | axis off; 40 | view([0, 0, -1]); 41 | 42 | subplot(2, 3, 6); 43 | title('pattern 5'); 44 | plotmesh([node, (cwdata(5, :))'], elem, 'linestyle', 'none'); 45 | shading interp; 46 | axis off; 47 | view([0, 0, -1]); 48 | -------------------------------------------------------------------------------- /examples/sharing/prop_sharing.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.01 10.0 0.9 1.37 3 | -------------------------------------------------------------------------------- /examples/sharing/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -n 1000000 -f sharing.inp -s sharing -b 1 -k 0 -D TP 4 | -------------------------------------------------------------------------------- /examples/sharing/sharing.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon counts (normally not used) 2 | -1 # RNG seed, negative to generate 3 | 10.0 10.0 -2.0 # source position in mm (corner 1) 4 | 0.0 0.0 1.0 # initial directional vector 5 | 0 5e-09 1e-10 # time-gates(s): start, end, step 6 | sharing # volume ('uchar' format) 7 | -1 # eid (not actually used) 8 | 1 2.0 # total number of detectors and radius 9 | 30.0 30.0 0.0 # detector 1 position (mm) 10 | pattern # source type 11 | 40.0 0.0 0.0 40 # parameters set 1 12 | 0.0 40.0 0.0 40 # parameters set 2 13 | patterns.pat 5 # number of patterns and pattern file name 14 | -------------------------------------------------------------------------------- /examples/skinvessel/dmmc_skinvessel.json: -------------------------------------------------------------------------------- 1 | { 2 | "Session": { 3 | "ID": "dmmc_skinvessel", 4 | "DoMismatch": 0, 5 | "OutputType": "flux", 6 | "DebugFlag": "TP", 7 | "RayTracer": "g", 8 | "RNGSeed": 1648335518, 9 | "Photons": 10000000 10 | }, 11 | "Mesh": { 12 | "MeshID": "dmmc_skinvessel", 13 | "InitElem": 6178 14 | }, 15 | "Forward": { 16 | "T0": 0, 17 | "T1": 5e-08, 18 | "Dt": 5e-08 19 | }, 20 | "Optode": { 21 | "Source": { 22 | "Pos": [0.5,0.5,-0.005], 23 | "Dir": [0,0,1], 24 | "Param1": [0.3,0,0,0], 25 | "Type": "disk" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/skinvessel/face_dmmc_skinvessel.dat: -------------------------------------------------------------------------------- 1 | 1 46 2 | 1 11 1062 1134 1 3 | 2 9 11 1062 1 4 | 3 9 1058 1059 1 5 | 4 9 10 12 1 6 | 5 9 11 12 1 7 | 6 9 1056 1058 1 8 | 7 1 1136 1137 1 9 | 8 10 12 1138 1 10 | 9 2 6 1138 1 11 | 10 3 1053 1054 1 12 | 11 3 1053 1135 1 13 | 12 3 1057 1061 1 14 | 13 3 1060 1061 1 15 | 14 7 11 1134 1 16 | 15 1 1053 1135 1 17 | 16 1136 1137 1138 1 18 | 17 2 1137 1138 1 19 | 18 1 1053 1054 1 20 | 19 6 10 1138 1 21 | 20 9 1061 1062 1 22 | 21 1060 1061 1062 1 23 | 22 4 12 1136 1 24 | 23 4 12 1138 1 25 | 24 3 1060 1062 1 26 | 25 3 1062 1134 1 27 | 26 3 1054 1056 1 28 | 27 1 1054 1056 1 29 | 28 3 1057 1059 1 30 | 29 1056 1058 1059 1 31 | 30 3 1056 1059 1 32 | 31 1057 1059 1061 1 33 | 32 9 1059 1061 1 34 | 33 1 3 1135 1 35 | 34 5 9 1056 1 36 | 35 6 10 1137 1 37 | 36 7 11 1136 1 38 | 37 11 12 1136 1 39 | 38 9 10 1137 1 40 | 39 5 9 1137 1 41 | 40 3 7 1136 1 42 | 41 1 5 1137 1 43 | 42 1 3 1136 1 44 | 43 2 6 1137 1 45 | 44 4 1136 1138 1 46 | 45 3 7 1134 1 47 | 46 1 5 1056 1 48 | -------------------------------------------------------------------------------- /examples/skinvessel/prop_dmmc_skinvessel.dat: -------------------------------------------------------------------------------- 1 | 1 4 2 | 1 3.564000e-05 1.000000e+00 1.000000e+00 1.370000e+00 3 | 2 2.305430e+01 9.398500e+00 9.000000e-01 1.370000e+00 4 | 3 4.580000e-02 3.565410e+01 9.000000e-01 1.370000e+00 5 | 4 1.657200e+00 3.759400e+01 9.000000e-01 1.370000e+00 6 | -------------------------------------------------------------------------------- /examples/skinvessel/run_dmmc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -f dmmc_skinvessel.json -n 1e8 -F bin $@ 4 | 5 | -------------------------------------------------------------------------------- /examples/skinvessel/run_mmc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -f skinvessel.json -n 1e8 -F bin $@ 4 | 5 | -------------------------------------------------------------------------------- /examples/skinvessel/skinvessel.json: -------------------------------------------------------------------------------- 1 | { 2 | "Session": { 3 | "ID": "skinvessel", 4 | "DoMismatch": 0, 5 | "OutputType": "flux", 6 | "DebugFlag": "TP", 7 | "RayTracer": "g", 8 | "RNGSeed": 1648335518, 9 | "Photons": 10000000 10 | }, 11 | "Mesh": { 12 | "MeshID": "skinvessel", 13 | "InitElem": 466437 14 | }, 15 | "Forward": { 16 | "T0": 0, 17 | "T1": 5e-08, 18 | "Dt": 5e-08 19 | }, 20 | "Optode": { 21 | "Source": { 22 | "Pos": [0.5,0.5,-0.005], 23 | "Dir": [0,0,1], 24 | "Param1": [0.3,0,0,0], 25 | "Type": "disk" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/sphere/README.txt: -------------------------------------------------------------------------------- 1 | = Validation of uniform planar source use a spherical domain = 2 | 3 | == Introduction == 4 | 5 | In this example, we test a simple widefield source -- uniform planar over a sphere model. 6 | Three corners of the 3D quadrilateral are specified by srcpos, srcpos+srcparam1(0:2), srcpos+srcparam2(0:2). 7 | The original mesh is re-tessellated after adding source nodes in addsource_sphere.m . 8 | -------------------------------------------------------------------------------- /examples/sphere/addsource_sphere.m: -------------------------------------------------------------------------------- 1 | [node, face, elem] = meshasphere([0 0 0], 24, 1, 2); 2 | elem(:, 5) = 1; 3 | 4 | cfg = struct('srctype', 'planar', 'srcpos', [-5 -5 25], 'srcdir', [0 0 -1], ... 5 | 'srcparam1', [10 0 0 0], 'srcparam2', [0 10 0 0]); 6 | [newnode, newelem] = mmcaddsrc(node, elem, cfg); 7 | 8 | cfg = struct('srctype', 'planar', 'srcpos', [-30 -5 -5], 'srcdir', [1 0 0], ... 9 | 'srcparam1', [0 10 0 0], 'srcparam2', [0 0 10 0]); 10 | [nodedet, elemdet] = mmcadddet(newnode, newelem, cfg); 11 | plotmesh(nodedet, elemdet); 12 | 13 | savemmcmesh('sphere', nodedet, elemdet); 14 | -------------------------------------------------------------------------------- /examples/sphere/planar.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon counts (normally not used) 2 | 1648335518 # RNG seed, negative to generate 3 | -5.0 -5.0 25.0 # source position in mm (corner 1) 4 | 0.0 0.0 -1.0 # initial directional vector 5 | 0 5e-09 1e-10 # time-gates(s): start, end, step 6 | sphere # volume ('uchar' format) 7 | -1 # eid (not actually used) 8 | 0 0 # total number of detectors and radius 9 | planar # source type 10 | 10.0 0.0 0.0 0.0 # parameters set 1 11 | 0.0 10.0 0.0 0.0 # parameters set 2 12 | -------------------------------------------------------------------------------- /examples/sphere/plotresults.m: -------------------------------------------------------------------------------- 1 | no = readmmcnode('node_sphere.dat'); 2 | el = readmmcelem('elem_sphere.dat'); 3 | load planar.dat; 4 | vv = reshape(planar(:, 2), size(no, 1), size(planar, 1) / size(no, 1)); 5 | vvv = sum(vv, 2); 6 | plotmesh([no, vvv], el(el(:, end) > 0, 1:4)); 7 | ppl = loadmch('planar.mch'); 8 | hold on; 9 | plotmesh(ppl(:, 4:6), 'r.'); % plot detected photon locations from a widefield detector 10 | figure; 11 | plotmesh([no, log10(vvv)], el(el(:, end) > 0, 1:4), 'x=0'); 12 | shading interp; 13 | -------------------------------------------------------------------------------- /examples/sphere/prop_sphere.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.0191 6.6 0.9 1.37 3 | 4 | -------------------------------------------------------------------------------- /examples/sphere/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #../../bin/mmc -n 100000 -f planar.inp -s planar -b 1 -x 1 -D E > debug.txt 4 | #grep '^x ' debug.txt | sed -e 's/^x //g'> exitpos.txt 5 | #grep '^e ' debug.txt | sed -e 's/^e //g'> enterpos.txt 6 | 7 | #../../bin/mmc -n 1 -f planar.inp -s planar -b 1 -x 1 -D M | sed -e 's/^M/1/g' -e 's/^B/0/g' -e 's/P/2/g'| sed '$d' > mov.txt 8 | #../../bin/mmc -n 1 -f planar.inp -s planar -b 1 -x 1 -D MA | sed -e 's/^[A-Z] //g' | sed '$d' > ad.txt 9 | 10 | ../../bin/mmc -n 10000000 -f planar.inp -s planar -b 1 -x 1 -D TP 11 | -------------------------------------------------------------------------------- /examples/sphshells/dmmc_sphshells.json: -------------------------------------------------------------------------------- 1 | { 2 | "Session": { 3 | "ID": "dmmc_sphshells", 4 | "DoMismatch": 1, 5 | "DebugFlag": "TP", 6 | "RayTracer": "g", 7 | "RNGSeed": 1648335518, 8 | "Photons": 3000000 9 | }, 10 | "Mesh": { 11 | "MeshID": "dmmc_sphshells", 12 | "InitElem": 4916 13 | }, 14 | "Forward": { 15 | "T0": 0, 16 | "T1": 5e-09, 17 | "Dt": 5e-10 18 | }, 19 | "Optode": { 20 | "Source": { 21 | "Pos": [30,30.1,0], 22 | "Dir": [0,0,1] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/sphshells/face_dmmc_sphshells.dat: -------------------------------------------------------------------------------- 1 | 1 12 2 | 1 3042 3043 3047 1 3 | 2 3040 3042 3043 1 4 | 3 3040 3044 3045 1 5 | 4 3044 3046 3047 1 6 | 5 3040 3041 3045 1 7 | 6 3044 3045 3047 1 8 | 7 3041 3043 3047 1 9 | 8 3040 3041 3043 1 10 | 9 3040 3044 3046 1 11 | 10 3040 3042 3046 1 12 | 11 3041 3045 3047 1 13 | 12 3042 3046 3047 1 14 | -------------------------------------------------------------------------------- /examples/sphshells/prop_dmmc_sphshells.dat: -------------------------------------------------------------------------------- 1 | 1 4 2 | 1 2.000000e-02 7.000000e+00 8.900000e-01 1.370000e+00 3 | 2 4.000000e-03 9.000000e-03 8.900000e-01 1.370000e+00 4 | 3 2.000000e-02 9.000000e+00 8.900000e-01 1.370000e+00 5 | 4 5.000000e-02 0.000000e+00 1.000000e+00 1.370000e+00 6 | -------------------------------------------------------------------------------- /examples/sphshells/run_dmmc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -f dmmc_sphshells.json -n 1e8 -F bin $@ 4 | 5 | -------------------------------------------------------------------------------- /examples/sphshells/run_mmc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../bin/mmc -f sphshells.json -n 1e8 -F bin $@ 4 | 5 | -------------------------------------------------------------------------------- /examples/ssehmin/ssehmin_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void main(){ 5 | __m128 O,T,S; 6 | float len; 7 | const float tmax=1e10f; 8 | int idx; 9 | const char maskmap[16]={4,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3}; 10 | 11 | T = _mm_set_ps(0.01f,0.1f,0.002f,0.1f); 12 | S = _mm_set_ps(1.0, 0.0, -1.0f, 1.0); 13 | 14 | O = _mm_cmpge_ps(S,_mm_set1_ps(0.f)); 15 | T = _mm_add_ps(_mm_andnot_ps(O,_mm_set1_ps(tmax)),_mm_and_ps(O,T)); 16 | S = _mm_movehl_ps(T, T); 17 | O = _mm_min_ps(T, S); 18 | S = _mm_shuffle_ps(O, O, _MM_SHUFFLE(1,1,1,1)); 19 | O = _mm_min_ss(O, S); 20 | 21 | _mm_store_ss(&len,O); 22 | idx=_mm_movemask_ps(_mm_cmpeq_ps(T,_mm_set1_ps(len))); 23 | printf("%f %d %d\n",len,idx,maskmap[idx]); 24 | } 25 | -------------------------------------------------------------------------------- /examples/statnoise/README.txt: -------------------------------------------------------------------------------- 1 | = Experimental: Fluence variation vs photon numbers = 2 | 3 | == Introduction == 4 | 5 | == Steps == 6 | 7 | 1. First, you need to create the mesh files to run this example. You 8 | need to first download and install iso2mesh version 1.0 or newer from 9 | 10 | http://iso2mesh.sourceforge.net/cgi-bin/index.cgi?Download 11 | 12 | 2. Start matlab, run createmesh to create all mesh files. Matlab will 13 | print a value for variable eid. This value indicates the initial element 14 | ID in the mesh that encloses the source. You need to open vartest.json 15 | with a text editor and replace the number after "InitElem". 16 | 17 | 3. Run the simulation bash script run_test.sh, this will run the simulation 18 | for 10 repetitions and save fluence maps for 1E4, 1E5, 1E6 and 1E7 photons. 19 | 20 | 4. When all simulations complete, you start matlab again, and 21 | run plotstdhist.m to generate a plot between signal standard error 22 | and photon number. 23 | 24 | 25 | *This test is experimental. The interpretations to the results need 26 | further understandings. 27 | -------------------------------------------------------------------------------- /examples/statnoise/createmesh.m: -------------------------------------------------------------------------------- 1 | sessionid = 'cube20'; 2 | 3 | addpath('../../matlab/'); 4 | [node, elem] = genT5mesh(0:1:20, 0:1:20, 0:1:20); 5 | 6 | elem(:, 1:4) = meshreorient(node, elem(:, 1:4)); 7 | 8 | srcpos = [10.1, 10.2, 0]; 9 | savemmcmesh(sessionid, node, elem, []); 10 | eid = tsearchn(node, elem(:, 1:4), srcpos); 11 | -------------------------------------------------------------------------------- /examples/statnoise/prop_cube20.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.005 1. 0.01 1.0 3 | 4 | -------------------------------------------------------------------------------- /examples/statnoise/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in {1..10} 4 | do 5 | echo "run #$i" 6 | ../../bin/mmc -f vartest.json -s v_$i -n 10000000 -b 0 -l -D TP -E 9876543$i 7 | done 8 | -------------------------------------------------------------------------------- /examples/statnoise/vartest.inp: -------------------------------------------------------------------------------- 1 | 30000000 # total photon 2 | 1648335518 # RNG seed, negative to generate 3 | 10.1 10.2 0.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.e+00 5.e-09 5e-09 # time-gates(s): start, end, step 6 | cube20 # mesh tag 7 | 2201 8 | 0 1 # detector number and radius (mm) 9 | -------------------------------------------------------------------------------- /examples/statnoise/vartest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Mesh": { 3 | "MeshID": "cube20", 4 | "InitElem": 2201 5 | }, 6 | "Session": { 7 | "Photons": 30000000, 8 | "RNGSeed": 27182818, 9 | "ID": "vartest", 10 | "Checkpoints": [10000,100000,1000000,10000000] 11 | }, 12 | "Forward": { 13 | "T0": 0.0e+00, 14 | "T1": 5.0e-09, 15 | "Dt": 5.0e-09 16 | }, 17 | "Optode": { 18 | "Source": { 19 | "Pos": [10.1, 10.2, 0.0], 20 | "Dir": [0.0, 0.0, 1.0] 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/validation/README.txt: -------------------------------------------------------------------------------- 1 | = Validation of MMCM in a homogeneous cubic domain = 2 | 3 | == Introduction == 4 | 5 | In this example, we validate the MMCM algorithm using a homogeneous 6 | cubic domain. This simulation generates the results 7 | shown in Fig. 2 in the paper. 8 | 9 | The cubic domain has a dimension of 60x60x60 mm with optical properties 10 | mua=0.001, mus=1, n=1.0 and g=0.01. The analytical solution 11 | can be computed by the cwdiffusion (for CW solution) and 12 | tddiffusion (for time-domain solutions) functions in the 13 | package of Monte Carlo eXtreme (MCX) under the mcx/utils directory. 14 | 15 | 16 | == Steps == 17 | 18 | 1. First, you need to create the 3 meshes to run this example. You 19 | need to first download and install iso2mesh version 1.0 or newer from 20 | 21 | http://iso2mesh.sourceforge.net/cgi-bin/index.cgi?Download 22 | 23 | 2. Start matlab, run createmesh to create all mesh files. Matlab will 24 | print a value for variable eid. This value indicates the initial element 25 | ID in the mesh that encloses the source. You need to manually set this 26 | number as the second integer on the 7-th line in cube.inp input file. 27 | 28 | 3. Run the simulation bash script run_test.sh, this will run 30000000 29 | photons with the specified mesh. 30 | 31 | 4. To produce Fig. 2, you need to run MCX simulations. 32 | You have to download MCX package from 33 | 34 | svn checkout --username anonymous_user https://orbit.nmr.mgh.harvard.edu/svn/mcextreme/mcextreme_cuda/trunk/ mcx 35 | 36 | using the password "anonymous_user". You can also download the pre-compiled 37 | binary package from http://mcx.sf.net/cgi-bin/index.cgi?Download 38 | 39 | 5. Assuming you have compiled and installed MCX, you can run MCX simulation by 40 | 41 | 5.1 go to mmc/examples/mcxsph run createmcxbin from matlab 42 | 5.2 open benchbox.sh, edit the thread number (-t) and thread block size (-T) 43 | based on the compute capability of your card. For 8800GT/9800GT, the -T number 44 | can not exceed 128; for 280/285/295, -T can not be more than 256; for 470, 45 | -T can not be more than 576 (for MCX 0.4.9 or newer, using -A option is 46 | recommended) 47 | 5.3 run benchbox.sh to generate the MCX output box.mc2 48 | 49 | 6. When all simulations are done, you start matlab again, and 50 | run plotcuberes to generate the plots. 51 | -------------------------------------------------------------------------------- /examples/validation/benchspeed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | time ../../bin/mmc -f cube.inp -s cube -n 100000 -b 0 -D PT 4 | -------------------------------------------------------------------------------- /examples/validation/createmesh.m: -------------------------------------------------------------------------------- 1 | sessionid = 'cube'; 2 | 3 | addpath('../../matlab/'); 4 | [node, elem] = genT5mesh(0:2:60, 0:2:60, 0:2:60); 5 | 6 | elem(:, 1:4) = meshreorient(node, elem(:, 1:4)); 7 | 8 | srcpos = [30.1, 30.2, 0]; 9 | savemmcmesh(sessionid, node, elem); 10 | eid = tsearchn(node, elem(:, 1:4), srcpos); 11 | -------------------------------------------------------------------------------- /examples/validation/cube.inp: -------------------------------------------------------------------------------- 1 | 30000000 # total photon 2 | 1648335518 # RNG seed, negative to generate 3 | 30.1 30.2 0.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.e+00 5.e-09 1e-10 # time-gates(s): start, end, step 6 | cube # volume ('uchar' format) 7 | 4497 8 | 4 1 # detector number and radius (mm) 9 | 30.0 20.0 0.0 # detector 1 position (mm) 10 | 30.0 40.0 0.0 # ... 11 | 20.0 30.0 0.0 12 | 40.0 30.0 0.0 13 | -------------------------------------------------------------------------------- /examples/validation/cube.json: -------------------------------------------------------------------------------- 1 | { 2 | "Domain": { 3 | "MeshID": "cube", 4 | "InitElem": 4497 5 | }, 6 | "Session": { 7 | "Photons": 30000000, 8 | "RNGSeed": 27182818, 9 | "ID": "cube" 10 | }, 11 | "Forward": { 12 | "T0": 0.0e+00, 13 | "T1": 5.0e-09, 14 | "Dt": 1.0e-10 15 | }, 16 | "Optode": { 17 | "Source": { 18 | "Pos": [30.1, 30.2, 0.0], 19 | "Dir": [0.0, 0.0, 1.0] 20 | }, 21 | "Detector": [ 22 | { 23 | "Pos": [30.0, 20.0, 0.0], 24 | "R": 1.0 25 | }, 26 | { 27 | "Pos": [30.0, 40.0, 0.0], 28 | "R": 1.0 29 | }, 30 | { 31 | "Pos": [20.0, 30.0, 0.0], 32 | "R": 1.0 33 | }, 34 | { 35 | "Pos": [40.0, 30.0, 0.0], 36 | "R": 1.0 37 | } 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/validation/cube2.inp: -------------------------------------------------------------------------------- 1 | 30000000 # total photon 2 | 1648335518 # RNG seed, negative to generate 3 | 30.1 30.2 0.0 # source position (mm) 4 | 0. 0. 1. # initial directional vector 5 | 0.e+00 5.e-09 1e-10 # time-gates(s): start, end, step 6 | cube2 # volume ('uchar' format) 7 | 2 8 | 4 1 # detector number and radius (mm) 9 | 30.0 20.0 0.0 # detector 1 position (mm) 10 | 30.0 40.0 0.0 # ... 11 | 20.0 30.0 0.0 12 | 40.0 30.0 0.0 13 | -------------------------------------------------------------------------------- /examples/validation/cube2.json: -------------------------------------------------------------------------------- 1 | { 2 | "Session": { 3 | "Photons": 30000000, 4 | "RNGSeed": 27182818, 5 | "ID": "cube2" 6 | }, 7 | "Domain" : { 8 | "Media": [ 9 | {"mua": 0.00, "mus": 0.0, "g": 1.00, "n": 1.0}, 10 | {"mua": 0.005,"mus": 1.0, "g": 0.01, "n": 1.37} 11 | ] 12 | }, 13 | "Mesh": { 14 | "MeshNode": [ 15 | [ 0, 0, 0], 16 | [60, 0, 0], 17 | [ 0,60, 0], 18 | [60,60, 0], 19 | [ 0, 0,60], 20 | [60, 0,60], 21 | [ 0,60,60], 22 | [60,60,60] 23 | ], 24 | "MeshElem": [ 25 | [1, 2, 8, 4, 1], 26 | [1, 3, 4, 8, 1], 27 | [1, 2, 6, 8, 1], 28 | [1, 5, 8, 6, 1], 29 | [1, 3, 8, 7, 1], 30 | [1, 5, 7, 8, 1] 31 | ], 32 | "InitElem": 2 33 | }, 34 | "Forward": { 35 | "T0": 0.0e+00, 36 | "T1": 5.0e-09, 37 | "Dt": 1.0e-10 38 | }, 39 | "Optode": { 40 | "Source": { 41 | "Pos": [30.1, 30.2, 0.0], 42 | "Dir": [0.0, 0.0, 1.0] 43 | }, 44 | "Detector": [ 45 | { 46 | "Pos": [30.0, 20.0, 0.0], 47 | "R": 1.0 48 | }, 49 | { 50 | "Pos": [30.0, 40.0, 0.0], 51 | "R": 1.0 52 | }, 53 | { 54 | "Pos": [20.0, 30.0, 0.0], 55 | "R": 1.0 56 | }, 57 | { 58 | "Pos": [40.0, 30.0, 0.0], 59 | "R": 1.0 60 | } 61 | ] 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /examples/validation/elem_cube2.dat: -------------------------------------------------------------------------------- 1 | 1 6 2 | 1 1 2 8 4 1 3 | 2 1 3 4 8 1 4 | 3 1 2 6 8 1 5 | 4 1 5 8 6 1 6 | 5 1 3 8 7 1 7 | 6 1 5 7 8 1 8 | -------------------------------------------------------------------------------- /examples/validation/facenb_cube2.dat: -------------------------------------------------------------------------------- 1 | 1 6 2 | 3 0 2 0 3 | 0 5 1 0 4 | 0 1 4 0 5 | 6 0 3 0 6 | 2 0 6 0 7 | 0 4 5 0 8 | -------------------------------------------------------------------------------- /examples/validation/node_cube2.dat: -------------------------------------------------------------------------------- 1 | 1 8 2 | 1 0.00000000e+00 0.00000000e+00 0.00000000e+00 3 | 2 6.00000000e+01 0.00000000e+00 0.00000000e+00 4 | 3 0.00000000e+00 6.00000000e+01 0.00000000e+00 5 | 4 6.00000000e+01 6.00000000e+01 0.00000000e+00 6 | 5 0.00000000e+00 0.00000000e+00 6.00000000e+01 7 | 6 6.00000000e+01 0.00000000e+00 6.00000000e+01 8 | 7 0.00000000e+00 6.00000000e+01 6.00000000e+01 9 | 8 6.00000000e+01 6.00000000e+01 6.00000000e+01 10 | -------------------------------------------------------------------------------- /examples/validation/prop_cube.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.005 1. 0.01 1.0 3 | 4 | -------------------------------------------------------------------------------- /examples/validation/prop_cube2.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 1 0.005 1. 0.01 1.0 3 | 4 | -------------------------------------------------------------------------------- /examples/validation/run_tess.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | time ../../bin/mmc -f cube2.inp -s cube2 -n 1e8 -b 0 -D TP -M G -F bin $@ 4 | -------------------------------------------------------------------------------- /examples/validation/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | time ../../bin/mmc -f cube.inp -s cube -n 1e8 -b 0 -F bin -D TP $@ 4 | -------------------------------------------------------------------------------- /examples/validation/tessmesh.m: -------------------------------------------------------------------------------- 1 | sessionid = 'cube2'; 2 | 3 | addpath('../../matlab/'); 4 | 5 | [node, elem] = meshgrid6(0:60:60, 0:60:60, 0:60:60); 6 | 7 | elem(:, 1:4) = meshreorient(node, elem(:, 1:4)); 8 | 9 | srcpos = [30.1, 30.2, 0]; 10 | savemmcmesh(sessionid, node, elem, []); 11 | eid = tsearchn(node, elem(:, 1:4), srcpos); 12 | -------------------------------------------------------------------------------- /examples/validation/velem_cube2.dat: -------------------------------------------------------------------------------- 1 | 1 6 2 | 1 3.600000e+04 3 | 2 3.600000e+04 4 | 3 3.600000e+04 5 | 4 3.600000e+04 6 | 5 3.600000e+04 7 | 6 3.600000e+04 8 | -------------------------------------------------------------------------------- /examples/widedet/README.txt: -------------------------------------------------------------------------------- 1 | = Output time-resolved images when using wide-field detector = 2 | 3 | == Notice == 4 | 5 | 1. In input file, the number of detectors is 1 (one wide-field) and the 6 | radius of that detector is 0, so that the detparams can be read. 7 | 8 | 2. The last two lines of input file are detparam1 and detparam1, 9 | they have the same meaning as srcparam1&2 when srctype is pattern. 10 | 11 | 3. In the shell file, set -x to be 2 and to get an "img" file as output, 12 | the file is binary and the size equlas to nx*ny*nTG, where nx and ny 13 | are number of pixels of detector defined in detparam1 and detparam2 14 | and nTG is the total number of time gates. 15 | 16 | 4. The order of row/column is different between order of C and Matlab, 17 | so we need to do a matrix transpose before plotting the image. -------------------------------------------------------------------------------- /examples/widedet/createmesh.m: -------------------------------------------------------------------------------- 1 | %% original mesh 2 | 3 | [node, face, c0] = latticegrid([0 60], [0 60], [0 5 10]); 4 | c0(:, 4) = [2; 3]; % maximum element size for bottom (label 1) and top (label 2) layers 5 | [node, elem] = surf2mesh(node, face, [], [], 1, [], c0); 6 | 7 | figure(1); 8 | plotmesh(node, elem); 9 | 10 | srcpos = [25.0 35.0 10.0]; 11 | 12 | %% extended detector domain 13 | 14 | detdef = struct('srctype', 'planar', 'srcpos', [10, 10, -1], 'srcdir', [0 0 1], ... 15 | 'srcparam1', [40 0 0 40], 'srcparam2', [0 40 0 40]); 16 | 17 | [newnode, newelem] = mmcadddet(node, elem, detdef); 18 | 19 | figure(2); 20 | plotmesh(newnode, newelem); 21 | 22 | newelem(:, 1:4) = meshreorient(newnode, newelem(:, 1:4)); 23 | eid = tsearchn(newnode, newelem(:, 1:4), srcpos); 24 | savemmcmesh('widedet', newnode, newelem); 25 | -------------------------------------------------------------------------------- /examples/widedet/plot_results.m: -------------------------------------------------------------------------------- 1 | nx = 40; 2 | ny = 40; 3 | nTG = 50; 4 | 5 | fd = fopen('widedet.img', 'rb', 'ieee-le'); 6 | data = fread(fd, nx * nx * nTG, 'float'); 7 | data = reshape(data, [nx ny nTG]); 8 | fclose(fd); 9 | 10 | datacw = sum(data, 3); 11 | figure(1); 12 | imagesc(datacw'); 13 | axis equal; 14 | xlim([0.5 nx + 0.5]); 15 | xlabel('offsetx (mm)'); 16 | ylabel('offsety (mm)'); 17 | -------------------------------------------------------------------------------- /examples/widedet/prop_widedet.dat: -------------------------------------------------------------------------------- 1 | 1 2 2 | 1 0.01 1.0 0.01 1.37 3 | 1 0.05 10.0 0.9 1.37 4 | 5 | -------------------------------------------------------------------------------- /examples/widedet/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # run with -x 2 to record detected photons in the form of time-resolved images 4 | ../../bin/mmc -f widedet.inp -s widedet -n 1000000 -x 2 -b 1 -D TP 5 | -------------------------------------------------------------------------------- /examples/widedet/widedet.inp: -------------------------------------------------------------------------------- 1 | 1000000 # total photon, not used 2 | 12345678 # RNG seed, negative to generate 3 | 25.0 35.0 10.0 # source position (mm) 4 | 0. 0. -1. # initial directional vector 5 | 0.0 2e-9 4e-11 # time-gates(s): start, end, step 6 | widedet # volume ('uchar' format) 7 | 2033 # initial eid 8 | 1 0 # detector number and radius (mm) 9 | 10.0 10.0 -1.0 0.0 # detector 1 position (mm) 10 | pencil 11 | 0 0 0 0 # source param1 12 | 0 0 0 0 # source param2 13 | 40.0 0.0 0.0 40 # detector param1 14 | 0.0 40.0 0.0 40 # detector param2 -------------------------------------------------------------------------------- /matlab/besselhprime.m: -------------------------------------------------------------------------------- 1 | function hp = besselhprime(n, k, z) 2 | % 3 | % hp=besselhprime(n,k,z) 4 | % 5 | % Hankel function first order derivative 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Hankel function 11 | % k: kind of the Hankel function 12 | % z: input variable 13 | % 14 | % output: 15 | % hn: Hankel function first order derivative 16 | % 17 | % example: 18 | % hn=besselhprime(0,1,1) 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | hp = besselh(n - 1, k, z) - n / z .* besselh(n, k, z); 26 | -------------------------------------------------------------------------------- /matlab/besseljprime.m: -------------------------------------------------------------------------------- 1 | function jp = besseljprime(n, z) 2 | % 3 | % jp=besseljprime(n,z) 4 | % 5 | % Bessel function (Bessel first kind) first order derivative 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Hankel function 11 | % z: input variable 12 | % 13 | % output: 14 | % jp: Bessel function (Bessel first kind) first order derivative 15 | % 16 | % example: 17 | % jp=besseljprime(0,1) 18 | % 19 | % this file is part of Mesh-based Monte Carlo (MMC) 20 | % 21 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 22 | % 23 | 24 | jp = besselj(n - 1, z) - n / z .* besselj(n, z); 25 | -------------------------------------------------------------------------------- /matlab/besselyprime.m: -------------------------------------------------------------------------------- 1 | function yp = besselyprime(n, z) 2 | % 3 | % yp=besselyprime(n,z) 4 | % 5 | % Neumann function (Bessel second kind) first order derivative 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Hankel function 11 | % z: input variable 12 | % 13 | % output: 14 | % yp: Neumann function (Bessel second kind) first order derivative 15 | % 16 | % example: 17 | % yp=besselyprime(0,1) 18 | % 19 | % this file is part of Mesh-based Monte Carlo (MMC) 20 | % 21 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 22 | % 23 | 24 | yp = bessely(n - 1, z) - n / z .* bessely(n, z); 25 | -------------------------------------------------------------------------------- /matlab/cart2sphorigin.m: -------------------------------------------------------------------------------- 1 | function [T, P, R] = cart2sphorigin(xi, yi, zi, x0, y0, z0) 2 | % 3 | % [T,P,R]=cart2sphorigin(xi,yi,zi,x0,y0,z0) 4 | % 5 | % Converting Cartesian coordinates to spherical with a reset of origin 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % xi,yi,zi: list of Cartesian coordinates 11 | % x0,y0,z0: new origin in Cartesian coordinates 12 | % 13 | % output: 14 | % T: theta of the output spherical coordinates 15 | % P: phi of the output spherical coordinates 16 | % R: R of the output spherical coordinates 17 | % 18 | % example: 19 | % [T,P,R]=cart2sphorigin(1:5,1:5,1:5,2,2,2); 20 | % 21 | % this file is part of Mesh-based Monte Carlo (MMC) 22 | % 23 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 24 | % 25 | 26 | xi = xi - x0; 27 | yi = yi - y0; 28 | zi = zi - z0; 29 | [T, P, R] = cart2sph(xi(:), yi(:), zi(:)); 30 | -------------------------------------------------------------------------------- /matlab/genT5mesh.m: -------------------------------------------------------------------------------- 1 | function [vertices, tess] = genT5mesh(varargin) 2 | % tess_lat: simplicial tessellation of a rectangular lattice 3 | % usage: [tessellation,vertices]=genT5mesh(v1,v2,v3,...) 4 | % 5 | % arguments: input 6 | % v1,v2,v3,... - numeric vectors defining the lattice in 7 | % each dimension. 8 | % Each vector must be of length >= 1 9 | % 10 | % arguments: (output) 11 | % vertices - factorial lattice created from (v1,v2,v3,...) 12 | % Each row of this array is one node in the lattice 13 | % tess - integer array defining simplexes as references to 14 | % rows of "vertices". 15 | 16 | % dimension of the lattice 17 | n = length(varargin); 18 | if (n ~= 3) 19 | error('only works for 3D case!'); 20 | end 21 | 22 | for i = 1:n 23 | v = varargin{i}; 24 | if (mod(length(v), 2) == 0) 25 | varargin{i} = linspace(v(1), v(end), length(v) + 1); 26 | end 27 | end 28 | 29 | % create a single n-d hypercube 30 | % list of vertices of the cube itself 31 | 32 | cube8 = ... 33 | [1 4 5 13; 1 2 5 11; 1 10 11 13; 11 13 14 5; 11 13 1 5; ... 34 | 2 3 5 11; 3 5 6 15; 15 11 12 3; 15 11 14 5; 11 15 3 5; ... 35 | 4 5 7 13; 5 7 8 17; 16 17 13 7; 13 17 14 5; 5 7 17 13; ... 36 | 5 6 9 15; 5 8 9 17; 17 18 15 9; 17 15 14 5; 17 15 5 9; ... 37 | 10 13 11 19; 13 11 14 23; 22 19 23 13; 19 23 20 11; 13 11 19 23; ... 38 | 11 12 15 21; 11 15 14 23; 23 21 20 11; 23 24 21 15; 23 21 11 15; ... 39 | 16 13 17 25; 13 17 14 23; 25 26 23 17; 25 22 23 13; 13 17 25 23; ... 40 | 17 18 15 27; 17 15 14 23; 26 27 23 17; 27 23 24 15; 23 27 17 15]'; 41 | 42 | % build the complete lattice 43 | nodecount = cellfun('length', varargin); 44 | if any(nodecount < 2) 45 | error 'Each dimension must be of size 2 or more.'; 46 | end 47 | vertices = lattice(varargin{:}); 48 | 49 | [ix, iy, iz] = meshgrid(1:2:nodecount(1) - 2, 1:2:nodecount(2) - 2, 1:2:nodecount(3) - 2); 50 | ind = sub2ind(nodecount, ix(:), iy(:), iz(:)); 51 | 52 | nodeshift = [0 1 2 nodecount(1) nodecount(1) + 1 nodecount(1) + 2 ... 53 | 2 * nodecount(1) 2 * nodecount(1) + 1 2 * nodecount(1) + 2]; 54 | nodeshift = [nodeshift, nodeshift + nodecount(1) * nodecount(2), nodeshift + 2 * nodecount(1) * nodecount(2)]; 55 | 56 | nc = length(ind); 57 | tess = zeros(nc * 40, 4); 58 | for i = 1:nc 59 | tess((1:40) + (i - 1) * 40, :) = reshape(nodeshift(cube8(:)), 4, 40)' + ind(i); 60 | end 61 | 62 | % ======== subfunction ======== 63 | function g = lattice(varargin) 64 | % generate a factorial lattice in n variables 65 | n = nargin; 66 | sizes = cellfun('length', varargin); 67 | c = cell(1, n); 68 | [c{1:n}] = ndgrid(varargin{:}); 69 | g = zeros(prod(sizes), n); 70 | for i = 1:n 71 | g(:, i) = c{i}(:); 72 | end 73 | -------------------------------------------------------------------------------- /matlab/genT6mesh.m: -------------------------------------------------------------------------------- 1 | function [vertices, tess] = genT6mesh(varargin) 2 | % tess_lat: simplicial tessellation of a rectangular lattice 3 | % usage: [tessellation,vertices]=genT6mesh(v1,v2,v3,...) 4 | % 5 | % URL: http://www.mathkb.com/Uwe/Forum.aspx/matlab/50484/Constant-surfaces 6 | % 7 | % arguments: input 8 | % v1,v2,v3,... - numeric vectors defining the lattice in 9 | % each dimension. 10 | % Each vector must be of length >= 1 11 | % 12 | % arguments: (output) 13 | % vertices - factorial lattice created from (v1,v2,v3,...) 14 | % Each row of this array is one node in the lattice 15 | % tess - integer array defining simplexes as references to 16 | % rows of "vertices". 17 | 18 | % dimension of the lattice 19 | n = length(varargin); 20 | 21 | % create a single n-d hypercube 22 | % list of vertices of the cube itself 23 | vhc = ('1' == dec2bin(0:(2^n - 1))); 24 | % permutations of the integers 1:n 25 | p = perms(1:n); 26 | nt = factorial(n); 27 | thc = zeros(nt, n + 1); 28 | for i = 1:nt 29 | thc(i, :) = find(all(diff(vhc(:, p(i, :)), [], 2) >= 0, 2))'; 30 | end 31 | 32 | % build the complete lattice 33 | nodecount = cellfun('length', varargin); 34 | if any(nodecount < 2) 35 | error 'Each dimension must be of size 2 or more.'; 36 | end 37 | vertices = lattice(varargin{:}); 38 | 39 | % unrolled index into each hyper-rectangle in the lattice 40 | ind = cell(1, n); 41 | for i = 1:n 42 | ind{i} = 0:(nodecount(i) - 2); 43 | end 44 | ind = lattice(ind{:}); 45 | k = cumprod([1, nodecount(1:(end - 1))]); 46 | ind = 1 + ind * k'; 47 | nind = length(ind); 48 | 49 | offset = vhc * k'; 50 | tess = zeros(nt * nind, n + 1); 51 | L = (1:nind)'; 52 | for i = 1:nt 53 | tess(L, :) = repmat(ind, 1, n + 1) + repmat(offset(thc(i, :))', nind, 1); 54 | L = L + nind; 55 | end 56 | 57 | % ======== subfunction ======== 58 | function g = lattice(varargin) 59 | % generate a factorial lattice in n variables 60 | n = nargin; 61 | sizes = cellfun('length', varargin); 62 | c = cell(1, n); 63 | [c{1:n}] = ndgrid(varargin{:}); 64 | g = zeros(prod(sizes), n); 65 | for i = 1:n 66 | g(:, i) = c{i}(:); 67 | end 68 | -------------------------------------------------------------------------------- /matlab/load_mc_prop.m: -------------------------------------------------------------------------------- 1 | function [mua, mus, g, n] = load_mc_prop(fname) 2 | % 3 | % [mua,mus,g,n]=load_mc_prop(fname) 4 | % 5 | % Loads the absorption and scattering coefficients, as well as the 6 | % scattering anisotropy and index of refraction from the MMC optical 7 | % property file given as an argument 8 | % 9 | % author: Stefan Carp (carp nmr.mgh.harvard.edu 10 | 11 | fid = fopen(fname, 'r'); 12 | if fid < 0 13 | error('File %s not found\n', fname); 14 | end 15 | 16 | mc_version = fscanf(fid, '%f', 1); 17 | if mc_version > 1 18 | fprintf('WARNING: MMC version greater than 1\n'); 19 | end 20 | num_tissues = fscanf(fid, '%f', 1); 21 | 22 | for I = 1:num_tissues 23 | tiss_ind = fscanf(fid, '%f', 1); 24 | mua(tiss_ind) = fscanf(fid, '%f', 1); 25 | mus(tiss_ind) = fscanf(fid, '%f', 1); 26 | g(tiss_ind) = fscanf(fid, '%f', 1); 27 | n(tiss_ind) = fscanf(fid, '%f', 1); 28 | end 29 | -------------------------------------------------------------------------------- /matlab/mmcadddet.m: -------------------------------------------------------------------------------- 1 | function varargout = mmcadddet(varargin) 2 | % 3 | % [newnode,newelem]=mmcadddet(node,elem,det,opt) 4 | % or 5 | % [newnode,newelem]=mmcadddet(node,elem,det,'Param1',value1, 'Param2',value2, ...) 6 | % 7 | % Adding an external wide-field (polyhedral) detector domain to an 8 | % existing tetrahedral mesh 9 | % 10 | % author: Qianqian Fang (q.fang neu.edu) 11 | % 12 | % input: 13 | % see mmcaddsrc for details. 14 | % 15 | % output: 16 | % see mmcaddsrc for details. 17 | % 18 | % example: 19 | % [node,face,elem]=meshasphere([0 0 0],24,1,2); 20 | % elem(:,5)=1; 21 | % 22 | % cfg=struct('srctype','cone','srcpos',[0 0 28],'srcdir',[0 0 -1]); 23 | % [nodesrc,elemsrc]=mmcaddsrc(node,elem,cfg); 24 | % 25 | % % example with additional options 26 | % cfg=struct('srctype','planar','srcpos',[-30 -5 5],'srcdir',[1 0 0],... 27 | % 'srcparam1',[0 10 0 0],'srcparam2',[0 0 8 0]); 28 | % [nodedet,elemdet]=mmcadddet(nodesrc,elemsrc,cfg); 29 | % plotmesh(nodedet,elemdet); 30 | % 31 | % cfg=struct('srctype','disk','srcpos',[-30 0 0],'srcdir',[1 0 0],'srcparam1',[4 0 0 0]); 32 | % [nodedet,elemdet]=mmcadddet(nodesrc,elemsrc,cfg); 33 | % figure;plotmesh(nodedet,elemdet); 34 | % 35 | % this file is part of Mesh-based Monte Carlo (MMC) 36 | % 37 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 38 | % 39 | 40 | [varargout{1:nargout}] = mmcaddsrc(varargin{:}, 'extcorelabel', -2, 'KeepShape', 1, 'Expansion', 1.0); 41 | -------------------------------------------------------------------------------- /matlab/mmcdettime.m: -------------------------------------------------------------------------------- 1 | function dett = mmcdettime(detp, prop, unitinmm) 2 | % 3 | % dett=mmcdettime(detp,prop,unitinmm) 4 | % 5 | % Recalculate the detected photon time using partial path data and 6 | % optical properties (for perturbation Monte Carlo or detector readings) 7 | % 8 | % author: Qianqian Fang (q.fang neu.edu) 9 | % Ruoyang Yao (yaor rpi.edu) 10 | % 11 | % input: 12 | % detp: the 2nd output from mmclab. detp must be a struct 13 | % prop: optical property list, as defined in the cfg.prop field of mmclab's input 14 | % unitinmm: voxel edge-length in mm, should use cfg.unitinmm used to generate detp; 15 | % if ignored, assume to be 1 (mm) 16 | % 17 | % output: 18 | % dett: re-caculated detected photon time based on the partial path data and optical property table 19 | % 20 | % this file is copied from Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mmc.space/ for details 23 | % 24 | 25 | R_C0 = 3.335640951981520e-12; % inverse of light speed in vacuum 26 | 27 | if (nargin < 3) 28 | if (isfield(detp, 'unitinmm')) 29 | unitinmm = detp.unitinmm; 30 | else 31 | unitinmm = 1; 32 | end 33 | end 34 | 35 | if (nargin < 2) 36 | if (isfield(detp, 'prop')) 37 | prop = detp.prop; 38 | else 39 | error('must provide input "prop"'); 40 | end 41 | end 42 | 43 | medianum = size(prop, 1); 44 | if (medianum <= 1) 45 | error('empty property list'); 46 | end 47 | 48 | if (isstruct(detp)) 49 | dett = zeros(size(detp.ppath, 1), 1); 50 | for i = 1:medianum - 1 51 | dett = dett + prop(i + 1, 4) * detp.ppath(:, i) * R_C0 * unitinmm; 52 | end 53 | else 54 | error('the first input must be a struct with a subfield named "ppath"'); 55 | end 56 | -------------------------------------------------------------------------------- /matlab/mmcdettpsf.m: -------------------------------------------------------------------------------- 1 | function tpsf = mmcdettpsf(detp, detnum, prop, time) 2 | % 3 | % tpsf=mmcdettpsf(detp,detnum,prop,time) 4 | % 5 | % Calculate the temporal point spread function curve of a specified detector 6 | % given the partial path data, optical properties, and distribution of time bins 7 | % 8 | % author: Qianqian Fang (q.fang neu.edu) 9 | % Ruoyang Yao (yaor rpi.edu) 10 | % 11 | % input: 12 | % detp: the 2nd output from mmclab. detp must be a struct 13 | % detnum: specified detector number 14 | % prop: optical property list, as defined in the cfg.prop field of mmclab's input 15 | % time: distribution of time bins, a 1*3 vector [tstart tend tstep] 16 | % could be defined different from in the cfg of mmclab's input 17 | % output: 18 | % tpsf: caculated temporal point spread function curve of the specified detector 19 | % 20 | % this file is copied from Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.space/ for details 23 | % 24 | 25 | % select the photon data of the specified detector 26 | detp.ppath = detp.ppath(detp.detid == detnum, :); 27 | detp.detid = detp.detid(detp.detid == detnum); 28 | 29 | % calculate the detected photon weight and arrival time 30 | replayweight = mmcdetweight(detp, prop); 31 | replaytime = mmcdettime(detp, prop); 32 | 33 | % define temporal point spread function vector 34 | nTG = round((time(2) - time(1)) / time(3)); % maximum time gate number 35 | tpsf = zeros(nTG, 1); 36 | 37 | % calculate the time bin, make sure not to exceed the boundary 38 | ntg = ceil((replaytime - time(1)) / time(3)); 39 | ntg(ntg < 1) = 1; 40 | ntg(ntg > nTG) = nTG; 41 | 42 | % add each photon weight to corresponding time bin 43 | for i = 1:length(replayweight) 44 | tpsf(ntg(i)) = tpsf(ntg(i)) + replayweight(i); 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /matlab/mmcdetweight.m: -------------------------------------------------------------------------------- 1 | function detw = mmcdetweight(detp, prop, unitinmm) 2 | % 3 | % detw=mmcdetweight(detp,prop,unitinmm) 4 | % 5 | % Recalculate the detected photon weight using partial path data and 6 | % optical properties (for perturbation Monte Carlo or detector readings) 7 | % 8 | % author: Qianqian Fang (q.fang neu.edu) 9 | % 10 | % input: 11 | % detp: the 2nd output from mmclab. detp must a struct 12 | % prop: optical property list, as defined in the cfg.prop field of mmclab's input 13 | % unitinmm: voxel edge-length in mm, should use cfg.unitinmm used to generate detp; 14 | % if ignored, assume to be 1 (mm) 15 | % 16 | % output: 17 | % detw: re-caculated detected photon weight based on the partial path data and optical property table 18 | % 19 | % this file is copied from Mesh-based Monte Carlo (MMC) 20 | % 21 | % License: GPLv3, see http://mmc.space/ for details 22 | % 23 | 24 | if (nargin < 2) 25 | if (isfield(detp, 'prop')) 26 | prop = detp.prop; 27 | else 28 | error('must provide input "prop"'); 29 | end 30 | end 31 | 32 | medianum = size(prop, 1); 33 | if (medianum <= 1) 34 | error('empty property list'); 35 | end 36 | 37 | if (nargin < 3) 38 | if (isfield(detp, 'unitinmm')) 39 | unitinmm = detp.unitinmm; 40 | else 41 | unitinmm = 1; 42 | end 43 | end 44 | 45 | if (isstruct(detp)) 46 | if (~isfield(detp, 'w0')) 47 | detw = ones(size(detp.ppath, 1), 1); 48 | else 49 | detw = detp.w0; 50 | end 51 | for i = 1:medianum - 1 52 | detw = detw .* exp(-prop(i + 1, 1) * detp.ppath(:, i) * unitinmm); 53 | end 54 | else 55 | error('the first input must be a struct with a subfield named "ppath"'); 56 | end 57 | -------------------------------------------------------------------------------- /matlab/mmcjacobian.m: -------------------------------------------------------------------------------- 1 | function [Jmua, Jmus] = mmcjacobian(cfg, detp, seeds, detnum) 2 | % 3 | % [Jmua, Jmus]=mmcjacobian(cfg,detp,seeds,detnum) (element based) 4 | % 5 | % Generate time-domain Jacobians (sensitivity matrix) for absorption and scattering (mus) 6 | % perturbation of a specified source-detector pair with configurations, detected photon 7 | % seeds and detector readings from an initial MC simulation 8 | % 9 | % author: Ruoyang Yao (yaor rpi.edu) 10 | % Qianqian Fang (q.fang neu.edu) 11 | % 12 | % input: 13 | % cfg: the simulation configuration structure used for the initial MC simulation by mmclab 14 | % detp: detector readings from the initial MC simulation 15 | % seeds: detected photon seeds from the initial MC simulation 16 | % detnum: the detector number whose detected photons will be replayed 17 | % 18 | % output: 19 | % Jmua: the Jacobian for absorption coefficient for a specified source-detector pair 20 | % also output Jmua as a by-product. 21 | % Jmus: (optional) the Jacobian for scattering perturbation of a specified source detector pair 22 | % number of rows is the number of the mesh elements 23 | % number of columns is the number of time gates 24 | % 25 | % example: 26 | % [cube,detp,ncfg,seeds]=mmclab(cfg); % initial MC simulation 27 | % [Jmua,Jmus] = mmcjacobian(ncfg,detp,seeds,1); % generate scattering Jacobian of the first detector 28 | % 29 | % this file is part of Mesh-based Monte Carlo (MMC) 30 | % 31 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 32 | % 33 | 34 | if (nargout == 1) 35 | Jmua = mmcjmua(cfg, detp, seeds, detnum); 36 | elseif (nargout == 2) 37 | [Jmus, Jmua] = mmcjmus(cfg, detp, seeds, detnum); 38 | end 39 | -------------------------------------------------------------------------------- /matlab/mmcjmua.m: -------------------------------------------------------------------------------- 1 | function [Ja, newcfg] = mmcjmua(cfg, detp, seeds, detnum) 2 | % 3 | % Ja=mmcjmua(cfg,detp,seeds,detnum) (element based) 4 | % 5 | % Generate a time-domain Jacobian (sensitivity matrix) for absorption (mua) perturbation of a specified detector 6 | % with configurations, detected photon seeds and detector readings from an initial MC simulation 7 | % 8 | % author: Ruoyang Yao (yaor rpi.edu) 9 | % Qianqian Fang (q.fang neu.edu) 10 | % 11 | % input: 12 | % cfg: the simulation configuration structure used for the initial MC simulation by mmclab 13 | % detp: detector readings from the initial MC simulation, must be a 14 | % structure (supported after MMC v2016.4) 15 | % seeds: detected photon seeds from the initial MC simulation 16 | % detnum: the detector number whose detected photons will be replayed 17 | % 18 | % output: 19 | % Ja: a Jacobian for absorption perturbation of the specified detector 20 | % number of rows is the number of the mesh nodes or elements 21 | % number of columns is the number of time gates 22 | % 23 | % example: 24 | % [cube,detp,ncfg,seeds]=mmclab(cfg); % initial MC simulation 25 | % Jmua = mmcjmua(ncfg,detp,seeds,1); % generate absorption Jacobian of the first detector 26 | % 27 | % this file is part of Mesh-based Monte Carlo (MMC) 28 | % 29 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 30 | % 31 | 32 | % preprocessing of the mesh to get possible missing fields 33 | newcfg = mmclab(cfg, 'prep'); 34 | % newcfg.basisorder=0; 35 | 36 | % specify the detector number to replay 37 | newcfg.replaydet = detnum; 38 | 39 | % select the photon seeds and data of the specified detector 40 | newcfg.seed = seeds.data(:, detp.detid == newcfg.replaydet); 41 | detp.data = detp.data(:, detp.detid == newcfg.replaydet); 42 | 43 | % calculate the detected photon weight and arrival time 44 | newcfg.replayweight = mmcdetweight(detp.data, newcfg.prop); 45 | newcfg.replaytime = mmcdettime(detp.data, newcfg.prop); 46 | 47 | % specify output type 48 | newcfg.isnormalized = 1; % should we leave this for users to decide? 49 | newcfg.outputtype = 'wl'; 50 | 51 | % now replay detected photons 52 | [jacob, detp1, newcfg] = mmclab(newcfg); 53 | 54 | % validate if the replay is successful 55 | if (all(ismember(round(detp1.data' * 1e10) * 1e-10, round(detp.data' * 1e10) * 1e-10, 'rows'))) 56 | % disp('replay is successful :-)'); 57 | Ja = -jacob.data; 58 | else 59 | error('replay failed :-('); 60 | end 61 | -------------------------------------------------------------------------------- /matlab/mmcmeanpath.m: -------------------------------------------------------------------------------- 1 | function avgpath = mmcmeanpath(detp, prop) 2 | % 3 | % avgpath=mmcmeanpath(detp,prop) 4 | % 5 | % Calculate the average pathlengths for each tissue type for a given source-detector pair 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % detp: the 2nd output from mmclab. detp can be either a struct or an array (detp.data) 11 | % prop: optical property list, as defined in the cfg.prop field of mmclab's input 12 | % 13 | % output: 14 | % avepath: the average pathlength for each tissue type 15 | % 16 | % this file is part of Mesh-based Monte Carlo (MMC) 17 | % 18 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 19 | % 20 | 21 | detw = mmcdetweight(detp, prop); 22 | avgpath = sum(detp.ppath .* repmat(detw(:), 1, size(detp.ppath, 2))) / sum(detw(:)); 23 | -------------------------------------------------------------------------------- /matlab/mmcmeanscat.m: -------------------------------------------------------------------------------- 1 | function avgnscat = mmcmeanscat(detp, prop) 2 | % 3 | % avgnscat=mmcmeanscat(detp,prop) 4 | % 5 | % Calculate the average scattering event counts for each tissue type for a given source-detector pair 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % detp: the 2nd output from mmclab. detp can be either a struct or an array (detp.data) 11 | % prop: optical property list, as defined in the cfg.prop field of mmclab's input 12 | % 13 | % output: 14 | % avgnscat: the average scattering event count for each tissue type 15 | % 16 | % this file is part of Mesh-based Monte Carlo (MMC) 17 | % 18 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 19 | % 20 | 21 | detw = mmcdetweight(detp, prop); 22 | avgnscat = sum(detp.nscat .* repmat(detw(:), 1, size(detp.ppath, 2))) / sum(detw(:)); 23 | -------------------------------------------------------------------------------- /matlab/mmcraytrace.m: -------------------------------------------------------------------------------- 1 | function [p, e0] = mmcraytrace(node, elem, p0, v0, e0) 2 | % 3 | % [p,e0]=mmcraytrace(node,elem,p0,v0,e0) 4 | % 5 | % Determine the entry position and element for a ray to intersect a mesh 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % node: the mesh coordinate list 11 | % elem: the tetrahedral mesh element list, 4 columns 12 | % p0: origin of the ray 13 | % v0: direction vector of the ray 14 | % e0: search direction: '>' forward search, '<' backward search, '-' bidirectional 15 | % 16 | % output: 17 | % p: the intersection position 18 | % e0: if found, the index of the intersecting element ID 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | p = p0; 26 | if (size(elem, 2) == 3) 27 | face = elem; 28 | else 29 | face = volface(elem); 30 | end 31 | [t, u, v, idx] = raytrace(p0, v0, node, face); 32 | if (isempty(idx)) 33 | error('ray does not intersect with the mesh'); 34 | else 35 | t = t(idx); 36 | if (e0 == '>') 37 | idx1 = find(t >= 0); 38 | elseif (e0 == '<') 39 | idx1 = find(t <= 0); 40 | elseif (isnan(e0) || e0 == '-') 41 | idx1 = 1:length(t); 42 | else 43 | error('ray direction specifier is not recognized'); 44 | end 45 | if (isempty(idx1)) 46 | error('no intersection is found along the ray direction'); 47 | end 48 | t0 = abs(t(idx1)); 49 | [tmin, loc] = min(t0); 50 | faceidx = idx(idx1(loc)); 51 | 52 | % update source position 53 | p = p0 + t(idx1(loc)) * v0; 54 | 55 | if (nargout < 2) 56 | return 57 | end 58 | 59 | % find initial element id 60 | if (size(elem, 2) == 3) 61 | e0 = faceidx; 62 | else 63 | felem = sort(face(faceidx, :)); 64 | f = elem; 65 | f = [f(:, [1, 2, 3]) 66 | f(:, [2, 1, 4]) 67 | f(:, [1, 3, 4]) 68 | f(:, [2, 4, 3])]; 69 | [tf, loc] = ismember(felem, sort(f, 2), 'rows'); 70 | loc = mod(loc, size(elem, 1)); 71 | if (loc == 0) 72 | loc = size(elem, 1); 73 | end 74 | e0 = loc; 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /matlab/readmmcelem.m: -------------------------------------------------------------------------------- 1 | function elem = readmmcelem(filename) 2 | % 3 | % elem=readmmcelem(filename) 4 | % 5 | % Loading MMC mesh element file 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % filename: the file name to the element data file 11 | % 12 | % output: 13 | % elem: the tetrahedral mesh element list 14 | % 15 | % example: 16 | % elem=readmmcelem('elem_sph1.dat'); 17 | % 18 | % this file is part of Mesh-based Monte Carlo (MMC) 19 | % 20 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 21 | % 22 | 23 | fid = fopen(filename, 'rt'); 24 | [header, c] = fscanf(fid, '%d', 2); 25 | elem = fscanf(fid, '%d', [6 header(2)]); 26 | fclose(fid); 27 | 28 | elem = elem'; 29 | elem = elem(:, 2:end); 30 | -------------------------------------------------------------------------------- /matlab/readmmcface.m: -------------------------------------------------------------------------------- 1 | function face = readmmcface(filename) 2 | % 3 | % face=readmmcface(filename) 4 | % 5 | % Loading MMC surface triangle file 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % filename: the file name to the surface element data file 11 | % 12 | % output: 13 | % face: the surface triangle element list 14 | % 15 | % example: 16 | % face=readmmcface('face_sph1.dat'); 17 | % 18 | % this file is part of Mesh-based Monte Carlo (MMC) 19 | % 20 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 21 | % 22 | 23 | fid = fopen(filename, 'rt'); 24 | [header, c] = fscanf(fid, '%d', 2); 25 | face = fscanf(fid, '%d', [5 header(2)]); 26 | fclose(fid); 27 | 28 | face = face'; 29 | face = face(:, 2:4); 30 | -------------------------------------------------------------------------------- /matlab/readmmcmesh.m: -------------------------------------------------------------------------------- 1 | function varargout = readmmcmesh(key) 2 | % 3 | % [node elem]=readmmcmesh(key) 4 | % 5 | % Loading MMC node and element data files 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % key: the file name stub to the node coordinate file. The full 11 | % file names are {node,elem}_key.dat 12 | % 13 | % output: 14 | % node: the node coordinate list 15 | % elem: the tetrahedra node index list 16 | % 17 | % example: 18 | % [node elem]=readmmcmesh('sph1'); 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | if (nargout >= 1) 26 | varargout{1} = readmmcnode(['node_', key, '.dat']); 27 | end 28 | if (nargout >= 2) 29 | varargout{2} = readmmcelem(['elem_', key, '.dat']); 30 | end 31 | if (nargout >= 3) 32 | varargout{3} = readmmcelem(['elem_', key, '.dat']); 33 | end 34 | -------------------------------------------------------------------------------- /matlab/readmmcnode.m: -------------------------------------------------------------------------------- 1 | function node = readmmcnode(filename) 2 | % 3 | % node=readmmcnode(filename) 4 | % 5 | % Loading MMC node coordinates data file 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % filename: the file name to the node coordinate file 11 | % 12 | % output: 13 | % node: the node coordinate list 14 | % 15 | % example: 16 | % node=readmmcnode('node_sph1.dat'); 17 | % 18 | % this file is part of Mesh-based Monte Carlo (MMC) 19 | % 20 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 21 | % 22 | 23 | fid = fopen(filename, 'rt'); 24 | hd = fscanf(fid, '%d', 2); 25 | node = fscanf(fid, '%d %e %e %e\n', hd(2) * 4); 26 | fclose(fid); 27 | 28 | node = reshape(node, [4, hd(2)])'; 29 | node = node(:, 2:4); 30 | -------------------------------------------------------------------------------- /matlab/spbesselh.m: -------------------------------------------------------------------------------- 1 | function hn = spbesselh(n, k, z) 2 | % 3 | % hn=spbesselhprime(n,k,z) 4 | % 5 | % spherical Hankel function 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Hankel function 11 | % k: kind of the Hankel function 12 | % z: input variable 13 | % 14 | % output: 15 | % hn: spherical Hankel function 16 | % 17 | % example: 18 | % hn=spbesselh(0,1,1) 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | if (k == 1) 26 | hn = spbesselj(n, z) + i * spbessely(n, z); 27 | elseif (k == 2) 28 | hn = spbesselj(n, z) - i * spbessely(n, z); 29 | else 30 | error('wrong value for the second parameter'); 31 | end 32 | -------------------------------------------------------------------------------- /matlab/spbesselhprime.m: -------------------------------------------------------------------------------- 1 | function hn = spbesselhprime(n, k, z) 2 | % 3 | % hn=spbesselhprime(n,k,z) 4 | % 5 | % spherical Hankel function first order derivative 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Hankel function 11 | % k: kind of the Hankel function 12 | % z: input variable 13 | % 14 | % output: 15 | % hn: spherical Hankel function first order derivative 16 | % 17 | % example: 18 | % hn=spbesselhprime(0,1,1) 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | if (k == 1) 26 | hn = spbesseljprime(n, z) + i * spbesselyprime(n, z); 27 | elseif (k == 2) 28 | hn = spbesseljprime(n, z) - i * spbesselyprime(n, z); 29 | else 30 | error('wrong value for the second parameter'); 31 | end 32 | -------------------------------------------------------------------------------- /matlab/spbesselj.m: -------------------------------------------------------------------------------- 1 | function jn = spbesselj(n, z) 2 | % 3 | % jn=spbesselj(n,z) 4 | % 5 | % spherical Bessel function 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Bessel function 11 | % z: input variable 12 | % 13 | % output: 14 | % jn: spherical Bessel function first order derivative 15 | % 16 | % example: 17 | % jn=spbesselj(0,1) 18 | % 19 | % this file is part of Mesh-based Monte Carlo (MMC) 20 | % 21 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 22 | % 23 | 24 | jn = besselj(n + 1 / 2, z) .* sqrt(pi ./ (2 * z)); 25 | -------------------------------------------------------------------------------- /matlab/spbesseljprime.m: -------------------------------------------------------------------------------- 1 | function jp = spbesseljprime(n, z) 2 | % 3 | % jp=spbesseljprime(n,z) 4 | % 5 | % spherical Bessel function first order derivative 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Bessel function 11 | % z: input variable 12 | % 13 | % output: 14 | % jp: spherical Bessel function first order derivative 15 | % 16 | % example: 17 | % jp=spbesseljprime(0,1) 18 | % 19 | % this file is part of Mesh-based Monte Carlo (MMC) 20 | % 21 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 22 | % 23 | 24 | jp = besseljprime(n + 1 / 2, z) .* sqrt(pi / (2 * z)) - sqrt(pi / 2) * besselj(n + 1 / 2, z) ./ (2 * z .* sqrt(z)); 25 | -------------------------------------------------------------------------------- /matlab/spbessely.m: -------------------------------------------------------------------------------- 1 | function yn = spbessely(n, z) 2 | % 3 | % yn=spbessely(n,z) 4 | % 5 | % spherical Neumann function 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Neumann function 11 | % z: input variable 12 | % 13 | % output: 14 | % yn: spherical Neumann function first order derivative 15 | % 16 | % example: 17 | % yn=spbessely(0,1) 18 | % 19 | % this file is part of Mesh-based Monte Carlo (MMC) 20 | % 21 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 22 | % 23 | 24 | yn = bessely(n + 1 / 2, z) .* sqrt(pi ./ (2 * z)); 25 | -------------------------------------------------------------------------------- /matlab/spbesselyprime.m: -------------------------------------------------------------------------------- 1 | function yp = spbesselyprime(n, z) 2 | % 3 | % yp=spbesselyprime(n,z) 4 | % 5 | % spherical Neumann function first order derivative 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % n: order of the spherical Neumann function 11 | % z: input variable 12 | % 13 | % output: 14 | % yp: spherical Neumann function first order derivative 15 | % 16 | % example: 17 | % yp=spbesselyprime(0,1) 18 | % 19 | % this file is part of Mesh-based Monte Carlo (MMC) 20 | % 21 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 22 | % 23 | 24 | yp = besselyprime(n + 1 / 2, z) .* sqrt(pi / (2 * z)) - sqrt(pi / 2) * bessely(n + 1 / 2, z) ./ (2 * z .* sqrt(z)); 25 | -------------------------------------------------------------------------------- /matlab/spharmonic.m: -------------------------------------------------------------------------------- 1 | function Y = spharmonic(l, m, theta, phi) 2 | % 3 | % Y=spharmonic(l,m,theta,phi) 4 | % 5 | % spherical harmonic function Y_{m,l}(theta,phi) 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % m: angular index 11 | % l: order 12 | % theta,phi: spherical angular coordinates, can be vectors 13 | % 14 | % output: 15 | % Y: the values for Y_{m,l}(theta,phi) 16 | % 17 | % example: 18 | % Y=spharmonic(l,m,theta,phi) 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | coeff = 1; 26 | oldm = m; 27 | if (m < 0) 28 | coeff = (-1)^m * prod(1:(l - m)) / prod(1:(l + m)); 29 | m = -m; 30 | end 31 | Lmn = legendre(l, cos((theta(:))')); 32 | if l ~= 0 33 | Lmn = squeeze(Lmn(m + 1, :))'; 34 | end 35 | Lmn = reshape(Lmn, size(theta)); 36 | m = oldm; 37 | Y = coeff * sqrt((2 * l + 1) * prod(1:(l - m)) / (prod(1:(l + m)) * 4 * pi)) * ... 38 | Lmn .* exp(i * m * phi); 39 | -------------------------------------------------------------------------------- /matlab/sphdiffAcoeff.m: -------------------------------------------------------------------------------- 1 | function A = sphdiffAcoeff(m, l, cfg) 2 | % 3 | % A=sphdiffAcoeff(m,l,cfg) 4 | % 5 | % sphere diffusion exterior solution A coefficients 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % m: angular index 11 | % l: order 12 | % cfg: the problem domain setup, see sphdiffusioninfinite.m 13 | % 14 | % output: 15 | % res: the coefficient at the specified order 16 | % 17 | % example: 18 | % A=sphdiffAcoeff(m,l,cfg) 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | if ((cfg.src(2) == pi | cfg.src(2) == 0) & m ~= 0) 26 | A = 0; 27 | return 28 | end 29 | x = cfg.kout * cfg.a; 30 | y = cfg.kin * cfg.a; 31 | Dout = cfg.Dout; 32 | Din = cfg.Din; 33 | A = -i * cfg.v * cfg.kout / Dout * spbesselh(l, 1, cfg.kout * cfg.src(1)) * conj(spharmonic(l, m, cfg.src(2), cfg.src(3))) * ... 34 | (Dout * x * spbesseljprime(l, x) * spbesselj(l, y) - Din * y * spbesselj(l, x) * spbesseljprime(l, y)) / ... 35 | (Dout * x * spbesselhprime(l, 1, x) * spbesselj(l, y) - Din * y * spbesselh(l, 1, x) * spbesseljprime(l, y)); 36 | -------------------------------------------------------------------------------- /matlab/sphdiffBcoeff.m: -------------------------------------------------------------------------------- 1 | function B = sphdiffBcoeff(m, l, cfg) 2 | % 3 | % B=sphdiffBcoeff(m,l,cfg) 4 | % 5 | % sphere diffusion exterior solution B coefficients 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % m: angular index 11 | % l: order 12 | % cfg: the problem domain setup, see sphdiffusioninfinite.m 13 | % 14 | % output: 15 | % res: the coefficient at the specified order 16 | % 17 | % example: 18 | % B=sphdiffBcoeff(0,1,cfg) 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | B = i * sphdiffAcoeff(m, l, cfg); 26 | -------------------------------------------------------------------------------- /matlab/sphdiffCcoeff.m: -------------------------------------------------------------------------------- 1 | function C = sphdiffCcoeff(m, l, cfg) 2 | % 3 | % C=sphdiffCcoeff(m,l,cfg) 4 | % 5 | % sphere diffusion interior solution C coefficients 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % m: angular index 11 | % l: order 12 | % cfg: the problem domain setup, see sphdiffusioninfinite.m 13 | % 14 | % output: 15 | % res: the coefficient at the specified order 16 | % 17 | % example: 18 | % C=sphdiffCcoeff(0,1,cfg) 19 | % 20 | % this file is part of Mesh-based Monte Carlo (MMC) 21 | % 22 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 23 | % 24 | 25 | if ((cfg.src(2) == pi | cfg.src(2) == 0) & m ~= 0) 26 | C = 0; 27 | return 28 | end 29 | x = cfg.kout * cfg.a; 30 | y = cfg.kin * cfg.a; 31 | Dout = cfg.Dout; 32 | Din = cfg.Din; 33 | C = -i * cfg.v * cfg.kout / Dout * spbesselh(l, 1, cfg.kout * cfg.src(1)) * conj(spharmonic(l, m, cfg.src(2), cfg.src(3))) * ... 34 | (Dout * x * spbesselh(l, 1, x) * spbesseljprime(l, x) - Dout * x * spbesselhprime(l, 1, x) * spbesselj(l, x)) / ... 35 | (Dout * x * spbesselhprime(l, 1, x) * spbesselj(l, y) - Din * y * spbesselh(l, 1, x) * spbesseljprime(l, y)); 36 | -------------------------------------------------------------------------------- /matlab/sphdiffexterior.m: -------------------------------------------------------------------------------- 1 | function res = sphdiffexterior(r, theta, phi, cfg) 2 | % 3 | % res=sphdiffexterior(r,theta,phi,cfg) 4 | % 5 | % sphere exterior solution (incident+scatter) of the diffusion model 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % r,theta,phi: source position in spherical coordinates. 11 | % cfg: the problem domain setup: 12 | % cfg.v: speed of light in vacuum (mm/s) 13 | % cfg.a: sphere radius (mm) 14 | % cfg.omua: background (outside) mua (1/mm) 15 | % cfg.omusp: background (outside) mus' (1/mm) 16 | % cfg.imua: sphere (inside) mua (1/mm) 17 | % cfg.imusp: sphere (inside) mus' (1/mm) 18 | % cfg.src: spherical source position (R,theta,phi) R in mm 19 | % cfg.maxl: maximum serial expansion terms 20 | % cfg.omega: DPDW modulation frequency 21 | % 22 | % output: 23 | % res: the output fluence for both interior and exterior regions 24 | % 25 | % example: 26 | % phi_ext=sphdiffexterior(30,pi,0,cfg); 27 | % 28 | % this file is part of Mesh-based Monte Carlo (MMC) 29 | % 30 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 31 | % 32 | 33 | res = sphdiffincident(r, theta, phi, cfg) + sphdiffscatter(r, theta, phi, cfg); 34 | -------------------------------------------------------------------------------- /matlab/sphdiffincident.m: -------------------------------------------------------------------------------- 1 | function phi = sphdiffincident(r, theta, phi, cfg) 2 | % 3 | % phi=sphdiffincident(r,theta,phi,cfg) 4 | % 5 | % insident field of a sphere with a diffusion model 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % r,theta,phi: source position in spherical coordinates. 11 | % cfg: the problem domain setup: 12 | % cfg.v: speed of light in vacuum (mm/s) 13 | % cfg.a: sphere radius (mm) 14 | % cfg.omua: background (outside) mua (1/mm) 15 | % cfg.omusp: background (outside) mus' (1/mm) 16 | % cfg.imua: sphere (inside) mua (1/mm) 17 | % cfg.imusp: sphere (inside) mus' (1/mm) 18 | % cfg.src: spherical source position (R,theta,phi) R in mm 19 | % cfg.maxl: maximum serial expansion terms 20 | % cfg.omega: DPDW modulation frequency 21 | % 22 | % output: 23 | % res: the output fluence for both interior and exterior regions 24 | % 25 | % example: 26 | % phi_inc=sphdiffincident(30,pi,0,cfg); 27 | % 28 | % this file is part of Mesh-based Monte Carlo (MMC) 29 | % 30 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 31 | % 32 | 33 | % matlab's theta and phi are defined differently 34 | [xs, ys, zs] = sph2cart(cfg.src(3), pi / 2 - cfg.src(2), cfg.src(1)); 35 | [x, y, z] = sph2cart(phi, pi / 2 - theta, r); 36 | dist = sqrt((x - xs) .* (x - xs) + (y - ys) .* (y - ys) + (z - zs) .* (z - zs)); 37 | phi = cfg.v ./ (4 * pi * cfg.Dout * dist) .* exp(i * cfg.kout * dist); 38 | 39 | % if(isfield(cfg,'src2')) 40 | % [xs,ys,zs] = sph2cart(cfg.src2(3),pi/2-cfg.src2(2),cfg.src2(1)); 41 | % dist=sqrt((x-xs).*(x-xs)+(y-ys).*(y-ys)+(z-zs).*(z-zs)); 42 | % phi=phi-cfg.v./(4*pi*cfg.Dout*dist).*exp(i*cfg.kout*dist); 43 | % end 44 | -------------------------------------------------------------------------------- /matlab/sphdiffinterior.m: -------------------------------------------------------------------------------- 1 | function res = sphdiffinterior(r, theta, phi, cfg) 2 | % 3 | % res=sphdiffinterior(r,theta,phi,cfg) 4 | % 5 | % sphere interior solution of the diffusion model 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % r,theta,phi: source position in spherical coordinates. 11 | % cfg: the problem domain setup: 12 | % cfg.v: speed of light in vacuum (mm/s) 13 | % cfg.a: sphere radius (mm) 14 | % cfg.omua: background (outside) mua (1/mm) 15 | % cfg.omusp: background (outside) mus' (1/mm) 16 | % cfg.imua: sphere (inside) mua (1/mm) 17 | % cfg.imusp: sphere (inside) mus' (1/mm) 18 | % cfg.src: spherical source position (R,theta,phi) R in mm 19 | % cfg.maxl: maximum serial expansion terms 20 | % cfg.omega: DPDW modulation frequency 21 | % 22 | % output: 23 | % res: the output fluence for both interior and exterior regions 24 | % 25 | % example: 26 | % phi_int=sphdiffinterior(30,pi,0,cfg); 27 | % 28 | % this file is part of Mesh-based Monte Carlo (MMC) 29 | % 30 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 31 | % 32 | 33 | res = 0; 34 | for l = 0:cfg.maxl 35 | for m = -l:l 36 | res = res + (sphdiffCcoeff(m, l, cfg) .* spbesselj(l, cfg.kin * r)) .* spharmonic(l, m, theta, phi); 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /matlab/sphdiffscatter.m: -------------------------------------------------------------------------------- 1 | function res = sphdiffscatter(r, theta, phi, cfg) 2 | % 3 | % res=sphdiffscatter(r,theta,phi,cfg) 4 | % 5 | % sphere exterior scattered field 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % r,theta,phi: source position in spherical coordinates. 11 | % cfg: the problem domain setup: 12 | % cfg.v: speed of light in vacuum (mm/s) 13 | % cfg.a: sphere radius (mm) 14 | % cfg.omua: background (outside) mua (1/mm) 15 | % cfg.omusp: background (outside) mus' (1/mm) 16 | % cfg.imua: sphere (inside) mua (1/mm) 17 | % cfg.imusp: sphere (inside) mus' (1/mm) 18 | % cfg.src: spherical source position (R,theta,phi) R in mm 19 | % cfg.maxl: maximum serial expansion terms 20 | % cfg.omega: DPDW modulation frequency 21 | % 22 | % output: 23 | % res: the output fluence for both interior and exterior regions 24 | % 25 | % example: 26 | % phi_scat=sphdiffscatter(30,pi,0,cfg); 27 | % 28 | % this file is part of Mesh-based Monte Carlo (MMC) 29 | % 30 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 31 | % 32 | 33 | % if(cfg.src(2) neu.edu) 8 | % 9 | % input: 10 | % xrange,yrange,zrange: a vector from where a grid will be created 11 | % and the phi values will be calculated 12 | % cfg: the problem domain setup: 13 | % cfg.v: speed of light in vacuum (mm/s) 14 | % cfg.a: sphere radius (mm) 15 | % cfg.omua: background (outside) mua (1/mm) 16 | % cfg.omusp: background (outside) mus' (1/mm) 17 | % cfg.imua: sphere (inside) mua (1/mm) 18 | % cfg.imusp: sphere (inside) mus' (1/mm) 19 | % cfg.src: spherical source position (R,theta,phi) R in mm 20 | % cfg.maxl: maximum serial expansion terms 21 | % cfg.omega: DPDW modulation frequency 22 | % 23 | % output: 24 | % res: the output fluence for both interior and exterior regions 25 | % 26 | % example: 27 | % [phi_ana,xa,ya,za]=sphdiffusioninfinite(-30:0.8:30,0,-30:0.8:30); 28 | % contourf(xa,za,log10(abs(phi_ana)),40) 29 | % 30 | % this file is part of Mesh-based Monte Carlo (MMC) 31 | % 32 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 33 | % 34 | 35 | if (nargin < 4) 36 | cfg.v = 299792458000; 37 | cfg.a = 10; 38 | cfg.omua = 0.002; 39 | cfg.omusp = 0.990; 40 | cfg.imua = 0.050; 41 | cfg.imusp = 0.500; 42 | cfg.src = [30, pi, 0]; 43 | cfg.maxl = 20; 44 | cfg.omega = 0; 45 | end 46 | 47 | cfg.Din = cfg.v / (3 * cfg.imusp); 48 | cfg.Dout = cfg.v / (3 * cfg.omusp); 49 | cfg.kin = sqrt((-cfg.v * cfg.imua + i * cfg.omega) / cfg.Din); 50 | cfg.kout = sqrt((-cfg.v * cfg.omua + i * cfg.omega) / cfg.Dout); 51 | 52 | [xi, yi, zi] = meshgrid(xrange, yrange, zrange); 53 | 54 | [P, T, R] = cart2sph(xi(:), yi(:), zi(:)); % matlab's theta and phi are defined differently 55 | T = pi / 2 - T; 56 | 57 | idx = find(R > cfg.a); 58 | res = zeros(length(R), 1); 59 | res(idx) = sphdiffexterior(R(idx), T(idx), P(idx), cfg); 60 | 61 | idx = find(R <= cfg.a); 62 | res(idx) = sphdiffinterior(R(idx), T(idx), P(idx), cfg); 63 | 64 | res = squeeze(reshape(res, size(xi))); 65 | xi = squeeze(xi); 66 | yi = squeeze(yi); 67 | zi = squeeze(zi); 68 | -------------------------------------------------------------------------------- /matlab/sphdiffusionscatteronly.m: -------------------------------------------------------------------------------- 1 | function [res, xi, yi, zi] = sphdiffusionscatteronly(xrange, yrange, zrange, cfg) 2 | % 3 | % [res,xi,yi,zi]=sphdiffusionscatteronly(xrange,yrange,zrange,cfg) 4 | % 5 | % analytical solution to the diffusion model (scattered field only) 6 | % 7 | % author: Qianqian Fang (q.fang neu.edu) 8 | % 9 | % input: 10 | % xrange,yrange,zrange: a vector from where a grid will be created 11 | % and the phi values will be calculated 12 | % cfg: the problem domain setup: 13 | % cfg.v: speed of light in vacuum (mm/s) 14 | % cfg.a: sphere radius (mm) 15 | % cfg.omua: background (outside) mua (1/mm) 16 | % cfg.omusp: background (outside) mus' (1/mm) 17 | % cfg.imua: sphere (inside) mua (1/mm) 18 | % cfg.imusp: sphere (inside) mus' (1/mm) 19 | % cfg.src: spherical source position (R,theta,phi) R in mm 20 | % cfg.maxl: maximum serial expansion terms 21 | % cfg.omega: DPDW modulation frequency 22 | % 23 | % output: 24 | % res: the output fluence for both exterior region 25 | % 26 | % example: 27 | % [phi_ana,xa,ya,za]=sphdiffusionscatteronly(-30:0.8:30,0,-30:0.8:30); 28 | % contourf(xa,za,log10(abs(phi_ana)),40) 29 | % 30 | % this file is part of Mesh-based Monte Carlo (MMC) 31 | % 32 | % License: GPLv3, see http://mcx.sf.net/mmc/ for details 33 | % 34 | 35 | if (nargin < 4) 36 | cfg.v = 299792458000; 37 | cfg.a = 10; 38 | cfg.omua = 0.002; 39 | cfg.omusp = 0.990; 40 | cfg.imua = 0.050; 41 | cfg.imusp = 0.500; 42 | cfg.src = [30, pi, 0]; 43 | cfg.maxl = 20; 44 | cfg.omega = 0; 45 | end 46 | 47 | cfg.Din = cfg.v / (3 * cfg.imusp); 48 | cfg.Dout = cfg.v / (3 * cfg.omusp); 49 | cfg.kin = sqrt((-cfg.v * cfg.imua + i * cfg.omega) / cfg.Din); 50 | cfg.kout = sqrt((-cfg.v * cfg.omua + i * cfg.omega) / cfg.Dout); 51 | 52 | [xi, yi, zi] = meshgrid(xrange, yrange, zrange); 53 | 54 | [P, T, R] = cart2sph(xi(:), yi(:), zi(:)); % matlab's theta and phi are defined differently 55 | T = pi / 2 - T; 56 | 57 | idx = find(R > cfg.a); 58 | res = zeros(length(R), 1); 59 | res(idx) = sphdiffscatter(R(idx), T(idx), P(idx), cfg); 60 | 61 | res = squeeze(reshape(res, size(xi))); 62 | xi = squeeze(xi); 63 | yi = squeeze(yi); 64 | zi = squeeze(zi); 65 | -------------------------------------------------------------------------------- /mmclab/PKG_ADD: -------------------------------------------------------------------------------- 1 | if(exist(file_in_loadpath('mmc.mex'))) 2 | autoload('mmc',file_in_loadpath('mmc.mex')) 3 | else 4 | autoload('mmc',file_in_loadpath(['octave' filesep regexprep(computer('arch'), 'darwin[0-9.]+-', 'darwin-') filesep 'mmc.mex'])) 5 | end 6 | -------------------------------------------------------------------------------- /mmclab/example/demo_example_onecube.m: -------------------------------------------------------------------------------- 1 | %% ----------------------------------------------------------------- 2 | %% simple demonstration for debug flags 3 | %% ----------------------------------------------------------------- 4 | % 5 | % In this example, we run photon migration in a toy-problem to show 6 | % the basic steps and behaviors of the simulation code. 7 | % The mesh used in this case is a simple cube, splitted into 8 | % 6 tetrahedra. The edge length of the cube is 10mm. 9 | % A total of 20 photons are simulated starting 10 | % from a source position [2,8,0] along an incident 11 | % vector [0 0 1]. We run the simulation and print out 12 | % the moving trajectories of the photon, and the exit and 13 | % accumulation sites. Using a matlab script, one can visualize 14 | % the photon moving from the output of the simulation. 15 | % 16 | %% ----------------------------------------------------------------- 17 | 18 | %% ----------------------------------------------------------------- 19 | %% defining mesh and input structure 20 | %% ----------------------------------------------------------------- 21 | 22 | addpath('../../matlab/'); 23 | 24 | [cfg.node, cfg.elem] = genT6mesh(0:10:10, 0:10:10, 0:10:10); 25 | cfg.elem = sortrows(cfg.elem); 26 | cfg.elemprop = ones(size(cfg.elem, 1), 1); 27 | cfg.prop = [0 0 1 1; 0.005 1.0101010101 0.01 1.0]; 28 | cfg.srcpos = [2, 8, 0]; 29 | cfg.srcdir = [0 0 1]; 30 | cfg.seed = 1648335518; 31 | cfg.nphoton = 100; 32 | cfg.tstart = 0; 33 | cfg.tend = 5e-9; 34 | cfg.tstep = 5e-10; 35 | 36 | %% ----------------------------------------------------------------- 37 | %% run simulation and print out photon movement 38 | %% ----------------------------------------------------------------- 39 | 40 | cfg.debuglevel = 'M'; 41 | flux = mmclab(cfg); 42 | 43 | cfg.debuglevel = 'A'; 44 | flux = mmclab(cfg); 45 | -------------------------------------------------------------------------------- /mmclab/example/demo_mmclab_basic.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % MMCLAB - Mesh-based Monte Carlo for MATLAB/Octave by Qianqina Fang 3 | % 4 | % In this example, we show the most basic usage of MMCLAB. 5 | % 6 | % This file is part of Mesh-based Monte Carlo (MMC) URL:http://mcx.sf.net/mmc 7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8 | 9 | % prepare simulation input 10 | 11 | clear cfg; 12 | cfg.nphoton = 1e6; 13 | [cfg.node, face, cfg.elem] = meshabox([0 0 0], [60 60 30], 6); 14 | cfg.elemprop = ones(size(cfg.elem, 1), 1); 15 | cfg.srcpos = [30 30 0]; 16 | cfg.srcdir = [0 0 1]; 17 | cfg.prop = [0 0 1 1; 0.005 1 0 1.37]; 18 | cfg.tstart = 0; 19 | cfg.tend = 5e-9; 20 | cfg.tstep = 5e-9; 21 | cfg.debuglevel = 'TP'; 22 | cfg.issaveref = 1; % in addition to volumetric fluence, also save surface diffuse reflectance 23 | cfg.method = 'elem'; 24 | 25 | %% run the simulation 26 | 27 | flux = mmclab(cfg); 28 | 29 | %% plotting the result 30 | 31 | % plot the cross-section of the fluence 32 | subplot(121); 33 | plotmesh([cfg.node(:, 1:3), log10(abs(flux.data(1:size(cfg.node, 1))))], cfg.elem, 'y=30', 'facecolor', 'interp', 'linestyle', 'none'); 34 | view([0 1 0]); 35 | colorbar; 36 | 37 | % plot the surface diffuse reflectance 38 | if (isfield(cfg, 'issaveref') && cfg.issaveref == 1) 39 | subplot(122); 40 | faces = faceneighbors(cfg.elem, 'rowmajor'); 41 | hs = plotmesh(cfg.node, faces, 'cdata', log10(flux.dref(:, 1)), 'linestyle', 'none'); 42 | colorbar; 43 | end 44 | -------------------------------------------------------------------------------- /mmclab/example/demo_mmclab_slit.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % MMCLAB - Mesh-based Monte Carlo for MATLAB/Octave by Qianqina Fang 3 | % 4 | % In this example, we show the most basic usage of MMCLAB. 5 | % 6 | % This file is part of Mesh-based Monte Carlo (MMC) URL:http://mcx.sf.net/mmc 7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8 | 9 | % prepare simulation input 10 | 11 | cfg.nphoton = 1e7; 12 | [cfg.node face cfg.elem] = meshabox([0 0 0], [60 60 30], 6); 13 | cfg.elemprop = ones(size(cfg.elem, 1), 1); 14 | cfg.srcpos = [20 30 -10]; 15 | cfg.srcdir = [0 0.2 sqrt(1 - 0.04)]; 16 | cfg.prop = [0 0 1 1; 0.005 0.1 0 1.37]; 17 | cfg.tstart = 0; 18 | cfg.tend = 5e-9; 19 | cfg.tstep = 5e-9; 20 | cfg.debuglevel = 'TP'; 21 | cfg.unitinmm = 1; 22 | cfg.method = 'elem'; 23 | cfg.srctype = 'slit'; 24 | cfg.srcparam1 = [30 0 0 0]; 25 | cfg.srcparam2 = [0 0 0 0]; 26 | 27 | % run the simulation 28 | 29 | flux = mmclab(cfg); 30 | 31 | % plotting the result 32 | 33 | % if you have the SVN version of iso2mesh, use the next line to plot: 34 | % qmeshcut(cfg.elem(:,1:4),cfg.node(:,1:3),log10(abs(flux.data(:))),'y=30','linestyle','none'); 35 | 36 | plotmesh([cfg.node(:, 1:3), log10(abs(flux.data(1:size(cfg.node, 1))))], cfg.elem, 'x=40', 'facecolor', 'interp', 'linestyle', 'none'); 37 | hold on; 38 | plotmesh([cfg.node(:, 1:3), log10(abs(flux.data(1:size(cfg.node, 1))))], cfg.elem, 'y=30', 'facecolor', 'interp', 'linestyle', 'none'); 39 | view(3); 40 | colorbar; 41 | -------------------------------------------------------------------------------- /mmclab/example/demo_photon_sharing.m: -------------------------------------------------------------------------------- 1 | % In this example, we show the photon sharing feature of MMCLAB. 2 | % i.e. obtain results of multiple source patterns with only one simulation 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | 5 | %% prepare simulation input 6 | 7 | cfg.nphoton = 3e6; 8 | [cfg.node, face, cfg.elem] = meshabox([0 0 0], [60 60 20], 2, 2); 9 | cfg.elemprop = ones(size(cfg.elem, 1), 1); 10 | cfg.srcpos = [10 10 -2]; 11 | cfg.srcdir = [0 0 1]; 12 | cfg.srctype = 'pattern'; 13 | cfg.srcparam1 = [40.0 0.0 0.0 40]; 14 | cfg.srcparam2 = [0.0 40.0 0.0 40]; 15 | cfg.prop = [0 0 1 1; 0.01 10 0.9 1.37]; 16 | cfg.tstart = 0; 17 | cfg.tend = 5e-9; 18 | cfg.tstep = 1e-10; 19 | cfg.gpuid = 1; 20 | cfg.method = 'elem'; 21 | cfg.debuglevel = 'TP'; 22 | 23 | %% 5 patterns represented by a 3D matrix 24 | 25 | pat = zeros(40, 40, 5); 26 | pat(:, :, 1) = ones(40); % full field illumination pattern 27 | pat(1:20, :, 2) = 1; % pattern with left half bright 28 | pat(:, 1:20, 3) = 1; % pattern with top half bright 29 | pat(11:30, 11:30, 4) = 1; % pattern with bright square in the middle 30 | pat(16:25, :, 5) = 1; 31 | pat(:, 16:25, 5) = 1; % pattern with a bright cross 32 | 33 | cfg.srcpattern = permute(pat, [3 1 2]); 34 | 35 | %% run the simulation 36 | 37 | [flux, detp] = mmclab(cfg); 38 | 39 | %% plot results (same as in the mmc example) 40 | 41 | [node, face, elem] = meshabox([0 0 0], [60 60 20], 2, 2); 42 | data = flux.data(:, 1:length(node), :); 43 | cwdata = squeeze(sum(data, 3)); 44 | 45 | figure(); 46 | 47 | subplot(1, 3, 1); 48 | title('pattern 1'); 49 | plotmesh([node, (cwdata(1, :))'], elem, 'linestyle', 'none'); 50 | shading interp; 51 | axis off; 52 | view([0, 0, -1]); 53 | 54 | subplot(2, 3, 2); 55 | title('pattern 2'); 56 | plotmesh([node, (cwdata(2, :))'], elem, 'linestyle', 'none'); 57 | shading interp; 58 | axis off; 59 | view([0, 0, -1]); 60 | 61 | subplot(2, 3, 3); 62 | title('pattern 3'); 63 | plotmesh([node, (cwdata(3, :))'], elem, 'linestyle', 'none'); 64 | shading interp; 65 | axis off; 66 | view([0, 0, -1]); 67 | 68 | subplot(2, 3, 5); 69 | title('pattern 4'); 70 | plotmesh([node, (cwdata(4, :))'], elem, 'linestyle', 'none'); 71 | shading interp; 72 | axis off; 73 | view([0, 0, -1]); 74 | 75 | subplot(2, 3, 6); 76 | title('pattern 5'); 77 | plotmesh([node, (cwdata(5, :))'], elem, 'linestyle', 'none'); 78 | shading interp; 79 | axis off; 80 | view([0, 0, -1]); 81 | -------------------------------------------------------------------------------- /mmclab/example/demo_wide_det.m: -------------------------------------------------------------------------------- 1 | addpath('../../matlab/'); 2 | addpath('..'); 3 | 4 | clear cfg; 5 | 6 | [node, face, c0] = latticegrid([0 60], [0 60], [0 5 10]); 7 | c0(:, 4) = [2; 3]; % maximum element size for bottom (label 1) and top (label 2) layers 8 | [node, elem] = surf2mesh(node, face, [], [], 1, [], c0); 9 | 10 | detdef = struct('srctype', 'planar', 'srcpos', [10, 10, -1], 'srcdir', [0 0 1], ... 11 | 'srcparam1', [40 0 0 40], 'srcparam2', [0 40 0 40]); 12 | 13 | [cfg.node, cfg.elem] = mmcadddet(node, elem, detdef); 14 | cfg.elemprop = cfg.elem(:, 5); 15 | cfg.elem = cfg.elem(:, 1:4); 16 | cfg.prop = [0 0 1 1 17 | 0.01 1.0 0.01 1.37 18 | 0.05 10.0 0.9 1.37]; 19 | 20 | cfg.srcpos = [25.0 35.0 10.0]; 21 | cfg.e0 = tsearchn(cfg.node, cfg.elem(:, 1:4), cfg.srcpos); 22 | cfg.srcdir = [0, 0, -1]; 23 | 24 | cfg.srctype = 'pencil'; 25 | cfg.srcparam1 = [0 0 0 0]; 26 | cfg.srcparam2 = [0 0 0 0]; 27 | 28 | cfg.detpos = [10.0, 10.0, -1.0, 0]; 29 | cfg.detparam1 = [40.0 0.0 0.0 40]; 30 | cfg.detparam2 = [0.0 40.0 0.0 40]; 31 | 32 | cfg.tstart = 0; 33 | cfg.tend = 2e-9; 34 | cfg.tstep = 4e-11; 35 | 36 | cfg.nphoton = 1e6; 37 | cfg.seed = 12345678; 38 | cfg.debuglevel = 'TP'; 39 | cfg.issaveexit = 2; 40 | 41 | [flux, detp] = mmclab(cfg); 42 | 43 | figure; 44 | imagesc(sum(detp.data, 3)'); 45 | axis equal; 46 | -------------------------------------------------------------------------------- /mmclab/example/head_atlas.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fangq/mmc/b85e750b59e346535b6c7ee432a5eb041cd02dbd/mmclab/example/head_atlas.mat -------------------------------------------------------------------------------- /mmclab/example/mmclab_selftest_input.m: -------------------------------------------------------------------------------- 1 | %% ----------------------------------------------------------------- 2 | %% MMClab self-test script 3 | %% ----------------------------------------------------------------- 4 | % 5 | % In this example, we generate various true or false input conditions 6 | % and test the robustness of the script to these conditions 7 | % 8 | 9 | dat = mmclab(); 10 | 11 | cfg = struct(); 12 | dat = mmclab(cfg); 13 | 14 | [cfg.node face cfg.elem] = meshabox([0 0 0], [10 10 10], 1); 15 | dat = mmclab(cfg); 16 | 17 | cfg.elem(:, 5) = 1; 18 | dat = mmclab(cfg); 19 | 20 | cfg.srcpos = [5 5 0]; 21 | cfg.srcdir = [0 0 1]; 22 | cfg.nphoton = 1000; 23 | cfg.prop = [0 0 1 1; 0.1 1 0.2 1.3]; 24 | dat = mmclab(cfg); 25 | 26 | cfg.tstart = 0; 27 | cfg.tend = 1e-9; 28 | dat = mmclab(cfg); 29 | 30 | cfg.tstep = 10e-9; 31 | dat = mmclab(cfg); 32 | 33 | cfg.srcpos = [-1 -1 -1]; 34 | dat = mmclab(cfg); 35 | 36 | cfg.srcparam1 = [0 0 0 0]; 37 | cfg.srcparam2 = [0 0 0 0]; 38 | dat = mmclab(cfg); 39 | -------------------------------------------------------------------------------- /mmclab/example/vessel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fangq/mmc/b85e750b59e346535b6c7ee432a5eb041cd02dbd/mmclab/example/vessel.mat -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | ROOTDIR = .. 2 | BINARY=mmc 3 | 4 | FILES=mmc_rand_xorshift128p mmc_mesh mmc_raytrace mmc_utils mmc_tictoc mmc_host mmc_highorder mmc_bench mmc_cl_utils mmc_cl_host 5 | CLPROGRAM=mmc_core 6 | 7 | #PLATFORM = $(shell uname -s) 8 | 9 | #ifeq ($(findstring Darwin,$(PLATFORM)), Darwin) 10 | # EXTRALIB:=-static-libgcc -lgcc_eh 11 | # MEXLINKOPT:=$(EXTRALIB) 12 | #endif 13 | 14 | DOXYCFG=mmc_doxygen.cfg 15 | 16 | USERCCFLAGS=-DUSE_OS_TIMER -DUSE_OPENCL -DMMC_XORSHIFT 17 | 18 | DUMMY:=$(shell mkdir -p built/cjson) 19 | 20 | ifneq (,$(filter $(MAKECMDGOALS),cuda cudamex cudaoct)) 21 | FILES+=mmc_cu_host 22 | USERCCFLAGS+=-DUSE_CUDA 23 | CUCCOPT= -DUSE_ATOMIC -DMCX_SAVE_DETECTORS -DMCX_DO_REFLECTION -DUSE_DMMC -DUSE_BLBADOUEL -Xcompiler -fPIC 24 | EXTRALIB+=-lcudart 25 | LIBCUDART=-L$(LIBOPENCLDIR) -lcudart 26 | endif 27 | 28 | include $(ROOTDIR)/commons/Makefile_common.mk 29 | -------------------------------------------------------------------------------- /src/SFMT/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima 2 | University. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | disclaimer in the documentation and/or other materials provided 13 | with the distribution. 14 | * Neither the name of the Hiroshima University nor the names of 15 | its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written 17 | permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /src/SFMT/SFMT-params19937.h: -------------------------------------------------------------------------------- 1 | #ifndef SFMT_PARAMS19937_H 2 | #define SFMT_PARAMS19937_H 3 | 4 | #define POS1 122 5 | #define SL1 18 6 | #define SL2 1 7 | #define SR1 11 8 | #define SR2 1 9 | #define MSK1 0xdfffffefU 10 | #define MSK2 0xddfecb7fU 11 | #define MSK3 0xbffaffffU 12 | #define MSK4 0xbffffff6U 13 | #define PARITY1 0x00000001U 14 | #define PARITY2 0x00000000U 15 | #define PARITY3 0x00000000U 16 | #define PARITY4 0x13c9e684U 17 | 18 | 19 | /* PARAMETERS FOR ALTIVEC */ 20 | #if defined(__APPLE__) /* For OSX */ 21 | #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) 22 | #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) 23 | #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) 24 | #define ALTI_MSK64 \ 25 | (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) 26 | #define ALTI_SL2_PERM \ 27 | (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8) 28 | #define ALTI_SL2_PERM64 \ 29 | (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0) 30 | #define ALTI_SR2_PERM \ 31 | (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) 32 | #define ALTI_SR2_PERM64 \ 33 | (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) 34 | #else /* For OTHER OSs(Linux?) */ 35 | #define ALTI_SL1 {SL1, SL1, SL1, SL1} 36 | #define ALTI_SR1 {SR1, SR1, SR1, SR1} 37 | #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} 38 | #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} 39 | #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8} 40 | #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0} 41 | #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} 42 | #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} 43 | #endif /* For OSX */ 44 | #define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6" 45 | 46 | #endif /* SFMT_PARAMS19937_H */ 47 | -------------------------------------------------------------------------------- /src/cjson/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Dave Gamble 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /src/makefile_logistic: -------------------------------------------------------------------------------- 1 | ROOTDIR = .. 2 | BINARY=mmc_log 3 | 4 | FILES=logistic_rand mmc_mesh mmc_raytrace mmc_utils mmc_tictoc mmc 5 | USERCCFLAGS=-DMMC_LOGISTIC -DUSE_OS_TIMER 6 | 7 | include $(ROOTDIR)/commons/Makefile_common.mk 8 | 9 | -------------------------------------------------------------------------------- /src/makefile_sfmt: -------------------------------------------------------------------------------- 1 | ROOTDIR = .. 2 | BINARY=mmc_sfmt 3 | 4 | PLATFORM = $(shell uname -s) 5 | ifeq ($(findstring MINGW32,$(PLATFORM)), MINGW32) 6 | FILES=SFMT/SFMT mmc_rand_sfmt mmc_mesh tettracing mmc_utils mmc_tictoc mmc_rand_drand48 mmc mmc_host cjson/cJSON mmc_highorder ubj/ubjw 7 | else 8 | FILES=SFMT/SFMT mmc_rand_sfmt mmc_mesh tettracing mmc_utils mmc_tictoc mmc mmc_host cjson/cJSON ubj/ubjw 9 | endif 10 | 11 | #ifeq ($(findstring Darwin,$(PLATFORM)), Darwin) 12 | # EXTRALIB:=-static-libgcc 13 | #endif 14 | 15 | DOXYCFG=mmc_doxyen.cfg 16 | 17 | USERCCFLAGS=-DMMC_SFMT -DUSE_OS_TIMER -DMEXP=19937 18 | 19 | DUMMY:=$(shell mkdir -p built/SFMT built/cjson) 20 | 21 | include $(ROOTDIR)/commons/Makefile_common.mk 22 | 23 | -------------------------------------------------------------------------------- /src/makefile_xorshift: -------------------------------------------------------------------------------- 1 | ROOTDIR = .. 2 | BINARY=mmc 3 | 4 | FILES=mmc_rand_xorshift128p mmc_mesh mmc_raytrace mmc_utils mmc_tictoc mmc mmc_host cjson/cJSON mmc_highorder ubj/ubjw 5 | 6 | PLATFORM = $(shell uname -s) 7 | ifeq ($(findstring MINGW32,$(PLATFORM)), MINGW32) 8 | FILES+=drand48_r_libgw32c 9 | endif 10 | ifeq ($(findstring CYGWIN,$(PLATFORM)), CYGWIN) 11 | FILES+=drand48_r_libgw32c 12 | endif 13 | 14 | ifeq ($(findstring Darwin,$(PLATFORM)), Darwin) 15 | EXTRALIB:=-static-libgcc -lgcc_eh 16 | MEXLINKOPT:=$(EXTRALIB) 17 | endif 18 | 19 | DOXYCFG=mmcdoxy.cfg 20 | 21 | USERCCFLAGS=-DUSE_OS_TIMER -DMMC_XORSHIFT 22 | 23 | DUMMY:=$(shell mkdir -p built/cjson) 24 | 25 | include $(ROOTDIR)/commons/Makefile_common.mk 26 | 27 | -------------------------------------------------------------------------------- /src/mexopts_cygwin64_gcc.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set MATLAB=%MATLAB% 4 | set MW_TARGET_ARCH=win64 5 | set PATH=C:\cygwin64\bin;%PATH% 6 | 7 | set COMPILER=x86_64-w64-mingw32-g++ 8 | set COMPFLAGS=-c -m64 -mwin32 -mdll -Wall -std=c++11 -DMATLAB_MEX_FILE 9 | set OPTIMFLAGS=-DNDEBUG -O2 10 | set DEBUGFLAGS=-g 11 | set NAME_OBJECT=-o 12 | 13 | set LINKER=x86_64-w64-mingw32-g++ 14 | set LINKFLAGS=-shared -L"%MATLAB%\extern\lib\win64\microsoft" -L"%MATLAB%\bin\win64" 15 | set LINKFLAGSPOST=-lmx -lmex -lmat 16 | set LINKOPTIMFLAGS=-O2 17 | set LINKDEBUGFLAGS=-g 18 | set LINK_FILE= 19 | set LINK_LIB= 20 | set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%" -------------------------------------------------------------------------------- /src/mingw64/include/CL/opencl.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2008-2015 The Khronos Group Inc. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and/or associated documentation files (the 6 | * "Materials"), to deal in the Materials without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Materials, and to 9 | * permit persons to whom the Materials are furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Materials. 14 | * 15 | * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS 16 | * KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS 17 | * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT 18 | * https://www.khronos.org/registry/ 19 | * 20 | * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 24 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26 | * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 27 | ******************************************************************************/ 28 | 29 | /* $Rev $ on $Date $ */ 30 | 31 | #ifndef __OPENCL_H 32 | #define __OPENCL_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #ifdef __APPLE__ 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #else 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #endif 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* __OPENCL_H */ 59 | 60 | -------------------------------------------------------------------------------- /src/mingw64/include/features.h: -------------------------------------------------------------------------------- 1 | /* features.h 2 | 3 | This file is part of Cygwin. 4 | 5 | This software is a copyrighted work licensed under the terms of the 6 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for 7 | details. */ 8 | 9 | #ifndef _FEATURES_H 10 | #define _FEATURES_H 11 | 12 | #include 13 | #include 14 | 15 | /* Various options should be defined here, but the framework to do this 16 | is not laid down so far. Especially notable are the following defines, 17 | which can be used by the application to switch on or off various 18 | datatypes and function prototypes: 19 | 20 | _BSD_SOURCE to include pure BSD functions which are not defined 21 | under POSIX. 22 | 23 | _POSIX_SOURCE if the application requests a POSIX compatible system. 24 | 25 | _XOPEN_SOURCE if X/Open functions and datatypes are requested. This 26 | option includes _POSIX_SOURCE. 27 | 28 | _GNU_SOURCE to turn on GNU extensions which might collide with defines 29 | used in application or library headers. This option 30 | includes _BSD_SOURCE, _XOPEN_SOURCE and _POSIX_SOURCE. 31 | */ 32 | 33 | #endif /* _FEATURES_H */ 34 | -------------------------------------------------------------------------------- /src/mingw64/include/sys/ioctl.h: -------------------------------------------------------------------------------- 1 | /* sys/ioctl.h 2 | 3 | This file is part of Cygwin. 4 | 5 | This software is a copyrighted work licensed under the terms of the 6 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for 7 | details. */ 8 | 9 | /* sys/ioctl.h */ 10 | 11 | #ifndef _SYS_IOCTL_H 12 | #define _SYS_IOCTL_H 13 | 14 | #include 15 | #include 16 | 17 | __BEGIN_DECLS 18 | 19 | /* /dev/windows ioctls */ 20 | 21 | #define WINDOWS_POST 0 /* Set write() behavior to PostMessage() */ 22 | #define WINDOWS_SEND 1 /* Set write() behavior to SendMessage() */ 23 | #define WINDOWS_HWND 2 /* Set hWnd for read() calls */ 24 | 25 | /* Some standard linux defines */ 26 | 27 | #define _IOC_NRBITS 8 28 | #define _IOC_TYPEBITS 8 29 | #define _IOC_SIZEBITS 14 30 | #define _IOC_DIRBITS 2 31 | 32 | #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) 33 | #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) 34 | #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) 35 | #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) 36 | 37 | #define _IOC_NRSHIFT 0 38 | #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) 39 | #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) 40 | #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) 41 | 42 | #define _IOC_NONE 0U 43 | #define _IOC_WRITE 1U 44 | #define _IOC_READ 2U 45 | 46 | #define _IOC(dir,type,nr,size) \ 47 | (((dir) << _IOC_DIRSHIFT) | \ 48 | + ((type) << _IOC_TYPESHIFT) | \ 49 | + ((nr) << _IOC_NRSHIFT) | \ 50 | + ((size) << _IOC_SIZESHIFT)) 51 | 52 | #define _LINUX_IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) 53 | #define _LINUX_IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) 54 | #define _LINUX_IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) 55 | #define _LINUX_IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) 56 | 57 | #ifdef __USE_LINUX_IOCTL_DEFS 58 | # define _IO _LINUX_IO 59 | # define _IOR _LINUX_IOR 60 | # define _IOW _LINUX_IOW 61 | # define _IOWR _LINUX_IOWR 62 | #endif /*__USE_LINUX_IOCTL_DEFS */ 63 | 64 | int __cdecl ioctl (int __fd, int __cmd, ...); 65 | 66 | __END_DECLS 67 | #endif 68 | -------------------------------------------------------------------------------- /src/mmc_bench.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | ** \mainpage Mesh-based Monte Carlo (MMC) - a 3D photon simulator 3 | ** 4 | ** \author Qianqian Fang 5 | ** \copyright Qianqian Fang, 2010-2025 6 | ** 7 | ** \section sref Reference: 8 | ** \li \c (\b Fang2010) Qianqian Fang, 9 | ** "Mesh-based Monte Carlo Method Using Fast Ray-Tracing 10 | ** in Plucker Coordinates," Biomed. Opt. Express, 1(1) 165-175 (2010). 11 | ** \li \c (\b Fang2012) Qianqian Fang and David R. Kaeli, 12 | ** 13 | ** "Accelerating mesh-based Monte Carlo method on modern CPU architectures," 14 | ** Biomed. Opt. Express 3(12), 3223-3230 (2012) 15 | ** \li \c (\b Yao2016) Ruoyang Yao, Xavier Intes, and Qianqian Fang, 16 | ** 17 | ** "Generalized mesh-based Monte Carlo for wide-field illumination and detection 18 | ** via mesh retessellation," Biomed. Optics Express, 7(1), 171-184 (2016) 19 | ** \li \c (\b Fang2019) Qianqian Fang and Shijie Yan, 20 | ** 21 | ** "Graphics processing unit-accelerated mesh-based Monte Carlo photon transport 22 | ** simulations," J. of Biomedical Optics, 24(11), 115002 (2019) 23 | ** \li \c (\b Yuan2021) Yaoshen Yuan, Shijie Yan, and Qianqian Fang, 24 | ** 25 | ** "Light transport modeling in highly complex tissues using the implicit 26 | ** mesh-based Monte Carlo algorithm," Biomed. Optics Express, 12(1) 147-161 (2021) 27 | ** 28 | ** \section slicense License 29 | ** GPL v3, see LICENSE.txt for details 30 | *******************************************************************************/ 31 | 32 | /***************************************************************************//** 33 | \file mmc_bench.h 34 | 35 | @brief MMC builtin benchmarks 36 | *******************************************************************************/ 37 | 38 | #ifndef _MCEXTREME_BENCHMARK_H 39 | #define _MCEXTREME_BENCHMARK_H 40 | 41 | #define MAX_MCX_BENCH 6 /**< Total number of built-in benchmarks */ 42 | extern const char* benchname[MAX_MCX_BENCH]; /**< String list defining the names of each built-in benchmark */ 43 | extern const char* benchjson[MAX_MCX_BENCH]; /**< JSON-formatted input configuration for each built-in benchmark */ 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/mmc_core.cu: -------------------------------------------------------------------------------- 1 | mmc_core.cl -------------------------------------------------------------------------------- /src/mmc_highorder.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | ** \mainpage Mesh-based Monte Carlo (MMC) - a 3D photon simulator 3 | ** 4 | ** \author Qianqian Fang 5 | ** \copyright Qianqian Fang, 2010-2025 6 | ** 7 | ** \section sref Reference: 8 | ** \li \c (\b Fang2010) Qianqian Fang, 9 | ** "Mesh-based Monte Carlo Method Using Fast Ray-Tracing 10 | ** in Plucker Coordinates," Biomed. Opt. Express, 1(1) 165-175 (2010). 11 | ** \li \c (\b Fang2012) Qianqian Fang and David R. Kaeli, 12 | ** 13 | ** "Accelerating mesh-based Monte Carlo method on modern CPU architectures," 14 | ** Biomed. Opt. Express 3(12), 3223-3230 (2012) 15 | ** \li \c (\b Yao2016) Ruoyang Yao, Xavier Intes, and Qianqian Fang, 16 | ** 17 | ** "Generalized mesh-based Monte Carlo for wide-field illumination and detection 18 | ** via mesh retessellation," Biomed. Optics Express, 7(1), 171-184 (2016) 19 | ** \li \c (\b Fang2019) Qianqian Fang and Shijie Yan, 20 | ** 21 | ** "Graphics processing unit-accelerated mesh-based Monte Carlo photon transport 22 | ** simulations," J. of Biomedical Optics, 24(11), 115002 (2019) 23 | ** \li \c (\b Yuan2021) Yaoshen Yuan, Shijie Yan, and Qianqian Fang, 24 | ** 25 | ** "Light transport modeling in highly complex tissues using the implicit 26 | ** mesh-based Monte Carlo algorithm," Biomed. Optics Express, 12(1) 147-161 (2021) 27 | ** 28 | ** \section slicense License 29 | ** GPL v3, see LICENSE.txt for details 30 | *******************************************************************************/ 31 | 32 | #ifndef _MCEXTREME_LOGISTIC_RAND_H 33 | #define _MCEXTREME_LOGISTIC_RAND_H 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | void mesh_10nodetet(tetmesh* mesh, mcconfig* cfg); 39 | void mesh_getfacenb(tetmesh* mesh, mcconfig* cfg); 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/mmc_neurojson.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | ** \mainpage Mesh-based Monte Carlo (MMC) - a 3D photon simulator 3 | ** 4 | ** \author Qianqian Fang 5 | ** \copyright Qianqian Fang, 2010-2025 6 | ** 7 | ** \section sref Reference: 8 | ** \li \c (\b Fang2010) Qianqian Fang, 9 | ** "Mesh-based Monte Carlo Method Using Fast Ray-Tracing 10 | ** in Plucker Coordinates," Biomed. Opt. Express, 1(1) 165-175 (2010). 11 | ** \li \c (\b Fang2012) Qianqian Fang and David R. Kaeli, 12 | ** 13 | ** "Accelerating mesh-based Monte Carlo method on modern CPU architectures," 14 | ** Biomed. Opt. Express 3(12), 3223-3230 (2012) 15 | ** \li \c (\b Yao2016) Ruoyang Yao, Xavier Intes, and Qianqian Fang, 16 | ** 17 | ** "Generalized mesh-based Monte Carlo for wide-field illumination and detection 18 | ** via mesh retessellation," Biomed. Optics Express, 7(1), 171-184 (2016) 19 | ** \li \c (\b Fang2019) Qianqian Fang and Shijie Yan, 20 | ** 21 | ** "Graphics processing unit-accelerated mesh-based Monte Carlo photon transport 22 | ** simulations," J. of Biomedical Optics, 24(11), 115002 (2019) 23 | ** \li \c (\b Yuan2021) Yaoshen Yuan, Shijie Yan, and Qianqian Fang, 24 | ** 25 | ** "Light transport modeling in highly complex tissues using the implicit 26 | ** mesh-based Monte Carlo algorithm," Biomed. Optics Express, 12(1) 147-161 (2021) 27 | ** 28 | ** \section slicense License 29 | ** GPL v3, see LICENSE.txt for details 30 | *******************************************************************************/ 31 | 32 | #ifndef _MCEXTREME_NEUROJSON_API_H 33 | #define _MCEXTREME_NEUROJSON_API_H 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | int runcommand(char* cmd, char* param, char** output); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/mmc_tictoc.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | ** \mainpage Mesh-based Monte Carlo (MMC) - a 3D photon simulator 3 | ** 4 | ** \author Qianqian Fang 5 | ** \copyright Qianqian Fang, 2010-2025 6 | ** 7 | ** \section sref Reference: 8 | ** \li \c (\b Fang2010) Qianqian Fang, 9 | ** "Mesh-based Monte Carlo Method Using Fast Ray-Tracing 10 | ** in Plucker Coordinates," Biomed. Opt. Express, 1(1) 165-175 (2010). 11 | ** \li \c (\b Fang2012) Qianqian Fang and David R. Kaeli, 12 | ** 13 | ** "Accelerating mesh-based Monte Carlo method on modern CPU architectures," 14 | ** Biomed. Opt. Express 3(12), 3223-3230 (2012) 15 | ** \li \c (\b Yao2016) Ruoyang Yao, Xavier Intes, and Qianqian Fang, 16 | ** 17 | ** "Generalized mesh-based Monte Carlo for wide-field illumination and detection 18 | ** via mesh retessellation," Biomed. Optics Express, 7(1), 171-184 (2016) 19 | ** \li \c (\b Fang2019) Qianqian Fang and Shijie Yan, 20 | ** 21 | ** "Graphics processing unit-accelerated mesh-based Monte Carlo photon transport 22 | ** simulations," J. of Biomedical Optics, 24(11), 115002 (2019) 23 | ** \li \c (\b Yuan2021) Yaoshen Yuan, Shijie Yan, and Qianqian Fang, 24 | ** 25 | ** "Light transport modeling in highly complex tissues using the implicit 26 | ** mesh-based Monte Carlo algorithm," Biomed. Optics Express, 12(1) 147-161 (2021) 27 | ** 28 | ** \section slicense License 29 | ** GPL v3, see LICENSE.txt for details 30 | *******************************************************************************/ 31 | 32 | /***************************************************************************//** 33 | \file mmc_tictoc.h 34 | 35 | \brief Interface of the timing unit 36 | *******************************************************************************/ 37 | 38 | #ifndef GETTIMEOFDAY_H 39 | #define GETTIMEOFDAY_H 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | unsigned int StartTimer (); 46 | unsigned int GetTimeMillis (); 47 | void sleep_ms(int milliseconds); 48 | 49 | #if defined(_WIN32) && defined(USE_OS_TIMER) && !defined(MCX_CONTAINER) 50 | int EnableVTMode(); 51 | #endif 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif /* GETTIMEOFDAY_H */ 58 | 59 | -------------------------------------------------------------------------------- /src/ubj/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(ubj) 3 | 4 | add_library(ubj ubjw.c ubjr.c ubjrw.c ubj_internal.h ubj.h) 5 | 6 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 7 | add_subdirectory(tests) 8 | 9 | 10 | 11 | add_subdirectory(tools) -------------------------------------------------------------------------------- /src/ubj/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Steven Braeger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/ubj/README.md: -------------------------------------------------------------------------------- 1 | ubj 2 | === 3 | 4 | UBJSON C/C++ libraries 5 | 6 | This library implements the current draft (draft 12) of the UBJSON specification in ANSI C. 7 | 8 | There are three components, each of which may be compiled and used seperately from each-other. 9 | 10 | The reader component (ubjr.c) the writer component (ubjw.c) and the transcoder (ubjrw.c). 11 | 12 | The API is defined in ubj.h 13 | -------------------------------------------------------------------------------- /src/zmat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ################################################################# 2 | # CMake configure file for ZMat 3 | # Qianqian Fang 4 | # 2020/05/23 5 | ################################################################# 6 | 7 | cmake_minimum_required(VERSION 3.3) 8 | 9 | project(zmat) 10 | 11 | find_package(ZLIB REQUIRED) 12 | #find_package(Matlab) 13 | 14 | option(STATIC_LIB "Build static library" ON) 15 | 16 | # C Options 17 | set(CMAKE_C_FLAGS "-g -Wall -O3 -fPIC -DNO_BLOSC2 -DNO_ZLIB -DNO_ZSTD -D_LARGEFILE64_SOURCE=1") 18 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../) 19 | 20 | # Add include directories 21 | #include_directories(./) 22 | include_directories(lz4) 23 | include_directories(miniz) 24 | include_directories(easylzma) 25 | include_directories(easylzma/pavlov) 26 | 27 | # Add all project units 28 | 29 | if(STATIC_LIB) 30 | add_library(zmat STATIC 31 | zmatlib.c 32 | lz4/lz4.c 33 | lz4/lz4hc.c 34 | miniz/miniz.c 35 | miniz/miniz.h 36 | easylzma/compress.c 37 | easylzma/decompress.c 38 | easylzma/lzma_header.c 39 | easylzma/lzip_header.c 40 | easylzma/common_internal.c 41 | easylzma/pavlov/LzmaEnc.c 42 | easylzma/pavlov/LzmaDec.c 43 | easylzma/pavlov/LzmaLib.c 44 | easylzma/pavlov/LzFind.c 45 | easylzma/pavlov/Bra.c 46 | easylzma/pavlov/BraIA64.c 47 | easylzma/pavlov/Alloc.c 48 | easylzma/pavlov/7zCrc.c 49 | ) 50 | else() 51 | # Add all project units 52 | add_library(zmat SHARED 53 | zmatlib.c 54 | lz4/lz4.c 55 | lz4/lz4hc.c 56 | miniz/miniz.c 57 | miniz/miniz.h 58 | easylzma/compress.c 59 | easylzma/decompress.c 60 | easylzma/lzma_header.c 61 | easylzma/lzip_header.c 62 | easylzma/common_internal.c 63 | easylzma/pavlov/LzmaEnc.c 64 | easylzma/pavlov/LzmaDec.c 65 | easylzma/pavlov/LzmaLib.c 66 | easylzma/pavlov/LzFind.c 67 | easylzma/pavlov/Bra.c 68 | easylzma/pavlov/BraIA64.c 69 | easylzma/pavlov/Alloc.c 70 | easylzma/pavlov/7zCrc.c 71 | ) 72 | endif() 73 | 74 | # Link options 75 | target_link_libraries( 76 | zmat 77 | ZLIB::ZLIB 78 | ) 79 | 80 | if(Matlab_FOUND) 81 | matlab_add_mex( 82 | NAME zipmat 83 | SRC zmat.cpp 84 | LINK_TO mex mx zmat 85 | ) 86 | endif() 87 | 88 | -------------------------------------------------------------------------------- /src/zmat/easylzma/README: -------------------------------------------------------------------------------- 1 | pavlov/ - contains original lzma compress/decompress source from Igor Pavlov 2 | easylzma/ - contains the public api of this library 3 | ./ - contains the implementation of this wrapper library 4 | -------------------------------------------------------------------------------- /src/zmat/easylzma/common_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | */ 10 | 11 | #include "common_internal.h" 12 | 13 | static void *elzmaAlloc(void *p, size_t size) { 14 | struct elzma_alloc_struct * as = (struct elzma_alloc_struct *) p; 15 | if (as->clientMallocFunc) { 16 | return as->clientMallocFunc(as->clientMallocContext, size); 17 | } 18 | return malloc(size); 19 | } 20 | 21 | static void elzmaFree(void *p, void *address) { 22 | struct elzma_alloc_struct * as = (struct elzma_alloc_struct *) p; 23 | if (as->clientFreeFunc) { 24 | as->clientFreeFunc(as->clientMallocContext, address); 25 | } else { 26 | free(address); 27 | } 28 | } 29 | 30 | void 31 | init_alloc_struct(struct elzma_alloc_struct * as, 32 | elzma_malloc clientMallocFunc, 33 | void * clientMallocContext, 34 | elzma_free clientFreeFunc, 35 | void * clientFreeContext) 36 | { 37 | as->Alloc = elzmaAlloc; 38 | as->Free = elzmaFree; 39 | as->clientMallocFunc = clientMallocFunc; 40 | as->clientMallocContext = clientMallocContext; 41 | as->clientFreeFunc = clientFreeFunc; 42 | as->clientFreeContext = clientFreeContext; 43 | } 44 | -------------------------------------------------------------------------------- /src/zmat/easylzma/common_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __ELZMA_COMMON_INTERNAL_H__ 2 | #define __ELZMA_COMMON_INTERNAL_H__ 3 | 4 | #include "easylzma/common.h" 5 | 6 | /** a structure which may be cast and passed into Igor's allocate 7 | * routines */ 8 | struct elzma_alloc_struct { 9 | void *(*Alloc)(void *p, size_t size); 10 | void (*Free)(void *p, void *address); /* address can be 0 */ 11 | 12 | elzma_malloc clientMallocFunc; 13 | void * clientMallocContext; 14 | 15 | elzma_free clientFreeFunc; 16 | void * clientFreeContext; 17 | }; 18 | 19 | /* initialize an allocation structure, may be called safely multiple 20 | * times */ 21 | void init_alloc_struct(struct elzma_alloc_struct * allocStruct, 22 | elzma_malloc clientMallocFunc, 23 | void * clientMallocContext, 24 | elzma_free clientFreeFunc, 25 | void * clientFreeContext); 26 | 27 | /** superset representation of a compressed file header */ 28 | struct elzma_file_header { 29 | unsigned char pb; 30 | unsigned char lp; 31 | unsigned char lc; 32 | unsigned char isStreamed; 33 | long long unsigned int uncompressedSize; 34 | unsigned int dictSize; 35 | }; 36 | 37 | /** superset representation of a compressed file footer */ 38 | struct elzma_file_footer { 39 | unsigned int crc32; 40 | long long unsigned int uncompressedSize; 41 | }; 42 | 43 | /** a structure which encapsulates information about the particular 44 | * file header and footer in use (lzip vs lzma vs (eventually) xz. 45 | * The intention of this structure is to simplify compression and 46 | * decompression logic by abstracting the file format details a bit. */ 47 | struct elzma_format_handler 48 | { 49 | unsigned int header_size; 50 | void (*init_header)(struct elzma_file_header * hdr); 51 | int (*parse_header)(const unsigned char * hdrBuf, 52 | struct elzma_file_header * hdr); 53 | int (*serialize_header)(unsigned char * hdrBuf, 54 | const struct elzma_file_header * hdr); 55 | 56 | unsigned int footer_size; 57 | int (*serialize_footer)(struct elzma_file_footer * ftr, 58 | unsigned char * ftrBuf); 59 | int (*parse_footer)(const unsigned char * ftrBuf, 60 | struct elzma_file_footer * ftr); 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/zmat/easylzma/easylzma/decompress.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | * 10 | * easylzma/decompress.h - The API for LZMA decompression using easylzma 11 | */ 12 | 13 | #ifndef __EASYLZMADECOMPRESS_H__ 14 | #define __EASYLZMADECOMPRESS_H__ 15 | 16 | #include "easylzma/common.h" 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | /** an opaque handle to an lzma decompressor */ 23 | typedef struct _elzma_decompress_handle * elzma_decompress_handle; 24 | 25 | /** 26 | * Allocate a handle to an LZMA decompressor object. 27 | */ 28 | elzma_decompress_handle EASYLZMA_API elzma_decompress_alloc(); 29 | 30 | /** 31 | * set allocation routines (optional, if not called malloc & free will 32 | * be used) 33 | */ 34 | void EASYLZMA_API elzma_decompress_set_allocation_callbacks( 35 | elzma_decompress_handle hand, 36 | elzma_malloc mallocFunc, void * mallocFuncContext, 37 | elzma_free freeFunc, void * freeFuncContext); 38 | 39 | /** 40 | * Free all data associated with an LZMA decompressor object. 41 | */ 42 | void EASYLZMA_API elzma_decompress_free(elzma_decompress_handle * hand); 43 | 44 | /** 45 | * Perform decompression 46 | * 47 | * XXX: should the library automatically detect format by reading stream? 48 | * currently it's based on data external to stream (such as extension 49 | * or convention) 50 | */ 51 | int EASYLZMA_API elzma_decompress_run( 52 | elzma_decompress_handle hand, 53 | elzma_read_callback inputStream, void * inputContext, 54 | elzma_write_callback outputStream, void * outputContext, 55 | elzma_file_format format); 56 | 57 | 58 | #ifdef __cplusplus 59 | }; 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/zmat/easylzma/lzip_header.h: -------------------------------------------------------------------------------- 1 | #ifndef __EASYLZMA_LZIP_HEADER__ 2 | #define __EASYLZMA_LZIP_HEADER__ 3 | 4 | #include "common_internal.h" 5 | 6 | /* lzip file format documented here: 7 | * http://download.savannah.gnu.org/releases-noredirect/lzip/manual/ */ 8 | 9 | void initializeLZIPFormatHandler(struct elzma_format_handler * hand); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/zmat/easylzma/lzma_header.h: -------------------------------------------------------------------------------- 1 | #ifndef __EASYLZMA_LZMA_HEADER__ 2 | #define __EASYLZMA_LZMA_HEADER__ 3 | 4 | #include "common_internal.h" 5 | 6 | /* LZMA-Alone header format gleaned from reading Igor's code */ 7 | 8 | void initializeLZMAFormatHandler(struct elzma_format_handler * hand); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/7zBuf.c: -------------------------------------------------------------------------------- 1 | /* 7zBuf.c -- Byte Buffer 2 | 2008-03-28 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #include "7zBuf.h" 7 | 8 | void Buf_Init(CBuf *p) 9 | { 10 | p->data = 0; 11 | p->size = 0; 12 | } 13 | 14 | int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) 15 | { 16 | p->size = 0; 17 | if (size == 0) 18 | { 19 | p->data = 0; 20 | return 1; 21 | } 22 | p->data = (Byte *)alloc->Alloc(alloc, size); 23 | if (p->data != 0) 24 | { 25 | p->size = size; 26 | return 1; 27 | } 28 | return 0; 29 | } 30 | 31 | void Buf_Free(CBuf *p, ISzAlloc *alloc) 32 | { 33 | alloc->Free(alloc, p->data); 34 | p->data = 0; 35 | p->size = 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/7zBuf.h: -------------------------------------------------------------------------------- 1 | /* 7zBuf.h -- Byte Buffer 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __7Z_BUF_H 5 | #define __7Z_BUF_H 6 | 7 | #include "Types.h" 8 | 9 | typedef struct 10 | { 11 | Byte *data; 12 | size_t size; 13 | } CBuf; 14 | 15 | void Buf_Init(CBuf *p); 16 | int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); 17 | void Buf_Free(CBuf *p, ISzAlloc *alloc); 18 | 19 | typedef struct 20 | { 21 | Byte *data; 22 | size_t size; 23 | size_t pos; 24 | } CDynBuf; 25 | 26 | void DynBuf_Construct(CDynBuf *p); 27 | void DynBuf_SeekToBeg(CDynBuf *p); 28 | int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); 29 | void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/7zBuf2.c: -------------------------------------------------------------------------------- 1 | /* 7zBuf2.c -- Byte Buffer 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include 5 | #include "7zBuf.h" 6 | 7 | void DynBuf_Construct(CDynBuf *p) 8 | { 9 | p->data = 0; 10 | p->size = 0; 11 | p->pos = 0; 12 | } 13 | 14 | void DynBuf_SeekToBeg(CDynBuf *p) 15 | { 16 | p->pos = 0; 17 | } 18 | 19 | int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) 20 | { 21 | if (size > p->size - p->pos) 22 | { 23 | size_t newSize = p->pos + size; 24 | Byte *data; 25 | newSize += newSize / 4; 26 | data = (Byte *)alloc->Alloc(alloc, newSize); 27 | if (data == 0) 28 | return 0; 29 | p->size = newSize; 30 | memcpy(data, p->data, p->pos); 31 | alloc->Free(alloc, p->data); 32 | p->data = data; 33 | } 34 | memcpy(p->data + p->pos, buf, size); 35 | p->pos += size; 36 | return 1; 37 | } 38 | 39 | void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) 40 | { 41 | alloc->Free(alloc, p->data); 42 | p->data = 0; 43 | p->size = 0; 44 | p->pos = 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/7zCrc.c: -------------------------------------------------------------------------------- 1 | /* 7zCrc.c -- CRC32 calculation 2 | 2008-08-05 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #include "7zCrc.h" 7 | 8 | #define kCrcPoly 0xEDB88320 9 | UInt32 g_CrcTable[256]; 10 | 11 | void MY_FAST_CALL CrcGenerateTable(void) 12 | { 13 | UInt32 i; 14 | for (i = 0; i < 256; i++) 15 | { 16 | UInt32 r = i; 17 | int j; 18 | for (j = 0; j < 8; j++) 19 | r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); 20 | g_CrcTable[i] = r; 21 | } 22 | } 23 | 24 | UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) 25 | { 26 | const Byte *p = (const Byte *)data; 27 | for (; size > 0 ; size--, p++) 28 | v = CRC_UPDATE_BYTE(v, *p); 29 | return v; 30 | } 31 | 32 | UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) 33 | { 34 | return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF; 35 | } 36 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/7zCrc.h: -------------------------------------------------------------------------------- 1 | /* 7zCrc.h -- CRC32 calculation 2 | 2008-03-13 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifndef __7Z_CRC_H 7 | #define __7Z_CRC_H 8 | 9 | #include 10 | 11 | #include "Types.h" 12 | 13 | extern UInt32 g_CrcTable[]; 14 | 15 | void MY_FAST_CALL CrcGenerateTable(void); 16 | 17 | #define CRC_INIT_VAL 0xFFFFFFFF 18 | #define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF) 19 | #define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) 20 | 21 | UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); 22 | UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/7zFile.h: -------------------------------------------------------------------------------- 1 | /* 7zFile.h -- File IO 2 | 2008-11-22 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __7Z_FILE_H 5 | #define __7Z_FILE_H 6 | 7 | #ifdef _WIN32 8 | #define USE_WINDOWS_FILE 9 | #endif 10 | 11 | #ifdef USE_WINDOWS_FILE 12 | #include 13 | #else 14 | #include 15 | #endif 16 | 17 | #include "Types.h" 18 | 19 | 20 | /* ---------- File ---------- */ 21 | 22 | typedef struct 23 | { 24 | #ifdef USE_WINDOWS_FILE 25 | HANDLE handle; 26 | #else 27 | FILE *file; 28 | #endif 29 | } CSzFile; 30 | 31 | void File_Construct(CSzFile *p); 32 | WRes InFile_Open(CSzFile *p, const char *name); 33 | WRes OutFile_Open(CSzFile *p, const char *name); 34 | WRes File_Close(CSzFile *p); 35 | 36 | /* reads max(*size, remain file's size) bytes */ 37 | WRes File_Read(CSzFile *p, void *data, size_t *size); 38 | 39 | /* writes *size bytes */ 40 | WRes File_Write(CSzFile *p, const void *data, size_t *size); 41 | 42 | WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); 43 | WRes File_GetLength(CSzFile *p, UInt64 *length); 44 | 45 | 46 | /* ---------- FileInStream ---------- */ 47 | 48 | typedef struct 49 | { 50 | ISeqInStream s; 51 | CSzFile file; 52 | } CFileSeqInStream; 53 | 54 | void FileSeqInStream_CreateVTable(CFileSeqInStream *p); 55 | 56 | 57 | typedef struct 58 | { 59 | ISeekInStream s; 60 | CSzFile file; 61 | } CFileInStream; 62 | 63 | void FileInStream_CreateVTable(CFileInStream *p); 64 | 65 | 66 | typedef struct 67 | { 68 | ISeqOutStream s; 69 | CSzFile file; 70 | } CFileOutStream; 71 | 72 | void FileOutStream_CreateVTable(CFileOutStream *p); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/7zVersion.h: -------------------------------------------------------------------------------- 1 | #define MY_VER_MAJOR 4 2 | #define MY_VER_MINOR 63 3 | #define MY_VER_BUILD 0 4 | #define MY_VERSION "4.63" 5 | #define MY_DATE "2008-12-31" 6 | #define MY_COPYRIGHT ": Igor Pavlov : Public domain" 7 | #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE 8 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/Alloc.h: -------------------------------------------------------------------------------- 1 | /* Alloc.h -- Memory allocation functions 2 | 2008-03-13 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifndef __COMMON_ALLOC_H 7 | #define __COMMON_ALLOC_H 8 | 9 | #include 10 | 11 | void *MyAlloc(size_t size); 12 | void MyFree(void *address); 13 | 14 | #ifdef _WIN32 15 | 16 | void SetLargePageSize(); 17 | 18 | void *MidAlloc(size_t size); 19 | void MidFree(void *address); 20 | void *BigAlloc(size_t size); 21 | void BigFree(void *address); 22 | 23 | #else 24 | 25 | #define MidAlloc(size) MyAlloc(size) 26 | #define MidFree(address) MyFree(address) 27 | #define BigAlloc(size) MyAlloc(size) 28 | #define BigFree(address) MyFree(address) 29 | 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/Bcj2.h: -------------------------------------------------------------------------------- 1 | /* Bcj2.h -- Converter for x86 code (BCJ2) 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __BCJ2_H 5 | #define __BCJ2_H 6 | 7 | #include "Types.h" 8 | 9 | /* 10 | Conditions: 11 | outSize <= FullOutputSize, 12 | where FullOutputSize is full size of output stream of x86_2 filter. 13 | 14 | If buf0 overlaps outBuf, there are two required conditions: 15 | 1) (buf0 >= outBuf) 16 | 2) (buf0 + size0 >= outBuf + FullOutputSize). 17 | 18 | Returns: 19 | SZ_OK 20 | SZ_ERROR_DATA - Data error 21 | */ 22 | 23 | int Bcj2_Decode( 24 | const Byte *buf0, SizeT size0, 25 | const Byte *buf1, SizeT size1, 26 | const Byte *buf2, SizeT size2, 27 | const Byte *buf3, SizeT size3, 28 | Byte *outBuf, SizeT outSize); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/Bra.h: -------------------------------------------------------------------------------- 1 | /* Bra.h -- Branch converters for executables 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __BRA_H 5 | #define __BRA_H 6 | 7 | #include "Types.h" 8 | 9 | /* 10 | These functions convert relative addresses to absolute addresses 11 | in CALL instructions to increase the compression ratio. 12 | 13 | In: 14 | data - data buffer 15 | size - size of data 16 | ip - current virtual Instruction Pinter (IP) value 17 | state - state variable for x86 converter 18 | encoding - 0 (for decoding), 1 (for encoding) 19 | 20 | Out: 21 | state - state variable for x86 converter 22 | 23 | Returns: 24 | The number of processed bytes. If you call these functions with multiple calls, 25 | you must start next call with first byte after block of processed bytes. 26 | 27 | Type Endian Alignment LookAhead 28 | 29 | x86 little 1 4 30 | ARMT little 2 2 31 | ARM little 4 0 32 | PPC big 4 0 33 | SPARC big 4 0 34 | IA64 little 16 0 35 | 36 | size must be >= Alignment + LookAhead, if it's not last block. 37 | If (size < Alignment + LookAhead), converter returns 0. 38 | 39 | Example: 40 | 41 | UInt32 ip = 0; 42 | for () 43 | { 44 | ; size must be >= Alignment + LookAhead, if it's not last block 45 | SizeT processed = Convert(data, size, ip, 1); 46 | data += processed; 47 | size -= processed; 48 | ip += processed; 49 | } 50 | */ 51 | 52 | #define x86_Convert_Init(state) { state = 0; } 53 | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); 54 | SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 55 | SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 56 | SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 57 | SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 58 | SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/Bra86.c: -------------------------------------------------------------------------------- 1 | /* Bra86.c -- Converter for x86 code (BCJ) 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "Bra.h" 5 | 6 | #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) 7 | 8 | const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; 9 | const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; 10 | 11 | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) 12 | { 13 | SizeT bufferPos = 0, prevPosT; 14 | UInt32 prevMask = *state & 0x7; 15 | if (size < 5) 16 | return 0; 17 | ip += 5; 18 | prevPosT = (SizeT)0 - 1; 19 | 20 | for (;;) 21 | { 22 | Byte *p = data + bufferPos; 23 | Byte *limit = data + size - 4; 24 | for (; p < limit; p++) 25 | if ((*p & 0xFE) == 0xE8) 26 | break; 27 | bufferPos = (SizeT)(p - data); 28 | if (p >= limit) 29 | break; 30 | prevPosT = bufferPos - prevPosT; 31 | if (prevPosT > 3) 32 | prevMask = 0; 33 | else 34 | { 35 | prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; 36 | if (prevMask != 0) 37 | { 38 | Byte b = p[4 - kMaskToBitNumber[prevMask]]; 39 | if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) 40 | { 41 | prevPosT = bufferPos; 42 | prevMask = ((prevMask << 1) & 0x7) | 1; 43 | bufferPos++; 44 | continue; 45 | } 46 | } 47 | } 48 | prevPosT = bufferPos; 49 | 50 | if (Test86MSByte(p[4])) 51 | { 52 | UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); 53 | UInt32 dest; 54 | for (;;) 55 | { 56 | Byte b; 57 | int index; 58 | if (encoding) 59 | dest = (ip + (UInt32)bufferPos) + src; 60 | else 61 | dest = src - (ip + (UInt32)bufferPos); 62 | if (prevMask == 0) 63 | break; 64 | index = kMaskToBitNumber[prevMask] * 8; 65 | b = (Byte)(dest >> (24 - index)); 66 | if (!Test86MSByte(b)) 67 | break; 68 | src = dest ^ ((1 << (32 - index)) - 1); 69 | } 70 | p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); 71 | p[3] = (Byte)(dest >> 16); 72 | p[2] = (Byte)(dest >> 8); 73 | p[1] = (Byte)dest; 74 | bufferPos += 5; 75 | } 76 | else 77 | { 78 | prevMask = ((prevMask << 1) & 0x7) | 1; 79 | bufferPos++; 80 | } 81 | } 82 | prevPosT = bufferPos - prevPosT; 83 | *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); 84 | return bufferPos; 85 | } 86 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/BraIA64.c: -------------------------------------------------------------------------------- 1 | /* BraIA64.c -- Converter for IA-64 code 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "Bra.h" 5 | 6 | static const Byte kBranchTable[32] = 7 | { 8 | 0, 0, 0, 0, 0, 0, 0, 0, 9 | 0, 0, 0, 0, 0, 0, 0, 0, 10 | 4, 4, 6, 6, 0, 0, 7, 7, 11 | 4, 4, 0, 0, 4, 4, 0, 0 12 | }; 13 | 14 | SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) 15 | { 16 | SizeT i; 17 | if (size < 16) 18 | return 0; 19 | size -= 16; 20 | for (i = 0; i <= size; i += 16) 21 | { 22 | UInt32 instrTemplate = data[i] & 0x1F; 23 | UInt32 mask = kBranchTable[instrTemplate]; 24 | UInt32 bitPos = 5; 25 | int slot; 26 | for (slot = 0; slot < 3; slot++, bitPos += 41) 27 | { 28 | UInt32 bytePos, bitRes; 29 | UInt64 instruction, instNorm; 30 | int j; 31 | if (((mask >> slot) & 1) == 0) 32 | continue; 33 | bytePos = (bitPos >> 3); 34 | bitRes = bitPos & 0x7; 35 | instruction = 0; 36 | for (j = 0; j < 6; j++) 37 | instruction += (UInt64)data[i + j + bytePos] << (8 * j); 38 | 39 | instNorm = instruction >> bitRes; 40 | if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) 41 | { 42 | UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); 43 | UInt32 dest; 44 | src |= ((UInt32)(instNorm >> 36) & 1) << 20; 45 | 46 | src <<= 4; 47 | 48 | if (encoding) 49 | dest = ip + (UInt32)i + src; 50 | else 51 | dest = src - (ip + (UInt32)i); 52 | 53 | dest >>= 4; 54 | 55 | instNorm &= ~((UInt64)(0x8FFFFF) << 13); 56 | instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); 57 | instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); 58 | 59 | instruction &= (1 << bitRes) - 1; 60 | instruction |= (instNorm << bitRes); 61 | for (j = 0; j < 6; j++) 62 | data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); 63 | } 64 | } 65 | } 66 | return i; 67 | } 68 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/CpuArch.h: -------------------------------------------------------------------------------- 1 | /* CpuArch.h 2 | 2008-08-05 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifndef __CPUARCH_H 7 | #define __CPUARCH_H 8 | 9 | /* 10 | LITTLE_ENDIAN_UNALIGN means: 11 | 1) CPU is LITTLE_ENDIAN 12 | 2) it's allowed to make unaligned memory accesses 13 | if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know 14 | about these properties of platform. 15 | */ 16 | 17 | #if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) 18 | #define LITTLE_ENDIAN_UNALIGN 19 | #endif 20 | 21 | #ifdef LITTLE_ENDIAN_UNALIGN 22 | 23 | #define GetUi16(p) (*(const UInt16 *)(p)) 24 | #define GetUi32(p) (*(const UInt32 *)(p)) 25 | #define GetUi64(p) (*(const UInt64 *)(p)) 26 | #define SetUi32(p, d) *(UInt32 *)(p) = (d); 27 | 28 | #else 29 | 30 | #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) 31 | 32 | #define GetUi32(p) ( \ 33 | ((const Byte *)(p))[0] | \ 34 | ((UInt32)((const Byte *)(p))[1] << 8) | \ 35 | ((UInt32)((const Byte *)(p))[2] << 16) | \ 36 | ((UInt32)((const Byte *)(p))[3] << 24)) 37 | 38 | #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) 39 | 40 | #define SetUi32(p, d) { UInt32 _x_ = (d); \ 41 | ((Byte *)(p))[0] = (Byte)_x_; \ 42 | ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ 43 | ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ 44 | ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } 45 | 46 | #endif 47 | 48 | #if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) 49 | 50 | #pragma intrinsic(_byteswap_ulong) 51 | #pragma intrinsic(_byteswap_uint64) 52 | #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) 53 | #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) 54 | 55 | #else 56 | 57 | #define GetBe32(p) ( \ 58 | ((UInt32)((const Byte *)(p))[0] << 24) | \ 59 | ((UInt32)((const Byte *)(p))[1] << 16) | \ 60 | ((UInt32)((const Byte *)(p))[2] << 8) | \ 61 | ((const Byte *)(p))[3] ) 62 | 63 | #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) 64 | 65 | #endif 66 | 67 | #define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/LzHash.h: -------------------------------------------------------------------------------- 1 | /* LzHash.h -- HASH functions for LZ algorithms 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZHASH_H 5 | #define __LZHASH_H 6 | 7 | #define kHash2Size (1 << 10) 8 | #define kHash3Size (1 << 16) 9 | #define kHash4Size (1 << 20) 10 | 11 | #define kFix3HashSize (kHash2Size) 12 | #define kFix4HashSize (kHash2Size + kHash3Size) 13 | #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) 14 | 15 | #define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); 16 | 17 | #define HASH3_CALC { \ 18 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 19 | hash2Value = temp & (kHash2Size - 1); \ 20 | hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } 21 | 22 | #define HASH4_CALC { \ 23 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 24 | hash2Value = temp & (kHash2Size - 1); \ 25 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 26 | hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } 27 | 28 | #define HASH5_CALC { \ 29 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 30 | hash2Value = temp & (kHash2Size - 1); \ 31 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 32 | hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ 33 | hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ 34 | hash4Value &= (kHash4Size - 1); } 35 | 36 | /* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ 37 | #define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; 38 | 39 | 40 | #define MT_HASH2_CALC \ 41 | hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); 42 | 43 | #define MT_HASH3_CALC { \ 44 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 45 | hash2Value = temp & (kHash2Size - 1); \ 46 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } 47 | 48 | #define MT_HASH4_CALC { \ 49 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 50 | hash2Value = temp & (kHash2Size - 1); \ 51 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 52 | hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/zmat/easylzma/pavlov/LzmaLib.c: -------------------------------------------------------------------------------- 1 | /* LzmaLib.c -- LZMA library wrapper 2 | 2008-08-05 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #include "LzmaEnc.h" 7 | #include "LzmaDec.h" 8 | #include "Alloc.h" 9 | #include "LzmaLib.h" 10 | 11 | static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } 12 | static void SzFree(void *p, void *address) { p = p; MyFree(address); } 13 | static ISzAlloc g_Alloc = { SzAlloc, SzFree }; 14 | 15 | MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, 16 | unsigned char *outProps, size_t *outPropsSize, 17 | int level, /* 0 <= level <= 9, default = 5 */ 18 | unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ 19 | int lc, /* 0 <= lc <= 8, default = 3 */ 20 | int lp, /* 0 <= lp <= 4, default = 0 */ 21 | int pb, /* 0 <= pb <= 4, default = 2 */ 22 | int fb, /* 5 <= fb <= 273, default = 32 */ 23 | int numThreads /* 1 or 2, default = 2 */ 24 | ) 25 | { 26 | CLzmaEncProps props; 27 | LzmaEncProps_Init(&props); 28 | props.level = level; 29 | props.dictSize = dictSize; 30 | props.lc = lc; 31 | props.lp = lp; 32 | props.pb = pb; 33 | props.fb = fb; 34 | props.numThreads = numThreads; 35 | 36 | return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, 37 | NULL, &g_Alloc, &g_Alloc); 38 | } 39 | 40 | 41 | MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, 42 | const unsigned char *props, size_t propsSize) 43 | { 44 | ELzmaStatus status; 45 | return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); 46 | } 47 | -------------------------------------------------------------------------------- /src/zmat/miniz/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013-2014 RAD Game Tools and Valve Software 2 | Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC 3 | 4 | All Rights Reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/zmat/miniz/zlib.h: -------------------------------------------------------------------------------- 1 | miniz.h -------------------------------------------------------------------------------- /webmmc/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 The Native Client Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style license that can be 3 | # found in the LICENSE file. 4 | 5 | # 6 | # GNU Make based build file.  For details on GNU Make see: 7 | # http://www.gnu.org/software/make/manual/make.html 8 | # 9 | 10 | # 11 | # Get pepper directory for toolchain and includes. 12 | # 13 | # If NACL_SDK_ROOT is not set, then assume it can be found three directories up. 14 | # 15 | THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) 16 | NACL_SDK_ROOT ?= $(abspath $(dir $(THIS_MAKEFILE))../../../nacl) 17 | MMC_ROOT ?= .. 18 | 19 | # Project Build flags 20 | WARNINGS := -Wno-long-long -Wall -Wswitch-enum -pedantic -Werror 21 | CXXFLAGS := -pthread -std=gnu++98 $(WARNINGS) 22 | 23 | # 24 | # Compute tool paths 25 | # 26 | GETOS := python $(NACL_SDK_ROOT)/tools/getos.py 27 | OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py 28 | OSNAME := $(shell $(GETOS)) 29 | RM := $(OSHELPERS) rm 30 | MAKE := make 31 | 32 | PNACL_TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_pnacl) 33 | PNACL_CXX := $(PNACL_TC_PATH)/bin/pnacl-clang++ 34 | PNACL_FINALIZE := $(PNACL_TC_PATH)/bin/pnacl-finalize 35 | CXXFLAGS := -I$(NACL_SDK_ROOT)/include -I$(MMC_ROOT)/src -DMMC_SFMT 36 | LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_cpp -lppapi -L$(MMC_ROOT)/src/bin -lmmc-pnacl 37 | 38 | # 39 | # Disable DOS PATH warning when using Cygwin based tools Windows 40 | # 41 | CYGWIN ?= nodosfilewarning 42 | export CYGWIN 43 | 44 | 45 | # Declare the ALL target first, to make the 'all' target the default build 46 | all: webmmc.pexe 47 | 48 | clean: 49 | $(RM) webmmc.pexe webmmc.bc 50 | 51 | webmmc.bc: webmmc.cc 52 | $(PNACL_CXX) -o $@ $< -O2 $(CXXFLAGS) $(LDFLAGS) 53 | 54 | webmmc.pexe: webmmc.bc $(MMC_ROOT)/src/bin/libmmc-pnacl.a 55 | $(PNACL_FINALIZE) -o $@ $< 56 | 57 | $(MMC_ROOT)/src/bin/libmmc-pnacl.a: 58 | $(MAKE) -C $(MMC_ROOT)/src clean 59 | $(MAKE) -C $(MMC_ROOT)/src -f makefile_sfmt pnacl BINARY=libmmc-pnacl.a NACL_SDK_ROOT=$(PNACL_TC_PATH) 60 | 61 | # 62 | # Makefile target to run the SDK's simple HTTP server and serve this example. 63 | # 64 | HTTPD_PY := python $(NACL_SDK_ROOT)/tools/httpd.py --no_dir_check 65 | 66 | .PHONY: serve 67 | serve: all 68 | $(HTTPD_PY) -C $(CURDIR) 69 | -------------------------------------------------------------------------------- /webmmc/make.bat: -------------------------------------------------------------------------------- 1 | @..\..\tools\make.exe %* 2 | -------------------------------------------------------------------------------- /webmmc/webmmc.cc: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 | /// Use of this source code is governed by a BSD-style license that can be 3 | /// found in the LICENSE file. 4 | /// 5 | /// @file webmmc.cc 6 | /// This example demonstrates loading, running and scripting a very simple NaCl 7 | /// module. To load the NaCl module, the browser first looks for the 8 | /// CreateModule() factory method (at the end of this file). It calls 9 | /// CreateModule() once to load the module code from your .nexe. After the 10 | /// .nexe code is loaded, CreateModule() is not called again. 11 | 12 | #include 13 | #include 14 | #include "ppapi/cpp/instance.h" 15 | #include "ppapi/cpp/module.h" 16 | #include "ppapi/cpp/var.h" 17 | #include "simpmesh.h" 18 | #include "tettracing.h" 19 | #include "mcx_utils.h" 20 | #include "tictoc.h" 21 | 22 | class WebMMCObject : public pp::Instance { 23 | public: 24 | mcconfig cfg; 25 | tetmesh mesh; 26 | raytracer tracer; 27 | visitor master; 28 | double Eabsorb; 29 | RandType ran0[RAND_BUF_LEN] __attribute__ ((aligned(16))); 30 | RandType ran1[RAND_BUF_LEN] __attribute__ ((aligned(16))); 31 | unsigned int i; 32 | float raytri; 33 | unsigned int threadid,ncomplete,t0,dt; 34 | 35 | explicit WebMMCObject(PP_Instance instance) : pp::Instance(instance){ 36 | WebMMC_Reset(); 37 | } 38 | virtual ~WebMMCObject() { 39 | mcx_clearcfg(&cfg); 40 | } 41 | int WebMMC_Reset(){ 42 | //memset(master,0,sizeof(visitor)); 43 | raytri=0.f; 44 | ncomplete=0; 45 | Eabsorb=0.0; 46 | mcx_clearcfg(&cfg); 47 | mcx_initcfg(&cfg); 48 | return 0; 49 | } 50 | 51 | virtual void HandleMessage(const pp::Var& var_message) { 52 | std::string msg = var_message.AsString(); 53 | if(msg.find("MMC_MSG_RESET")==0){ 54 | WebMMC_Reset(); 55 | }else if(msg.find("{")==0){ 56 | cJSON *jroot = cJSON_Parse(msg.c_str()); 57 | if(jroot){ 58 | mcx_loadjson(jroot,&cfg); 59 | cJSON_Delete(jroot); 60 | } 61 | } 62 | } 63 | }; 64 | 65 | class WebMMCModule : public pp::Module { 66 | public: 67 | WebMMCModule() : pp::Module() {} 68 | virtual ~WebMMCModule() {} 69 | virtual pp::Instance* CreateInstance(PP_Instance instance) { 70 | return new WebMMCObject(instance); 71 | } 72 | }; 73 | 74 | namespace pp { 75 | Module* CreateModule() { 76 | return new WebMMCModule(); 77 | } 78 | } // namespace pp 79 | -------------------------------------------------------------------------------- /webmmc/webmmc.nmf: -------------------------------------------------------------------------------- 1 | { 2 | "program": { 3 | "portable": { 4 | "pnacl-translate": { 5 | "url": "webmmc.pexe" 6 | } 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /win32/cbuilder/mmcbcc.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #endif 4 | 5 | --------------------------------------------------------------------------------