Wide field detector set up

28 views
Skip to first unread message

Xiuxiu Zhang

unread,
Nov 5, 2025, 10:12:02 AMNov 5
to mmc-users

Dear Dr. Qianqian Fang and mmcusers,

Thank you for developing and continuously improving the MMC software suite. I was recently introduced to it and have been exploring the example codes.

While reviewing demo_wide_det.m, I noticed two sections related to the detector setup:

  1. detdef = struct('srctype', 'planar', 'srcpos', [10, 10, -1], 'srcdir', [0 0 1], ...

                'srcparam1', [40 0 0 40], 'srcparam2', [0 40 0 40]);

[cfg.node, cfg.elem] = mmcadddet(node, elem, detdef);

  1. cfg.detpos = [10.0, 10.0, -1.0, 0];

cfg.detparam1 = [40.0 0.0 0.0 40];

cfg.detparam2 = [0.0 40.0 0.0 40];

I was wondering what the difference is between these two definitions. I also noticed that cfg.saveexit is set to 2 in this demo, and when I tested it, the resulting detphoton size appeared to depend on the definition in section (2).

Lastly, could you please clarify what distinguishes a wide-field detector from a normal planar detector in this context?

Thank you very much for your time and for creating such a powerful and well-documented tool.

Best regards,

Xiuxiu

Qianqian Fang

unread,
Nov 10, 2025, 12:57:03 PMNov 10
to mmc-...@googlegroups.com, Xiuxiu Zhang

hi Xiuxiu, sorry for the delay

see my replies below

On 11/5/25 09:28, Xiuxiu Zhang wrote:

You don't often get email from zha...@seas.upenn.edu. Learn why this is important

Dear Dr. Qianqian Fang and mmcusers,

Thank you for developing and continuously improving the MMC software suite. I was recently introduced to it and have been exploring the example codes.


supporting widefield source (i.e. photons are launched or received from outside of the target domain) or detector is more complex in mmc than mcx. 

in mmc, the mesh must be modified in order to cover the source or detector if they are located outside of the object mesh. for details, please see this previous BOE paper

https://opg.optica.org/boe/fulltext.cfm?uri=boe-7-1-171

we call this mesh modification (extending from the domain's original mesh to include the source/detector aperture) as "mesh retessellation" - this is a required pre-processing step for all widefield mmc simulations.


While reviewing demo_wide_det.m, I noticed two sections related to the detector setup:

  1. detdef = struct('srctype', 'planar', 'srcpos', [10, 10, -1], 'srcdir', [0 0 1], ...

                'srcparam1', [40 0 0 40], 'srcparam2', [0 40 0 40]);

[cfg.node, cfg.elem] = mmcadddet(node, elem, detdef);


the above two lines performs the mesh retesellation - and returns the extended mesh in cfg.node and cfg.elem. you can plot them before (plotmesh(node, elem)) and after (plotmesh(cfg.node, cfg.elem)) this step to see the difference.

a side note, for wide field sources, you call mmcaddsrc().


  1. cfg.detpos = [10.0, 10.0, -1.0, 0];

cfg.detparam1 = [40.0 0.0 0.0 40];

cfg.detparam2 = [0.0 40.0 0.0 40];


these tells mmc simulation about the detector position and x/y spans. These parameters must match the parameter used for extending the mesh above.


I was wondering what the difference is between these two definitions.


you need both steps for widefield detector to work


I also noticed that cfg.saveexit is set to 2 in this demo, and when I tested it, the resulting detphoton size appeared to depend on the definition in section (2).


if you don't set cfg.saveexit to 2, all individual photons arriving at the above wideifeld detector's "aperture" will be captured and stored as the "detected photon" data, but for widefield detectors, this file can be huge - even you can save those, you still need to load them and post-process.

when setting cfg.saveexit to 2, this triggers mmc to use a simplified output mode - all photons arriving at the detectors are binned and summed to output a 2D array of intensities, as if it is a CCD/CMOS detector.

an alternative to cfg.saveexit=2 is to use the diffuse reflectance output on the domain surface by setting cfg.issaveref=1 - in this case, you obtain light intensities on all surface triangles,

https://github.com/fangq/mmc/blob/v2025.10/mmclab/mmclab.m#L161-L167

this does not require you to add a widefield detector. how you use this surface light intensity to obtain any widefield detector readings using integration as postprocessing, or if an integration is overkill (which is often the case), you can simply interpolate the surface diffuse reflectance at the detector pixel projection on the surface.


Lastly, could you please clarify what distinguishes a wide-field detector from a normal planar detector in this context?


in our software, we call any detectors (or sources) that are located outside of the target domain (voxel, mesh) as "widefield". for example, even a pencil beam that is launching photon from outside of the domain is a widefield source.

this definition is not necessarily translatable to other context, but we use it consistently in our tools/documentations.

let me know if these explanations help


Qianqian


Thank you very much for your time and for creating such a powerful and well-documented tool.

Best regards,

Xiuxiu

--
You received this message because you are subscribed to the Google Groups "mmc-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mmc-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mmc-users/a809158b-39f3-4499-bf95-5fa46c9ae833n%40googlegroups.com.

Xiuxiu Zhang

unread,
Nov 10, 2025, 1:25:04 PMNov 10
to mmc-users
Thanks for your reponse, Dr. Fang. 

when setting cfg.saveexit to 2, this triggers mmc to use a simplified output mode - all photons arriving at the detectors are binned and summed to output a 2D array of intensities, as if it is a CCD/CMOS detector.

Is there any parameter I could adjust so that the output array has finer resolution- pixels were smaller? Instead of 40*40 in this case, for instance, 80*80?

Thanks,
Xiuxiu

Qianqian Fang

unread,
Nov 10, 2025, 6:06:48 PMNov 10
to mmc-...@googlegroups.com, Xiuxiu Zhang

I realized that this information is never explained in the demo.

I just added an explanation on how to set the pxiel count (via detparam1(4) and detparam2(4)), see this commit

https://github.com/fangq/mmc/commit/f65b5a79f60bf7017a047cc93c97d7561f686c04

the help info is copied below:


%      cfg.detparam1:   a 4-element vector: [u1, u2, u3, Nx], define the x-axis of a widefield
%                       detector, [u1,u2,u3] is the x-axis vector; Nx is the pixel count in the x-axis
%      cfg.detparam2:   a 4-element vector: [v1, v2, v3, Ny], define the y-axis of a widefield
%                       detector, [v1,v2,v3] is the y-axis vector; Ny is the pixel count in the y-axis

%      cfg.issaveexit: [0]-whether to save the position (x,y,z) and (vx,vy,vz) for a detected photon
%                      When issaveexit is set to 2, this signals mmclab to output a 2D array
%                      a widefield detector defined by cfg.detparam1 and cfg.detparam2.
%                      Specifically, instead of output individual detected photon data,
%                      the exiting weight of all detected photons are binned and summed
%                      into a detparam1(4)-by-detparam2(4) pixelated output, covering
%                      the quadrilateral area with 4 corners defined by (only 1:3 elem are used)
%                      [detpos, detpos+detparam1, detpos+detparam1+detaram2, detpos+detparam2].
%                      When a widefield detector is used, detector radii are ignored.

Reply all
Reply to author
Forward
0 new messages