Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pf.analyze() throws an exception with Varian Truebeam picket fence file #470

Open
ekamperi opened this issue Nov 14, 2023 · 7 comments
Open

Comments

@ekamperi
Copy link

ekamperi commented Nov 14, 2023

Describe the bug
Analyzing a picket fence dicom file obtained from a Varian Truebeam linac throws an exception during the detection of the left edge detection.

(dicom) ➜  ~ python
Python 3.11.4 | packaged by conda-forge | (main, Jun 10 2023, 18:08:41) [Clang 15.0.7 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from pylinac import PicketFence
>>> pf = PicketFence('/Users/stathis/Downloads/crash.dcm')
>>> pf.analyze()
/Users/stathis/miniforge3/envs/dicom/lib/python3.11/site-packages/numpy/core/fromnumeric.py:3504: RuntimeWarning: Mean of empty slice.
  return _methods._mean(a, axis=axis, dtype=dtype,
/Users/stathis/miniforge3/envs/dicom/lib/python3.11/site-packages/numpy/core/_methods.py:129: RuntimeWarning: invalid value encountered in scalar divide
  ret = ret.dtype.type(ret / rcount)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/stathis/miniforge3/envs/dicom/lib/python3.11/site-packages/pylinac/picketfence.py", line 597, in analyze
    window = self._get_mlc_window(
             ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/stathis/miniforge3/envs/dicom/lib/python3.11/site-packages/pylinac/picketfence.py", line 693, in _get_mlc_window
    left_edge = max(int(approx_idx - spacing / 2), 0)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: cannot convert float NaN to integer
>>>

I tried with invert=True and also with LEFT_RIGHT and UP_DOWN orientation. Same result.

To Reproduce
Please find the faulty picket fence dicom file here.

Expected behavior
Pylinac should either succeed in analyzing the picket fence file or display some more informative message to guide the user.

Screenshots
This is the orientation of the picket fence image data:

image

Additional context
For what is worth this happens only in static picket fence dicom files. When obtaining a picket fence over an arc beam, pylinac succeeds. Happy to provide any further information that could help to figure out what's going on.

@crcrewso
Copy link
Contributor

That image does not look like a successful picket fence delivery. I'm only seeing horizontal streaks, not the expected vertical dose bars.

@ekamperi
Copy link
Author

ekamperi commented Nov 14, 2023

Indeed. However I get the exact same behavior from a seemingly valid picket fence.

image

I added some debug print()s in picketfence.py and it appears that spacing isn't calculated properly. If I hardcode it, pylinac doesn't throw but it doesn't recognise all the fences. E.g.

pf_good.analyze(picket_spacing=None) throws but pf_good.analyze(picket_spacing=50) succeeds though only one fence is detected:

image

@jrkerns
Copy link
Owner

jrkerns commented Nov 15, 2023

I'm not able to access your link.

@ekamperi
Copy link
Author

ekamperi commented Nov 15, 2023

I'm not able to access your link.

Apologies, I fixed the link. It should work now.

EDIT: I guess GitHub is blocking external links that are not https? Anyway, copying and pasting manually http://test2.ogkologia.gr/picket.dcm should work.

@jrkerns
Copy link
Owner

jrkerns commented Nov 15, 2023

pf = PicketFence(<file>)
pf.analyze(required_prominence=0.1)
pf.plot_analyzed_image()

This works for me.

The reason it won't analyze is due to the narrow y-range of the MLCs. Opening the Y-jaws more will generally analyze without any extra parameters. I'll play around to see if I can auto-detect the initial picket locations better out of the box. Thanks.

@alanphys
Copy link
Contributor

alanphys commented Apr 12, 2024

Hi James

I am getting the same error with the HD Millenium MLC with the attached file. I see in the predefined MLC types the HD Millenium MLC is defined as:
HD_MILLENNIUM = {
"name": "HD Millennium",
"arrangement": MLCArrangement([(10, 5), (40, 2.5), (10, 5)]),
} #:

The Varian Truebeam system overview gives the HD Millenium arrangement as:
image
Shouldn't the MLCArrangement be (14,5), (32, 2.5), (14, 5)] ?

However I tried the following:

>>> mlc_setup = MLCArrangement(leaf_arrangement=[(14,5), (32, 2.5), (14, 5)])
>>> pf = PicketFence('/home/alanphys/Sites/VP/Static.dcm', mlc=mlc_setup)
>>> pf.analyze()

and

>>> mlc_setup = MLCArrangement(leaf_arrangement=[(32, 2.5)])
>>> pf = PicketFence('/home/alanphys/Sites/VP/Static.dcm', mlc=mlc_setup)
>>> pf.analyze()

as well as

>>> pf = PicketFence('/home/alanphys/Sites/VP/Static.dcm', mlc='HD Millennium')
>>> pf.analyze()

and they all gave the same error. Your workaround above worked though. The MLC arrangement doesn't seem to affect the analysis.
StaticNew.zip

Regards
Alan

@jrkerns
Copy link
Owner

jrkerns commented Apr 12, 2024

Ugh, you're right. How embarrassing 🤦. I'll adjust that in the next release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants