Cheese Phantom Module for Gammex 467 Phantom

Hi Folks,

I’m trying to create a custom ED phantom analysis script for the Gammex Model 467 CT to ED phantom using the Cheese module.

I’m getting errors when I try to create a very simple custom test routine with 5 ROI’s running the attached python script (using the Pylinac documentation guide):

When .analyze() is called, its giving errors:

Traceback (most recent call last):

File “U:\Python Scripts\Pylinac\CTtoED\new_phantom_config.py”, line 59, in
swiss.analyze()

File “C:\Users\johnccronin\Anaconda3\lib\site-packages\pylinac\cheese.py”, line 211, in analyze
self.localize()

File “C:\Users\johnccronin\Anaconda3\lib\site-packages\pylinac\ct.py”, line 1699, in localize
self._phantom_center_func = self.find_phantom_axis()

File “C:\Users\johnccronin\Anaconda3\lib\site-packages\pylinac\ct.py”, line 1727, in find_phantom_axis
p30, p70 = np.percentile(center_x, [30, 70])

File “<array_function internals>”, line 5, in percentile

File “C:\Users\johnccronin\Anaconda3\lib\site-packages\numpy\lib\function_base.py”, line 3867, in percentile
return _quantile_unchecked(

File “C:\Users\johnccronin\Anaconda3\lib\site-packages\numpy\lib\function_base.py”, line 3986, in _quantile_unchecked
r, k = _ureduce(a, func=_quantile_ureduce_func, q=q, axis=axis, out=out,

File “C:\Users\johnccronin\Anaconda3\lib\site-packages\numpy\lib\function_base.py”, line 3564, in _ureduce
r = func(a, **kwargs)

File “C:\Users\johnccronin\Anaconda3\lib\site-packages\numpy\lib\function_base.py”, line 4098, in _quantile_ureduce_func
n = np.isnan(ap[-1])

IndexError: index -1 is out of bounds for axis 0 with size 0

This phantom has a 33 cm diameter so I suspect this has something to do with it having difficulty detecting the center of the phantom and trying to account for roll?

See attached phantom dimensions and also the CT images I’m trying to analyze.

Thanks,

John

gammex_phantom.zip (4.95 MB)

new_ed_phantom_pylinac.py (1.66 KB)

Hi John,

first a remark: I think your angles are off, If you have a look at the source angles go from -180 to 180.

None the less I more or less get the same error here. (pylinac 3.11.0, numpy 1.24.3, python 3.10.5)

C:\WPy64-31050\python-3.10.5.amd64\lib\site-packages\pylinac\ct.py in find_phantom_axis(self)

1725 center_xs = np.array(center_x)

1726 center_ys = np.array(center_y)

->1727 p30, p70 = np.percentile(center_x, [30, 70])

1728 x_idxs = np.argwhere((p30 < center_xs) & (center_xs < p70))

1729 p30, p70 = np.percentile(center_y, [30, 70])

C:\WPy64-31050\python-3.10.5.amd64\lib\site-packages\numpy\core\fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)

56 try: —>

57 return bound(*args, **kwds)
58 except TypeError:

59 # A TypeError occurs if the object does have such a method in its Index

Error: cannot do a non-empty take from an empty axes.

regards
Thomas

error_log.txt (3.98 KB)

gammex_rmi.py (3.17 KB)

gammex.zip (5.22 MB)

Here’s a gist that should work that we made for a RadMachine customer. I’ve not added it to the officially supported list yet as I’m still waiting on more data to validate. gammex (github.com)
The phantom appears to be sitting directly on the table, which is causing the center of the phantom to appear lower than it really is as the table and phantom create one contiguous ROI for the purposes of finding the phantom center.
If you set the phantom on something low-HU like foam this should solve the problem.

Hi James,

That makes sense about the phantom begin in contact with the couch top, sorry I missed that!

Thanks so much too for the Gammex code. My next step was to figure out all the geometries so this is more than I could have hoped for!

Well done and keep up the good work!

John

Hi James,

in your phantom class you set air_bubble_radius_mm = 55. Why is the radius here so large?

regards
Thomas

Hi,

just put the phantom on some styrodur and the analysis worked like a charm. Thanks for the tip.

gammex_styrodur.PNG

I will upload the dataset to the image donation form.

regards
Thomas