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

WIP: Adding DICOM-RT Dose grid summation w/ interpolation from DVHA code #164

Merged
merged 22 commits into from Aug 12, 2020
Merged

Conversation

cutright
Copy link
Contributor

Initial commit to add DICOM dose summation with interpolation as a part of dicompyler-core.

Copy link
Member

@bastula bastula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before merging we need:

  • Test cases
  • Documentation

@cutright
Copy link
Contributor Author

Some DICOM tags to update (per my conversation with @bastula ):

  • (3004, 0006) - Dose Comment (indication of direct or interpolated sum)
  • (0008, 0018) - SOPInstanceUID (with dicompyler UID prefix)
  • (0008, 0023) - Content Date
  • (0008, 0033) - Content Time

Possible to store SOPInstanceUIDs of source dose files?

Copy link
Member

@bastula bastula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good. Just waiting for the unit tests. I'll start helping with documentation.

dicompylercore/dose.py Outdated Show resolved Hide resolved
dicompylercore/dose.py Outdated Show resolved Hide resolved
dicompylercore/dose.py Outdated Show resolved Hide resolved
dicompylercore/dose.py Outdated Show resolved Hide resolved
@pep8speaks
Copy link

pep8speaks commented Aug 2, 2020

Hello @cutright! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻

Comment last updated at 2020-08-12 15:36:33 UTC

@cutright
Copy link
Contributor Author

cutright commented Aug 2, 2020

interp_by_block is currently failing the unit test

…mation

* Began using Black to format code with 79 character line length
* Doc string formatting updated to be consistent with other dicompyler-core files
* The other_factor parameter in add, direct_sum, and interp_sum was removed in favor of multiply() and * overload
Copy link
Contributor

@darcymason darcymason left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few thoughts/comments. These could be dealt with after the basic transfer to dicompyler-core is complete, but I thought I would put them out there and see whether you want to incorporate now or consider later.

dicompylercore/dose.py Show resolved Hide resolved
dicompylercore/dose.py Show resolved Hide resolved
dicompylercore/dose.py Show resolved Hide resolved
…mments

* Avoid extra list creation in DoseGrid.shape
* DoseGrid.scale raises UserWarning if non-uniform GridFrameOffsetVector detected
* Raise UserWarning in DoseGrid.add() if mismatched DoseSummationType, DoseType, DoseUnits, ImageOrientationPatient
@lgtm-com
Copy link

lgtm-com bot commented Aug 5, 2020

This pull request introduces 1 alert when merging a5bd38a into 13b492c - view on LGTM.com

new alerts:

  • 1 for Unused exception object

@cutright
Copy link
Contributor Author

cutright commented Aug 5, 2020

The unit tests are nearly complete. Let me know if any other tests should be added beyond the following:

  • dose.DoseGrid.get_ijk_points
  • dose.DoseGrid.set_dicom_tag_value
  • dose.add_dicom_sequence
  • dose.validate_attr_equality

I'm actually not sure of an appropriate way to test get_ijk_points. Any thoughts?

@bastula
Copy link
Member

bastula commented Aug 5, 2020

I'm actually not sure of an appropriate way to test get_ijk_points. Any thoughts?

Not sure if get_ijk_points needs testing but it's getting covered during execution. See: https://coveralls.io/builds/32566880/source?filename=dicompylercore/dose.py

The following properties/methods need coverage. I'm not sure if you're calling dose.points anywhere. If not, maybe it can be removed? Unless it's for internal debugging?

  • dose.points
  • dose.save_dcm
  • dose.update_dicom_tags

@cutright
Copy link
Contributor Author

cutright commented Aug 5, 2020 via email

@cutright
Copy link
Contributor Author

cutright commented Aug 6, 2020

Not sure if get_ijk_points needs testing but it's getting covered during execution. See: https://coveralls.io/builds/32566880/source?filename=dicompylercore/dose.py

The following properties/methods need coverage. I'm not sure if you're calling dose.points anywhere. If not, maybe it can be removed? Unless it's for internal debugging?

  • dose.points
  • dose.save_dcm
  • dose.update_dicom_tags

Testing for dose.save_dcm is now added, which I think covers dose.update_dicom_tags? All of the function calls in dose.update_dicom_tags are tested individually... unless pydicom.generate_uid should be tested too?

dose.points are not used. I'd be OK taking it out. I think I wrote it for other interpolation methods before settling on scipy.ndimage.map_coordinates.

@darcymason
Copy link
Contributor

One more question/thought - what happens if two dose grids are not covering the same spatial extent for interp_sum? E.g. if one's X position values range from -10 to + 10, and the other from 0 to +20, then (if I understand correctly), the second will be assumed to be zero from -10 to 0, and the second's dose from +10 to +20 will be ignored because it doesn't match the primary's grid. (?)

It seems to me the only reliable dose would be in the overlap region of the two grids. Of course it could be left to user code to check the two being added and reduce the spatial extent to the common region if desired. But it would be nice to at least document what happens for these situations.

Conversely, perhaps it could be allowed to direct sum two with different extents (but same spacing, etc.) and return only the common region?

And... again, if I'm being too much of a pain, any or all of this could be left for future work.

@cutright
Copy link
Contributor Author

cutright commented Aug 12, 2020

You are correct, extrapolated points are assumed to have a value of zero. We could easily allow dicompyler-core users to pass in mode and cval for the map_coordinates function (we already let them set order). The nearest mode might be more reasonable than the default of constant. See documentation here.

I agree it's a good idea to document this. I'll add that before we merge.

As far as cropping to the overlapping region, maybe let's gauge the need for it and leave that to another release? I think users should be responsible for having their dose grid boundaries extended to near-zero values. Maybe the more appropriate solution is to raise a warning if any boundary dose is greater than some user-editable threshold (e.g., 0.01% max default maybe)?

@cutright
Copy link
Contributor Author

I set the boundary dose threshold to 0.1% of maximum dose. I felt this was a better approach than involving prescription dose since that's not set consistently across vendors.

tests/test_dose.py Outdated Show resolved Hide resolved
tests/test_dose.py Outdated Show resolved Hide resolved
tests/test_dose.py Outdated Show resolved Hide resolved
Copy link
Contributor

@darcymason darcymason left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple more minor clean-up suggestions

tests/test_dose.py Show resolved Hide resolved
tests/test_dose.py Show resolved Hide resolved
@cutright
Copy link
Contributor Author

Thanks all of the feedback @darcymason
@bastula I think we might be ready for prime time now?

@bastula
Copy link
Member

bastula commented Aug 12, 2020

LGTM, some minor documentation changes, but I will do that in a separate commit.

@bastula bastula merged commit 7db59a4 into dicompyler:master Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants