Go to Documentation
Go to Documentation

Get Started

MCX can simulate photon propagations inside arbitrarily complex 3D turbid media. It is one of the fastest simulators because it takes advantage of the massive number of parallel threads in a modern GPU. Above all, MCX is open-source and free for everyone. Give it a try!

Preparation: JSON input
   "Domain": {
	"VolumeFile": "semi60x60x60.bin",
        "Dim":    [60,60,60],
        "Media": [
             {"mua": 0.00, "mus": 0.0, "g": 1.00, "n": 1.0},
             {"mua": 0.005,"mus": 1.0, "g": 0.01, "n": 1.0}
    "Session": {
	"Photons":  1000000,
	"RNGSeed":  29012392,
	"ID":       "qtest"
    "Forward": {
	"T0": 0.0e+00,
	"T1": 5.0e-09,
	"Dt": 5.0e-09
    "Optode": {
	"Source": {
	    "Pos": [29.0, 29.0, 0.0],
	    "Dir": [0.0, 0.0, 1.0],
	    "Type": "pencil",
	    "Param1": [0.0, 0.0, 0.0, 0.0],
	    "Param2": [0.0, 0.0, 0.0, 0.0]
	"Detector": [
		"Pos": [29.0,  19.0,  0.0],
		"R": 1.0
Preparation: Define the volume
The volume file is a binary file, representing the tissue information of
a 3D volume. Each byte of the file is a label of a voxel - the label value
(0-255) is the index of the voxel's tissue type.

The volume file is specified in the JSON input file by the "VolumeFile" tag in
the "Domain" section. If one uses the legacy input file, the volume file is
specified in the 4th line.

Preparation: Legacy input file
MCX supports a legacy input file (*.inp). The format of this input file is
explained below:

1000000              # total photon, use -n to overwrite in the command line
29012392             # RNG seed, negative to generate
30.0 30.0 0.0 1      # source position (in grid unit), the last num (optional) sets srcfrom0 (-z)
0 0 1                # initial directional vector
0.e+00 1.e-09 1.e-10 # time-gates(s): start, end, step
semi60x60x60.bin     # volume ('unsigned char' format)
1 60 1 60            # x voxel size in mm (isotropic only), dim, start/end indices
1 60 1 60            # y voxel size, must be same as x, dim, start/end indices
1 60 1 60            # y voxel size, must be same as x, dim, start/end indices
1                    # num of media
1.010101 0.01 0.005 1.37  # scat. mus (1/mm), g, mua (1/mm), n
4       1.0          # detector number and default radius (in grid unit)
30.0  20.0  0.0  2.0 # detector 1 position (real numbers in grid unit) and individual radius (optional)
30.0  40.0  0.0      # ..., if individual radius is ignored, MCX will use the default radius
20.0  30.0  0.0      #
40.0  30.0  0.0      #
pencil               # source type (optional)
0 0 0 0              # parameters (4 floats) for the selected source
0 0 0 0              # additional source parameters

Output: Fluence output
MCX outputs the 3D flux distribution by default (unless "-S 0" is used). Alternatively, if a user specifies "-O F", the output volume is the fluence; if "-O E" is used, the output volume is the energy deposit; if "-O J" or "-O T" is used, the output is the absorption sensitivity profile, i.e. the Jacobian of mua.

The volumetric output file has a suffix of "".mc2", and is a binary file with a size of (Nx x Ny x Nz x Nt x 4) bytes, where Nx/Ny/Nz are the dimensions of the input volume in the x/y/z direction, respectively, Nt is the total number of time gates, calculated by ceil(tend-tstart)/tstep), and the number 4 represents the byte length of a single-precision floating-point number. The first (Nx x Ny x Nz) floating point numbers (4-byte each) are the accummulated fluence distribution, in the unit of (1/(s*mm^2)), for the first time gate (averaged at the middle of the time gate); then the second gate, and so on.

By default, MCX's flux/fluence output is normalized to produce a time-domain Green's function, or time-domain point-spread function (TPSF) - i.e. the solution for an impulse input of unitary energy at t=0. One can disable the normalization by using "-U 0".

The mc2 file can be loaded into matlab using the loadmc2() function, provided under the mcx/utils folder. Please run help loadmc2 for details.

To convert the flux output to fluence, one simply multiply the solution by the time gate width, tstep, defined in the input file. Similarly, dividing tstep from the fluence solution produces the flux.

Output: Detected photon info
By default, MCX saves the information of the detected photons. One can also enable this feature by appending "-d 1" in the command line. The output file with the detected photon info is named as "session_name.mch".

The mch file can be loaded into matlab using the loadmch() function, provided under the mcx/utils folder. Please run help loadmch for details.

The mch file is a binary file containing the following 3 blocks: a 256-byte header, followed by a block of floating-point numbers for the partial path lengths, then followed by a block of byte arrays recording the random number generator (RNG) seed data for each detected photon (20 byte per photon). An mch file may contain multiple repetitions of the above 3-block data chunks.

The header contains the following information

typedef struct MCXHistoryHeader{
	char magic[4];            /*magic header, 4 bytes, always 'M','C','X','H'*/
	unsigned int  version;    /*mch file version number, integer*/
	unsigned int  maxmedia;   /*maximum num of media, integer*/
	unsigned int  detnum;     /*num of detectors, integer*/
	unsigned int  colcount;   /*how many floating-point numbers associated with each detected photon*/
	unsigned int  totalphoton;/*the total number of photons being simulated*/
	unsigned int  detected;   /*the number of detected photons*/
	unsigned int  savedphoton;/*how many photons are saved in this block*/
	float unitinmm;           /*the physical width of the voxel in mm, as set by -U flag*/
	unsigned int  seedbyte;   /*the byte length of the RNG seed for each photon*/
	int reserved[6];          /*reserved fields*/

Following the header, a total of savedphoton*colcount words (32bit) records represent the detected photon info, each photon occupies "colcount" words saved in the order of being detected. A typical detected photon record consists of the following:

  DetID, ScatNum, PP1, PP2, ..., PPN

where DetID is an integer, indicating the index of the detector that captures the photon; ScatNum records the total number of scattering events before the photon is captured; PP1 - PPN are floating point numbers, denoting the partial path lengths for media time 1 to N.

Output: Command line output
MCX outputs a text log on the command line window (stdout). In this log,
one can find the thread/block configuration, timing of each section of the simulation,
the detected photon info, and normalization information.

When -p/--printlen is used in the command line, mcx also prints the final state
of the last photon simulated by each thread. This information can be used to
debug mcx.

When compiling mcx with "make debug", mcx can print step by step debug info
of each simulated photon.
Click the below options to show details
Click items below to show help info
To use MCX, you must have a CUDA-enabled GPU and have installed
the proper NVIDIA driver and libraries.

Please use the following steps to determine if all needed libraries are properly
installed on your computer.

Installation: GPU Hardware
Your computer must have a CUDA-enabled GPU.

Generally speaking, all graphics cards made by NVIDIA after 2010 are CUDA-enabled.
However, if you use an integrated GPU (Intel) or AMD GPU, you may not run MCX
(you should consider MCXCL).

The more cores (stream processors) in your GPU generally means better simulation
speed. On the other hand, MCX does not require a large GPU memory. Therefore,
a NVIDIA Tesla card is not entirely needed unless you need to simulate a very
large domain with many time-gates.

If you are not sure what type of graphics card on your operating system, please
use the following instructions:

* Windows: download and run gpu-z, a freeware.
* Mac OSX: open a terminal, run command "system_profiler"
* Linux: open a terminal, run command "lspci | grep -i --color 'vga|3d|2d'"

You should see at least one NVIDIA graphics card that is available. In addition,
you should also have installed the proper driver for the graphics card. Please
consult your graphics card installation guide for details.

Installation: CUDA library
The provided MCX binaries are compiled against a specific
version of the CUDA library.

For Windows users, starting from 1.0-beta, we will include the needed
library files (.dll on windows) in our binary packages. However, if you run mcx
and receive an error message complaining about "cuda*.dll is missing", please search
this file name in a search engine and find a download link. Once you download the
dll file, you should save it under your Windows folder (typically C:\Windows).

For Linux and OSX users, you should download the matching CUDA Toolkit from

Installation: Initial test
Once you have verified your GPU hardware and CUDA library,
you may test MCX by the following command

    mcx -L

type this in a terminal (In Windows, Start menu\Run\cmd). You should see a list
of supported graphics card(s). If you see an error, that means either your hardware
does not support MCX, or CUDA library is missing.

Run: show mcx help
Runing "mcx" without parameter prints the help information, including
all supported command line options. This is also the first command to test after
installing mcx. If your see an error, such as missing libraries, this typically
indicates a problem with your NVIDIA driver or CUDA toolkit
Run: list GPU
Runing "mcx -L" lists all supported GPUs on your computer. A sample output
looks like below:

fangq@wazu:mcx/bin$ ./mcx -L
=============================   GPU Infomation  ================================
Device 1 of 4:		GeForce GTX 980 Ti
Compute Capability:	5.2
Global Memory:		2147287040 B
Constant Memory:	65536 B
Shared Memory:		49152 B
Registers:		65536
Clock Speed:		1.19 GHz
Number of MPs:		22
Number of Cores:	2816
SMX count:		22
=============================   GPU Infomation  ================================
Device 2 of 4:		GeForce GTX 590
Compute Capability:	2.0
Global Memory:		1610285056 B
Constant Memory:	65536 B
Shared Memory:		49152 B
Registers:		32768
Clock Speed:		1.26 GHz
Number of MPs:		16
Number of Cores:	512
SMX count:		16
=============================   GPU Infomation  ================================
Device 3 of 4:		GeForce GTX 590
Compute Capability:	2.0
Global Memory:		1609760768 B
Constant Memory:	65536 B
Shared Memory:		49152 B
Registers:		32768
Clock Speed:		1.26 GHz
Number of MPs:		16
Number of Cores:	512
SMX count:		16
=============================   GPU Infomation  ================================
Device 4 of 4:		GeForce GT 730
Compute Capability:	3.5
Global Memory:		1073545216 B
Constant Memory:	65536 B
Shared Memory:		49152 B
Registers:		65536
Clock Speed:		0.90 GHz
Number of MPs:		2
Number of Cores:	384
SMX count:		2

Run: autopilot mode
The command "mcx -A -n 1e6 -f input.json" asks mcx to simulate 10^6 photons (-n)
using the settings specified (-f) in the input file "input.json"; it also asks
mcx to automatically configure (-A) the thread and block sizes to maximize
speed. If the simulation successfully completes, an output named "input.json.mc2"
will be created in the current folder.

In the autopilot mode, mcx uses a built-in huristic algorithm to determine the
thread and block sizes. The goal is to launch as many threads as possible to keep
all GPU hardware busy, thus achieving maximized efficiency
Run: session name and voxel size
The command "mcx -A -n 1e6 -f input.json -s test -u 0.5" adds two additional
options to the previous command:

-s test: instead of writing the output file as input.json.mc2, the output files
         will be named as test.mc2

-u 0.5:  by default, mcx assumes isotropic 1 x 1 x 1 mm^3 voxels in the volume;
         if your volume has a voxel dimension larger or smaller than 1mm, you
         may specify it by the -u flag. Here we say all voxels are
         0.5 x 0.5 x 0.5 mm^3 in size
Run: manual thread configuration
Instead of using the autopilot mode (-A), in this command,
"mcx -t 10240 -T 32 -n 1e6 -f input.json", we explicitly specify the thread
and block sizes using the -t and -T flags, respectively. 
Click items below to show help info
Click items below to show help info
Click the sample command below to show help info

Get Involved!

Become an MCXer, enjoy the software, become a friend with the developers, other users, and share your stories, suggestions, or creations with everyone else. We together make MCX better and better!

Share a story
Go Back
Project maintainer:
Qianqian Fang, PhD
Fanny Nina Paravecino
Leiming Yu
Ruoyang Yao
Qianqian Fang
David Kaeli, PhD
Xavier Intes, PhD
Simon Arridge, PhD
This project is funded by the NIH/NIGMS under the grant R01-GM114365.


The MCX Developers

  • Our team is dedicated to advancing our MCX/MMC platform towards one of the fastest, most accurate and most versatle Monte Carlo particle simulator. We have gathered a team including experts in GPU computing and optical imaging. Our project is among one of the few open-source optical imaging packages officially funded by the National Institute of Health.

    Click on each member to read more.
  • Qianqian Fang PhotoDr. Fang is currently an Assistant Professor in the Dept. of Bioengineering, Northeastern University. He is the original author of MCX and MMC, and is the current maintainer of the project. He enjoys programming, and interactions with the users.
  • Fanny is a PhD student in the ECE department of Northeastern University, co-mentored by Drs. Kaeli and Fang. She is our lead developer for MCX and is dedicated to making MCX faster through her insights in GPU archetecture and auto-tuning techniques.
  • Leiming is a PhD student in the GPU archetecture lab of Northeastern University. He is currently working on the OpenCL version of MCX.
  • Ruoyang Yao PhotoRuoyang is a PhD student at RPI, co-mentored by Drs. Xavier Intes and Fang. Ruoyang is our lead developer for our next generation MMC software.
  • Dr. David Kaeli is a Professor in the ECE department of ECE of Northeatern University. He is our GPU guru and will guide us on every step of making MCX/MMC better and faster.
  • Dr. Xavier Intes is a Associate Professor at RPI. He is our imaging master, will help us make sure our algorithm and software are up to real world experimental tests.
  • Dr. Simon Arridge is a Professor at Univ. College London, UK. He is a well-known pioneer of optical tomography, and will help us pack more of the latest optical imaging methods into our software.
Go to Documentation