Create RDSR from Toshiba CT dose summary images and import
Create RDSR from Toshiba CT dose summary images, update the information using tags in associated images, then import in to OpenREM.
Comments (82)
-
reporter -
reporter Initial commit for code to create RDSR from Toshiba dose summary image, and then update it with additional information contained in the associated images. Currently the code will create an RDSR and then add acquisition protocol names to each acquisition if they are missing from the intial RDSR but available in the CT image tags. References issue
#480→ <<cset fc57a19ccca6>>
-
reporter @edmcdonagh. Apologies: at first I created this branch from the wrong starting branch (a 0.5 version), so I've had to remove it, and then add it again.
-
That would explain the odd message I had from QuantifiedCode referring to commits I couldn't find!
-
reporter Trying to update pitch, but the numeric value is in the wrong place at the moment. References issue
#480→ <<cset 24787c25b826>>
-
reporter The pitch should have this construction (from a Siemens RDSR):
--------- (0040, a010) Relationship Type CS: 'CONTAINS' (0040, a040) Value Type CS: 'NUM' (0040, a043) Concept Name Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '113828' (0008, 0102) Coding Scheme Designator SH: 'DCM' (0008, 0104) Code Meaning LO: 'Pitch Factor' --------- (0040, a300) Measured Value Sequence 1 item(s) ---- (0040, 08ea) Measurement Units Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '{ratio}' (0008, 0102) Coding Scheme Designator SH: 'UCUM' (0008, 0103) Coding Scheme Version SH: '1.4' (0008, 0104) Code Meaning LO: 'ratio' --------- (0040, a30a) Numeric Value DS: '0.6' --------- ---------
My code currently produces this:
--------- (0040, a010) Relationship Type CS: 'CONTAINS' (0040, a040) Value Type CS: 'NUM' (0040, a043) Concept Name Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '113828' (0008, 0102) Coding Scheme Designator SH: 'DCM' (0008, 0104) Code Meaning LO: 'Pitch Factor' --------- (0040, a300) Measured Value Sequence 1 item(s) ---- (0040, 08ea) Measurement Units Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '{ratio}' (0008, 0102) Coding Scheme Designator SH: 'UCUM' (0008, 0103) Coding Scheme Version SH: '1.4' (0008, 0104) Code Meaning LO: 'ratio' --------- --------- (0040, a30a) Numeric Value DS: '0.844' ---------
The Numeric Value isn't in the right place. @edmcdonagh, can you help?
-
What about:
pitch_value = Dataset() pitch_value.NumericValue = 0.6 measured_value_sequence = Sequence([measurement_units_container, pitch_value])
-
reporter That modifies things a bit, but it's still not right, as there's now 2 items in the Measured Value Sequence...
--------- (0040, a010) Relationship Type CS: 'CONTAINS' (0040, a040) Value Type CS: 'NUM' (0040, a043) Concept Name Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '113828' (0008, 0102) Coding Scheme Designator SH: 'DCM' (0008, 0104) Code Meaning LO: 'Pitch Factor' --------- (0040, a300) Measured Value Sequence 2 item(s) ---- (0040, 08ea) Measurement Units Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '{ratio}' (0008, 0102) Coding Scheme Designator SH: 'UCUM' (0008, 0103) Coding Scheme Version SH: '1.4' (0008, 0104) Code Meaning LO: 'ratio' --------- --------- (0040, a30a) Numeric Value DS: '0.844' --------- ---------
-
Your first attempt was nearly right. Just the NumericValue was one level too deep:
coding.CodeValue = '113828' coding.CodingSchemeDesignator = "DCM" coding.CodeMeaning = "Pitch Factor" # Create the second inner coding bit coding2.CodeValue = '{ratio}' coding2.CodingSchemeDesignator = "UCUM" coding2.CodingSchemeVersion = "1.4" coding2.CodeMeaning = "ratio" measurement_units_container = Dataset() measurement_units_container.MeasurementUnitsCodeSequence = Sequence([coding2]) # next line is the one that is changed measurement_units_container.NumericValue = val measured_value_sequence = Sequence([measurement_units_container]) # Create the outer container bit pitch_container = Dataset() pitch_container.RelationshipType = "CONTAINS" pitch_container.ValueType = "NUM" # Add the coding sequence into the container. # Sequences are lists. pitch_container.ConceptNameCodeSequence = Sequence([coding]) pitch_container.MeasuredValueSequence = measured_value_sequence container2b.ContentSequence.append(pitch_container)
-
If I've made the same corrections in the code above as I did in my freehand shell version, you should get the same as I did:
>>> pitch_container (0040, a010) Relationship Type CS: 'CONTAINS' (0040, a040) Value Type CS: 'NUM' (0040, a043) Concept Name Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '113828' (0008, 0102) Coding Scheme Designator SH: 'DCM' (0008, 0104) Code Meaning LO: 'Pitch Factor' --------- (0040, a300) Measured Value Sequence 1 item(s) ---- (0040, 08ea) Measurement Units Code Sequence 1 item(s) ---- (0008, 0100) Code Value SH: '{ratio}' (0008, 0102) Coding Scheme Designator SH: 'UCUM' (0008, 0103) Coding Scheme Version SH: '1.4' (0008, 0104) Code Meaning LO: 'ratio' --------- (0040, a30a) Numeric Value DS: '0.844' ---------
-
reporter Pitch value is now added if it is not present in the initial RDSR but is available from the image tag data. References issue
#480→ <<cset a8fab866d21e>>
-
reporter @edmcdonagh, thanks for your help with the pitch.
-
reporter I'll add a "CT X-Ray Source Parameters" container to each "CT Acquisition Parameters" container next so that I can add kVp, exposure time per rotation etc. to the created RDSR.
-
Good stuff
-
reporter kVp is now added if it is not present in the initial RDSR but is available from the image tag data. References issue
#480→ <<cset 178b514a5f20>>
-
reporter Modified the file layout so that it can be called using python.
Added import in to OpenREM.
Adding the extra study information doesn't seem to work at the moment.
References issue
#480→ <<cset 6271254faa42>>
-
reporter Updated how study-level information is found in the images and then used to update the initial RDSR. Need to see how this works with a clinical scan. References issue
#480.→ <<cset cf10b607d783>>
-
reporter Need to store the folders for java.exe, dcmtk and pixelmed.jar somewhere in the system so that I don't have to keep changing them from home to work... Perhaps in local_settings.py?
-
Either in
local_settings.py
or in a singleton in the database. Probably easier to put it inlocal_settings.py
for now and we can reconsider later. -
reporter Put paths to various tools in local_settings.py.example. Import these into the Toshiba RDSR creation routine. Should make it easier when moving from one system to the next, and I think a good idea to keep the configuration in one place. References issue
#480.→ <<cset faef3f382d06>>
-
reporter kVp now added to RDSR objects created from Toshiba CT scan images and dose summary files. References issue
#480and issue→ <<cset 6c12eba8879f>>
-
reporter Requested procedure now obtained from two possible locations in the image data. Uniqueness of acquisitions improved by combining acquisition number with acquisition time. Included the Lua script that I am using to run this routine. Conquest is configured to run the script using an import converter like this:
ImportModality4 = CT ImportConverter4 = process patient after 0 by openrem_import_ct.lua %p::%V0008,0070::%V0008,1090::%V0018,1020::%V0008,1010;
→ <<cset 9de77fc4ba9e>>
-
reporter I need to obtain the contents of "SoftwareVersions" (0018,1020) from the CT images and add it to the appropriate place in the RDSR.
-
reporter Updated routine to create RDSR from Toshiba dose summary image. This is now called from a script in the
Scripts
Python folder. The routine itself is now run using celery by including @shared_task before the routine. This fixes a problem that I was having where importing Toshiba CT data using this routine blocked the celery task queue. References issue#480. I've also added an example dicom.ini file for Conquest, together with some Lua scripts that I am using to import data. I am now using Lua scripts in preference to Windows batch files. The current scripts contain some Windows-specific things, so aren't completely general at the moment. This references issue#150→ <<cset 2bbfc1f23d02>>
-
reporter Added the Toshiba CT rdsr creation routine to the extractor init.py file. Fixed an error in the extractor code. Made python line in script the same as other extractors. References issue
#480→ <<cset 5256f5f64b81>>
-
reporter Small updates to Toshiba CT RDSR creation. Updated example dicom.ini files and associated Lua scripts. Also added example Windows PowerShell scripts that I am using to schedule query-retrieve from PACS. Also added example batch file that runs celery. Updated celery settings in settings.py to reflect what I am using successfully here. References issue
#480→ <<cset 7cc8190761ce>>
-
reporter Reminder for myself:
- Add code to set whether to delete the folder of images or not, much like for the other extractors
- Remove Making explicit VR little endian part (isn't needed, slows things down)
- Remove DICOMDIR (isn't needed, slows things down)
- Check insertion of kVp data in to the initial RDSR
-
reporter Removed two stages of the extractor as they are not needed: creating DICOMDIR, which in turn required all DICOM objects to be explicit VR little endian. This also reduces the time required to create the RDSR. I've also altered the method of inserting the kVp, as I found that the previous method failed when encountering multiple axial acquisitions that use the same exposure factors. References issue
#480→ <<cset 4bc2ee66b23a>>
-
reporter This extractor also works for GE LightSpeed Plus studies that include a dose summary image, although no acquisition protocol names are obtained.
-
Cool. Does it not get any protocol names? The pixelmed routine normally can get the overarching protocol name, like 5.13 abdomen blah blah, but not the series group names.
-
reporter Hi Ed. For the LightSpeed Plus in OpenREM I have:
- Accession number
- Study date and time
- Study description
- Requested procedure (same as study description in this case)
- Patient age
- Hospital
- Scanner make and model
- Study UID
- Total number of events
- Total DLP
For each scan component I have:
- Type
- CTDIvol
- DLP
- Scanning length
-
reporter Added extraction of exposure time per rotation. References issue
#480→ <<cset edf33f10274c>>
-
reporter Removed some split lines and uncommented out the
rmtree
command. References issue#480→ <<cset 08400c6ba296>>
-
reporter Added x-ray modulation type, nominal single collimation width and nominal total collimation width to the extractor. References issue
#480→ <<cset 41d61a19de0e>>
-
reporter Added debug logging for the Toshiba RDSR creation extractor and removed quite a few
print
statements. References issue#480→ <<cset fe16e579f3d8>>
-
reporter Fixing error - didn't change name of
store_file
toextractor_file
insettings.py
. References issue#480→ <<cset 5e311897450c>>
-
reporter Updated Toshiba RDSR creation routine to combine multiple RDSRs together if there is more than one dose summary in the study. References issue
#480→ <<cset 055ec10621d5>>
-
reporter I need to update the code that checks if there is more than one dose summary per study. At the moment it looks for multiple instances of series number 9000 (used by one of our Toshiba scanners). However, another of our Toshiba scanners uses series number 1000 for the dose summary objects, and a third scanner uses a series number in the normal range. This third system always has the text "SUMMARY" as part of the SeriesDescription, and this combined with an SOPClassUID of 1.2.840.10008.5.1.4.1.1.7 may make it identifiable as a dose summary.
-
reporter Added SoftwareVersions and DeviceSerialNumber to the created RDSR. Now looking for Secondary Capture Image Storage objects when seeing if there is more than one study contained within each study uid. References issue
#480→ <<cset faad557c6588>>
-
reporter Added code to check that the secondary capture object is a dose summary, and not some other type of secondary capture. I've done this because some virtual colonoscopy studies include surface rendered snapshots as secondary capture. References issue
#480→ <<cset b516d486edd5>>
-
First pass at a solution for @dplatten and ref
#480. Need to work out how to test it. Refs#546→ <<cset 49792cceb3b0>>
-
Hi @dplatten. Just wanted to check if this is still in future, or if it should be tidied up and documented for 0.8.0?
-
reporter I think it should be in 0.8.
-
- changed milestone to 0.8.0
-
reporter Tidied up tbe Toshiba extractor a little. No functional changes. References issue
#480→ <<cset 729f232a8367>>
-
reporter Started to update documentation for the new Toshiba RDSR creation extractor. Need to add info on how to install dcmtk, java.exe and pixelmed.jar. References issue
#480→ <<cset 59326ecf883c>>
-
-
reporter Updated documentation a little to fix some layout issues. Need to add info on how to install dcmtk, java.exe and pixelmed.jar. References issue
#480→ <<cset 0064415f6501>>
-
reporter Added documentation for java, dcmtk and pixelmed.jar. References issue
#480→ <<cset d0338e95a978>>
-
reporter Correcting typo in pixelmed.jar link. References issue
#480→ <<cset d950e2409060>>
-
reporter Added documentation for using a Windows PowerShell script to schedule a query-retrieve. References issue
#480→ <<cset 0aa91fc9a02d>>
-
reporter Revising PowerShell wording. References issue
#480→ <<cset e93621f0350f>>
-
reporter Amending Conquest dicom.ini file to use LittleEndianExplicit for file storage. References issue
#480→ <<cset 6a47a1381d2c>>
-
reporter - changed status to resolved
This is now working as I would like it to.
-
reporter Addressing some codacy issues. References issue
#480→ <<cset 61f0b9802aef>>
-
I need to think how these files are delivered to the user - I don't think I usually keep the
stuff
folder in the bundle that gets uploaded to pypi... -
I haven't reviewed your docs for this by the way - maybe you've covered it - apologies if you have!
-
reporter I've not covered anything about what's in the
stuff
folder. -
- changed status to open
Reopen until the pull request is merged. I need to review the docs and make sure it makes sense to me.
-
Fixing some of the codacy complaints. Refs
#480→ <<cset b4d0e09c1cc2>>
-
Fixing some of the codacy complaints. Refs
#480→ <<cset 6a75dac4eb8a>>
-
Adding some more to the docs. Refs
#480→ <<cset 4e3712a390d7>>
-
Correcting links and italics. Refs
#480→ <<cset 3346e231713a>>
-
Added entry to release docs. Refs
#480→ <<cset 1f9ae7687d0d>>
-
Adding in hrefs. Refs
#480→ <<cset feacad4fd1dc>>
-
Added some linux instructions to the release version initially. Refs
#480→ <<cset d0f1bf7471b6>>
-
MInor corrections and copying across to the install doc. Refs
#480→ <<cset 455647824f8f>>
-
Adding comment to suppress Codacy/Bandit from flagging this as an issue. Refs
#480→ <<cset 699c6673fc5d>>
-
Adding usual copyright statement. Refs
#480→ <<cset a17caf5db315>>
-
No real change - trying to get PR to update. Refs
#480→ <<cset 79a50c4be3b4>>
-
Adding nosec to other calls. Refs
#480→ <<cset c8f35f436879>>
-
Not sure how the # nosec lost a c... Refs
#480→ <<cset 8c744ad1f683>>
-
- changed status to resolved
Merged in issue480ToshibaRDSRCreation (pull request #123)
Issue480ToshibaRDSRCreation
Fixes
#480. Refs#552Approved-by: Ed McDonagh ed@mcdonagh.org.uk→ <<cset d644cc567a6f>>
-
I keep getting a
openrem_extractor.log
file created in the openrem folder - and I can't see why. Any ideas? -
reporter Started to document Conquest configuration using lua, including forwarding Toshiba CT data to the RDSR creation importer. References issue
#480→ <<cset b8df0e4a4016>>
-
reporter Some minor updates to the Conquest configuration document. References issue
#480→ <<cset 0246acb38c9c>>
-
reporter Some minor updates to the Conquest configuration document. References issue
#480→ <<cset ec6233414697>>
-
Thanks for doing this @dplatten. One you might want to edit:
"The above script depends on openrem_string_split are"
-
reporter Minor correction to Conquest documentation. References issue
#480→ <<cset dd6faeae9cd2>>
-
reporter Updated Conquest configuration document and added new document containing a full example dicom.ini file. References issue
#480→ <<cset 404b3e117d7c>>
-
reporter Added link to example Conquest dicom.ini file doc to the netdicom doc. References issue
#480→ <<cset 472041b11403>>
-
reporter Correcting link. References issue
#480→ <<cset 49c777e21d48>>
- Log in to comment
Initial commit for code to create RDSR from Toshiba dose summary image, and then update it with additional information contained in the associated images. Currently the code will create an RDSR and then add acquisition protocol names to each acquisition if they are missing from the intial RDSR but available in the CT image tags. References issue
#480→ <<cset 174f83b33f47>>