pydicom / pynetdicom

A Python implementation of the DICOM networking protocol
https://pydicom.github.io/pynetdicom
MIT License
513 stars 180 forks source link

How to get studyinstance uid or dicom dataset in SCP EVT_RELEASE handler #702

Closed evergreen-shankar closed 3 years ago

evergreen-shankar commented 3 years ago

Hi, I am trying to cmove and in SCP side i have create cstore handler and to know when association is release added evt_released handler as well.

def on_association_released(event, message):
    LOGGER.info("Association Released - {}".format(message))

handlers=[
        (evt.EVT_C_STORE, handle_store, [output_folder]), 
        (evt.EVT_RELEASED, on_association_released, ['SCP EVT_RELEASED STUDY LEVEL'])
    ]

is there any way to get dicom dataset or study instance uid to know association released for which study inside above method on_association_released. Thanks in advance

Note: i don't have control over SCU as it is being requested from other places.

scaramallion commented 3 years ago

Not directly, there isn't. They're entirely unrelated events. You could try using the EVT_C_STORE handler to track the last received Study Instance UID and access that from the EVT_RELEASED handler?

evergreen-shankar commented 3 years ago

@scaramallion Below is the cstore handler code to save images. Could you please give me sample code how to get siuid in cstore and access from released handler. It will be helpful to me. thanks

def handle_store(event, storage_dir):
    """Handle EVT_C_STORE events."""

    ds = event.dataset
    affected_sop_instance_uid = event.request.AffectedSOPInstanceUID 
    try:
        storage_dir = os.path.join(storage_dir, ds.StudyInstanceUID)
        os.makedirs(storage_dir, exist_ok=True)
    except Exception as e:
        # Unable to create output dir, return failure status
        LOGGER.error("Unable to create output dir")
        LOGGER.error(traceback.format_exc())
        #print(type(e).__name__ + ": " + str(e))
        return 0xC001

    ds.file_meta = event.file_meta

    # Save the dataset using the SOP Instance UID as the filename
    filename = os.path.join(storage_dir, event.request.AffectedSOPInstanceUID)
    ds.save_as(filename, write_like_original=False)
    # Return a 'Success' status
    return 0x0000
scaramallion commented 3 years ago
from queue import LifoQueue

from pynetdicom import AE, evt, StoragePresentationContexts

def handle_store(evt, q):
    q.put(evt.dataset.StudyInstanceUID)
    return 0x0000

def handle_release(evt, q):
    # Add code to handle `q` being empty here
    print(q.get())

q = LifoQueue()

handlers = [
    (evt.EVT_C_STORE, handle_store, [q]), 
    (evt.EVT_RELEASE, handle_release, [q]), 
]

ae = AE()
ae.supported_contexts = StoragePresentationContexts
ae.start_server(('', 11112), evt_handlers=handlers)

This won't work as-is (all associations will use the same queue object and it doesn't get cleaned out), but it should give you the general idea

evergreen-shankar commented 3 years ago

@scaramallion Ok, I will check on. I have one question here that study will keep adding in queue in the sequence as requested from scu but few studies will have less images and it will finish early. so when will access in evt_released, will queue will return the same study which finished early?

evergreen-shankar commented 3 years ago

@scaramallion as you told, sometimes queue was returning the same study twice so used dictionary to add association native id as key and siuid as value , once released use the value then remove from dict. its working now. thanks

scaramallion commented 3 years ago

No problem