Skip to content

pmcx fails to read cfg['angleinvcdf'] and cfg['invcdf'] array data #233

Closed
@fangq

Description

@fangq

this was reported by @vzoutenbier in the following post in #194

#194 (comment)

the issue seems that the supplied data are only read partially.

Hi Dr. Fang,

Thanks for your quick response. I am using v 0.3.2 so I expect it to have these updates :)

I wrote a script, pasted below, which is able to reproduce my issue across multiple machines. It allows for relatively easy tests. I show some tests below which indicate the issue is within pmcx, or "between the keyboard and the chair".

it seems that only the first entry of a list/numpy array is considered when defining cfg['angleinvcdf']. Below I put in an np.array, list of two entries, and a list of one entry and get the same outputs for all three.

cfg['angleinvcdf'] = np.linspace(1/6,1/5,5) -> (Output A, below) thin cone, not expected
cfg['angleinvcdf'] = [1/6,1/5]                      -> (Output A,) thin cone, not expected
cfg['angleinvcdf'] = **[**1/6**]**                            -> (Output A) thin cone, expected

Output A
image

This shows that no matter what the length of the input array, it always evaluates the first entry as the only entry.

Changing the first entry of the list does make a difference, we can use it to adjust the emission conical angle:

cfg['angleinvcdf'] = np.linspace(1/6,1/5,5) -> (Output A, above)
cfg['angleinvcdf']= np.linspace(1/12,1/5,5) -> (Output C, below) Changes angle of thin cone

Output C
image

So, this code only considers the first entry for the output emission.

I also found that the angleinvcdf must be defined in an array, or it evaluates incorrectly:

cfg['angleinvcdf'] = np.array([1/6])              -> (Output A) 
cfg['angleinvcdf'] = **[**1/6**]**                            -> (Output A) thin cone, expected
cfg['angleinvcdf'] = 1/6                               -> (Output B) light emitted exactly along srcdir

Output B
image

So, it doesnt matter if it's a pythonic list, or a numpy array.

All these results are true, independent of the 4th entry of the source dir.
cfg['srcdir']=[0,0,1,0]
or
cfg['srcdir']=[0,0,1,1]
which should be the difference between interpolation between angles and discrete points- but I don't see any changes.

Something that I notice is that when running the simulation, the terminal output says:

nphoton: 1e+07
tstart: 0
tstep: 5e-09
tend: 5e-09
isreflect: 0
issrcfrom0: 1
srcpos: [30, 30, 15, 1]
srcdir: [0, 0, 1, 0]

which shows that pmcx has appended a fourth entry to the srcpos, this is typically the radius of the source. I can assign this to be anything non zero and the output is the same. If I assign it to 0 the simulation freezes.

Any leads or help here greatly appreciated.

Best regards,
Vincent Zoutenbier

This is basically a verbatim translation from your demo mcxlab example code demo_mcxlab_launchangle.m with pythonic plotting along 3 planes, translated to python. Testing within your group and/or any feedback greatly appreciated.

(replace [hashtag] with a #, these are comments that show as headers in markdown on this website.)

import pmcx
import numpy as np
import matplotlib.pyplot as plt
from Software import tmcx
from copy import deepcopy

gpus=pmcx.gpuinfo()
gpus[0]

# Method 1, setup simulation
cfg={}
cfg['nphoton']=1e7
cfg['vol']=np.ones([61,61,61], dtype='uint8')
cfg['srcpos']=[30,30,15]
cfg['srcdir']=[0,0,1,0]
cfg['prop']=[[0,0,1,1],[0.001,0,1,1]]
cfg['tstart']=0
cfg['tend']=5e-9
cfg['tstep']=5e-9
cfg['isreflect']=0
cfg['issrcfrom0']=1

# define angleinvcdf in launch angle using cfg['angleinvcdf']
cfg['angleinvcdf']=np.linspace(1/6,1/5,5)  # launch angle is uniformly distributed between [pi/6 and pi/5] with interpolation (odd-number length)

# Run the simulation
res=pmcx.run(cfg)

# plot every point with negligable offset
res['flux']=res['flux']+1e-40

# plot cross sections
fig = plt.figure()
gs = fig.add_gridspec(2, 2)
(ax1, ax2), (ax3, ax4) = gs.subplots()
vmin = np.log10(res['flux'].max())-3
vmax = np.log10(res['flux'].max())
ax1.imshow(np.log10(res['flux'][:,:,45]),interpolation='nearest',vmin=vmin, vmax=vmax)
ax1.set_title('Z=45')
ax2.set_axis_off()
ax3.imshow(np.log10(np.squeeze(res['flux'][:,30,:])).T,interpolation='nearest',vmin=vmin, vmax=vmax)
ax3.set_title('Y=30')
ax4.imshow(np.log10(np.squeeze(res['flux'][30,:,:])).T,interpolation='nearest',vmin=vmin, vmax=vmax)
ax4.set_title('X=30')

plt.show()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions