Dear Dr. Fang and all MCX-users,
First of all, thank you for this interesting group and very valuable discussions!
I would like to ask a question related to the Jacobians with respect to mua. As we know, MCX outputs these in the replay mode if we set 'jacobian' as the output type. I use MCX in MATLAB environment, thus MCXLAB.
I have voxel side length other than 1 mm, thus I set cfg.unitinmm = voxel side length. My question is: After obtaining the Jacobians, shouldn't I multiply the voxel-wise values with cfg.unitinmm to get correct units ([mm])? So, jacobian_final = cfg.unitinmm.*jacobian?
This is my interpretation after reading the source codes (mcx_core.cu and mcx_utils.c). MCX takes cfg.unitinmm into account when calculating the total detected weights (in replay.weight, mcx_utils.c line 1097), but when the voxel-wise path lengths are scaled with the weight, the path length unit seems to be in grid unit (Lmove in mcx_core.cu line 778).
In this part of the code, mua and mus are in grid unit, thus path lengths in grid unit are otherwise appropriate. For fluence and flux, the units are fixed during normalization (mcx_core.cu line 1606), but Jacobian is just scaled with unitless detected weight. In my opinion, this gives the sensitivity with respect to mua in grid unit [1/grid unit], thus we need to multiply with voxel side length to get mm as Jacobian unit. Am I correct or what have I missed?
Also, does setting cfg.seed = -1 (negative) in MCXLAB mean that the seeds are (repeatedly) randomly generated?
I would be extremely grateful for comments!
Best regards,
Pauliina Hirvi
--
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 post to this group, send email to mcx-...@googlegroups.com.
Visit this group at https://groups.google.com/group/mcx-users.
For more options, visit https://groups.google.com/d/optout.
Dear Dr. Fang,
Thank you for Your reply, and sorry for my late response.
Correct me if I have misunderstood, but I think that now in the fixed version the jacobian is divided by cfg.unitinmm, instead of multiplying by it. My interpretation was that you should multiply (jacobian_final = cfg.unitinmm.*jacobian), since when
the voxel-wise path lengths are scaled with the weight, the path lengths are in grid unit.
Now in mcx_core.cu we first multiply the scale with cfg.unitinmm, but then perform scale=1.f/scale, and in the function mcx_normalize (mcx_utils.c), the values are multiplied with the scale, thus divided with cfg.unitinmm. So I suggest performing
scale=1.f/scale before multiplication by cfg.unitinmm.
Furthermore, if the user doesn't wish to normalize the values (for example I don't need values divided by total detected weight at this point), then the obtained jacobians are in grid units, not mm. Maybe this could be commented, or then multiplication
by cfg.unitinmm could be part of the general calculation?
Relating to the question I asked about cfg.seed = -1 (negative): With " repeatedly" I referred to the fact that by default MCX reseeds the RNG after 1e7 steps in each thread, thus the values are "repeatedly" randomly generated. I just wasn't sure whether cfg.seed=-1 works in the matlab version. Thanks for confirming this!
Thank you for the help and valuable discussion!
Best regards,
Pauliina Hirvi
Dear Dr. Fang,
Thank you for Your reply, and sorry for my late response.
Correct me if I have misunderstood, but I think that now in the fixed version the jacobian is divided by cfg.unitinmm, instead of multiplying by it. My interpretation was that you should multiply (jacobian_final = cfg.unitinmm.*jacobian), since when the voxel-wise path lengths are scaled with the weight, the path lengths are in grid unit.
Now in mcx_core.cu we first multiply the scale with cfg.unitinmm, but then perform scale=1.f/scale, and in the function mcx_normalize (mcx_utils.c), the values are multiplied with the scale, thus divided with cfg.unitinmm. So I suggest performing scale=1.f/scale before multiplication by cfg.unitinmm.
Furthermore, if the user doesn't wish to normalize the values (for example I don't need values divided by total detected weight at this point), then the obtained jacobians are in grid units, not mm. Maybe this could be commented, or then multiplication by cfg.unitinmm could be part of the general calculation?
Relating to the question I asked about cfg.seed = -1 (negative): With " repeatedly" I referred to the fact that by default MCX reseeds the RNG after 1e7 steps in each thread, thus the values are "repeatedly" randomly generated. I just wasn't sure whether cfg.seed=-1 works in the matlab version. Thanks for confirming this!
Dear Dr. Fang,
Thank you for your quick reply!
Yes, the scale is correctly multiplied by cfg.unitinmm on line #1694 of the patch (https://github.com/fangq/mcx/commit/fff057cc550606eed5fedcdf720d1196b26e06a0#diff-0083a506345d0d19caffd23f50b59bcdR1694).
However, right after this on line #1696 the scale is inverted (scale = 1/scale). Thus,
the function mcx_normalize (line #446 here
https://github.com/fangq/mcx/blob/master/src/mcx_utils.c) divides the Jacobian by cfg.unitinmm, though it should multiply. Maybe I misunderstand the line #1696 here? Sorry for this trouble.
Best wishes,
Pauliina Hirvi
Dear Dr. Fang,
Thank you for Your reply, and sorry for my late response.
Correct me if I have misunderstood, but I think that now in the fixed version the jacobian is divided by cfg.unitinmm, instead of multiplying by it. My interpretation was that you should multiply (jacobian_final = cfg.unitinmm.*jacobian), since when the voxel-wise path lengths are scaled with the weight, the path lengths are in grid unit.
Now in mcx_core.cu we first multiply the scale with cfg.unitinmm, but then perform scale=1.f/scale, and in the function mcx_normalize (mcx_utils.c), the values are multiplied with the scale, thus divided with cfg.unitinmm. So I suggest performing scale=1.f/scale before multiplication by cfg.unitinmm.
Furthermore, if the user doesn't wish to normalize the values (for example I don't need values divided by total detected weight at this point), then the obtained jacobians are in grid units, not mm. Maybe this could be commented, or then multiplication by cfg.unitinmm could be part of the general calculation?
Relating to the question I asked about cfg.seed = -1 (negative): With " repeatedly" I referred to the fact that by default MCX reseeds the RNG after 1e7 steps in each thread, thus the values are "repeatedly" randomly generated. I just wasn't sure whether cfg.seed=-1 works in the matlab version. Thanks for confirming this!
Dear Dr.Fang,
Unfortunately I am still wondering about the scaling on lines #1694-1696 on the patch (https://github.com/fangq/mcx/commit/fff057cc550606eed5fedcdf720d1196b26e06a0#diff-0083a506345d0d19caffd23f50b59bcdR1694). I think that on line #1696 the scale is inverted (scale = 1/scale), thus the code divides jacobian by cfg.unitinmm, when it should multiply. I would be gratefult if you could explain!
In addition, I was wondering whether you are planning to enable anisotropic voxels (voxels with different x,y and z side length) in the
near future?
Best regards,
Pauliina Hirvi
Dear Dr. Fang,
Thank you for your quick reply!
Yes, the scale is correctly multiplied by cfg.unitinmm on line #1694 of the patch (https://github.com/fangq/mcx/commit/fff057cc550606eed5fedcdf720d1196b26e06a0#diff-0083a506345d0d19caffd23f50b59bcdR1694).
However, right after this on line #1696 the scale is inverted (scale = 1/scale). Thus,
the function mcx_normalize (line #446 here
https://github.com/fangq/mcx/blob/master/src/mcx_utils.c) divides the Jacobian by cfg.unitinmm, though it should multiply. Maybe I misunderstand the line #1696 here? Sorry for this trouble.
Best wishes,
Pauliina Hirvi
Dear Dr. Fang,
Thank you for Your reply, and sorry for my late response.
Correct me if I have misunderstood, but I think that now in the fixed version the jacobian is divided by cfg.unitinmm, instead of multiplying by it. My interpretation was that you should multiply (jacobian_final = cfg.unitinmm.*jacobian), since when the voxel-wise path lengths are scaled with the weight, the path lengths are in grid unit.
Now in mcx_core.cu we first multiply the scale with cfg.unitinmm, but then perform scale=1.f/scale, and in the function mcx_normalize (mcx_utils.c), the values are multiplied with the scale, thus divided with cfg.unitinmm. So I suggest performing scale=1.f/scale before multiplication by cfg.unitinmm.
Furthermore, if the user doesn't wish to normalize the values (for example I don't need values divided by total detected weight at this point), then the obtained jacobians are in grid units, not mm. Maybe this could be commented, or then multiplication by cfg.unitinmm could be part of the general calculation?
Relating to the question I asked about cfg.seed = -1 (negative): With " repeatedly" I referred to the fact that by default MCX reseeds the RNG after 1e7 steps in each thread, thus the values are "repeatedly" randomly generated. I just wasn't sure whether cfg.seed=-1 works in the matlab version. Thanks for confirming this!
Dear Dr.Fang,
Unfortunately I am still wondering about the scaling on lines #1694-1696 on the patch (https://github.com/fangq/mcx/commit/fff057cc550606eed5fedcdf720d1196b26e06a0#diff-0083a506345d0d19caffd23f50b59bcdR1694). I think that on line #1696 the scale is inverted (scale = 1/scale), thus the code divides jacobian by cfg.unitinmm, when it should multiply. I would be gratefult if you could explain!
In addition, I was wondering whether you are planning to enable anisotropic voxels (voxels with different x,y and z side length) in the near future?