C-GET with success status even if sub-operations failed

155 views
Skip to first unread message

Kai Schlamp

unread,
Oct 19, 2020, 8:01:32 PM10/19/20
to Orthanc Users
Hi.

I am doing a C-GET (SCU) request with pynetdicom where I explicitly return an error code (0xA702) in the handler of the C-Store event. From what I read from the DICOM standard the C-GET should at least return a warning (0xB000), see C.4.3.1.4 Status as one or more sub-operations failed. I tried it with Orthanc as the SCP and it returns a success status (0x0000) even if all sub-operations failed. Is this the correct behavior? The strange thing is that our GE PACS has the same "problem".

Best regards,
Kai

Here is the code I use with pynetdicom:

<code>
from pydicom.dataset import Dataset
from pynetdicom import (
    AE,
    evt,
    build_role,
    debug_logger,
)
from pynetdicom.sop_class import (
    PatientRootQueryRetrieveInformationModelGet,
    CTImageStorage,
)

debug_logger()


def handle_store(event):
    data = event.dataset
    data.file_meta = event.file_meta
    print(data.PatientName)
    print("in here")
    # data.save_as(data.SOPInstanceUID, write_like_original=False)
    return 0xA702


handlers = [(evt.EVT_C_STORE, handle_store)]

ae = AE(ae_title="ADIT1")

ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
ae.add_requested_context(CTImageStorage)
role = build_role(CTImageStorage, scp_role=True, scu_role=True)

ds = Dataset()
ds.QueryRetrieveLevel = "IMAGE"
ds.PatientID = "10001"
ds.StudyInstanceUID = "1.2.840.113845.11.1000000001951524609.20200705182951.2689481"
ds.SeriesInstanceUID = "1.3.12.2.1107.5.1.4.66002.30000020070513455668000000609"
ds.SOPInstanceUID = "1.3.12.2.1107.5.1.4.66002.30000020070513455668000000610"

assoc = ae.associate("127.0.0.1", 7501, ext_neg=[role], evt_handlers=handlers)

if assoc.is_established:
    responses = assoc.send_c_get(ds, PatientRootQueryRetrieveInformationModelGet)
    for (status, identifier) in responses:
        print(status)
        if status:
            print("C-GET query status: 0x{0:04x}".format(status.Status))
        else:
            print("Connection timed out, was aborted or received invalid response")

    assoc.release()
else:
    print("Association rejected, aborted or never connected")
</code>

And the last part of the log:
<log>
I: Get SCP Result: 0x0000 (Success)
I: Sub-Operations Remaining: 0, Completed: 0, Failed: 1, Warning: 0
(0000, 0900) Status                              US: 0
(0000, 1021) Number of Completed Sub-operations  US: 0
(0000, 1022) Number of Failed Sub-operations     US: 1
(0000, 1023) Number of Warning Sub-operations    US: 0
C-GET query status: 0x0000
</log>

Sébastien Jodogne

unread,
Oct 20, 2020, 3:54:49 AM10/20/20
to Orthanc Users
Hello,

Thanks for reporting this issue. It should be fixed by the following changeset that is pending in the mainline (and that will be part of forthcoming 1.8.1 release):

With this changeset, here is the output of your pynetdicom script:

(0000, 0900) Status                              US: 42754
(0000, 1021) Number of Completed Sub-operations  US: 0
(0000, 1022) Number of Failed Sub-operations     US: 1
(0000, 1023) Number of Warning Sub-operations    US: 0
C-GET query status: 0xa702

HTH,
Sébastien-

Kai Schlamp

unread,
Oct 20, 2020, 7:47:21 AM10/20/20
to Orthanc Users
Hi Sébastien,

thanks for fix (it would be a dream if GE would fix our PACS in the hospital that fast ... or at all ;-)). Another little question... The DICOM standard says that the SCU may cancel the C-GET operation by issuing a C-GET-CANCEL request at any time during the processing of the C-GET request. What would be the correct way to cancel a C-GET? I tried to return 0xFE00 status from the handler, but this does not work with Orthanc (at least in the last released version). Or would be the correct way to send a C-CANCEL in the event handler (by using event.assoc.send_c_cancel)? (Sorry, not sure if this is more a pynetdicom question).

Best regards,
Kai

Kai Schlamp

unread,
Oct 21, 2020, 4:56:32 AM10/21/20
to Orthanc Users
I did some further tests and it seems sending a C-CANCEL is also not really respected by Orthanc during the C-STORE event (code below). But it seems that this is handled quite differently by the other PACS servers. Our GE PACS in the hospital just aborts the association (but only after some time). DCMTKs dcmqrscp on the other side seems to handle it correctly (see https://github.com/pydicom/pynetdicom/issues/553).

Here the code I tried (same as in the mentioned pynetdicom issue):
<code>
from pydicom.dataset import Dataset
from pynetdicom import (
    AE,
    evt,
    build_role,
    debug_logger,
)
from pynetdicom.sop_class import (
    PatientRootQueryRetrieveInformationModelGet,
    CTImageStorage,
)

debug_logger()

def handle_store(event):
    to_match = PatientRootQueryRetrieveInformationModelGet
    cxs = [cx for cx in assoc.accepted_contexts if cx.abstract_syntax == to_match]
    cx_id = cxs[0].context_id
    event.assoc.send_c_cancel(9999, cx_id)

    return 0xA702

handlers = [(evt.EVT_C_STORE, handle_store)]

ae = AE(ae_title="ADIT1")

ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
ae.add_requested_context(CTImageStorage)
role = build_role(CTImageStorage, scp_role=True, scu_role=True)

ds = Dataset()
ds.QueryRetrieveLevel = "STUDY"

ds.PatientID = "10001"
ds.StudyInstanceUID = "1.2.840.113845.11.1000000001951524609.20200705182951.2689481"

assoc = ae.associate("127.0.0.1", 7501, ext_neg=[role], evt_handlers=handlers)

if assoc.is_established:
    responses = assoc.send_c_get(
        ds,
        PatientRootQueryRetrieveInformationModelGet,
        msg_id=9999,

    )
    for (status, identifier) in responses:
        print(status)
        if status:
            print("C-GET query status: 0x{0:04x}".format(status.Status))
        else:
            print("Connection timed out, was aborted or received invalid response")

    assoc.release()
else:
    print("Association rejected, aborted or never connected")
</code>

Sébastien Jodogne

unread,
Oct 26, 2020, 7:26:55 AM10/26/20
to Orthanc Users
Hello,

I have done a full rewrite of the response and canceling in C-GET SCP:

This code is pending in the mainline, and will be part of forthcoming 1.8.1 release.

I have also created a suite of integration tests using pydicom to test C-GET SCP:

I hope this fixes all the issues you have reported. Feedback is more than welcome!

Regards,
Sébastien-

Sylvain Rouquette

unread,
Dec 11, 2020, 4:03:49 AM12/11/20
to Orthanc Users
Hello,

what would be the right action in that scenario?
Orthanc doesn't expose the DIMSE status when a job fails, and it seems the latest version of Orthanc won't retry automatically.

Sylvain Rouquette

unread,
Jan 22, 2021, 11:53:39 AM1/22/21
to Orthanc Users
We also have a problem recently and I don't know if it's related to this update.

We have a lot of errors regarding query/retrieve, where the PACS doesn't send some series. It wasn't happening with version 1.6.
Some PACS send a DIMSE, so we know that it's "normal" if we don't receive something in this case.
But some PACS don't send DIMSE, the job complete successfully, but we don't receive one of the series.
We request each series one by one.

Any ideas which part of the code would produce this error, so I can look into it?

Sébastien Jodogne

unread,
Jan 27, 2021, 11:53:41 AM1/27/21
to Orthanc Users
Hello,

We would need a minimal working example to understand what your problem is:

Unfortunately, if we can't reproduce your issue, we are not able to provide any useful help.

Note that Orthanc 1.9.0 will soon be released, maybe this new version could help.

Regards,
Sébastien-
Reply all
Reply to author
Forward
0 new messages