question on dvhcalc.calculate_dvh

103 views
Skip to first unread message

mg13...@gmail.com

unread,
Dec 5, 2020, 10:32:06 PM12/5/20
to dicompyler
I'm wondering if someone can explain why I'm getting a KeyError when I try to execute:

dvhcalc.calculate_dvh(structures[10], rtdose)

Traceback (most recent call last):

  File "<ipython-input-14-2bb86a182d26>", line 1, in <module>
    dvhcalc.calculate_dvh(structures[10], rtplan)

  File "/opt/anaconda3/lib/python3.7/site-packages/dicompylercore/dvhcalc.py", line 115, in calculate_dvh
    planes = collections.OrderedDict(sorted(iteritems(structure['planes'])))

KeyError: 'planes'

I'm defining:

structures = rtss.GetStructures()
rtdose = dicomparser.DicomParser('dose.dcm')
rtss = dicomparser.DicomParser('structures.dcm')

I don't understand why it's looking for a key of 'planes'.  

Thanks for any help.

Mike

Dan Cutright

unread,
Dec 5, 2020, 11:00:36 PM12/5/20
to dicompyler
calc_dvh does not take structures[10] by itself. You need to add planes and thickness keys.  If for some reason you really want calcdvh, take a look at the source code for get_dvh as an example:

I think perhaps you want dvhcalc.get_dvh instead?

So something like this should work:
dvh = dvhcalc.get_dvh(rtss, rtdose, 10)

Mike Grams

unread,
Dec 6, 2020, 9:33:38 AM12/6/20
to dicom...@googlegroups.com
Thank you Dan. I am actually just trying to better understand dicompyler and what it can do, so I was working through the "readthedocs" pdf and also looking at the source code when I got stuck.  My understanding is calculate_dvh will get you a differential DVH as opposed to get_dvh which gives a cumulative one.  It's no big deal because  it appears I can calculate and plot a differential DVH with this:

gtv_DVH = rtdose.GetDVHs()[9]
gtv_DVH.name = 'GTV'
gtv_DVH.rx_dose = 20
gtv_DVH.absolute_dose().relative_volume.differential.plot()

I guess my question now is how should I have interpreted the following information on calculate_dvh from the readthedocs file?  To my untrained eye, it would suggest it does not require planes and thickness keys. 
image.png

Furthermore, 
b = dvhcalc.get_dvh('structures.dcm', 'dose.dcm', 9)
b.plot()

Works absolutely fine, but the structure and dose parameters are also slightly different when compared to calculate_dvh:
image.png

So essentially my question is based on how I can learn to better interpret the readthedocs.

Thanks again for helping.  I appreciate it.

Mike

--
-- You received this message because you are subscribed to the Google Groups dicompyler group. To post to this group, send email to dicom...@googlegroups.com. To unsubscribe from this group, send email to dicompyler+...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/dicompyler?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "dicompyler" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/dicompyler/Peil-ziqX_c/unsubscribe.
To unsubscribe from this group and all its topics, send an email to dicompyler+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dicompyler/93c2a604-ae90-44cb-a8f9-788c06318096n%40googlegroups.com.

Dan Cutright

unread,
Dec 6, 2020, 9:43:07 AM12/6/20
to dicompyler
Honestly, I've never tried working with calculate_dvh directly, so I'll leave that for Aditya.  But my hunch is that you just found a gap in the documentation / docstring.

Aditya Panchal

unread,
Dec 7, 2020, 1:09:15 AM12/7/20
to dicom...@googlegroups.com
Hi Mike,

These are all great questions. Thank you for looking into this. Most end users (as Dan alluded to) of the dicompyler-core library will be using get_dvh() to calculate their DVHs as it has all the parameters for configuring your DVH calculation. calculate_dvh() is an internal function called by get_dvh() and typically won't be called by the end user.

I plan to rewrite the docstring for calculate_dvh() to make that more clear. Also one thing that may have come up in your case, is that the documentation sorts the functions alphabetically. I will make a change so that it lists the functions and methods in source code order. That way, get_dvh() will show up at the beginning of the dvhcalc module.

Regarding differential and cumulative DVHs, you are correct in your statement that you can just take the output of get_dvh() and apply the attribute differential to it. These are the DVH class attributes that you can use to transform the DVH into different formats.

Let me know if you have any other questions or need clarification.

Thanks,

Adit



You received this message because you are subscribed to the Google Groups "dicompyler" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dicompyler+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dicompyler/53ecf2c1-46c5-484b-9ea1-b3104534d06cn%40googlegroups.com.

Aditya Panchal

unread,
Dec 7, 2020, 10:43:17 PM12/7/20
to dicom...@googlegroups.com
A follow up to this thread. In addition to the documentation changes, calculate_dvh() was renamed to _calculate_dvh() to better indicate that it is an internal function. It will no longer show up in the documentation, but is still present (and documented) in the source. As of the latest push to master, this is the case. For those of you still using calculate_dvh() directly, no functionality was changed, but you will have to rename your function calls in 0.5.6 or later.

Hope this reduces confusion.

Mike Grams

unread,
Dec 8, 2020, 11:44:09 AM12/8/20
to dicom...@googlegroups.com
Thank you Adit, very helpful and I appreciate it. Are there other functions that might benefit from similar clarification?  For example, I’ve had my eye on dvhcalc.get_contour_mask for a particular application I have but think I will probably run into a similar problem if I try to use it directly. In truth, I hacked something together to get contour masks anyway but if there’s a quick and easy way to do this with dicompyler that would be great. 

Thanks again. 

Mike

Aditya Panchal

unread,
Dec 8, 2020, 10:21:14 PM12/8/20
to dicom...@googlegroups.com
Not a problem Mike. I think the remaining functions could have better docstrings created to show what each argument represents as well as the return value. A lot of the functions were created back when dicompyler was originally written and only new functions (i.e. DVH interpolation) had fully fleshed out docstrings.

I'll cite this thread on GH as there is already an issue to improve documentation.

Regarding dvhcalc.get_contour_mask - it just takes a numpy.meshgrid of the x,y doseplane coordinates and an individual contour sequence and creates a mask. dd is just a dictionary from the result of dicomparser.GetDoseData() on the RT Dose file. Ultimately a lot of these functions could be generalized for contour masking on any dose or image plane, but currently it's sitting in dvhcalc. There was a request on here before for a CT image histogram, so definitely this method could be used for that as well.

Hope that's helpful.

Reply all
Reply to author
Forward
0 new messages