@pieper: I’d say pynetdicom is as mature as pydicom and closely related to it. The documentation is excellent, the code actively maintained, and a good release cycle.
The least destructive way I can see to add basic pynetdicom c_store support is to:
- Change line 41 of Modules > Scripted > DICOMLib > DICOMSendDialog.py to:
- Insert the following after line 388 of Modules > Scripted > DICOMLib > DICOMProcesses.py (i.e. in the send function of the DICOMSender class as an additional protocol selection choice):
elif self.protocol == "pynetdicom":
logging.info("Installing pynetdicom for sending DICOM")
from pydicom import dcmread
from pynetdicom import (AE, StoragePresentationContexts)
remoteAE = AE()
remoteAE.requested_contexts = StoragePresentationContexts
assoc = remoteAE.associate(self.destinationUrl.host(), self.destinationUrl.port())
if not assoc.is_established:
raise UserWarning('Could not establish SCU association')
for file in self.files:
if not self.progressCallback("Sending %s to %s using %s" % (file, self.destinationUrl.toString(), self.protocol)):
raise UserWarning("Sending was cancelled, upload is incomplete.")
ds = dcmread(file)
assoc.release() # Release after the for loop cycles through all of the files
Alternatively the contents of the pynetdicom elif block could simply replace the contents of the “DIMSE” else block and the original selector of “DIMSE”, “DICOMWeb” could remain unchanged.
StoragePresentationContexts is a prebuilt list of presentation contexts for the first 128 SOP classes, including SegmentationStorage and confers to the AE the ability to negotiate storage of objects of those classes.
dcmtk store_scu only supports 64 SOP classes without the optional config file suggested above.
I don’t have a Slicer dev environment set up nor the developer chops to do it, but am happy to send the modified DICOMProcesses.py and DICOMSendDIalog.py to any willing devs.