dicompydicompynetdicom

How to get a list of all SOP instances that were not successfully retrieved during a C-MOVE call?


I'm using PyNetDicom to download (C-MOVE) images from a PACS server. I've implemented a SCU that sends C-MOVE requests to PACS, and a SCP that receives the C-STORE requests.

I download entire studies, meaning a few thousand DICOM images at a time. For some reason, I fail to receive some of them. The responses I get from the C-MOVE requests shows how many images were sent successfully and how many failed (as well as how many are in progress, plus any warnings).

I'd like to know not only how many failed, but also which ones failed, meaning I want to get the Failed SOP Instance UID List. This is the relevant part of my code:

# Not shown: Implementation of association (assoc) and making a dataset to query PACS (query_dataset)
responses = assoc.send_c_move(query_dataset, b'NAME_OF_STORAGE_SCP', StudyRootQueryRetrieveInformationModelMove)

for (status, identifier) in responses: 
    # This works
    remaining_operations = status.NumberOfRemainingOperations
    completed_operations = status.NumberOfCompletedOperations
    failed_operations = status.NumberOfFailedOperations
    warning_operations = status.NumberOfWarningOperations

    if identifier: 
        failed_UID_list = identifier.FailedSOPInstanceUIDList   # This does not work

This does not work, the identifier is always None, even when status.Status shows that the operation failed. Am I doing something wrong, or is the PACS I'm associating with not DICOM-compliant?


Solution

  • There is no way to get the identifier (SOP Instance UID) for failed instances when you are acting as C-MOVE SCU.

    1. You can either engage C-MOVE SCP to get the details/logs separately (out of DICOM).
    2. If the failure was on your C-STORE SCP, check the logs or details there. This may not be helpful if failure was on C-STORE SCU (other system), you need to engage them again.

    Not exactly a solution but, you can do the SERIES level query (C-FIND) before C-MOVE and get the count of instances (NumberOfSeriesRelatedInstances) to be pulled in advance. But this only gives a count; not the identifier. Same is true for STUDY and PATIENT level query.

    Storage Commitment may not be useful in this case because again, instances does not exist on your system; you do not know the identifiers.

    With IMAGE level query (C-FIND), you can pass on Series Instance UID and get the list of instances for that series. But, I have came across some systems those also force SOP Instance UID. If other system in your case supports this, you can do the following:

    To answer your comment:

    I missed the Failed SOP Instance UID List (0008,0058) tag.

    C.4.2.1.4.2 Response Identifier Structure
    The Failed SOP Instance UID List (0008,0058) specifies a list of UIDs of the C-STORE sub-operation SOP Instances for which this C-MOVE operation has failed. An Identifier in a C-MOVE response shall conditionally contain the Failed SOP Instance UID List (0008,0058) based on the C-MOVE response status value. If no C-STORE sub-operation failed, Failed SOP Instance UID List (0008,0058) is absent and therefore no Data Set shall be sent in the C-MOVE response.
    Reference: DICOM PS3.4 2020e - Service Class Specifications

    It appears that it should do your job. But frankly, I never came across (or did not noticed) the C-MOVE SCP that sends such list of failed instances. From your code, you are not receiving the data as well. I will recommend not to rely on it.