Source code for imagedata.transports.dicomtransport

"""Send DICOM images to DICOM Storage SCP
"""

# Copyright (c) 2019 Erling Andersen, Haukeland University Hospital, Bergen, Norway

import platform
import logging
import pynetdicom
from imagedata.transports.abstracttransport import AbstractTransport
from imagedata.transports import FunctionNotSupported


[docs]class AssociationNotEstablished(Exception): pass
[docs]class AssociationFailed(Exception): pass
[docs]class AETitleNotGiven(Exception): pass
[docs]class DicomTransport(AbstractTransport): """Send DICOM images to DICOM Storage SCP """ name = "dicom" description = "Send DICOM images to DICOM Storage SCP." authors = "Erling Andersen" version = "1.0.0" url = "www.helse-bergen.no" schemes = ["dicom"] def __init__(self, netloc=None, root=None, mode='r', read_directory_only=False, opts=None): super(DicomTransport, self).__init__(self.name, self.description, self.authors, self.version, self.url, self.schemes) self.read_directory_only = read_directory_only logging.debug("DicomTransport __init__ root: {} ({})".format(root, mode)) if mode[0] == 'r': raise FunctionNotSupported('DICOM receive is not supported.') if len(root) < 1: raise AETitleNotGiven('AE Title not given') if root[0] == '/': root = root[1:] self.__root = root self.__mode = mode # Open DICOM Storage Association as SCU if opts is None: opts = {} if 'calling_aet' in opts and opts['calling_aet'] is not None: local_ae = opts['calling_aet'] else: try: hostname = platform.node() local_ae = hostname.split('.')[0] except IndexError: local_ae = 'IMAGEDATA' logging.debug("DicomTransport __init__ calling AET: {}".format(local_ae)) self.__ae = pynetdicom.AE(ae_title=local_ae) self.__ae.requested_contexts = \ pynetdicom.StoragePresentationContexts host, port = netloc.split(':') port = int(port) self.__assoc = self.__ae.associate(host, port, ae_title=root) if self.__assoc.is_established: return else: raise AssociationNotEstablished( 'Association rejected, aborted or never connected')
[docs] def close(self): """Close the DICOM association transport """ self.__assoc.release()
[docs] def walk(self, top): """Generate the file names in a directory tree by walking the tree. Input: - top: starting point for walk (str) Return: - tuples of (root, dirs, files) """ # raise FunctionNotSupported('Walking the DICOM server is not supported.') return []
[docs] def isfile(self, path): """Return True if path is an existing regular file. """ raise FunctionNotSupported('Accessing the DICOM server is not supported.')
[docs] def open(self, path, mode='r'): """Extract a member from the archive as a file-like object. """ raise FunctionNotSupported('Open the DICOM server is not supported.')
[docs] def store(self, ds): """Store DICOM dataset using DICOM Storage SCU protocol. """ logging.debug('DicomTransport.store: send dataset') status = self.__assoc.send_c_store(ds) if status: logging.debug('DicomTransport.store: C-STORE request status: 0x{0:04x}'.format(status.Status)) else: raise AssociationFailed('C-STORE request status: 0x{0:04x}'.format(status.Status))