Add DICOM support for volume additions#398
Conversation
|
nice!! before i review just quickly:
|
d6321e1 to
3a5702e
Compare
I added the data source to the PR description. Also, I reworded the comits. |
|
Thanks for sharing data sources. Based on the readme at https://github.com/pydicom/pydicom/tree/a68344bff1caaa4a5ea17946b233ae07f02056e4/src/pydicom/data/test_files it seems we are free to use the data files here. |
ebrahimebrahim
left a comment
There was a problem hiding this comment.
Great work! We just need to work the affine into this now and not later, because the wrong affine can be dangerous.
Note to self: in the next review test this in SlicerOpenLIFU
There was a problem hiding this comment.
Thanks for the updates
I tried testing this in SlicerOpenLIFU itself, and it looks like something is off with the affine:
Here's how I got that screenshot:
- Used Slicer to convert the nifti volume in our dvc data to DICOM. Here is the resulting dicom (shared with @arhowe00)
- Made a tweak to SlicerOpenLIFU to enable specifying a folder rather than a file when adding volume. (Later we will have to come up with a way to allow both)
- Used the add volume dialog in SlicerOpenLIFU to add a volume. This internally calls
Database.write_volumeso I could have just done that instead of using SlicerOpenLIFU. - Load the volume (which has now been converted to NIFTI) back into Slicer
The right affine metadata is definitely there in the dicom file, because when I used Slicer's dicom importer it came out matching the original nifti.
So something must be wrong with the affine handling in the dicom-to-nifti conversion in this PR
Nice catch! I did not rotate the affine from LPS to RAS in patient-space, which should be done when loading the volume as nifti. I fixed this and tested it, in CLI, I also improved the tests to be more flushed out. |
4013d1f to
23909aa
Compare
ebrahimebrahim
left a comment
There was a problem hiding this comment.
The fix worked! I added comments and you can feel free to deal with or ignore them, then please go ahead and hit "rebase and merge" when you are happy. 😄
- Add pydicom dependency to handle DICOM input files - Implement is_dicom_file_or_directory() to detect DICOM files/directories - Implement convert_dicom_to_nifti() for format conversion - Update write_volume() to automatically convert DICOM to NIfTI - Add comprehensive tests and testing data - A DICOM series containing 2 slices (`tests/resources/dicom_series/`) - A DICOM file containing a CT (`tests/resources/CT_small.dcm`)
…396) - Move is_dicom_file_or_directory() and convert_dicom_to_nifti() from database.py to new util/volume_conversion.py - Implement extract_affine_from_dicom() using ImageOrientationPatient, ImagePositionPatient, and PixelSpacing from DICOM headers - Create tests/test_volume_conversion.py with unit tests for conversion functions - Remove conversion function tests from test_database.py, keep integration tests for write_volume - Update imports in database.py and test_database.py
``` nox > pylint openlifu ************* Module openlifu.db.database Warning: .nox/pylint/lib/python3.12/site-packages/openlifu/db/database.py:396:24: R1732: Consider using 'with' for resource-allocating operations (consider-using-with) ************* Module openlifu.nav.photoscan Warning: .nox/pylint/lib/python3.12/site-packages/openlifu/nav/photoscan.py:195:13: I1101: Module 'OpenEXR' has no 'File' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) ```
Renamed 'dicom_dataset' and 'ds' to 'header' throughout for better readability. Added complete type annotation for dicom_slices parameter and clarified in docstring that header is a pydicom.Dataset containing DICOM metadata tags.
928e68d to
e9157a5
Compare
Closes #396
Dicom series and dicom files are converted to nifti format and stored in the database.
Data
The added test data comes from the data used for pydicom's unit testing:
CT_small.dcm:
dicom_series files (6293 and 6924):