MMC detphoton from command line

34 views
Skip to first unread message

alejandro martinez

unread,
May 8, 2026, 8:05:33 AMMay 8
to mcx-users

Hi Dr. Fang, 
Thanks for this amazing software.

I'm working with MMC widefield sources and detectors via the cli interface using json config and missing some features that I see are present in the mmclab.

Specifically, when defining a detector they just accept "Pos" and "R", and from tests I inferred this detector is located in the XY plane. From the mmclab i can see that actually you can define detparam1 and detparam2, which allow you to use issaveexit=2. Is this behavior allowed from the command line using json input?

On the other hand, when working with detectors and activating the -x flag to save exit position/direction i get a mch file containing the following:

  • MCH header: {'version': 1, 'medianum': 1, 'detnum': 0, 'recordnum': 10, 'totalphoton': 500000, 'detectedphoton': 1572, 'savedphoton': 1572, 'lengthunit': 1.0, 'seedbyte': 0, 'normalizer': 400.0816955566406, 'respin': 1, 'srcnum': 1, 'savedetflag': 0} 
  • Sample MCH row: [1.9045000e+04 0.0000000e+00 0.0000000e+00 1.0908831e+01 1.0329286e+01 3.0000000e+01 1.0902426e-03 1.1011607e-02 9.9993873e-01 1.0000000e+00]
As you can see, for the scattering, path length and momentum, I just get two 0 values (--momentum flag active). 

The position and direction works, and i can plot both the mct and mch data which seems coherent.

But I'm missing the way to be able to know the weight of the photons when reaching the detector, as well as detected photon time, mean path per tissue and mean scat.

Would I need to trace each photon path from the mct file and somehow determine in which element are they present at each moment to track that information? 

Looking though the repo I found matlab/mmcdetweight.m and matlab/mmcmeanscat.m, but they use the detp object from mmclab which already contains things like ppath or nscat that I don’t have. I’m sure I’m missing something to be able to have that information. Can you kindly point me in the right direction?

Thanks in advance,

Alejandro


Find the information on the system and mesh below:

MMC in Ubuntu 24 x64, RTX 4060 (Rev::a1465d$v2025.10$Date::2026-03-27 17:07:15 -04$ by $Author::Qianqian Fang), latest version of iso2mesh. Command for MMC:

mmc -f config.json -V 1 -k 0 -b 1 -M P -D SEMW -x 1 --momentum

Simulation mesh can be generated as:

voxelCube = ones(20, 20, 20);
voxelCube = uint8(voxelCube);
[node, elem, face] = v2m(voxelCube, [], 1, 1, 'cgalmesh');

% Source
srcPos      = [10, 10, 25];  
srcDir      = [ 0,0,-1];          
srcType     = 'planar';

srcStruct = struct( ...
    'srctype',   srcType, ...
    'srcpos',    srcPos, ...  
    'srcdir',    srcDir, ...
    'srcparam1', [2 0 0 0], ...  
    'srcparam2', [0 2 0 0]);      

[nodes_final, elem_final] = mmcaddsrc(node, elem, srcStruct);

% Detector
detStruct = struct( ...
    'srctype',   'disk', ...
    'srcpos',    [10, 10, 30], ...  
    'srcdir',    srcDir, ...
    'srcparam1', [2 0 0 0], ...  
    'srcparam2', [0 0 0 0]);      

[nodes_final, elem_final] = mmcadddet(nodes_final, elem_final, detStruct);

eid = tsearchn(nodes_final, elem_final(:,1:4), srcPos);
savemmcmesh('mesh', nodes_final, elem_final);

Props are:
1 1
1 0.1 1 0.2 1.3

And json config:
{
  "Mesh": {
    "MeshID": "sample_cube",
    "InitElem": -1
  },
  "Session": {
    "Photons": 200000,
    "Seed": 42,
    "ID": "sample_cube"
  },
  "Forward": {
    "T0": 0.0,
    "T1": 5e-09,
    "Dt": 5e-09
  },
  "Optode": {
    "Source": {
      "Type": "planar",
      "Pos": [
        10,
        10,
        25
      ],
      "Dir": [
        0,
        0,
        -1
      ],
      "Param1": [
        2.0,
        0.0,
        0.0,
        0.0
      ],
      "Param2": [
        0.0,
        2.0,
        0.0,
        0.0
      ]
    },
  "Detector": [{
   "Pos": [10,10,30],
   "R": 2
  }]
  }
}


Qianqian Fang

unread,
May 8, 2026, 6:35:19 PMMay 8
to mcx-...@googlegroups.com, alejandro martinez

hi Alejandro,

see my replies below.


On 5/8/26 07:02, alejandro martinez wrote:

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

Hi Dr. Fang, 
Thanks for this amazing software.

I'm working with MMC widefield sources and detectors via the cli interface using json config and missing some features that I see are present in the mmclab.

Specifically, when defining a detector they just accept "Pos" and "R", and from tests I inferred this detector is located in the XY plane. From the mmclab i can see that actually you can define detparam1 and detparam2, which allow you to use issaveexit=2. Is this behavior allowed from the command line using json input?


you are correct. the detparam1/detparam2 inputs were implemented over 10 years ago, and it was only supported in the .inp file input format (see https://github.com/fangq/mmc/blob/v2025.10/src/mmc_utils.c#L2056-L2062), but not in the .json format.

I just made the following commit

https://github.com/fangq/mmc/commit/82994b1fb1efd725fe918f26a5bf84a6d8a735b1

it should be supported in the JSON input as well.


On the other hand, when working with detectors and activating the -x flag to save exit position/direction i get a mch file containing the following:

  • MCH header: {'version': 1, 'medianum': 1, 'detnum': 0, 'recordnum': 10, 'totalphoton': 500000, 'detectedphoton': 1572, 'savedphoton': 1572, 'lengthunit': 1.0, 'seedbyte': 0, 'normalizer': 400.0816955566406, 'respin': 1, 'srcnum': 1, 'savedetflag': 0} 
  • Sample MCH row: [1.9045000e+04 0.0000000e+00 0.0000000e+00 1.0908831e+01 1.0329286e+01 3.0000000e+01 1.0902426e-03 1.1011607e-02 9.9993873e-01 1.0000000e+00]
As you can see, for the scattering, path length and momentum, I just get two 0 values (--momentum flag active). 

The position and direction works, and i can plot both the mct and mch data which seems coherent.

But I'm missing the way to be able to know the weight of the photons when reaching the detector, as well as detected photon time, mean path per tissue and mean scat.


please add -F jnii in your command line, this asks mmc to save the detected photon data to a JSON based output file, which contains the detid, ppath, nscat etc subkeys in the output data structure. you use jsonlab's loadjson or loadjd to load this file to matlab, you should see those subfields

https://github.com/fangq/mmc/blob/v2025.10/src/mmc_utils.c#L999-L1001

Qianqian

--
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/493840e7-414e-4cfe-bdf0-6821a9eb8e39n%40googlegroups.com.

alejandro martinez

unread,
May 9, 2026, 5:02:42 AMMay 9
to mcx-users
Thank you for the prompt response, 

When using in the previous example with the save flag i get:
  • -F jnii I get the following: MMC ERROR(-1):error when converting to JSON in unit mmc_utils.c:831
  • -F bnii gives the following: MMC ERROR(-1):error when converting to JSON in unit mmc_utils.c:704
Thanks in advance, 
Alejandro

Qianqian Fang

unread,
May 10, 2026, 3:06:04 PMMay 10
to mcx-...@googlegroups.com, alejandro martinez

hi Alejandro,

thanks for reporting this. it appears that the current mmc binary only saves .mch/.mct binary files despite that json-based output function do exist (ported from mcx).

I've created a new ticket on github

https://github.com/fangq/mmc/issues/124

and was able to fix it with this commit

https://github.com/fangq/mmc/commit/2a7c1f83d8909c174c3ebee4c22efe5238b92e29


also added binary JSON output via -F bnii

https://github.com/fangq/mmc/commit/76f945de7958d95d094aac8d076e631762211c02


going back to your original question:


Would I need to trace each photon path from the mct file and somehow determine in which element are they present at each moment to track that information? 

Looking though the repo I found matlab/mmcdetweight.m and matlab/mmcmeanscat.m, but they use the detp object from mmclab which already contains things like ppath or nscat that I don’t have. I’m sure I’m missing something to be able to have that information. Can you kindly point me in the right direction?


correct. mcx/mmc does not save the detected weight. instead, it saves the partial path lengths, and passing detp output struct to mmcdetweight() will allow you to recompute the detected weight (and you can perturb the ma for each label via changing the prop input to mmcdetweight). same for other derivable per-photon data, such as meanpath, meannscat, dettime, detpsf, with functions under mmc/matlab/ folder.

by the way, the detected photon has a field of w0, but it is not the detected/final weight, but the initial weight. if you have a pencil beam, all values of w0 should be 1. w0 is only useful in source types where the launch weight is spatially varying - such as pattern/fourier etc.


Qianqian

alejandro martinez

unread,
May 11, 2026, 6:32:27 AMMay 11
to mcx-users
Hi Qianqian, 

Thanks again, unfortunately, I'm not able to reproduce fixes, I've cloned and compiled latest master and now I encounter that:
  • mct files are not generated at all
  • when trying to use -F to save in jnii or bnii:
    • jnii: MMC ERROR(-1):error when converting to JSON in unit mmc/src/mmc_utils.c:856
    • bnii: MMC ERROR(-1):error when converting to JSON in unit mmc/src/mmc_utils.c:729 
I've traced back the saving error to cfg->nodenum being initialized as 0 and not being updated before saving, which makes dimensions wrong. 
By initializing in line 338 cfg->nodenum=1 i was able to save correctly, but this is no good fix.

Thanks, 
Alejandro

Qianqian Fang

unread,
May 20, 2026, 12:07:18 PMMay 20
to mcx-...@googlegroups.com, alejandro martinez

hi Alejandro

using the binary built from the latest github version of mmc, and a built-in example, I don't see any error when saving data with either -F jnii or -F bnii

../bin/mmc  --bench dmmc-cube60 -F jnii -d 1
-rw-rw-r-- 1 fangq fangq     23843 May 20 12:03 dmmc-cube60_detp.jdt
-rw-rw-r-- 1 fangq fangq   2177665 May 20 12:03 dmmc-cube60.jnii

../bin/mmc  --bench dmmc-cube60 -F bnii -d 1
-rw-rw-r-- 1 fangq fangq     17834 May 20 12:05 dmmc-cube60_detp.jdb
-rw-rw-r-- 1 fangq fangq   1633416 May 20 12:05 dmmc-cube60.bnii


does this work for you? if this error only happens for your own input, please let me know how to reproduce.

Qianqian

alejandro martinez

unread,
May 21, 2026, 11:29:22 AMMay 21
to mcx-users
Hello Qianqian, 

Actually, when using the benchmark line you provided it works correctly, but using any other mesh does not, as the provided example above.

The provided example is just a cube and some widefield source and detector. I've removed both widefields (since they were not the source of error) and provide the following reduced example, which is just a cube with a isotropic light source in the middle. With this I've identified that the error occurs when -M != G, the other flags did not cause the error.
Please find below the matlab code to generate the simple domain and the json config.
Running with ../../bin/mmc -f config.json -F jnii (changing the -M).
MMC compiled from source from latest commit (as for now) 5442e3e.

voxelCube = uint8(ones(20,20,20));
[node, elem, face] = v2m(voxelCube, [], 1, 1, 'cgalmesh');
node = node(:,1:3);
savemmcmesh('sample_cube', node, elem);

{
"Mesh": {
"MeshID": "sample_cube",
"InitElem": -1
},
"Session": {
"Photons": 20000,
"Seed": 42,
"ID": "sample_cube"
},
"Forward": {
"T0": 0.0,
"T1": 5e-09,
"Dt": 5e-09
},
"Optode": {
"Source": {
"Type": "isotropic",
"Pos": [
10,
10,
10
],
"Dir": [
0,
0,
-1
],
"Param1": [
2.0,
0.0,
0.0,
0.0
],
"Param2": [
0.0,
2.0,
0.0,
0.0
]
}
}
}

Thanks, 
Alejandro
Reply all
Reply to author
Forward
0 new messages