Volume source in MCXLAB

39 views
Skip to first unread message

vijit...@gmail.com

unread,
Mar 25, 2026, 3:55:22 PM (10 days ago) Mar 25
to mcx-users
I am trying to simulate digimouse with the liver as a source (to mimic fluroscence imaging). But in Matlab scrtype doesnt accept volume as input. Is there a work around

Qianqian Fang

unread,
Apr 1, 2026, 11:37:34 AM (3 days ago) Apr 1
to mcx-...@googlegroups.com, vijit...@gmail.com

mcx's srctype does support volumetric source. please follow this built-in example

https://github.com/fangq/mcx/blob/v2025.10/mcxlab/examples/demo_mcxlab_srctype.m#L291-L316


On 3/25/26 15:55, vijit...@gmail.com wrote:

You don't often get email from vijit...@gmail.com. Learn why this is important

I am trying to simulate digimouse with the liver as a source (to mimic fluroscence imaging). But in Matlab scrtype doesnt accept volume as input. Is there a work around --
You received this message because you are subscribed to the Google Groups "mcx-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mcx-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mcx-users/3940d221-4e3f-4359-b582-c7c6d6a46d8en%40googlegroups.com.

Vijitha Periyasamy

unread,
Apr 2, 2026, 4:52:18 PM (2 days ago) Apr 2
to mcx-users
Hi Fang,

Thank you for your speedy support. Highly appreciate the same.
I am trying to preview the example above and it throws a error. Is it because of the cfg.shape.
clc;clear all;close all
Rsrc = 20;
[xi, yi, zi] = ndgrid(-Rsrc:Rsrc, -Rsrc:Rsrc, -Rsrc:Rsrc);
sphsrc = ((xi .* xi + yi .* yi + zi .* zi) <= Rsrc * Rsrc);

dim=60;
cfg.nphoton = 1e7;
cfg.tstart = 0;
cfg.tend = 5e-9;
cfg.tstep = 5e-9;
cfg.respin = 1;
cfg.seed = 99999;
cfg.outputtype = 'energy'; % should get the energy deposits in each voxel

cfg.srctype = 'pattern3d';
cfg.srcpattern = sphsrc;
cfg.srcparam1 = size(cfg.srcpattern);
cfg.srcpos = [10, 10, 20];
cfg.srcdir = [0 0 1 nan];
cfg.autopilot = 1;

% define volume and inclusions
cfg.vol = ones(dim, dim, dim);
%% you can use a JSON string to define cfg.shapes
cfg.shapes = '{"Shapes":[{"Sphere":{"O":[25,21,10],"R":10,"Tag":2}}]}';
cfg.prop = [0      0    1    1     % Boundary
            0.003  0.03 0.8  1     % Tissue mua = 0.003 mus = 0.03 n = 1.85/1.37
            0.006  0.09 0.8  1     % Cancer mus  = 1.09 n = 1.37
            1.3    0.8  0.8  1];   % TAM mua = 0.003, n = 0.095
cfg.unitinmm = 1e-3;


flux = mcxlab(cfg);

Qianqian Fang

unread,
Apr 2, 2026, 4:57:20 PM (2 days ago) Apr 2
to mcx-...@googlegroups.com, Vijitha Periyasamy

Vijitha Periyasamy

unread,
Apr 2, 2026, 5:05:12 PM (2 days ago) Apr 2
to mcx-users
Fang, should the srcpattern for a pattern3D be a array (size of x*y*z dimensions ) or a 3D matrix or a Nx4 array where, N=x*y*z, N(:,1:3) = x,y,z pixel index and N(:,4) is the intensity of the pixel.

vijit...@gmail.com

unread,
Apr 3, 2026, 12:54:21 PM (yesterday) Apr 3
to mcx-users
Hi Fang,
The source in this example is outside the volume of interest. Is there an example where the source is within the object.

Qianqian Fang

unread,
Apr 3, 2026, 2:04:25 PM (yesterday) Apr 3
to mcx-...@googlegroups.com, vijit...@gmail.com

I am not sure what you meant by "volume of interest". the volume source in the built-in example spans between x=10-50, y=10-50, and z=20-60, which is within the original 60^3 volume.

even you push the volume source outside of the original volume, by setting cfg.srcpos=[10,10,30], the volumetric source can still be simulated, with the source being truncated outside of the volume.


I can not run your cylindrical source sample code. some functions are not defined in your sample code.

vijit...@gmail.com

unread,
Apr 3, 2026, 2:17:29 PM (yesterday) Apr 3
to mcx-users
here is the defineCylinder code

function cylinderMask = defineCylinder(cyl_R, cyl_H, matrixSize)

[X, Y, Z] = meshgrid(1:matrixSize, 1:matrixSize, 1:matrixSize);

% 3. Calculate distance from the center (assumed to be center of matrix)
center = matrixSize / 2;
distSq = (X - center).^2 + (Y - center).^2;

% 4. Create the Cylinder Mask
% The cylinder consists of points inside the radius,
% and within the specified height range.
cylinderMask = (distSq <= cyl_R^2) & (Z >= 1) & (Z <= cyl_H);

could you please let me know if I am missing some input.
Happy to get on a call, if you are avaiable.

Thanks

Qianqian Fang

unread,
Apr 3, 2026, 2:56:25 PM (yesterday) Apr 3
to mcx-...@googlegroups.com, vijit...@gmail.com

the bug is actually in your code


cfg.srctype = 'pattern3D';
cfg.srcpattern = logical(src_pattern);
cfg.srcpos = [85.0 248.0 72.0];
cfg2.srcparam1 = size(src_pattern);
cfg.srcdir = [0 0 -1 nan];


you never set cfg.srcparam1 to the right dimensions to match the srcpattern array size, instead you set it to a new struct cfg2.

renaming cfg2 to cfg make your code run.

Vijitha Periyasamy

unread,
Apr 3, 2026, 3:01:54 PM (yesterday) Apr 3
to mcx-...@googlegroups.com
I realized it later. I corrected the same
clc;
clear all;
close all

addpath /scratch/vijitha/mcxlab/matlab/
addpath /scratch/vijitha/mcxlab
addpath /scratch/vijitha/mcxlab/examples/
addpath /scratch/vijitha/iso2mesh/

box_vol = ones(100, 100, 100);
box_vol_og = ones(100, 100, 100);
cyl_R = 5;
cyl_H = 30; matsize = cyl_H;
cyl_mask = defineCylinder(cyl_R,cyl_H,matsize);cyl_mask=cyl_mask*2;
cyl_mask(find(cyl_mask==0))=1;
cyl_mask_rot = imrotate3(cyl_mask,90,[0 1 0]);
cyl_cent = matsize/2;

vol_cent = [50 50 50];
box_vol(vol_cent(1)-cyl_cent:vol_cent(1)+cyl_cent-1, vol_cent(2)-cyl_cent:vol_cent(2)+cyl_cent-1, vol_cent(3)-cyl_cent:vol_cent(3)+cyl_cent-1) = cyl_mask_rot;

src_pattern = zeros(size(box_vol));
src_pattern(find(box_vol == 2)) = 1;

cfg.vol = uint8(box_vol_og);


cfg.prop = [0      0    1    1     % Boundary
            0.033 77 0.9 1.33     % Tissue
            4.5 592 0.9799 1.33];   % Blood vessel


cfg.srctype = 'pattern3D';
cfg.srcpattern = logical(src_pattern);
cfg.srcpos = [50 50 50];
cfg.srcparam1 = size(cfg.srcpattern);%[50 50 50];

cfg.srcdir = [0 0 -1 nan];


cfg.isnormalized = 0;
cfg.outputtype = 'energy';

cfg.tstart = 0;
cfg.tend = 5e-9;
cfg.tstep = 5e-9;
cfg.nphoton = 1e6;
cfg.autopilot = 1;
cfg.gpuid = 1;
cfg.unitinmm = 0.1 * 2;
cfg.debuglevel = 'P';
cfg.bc = '______111111';  % capture photons existing from all faces except z=z_max
cfg.savedetflag = 'dpx';
cfg.issaveref = 1;

flux = mcxlab(cfg);
fcw = flux.data;

The result seems to have the source from 100 100 100

image.png


vijit...@gmail.com

unread,
Apr 3, 2026, 3:16:27 PM (yesterday) Apr 3
to mcx-users
Actually, I observed the same in another example that I have been working on. The clyinder in the middle is supposed to be the source


Screenshot 2026-04-03 141542.png

vijit...@gmail.com

unread,
Apr 3, 2026, 5:43:01 PM (22 hours ago) Apr 3
to mcx-users
Hi Fang,
Could you please let me know if you are also getting the same output please.
It will be very helpful.

Qianqian Fang

unread,
Apr 3, 2026, 6:04:47 PM (22 hours ago) Apr 3
to mcx-...@googlegroups.com, vijit...@gmail.com

Please be conscious that there are over 400 subscribers in this mailing list. Please do not flood this forum with exchange of brief conversations or chats. This is not the right place for that.

I also strongly encourage you to read mcx/mcxlab documentation and all examples carefully and do the troubleshoot yourself before you ask questions.

If you have to ask, please provide detailed information with a reproducer code so that others can see the same problem. Describe what you have done, and why the results you believe is problematic. The more you provide, the better the developer know how to advise.

If you haven't read this before, I strongly encourage you to take a look at this classic article on how to ask questions on the Internet

http://www.catb.org/~esr/faqs/smart-questions.html


for now, please move further discussions (following the guideline described above), if necessary, to my email only and remove the mailing list from the recipient list.

Reply all
Reply to author
Forward
0 new messages