Search code examples
dicompydicompynetdicom

Receive private SOPClassUID images in pydicom


I am trying to accept all the presentation contexts in the association negotiation.

After adding the abstract syntax to the supported context, the association is getting aborted. Logs -

D: Accept Parameters:
D: ======================= OUTGOING A-ASSOCIATE-AC PDU ========================
D: Our Implementation Class UID:      1.2.826.0.1.3680043.9.3811.2.0.2
D: Our Implementation Version Name:   PYNETDICOM_202
D: Application Context Name:    1.2.840.10008.3.1.1.1
D: Responding Application Name: resp. AE Title
D: Our Max PDU Receive Size:    65536
D: Presentation Contexts:
D:   Context ID:        1 (Accepted)
D:     Abstract Syntax: =1.3.46.670589.2.5.1.1
D:     Accepted SCP/SCU Role: Default
D:     Accepted Transfer Syntax: =Implicit VR Little Endian
D:   Context ID:        3 (Accepted)
D:     Abstract Syntax: =1.3.46.670589.2.5.1.1
D:     Accepted SCP/SCU Role: Default
D:     Accepted Transfer Syntax: =Explicit VR Little Endian
D: Accepted Extended Negotiation: None
D: Accepted Asynchronous Operations Window Negotiation: None
D: User Identity Negotiation Response: None
D: ========================== END A-ASSOCIATE-AC PDU ==========================
D: pydicom.read_dataset() TransferSyntax="Little Endian Implicit"
I: Received Store Request
D: ========================== INCOMING DIMSE MESSAGE ==========================
D: Message Type                  : C-STORE RQ
D: Presentation Context ID       : 3
D: Message ID                    : 1
D: Affected SOP Class UID        : 1.3.46.670589.2.5.1.1
D: Affected SOP Instance UID     : 1.2.840.113663.1500.1.441344181.10.1.20230914.95415.944
D: Data Set                      : Present
D: Priority                      : Medium
D: ============================ END DIMSE MESSAGE =============================
E: No supported service class available for the SOP Class UID '1.3.46.670589.2.5.1.1'
I: Aborting Association
D: Abort Parameters:
D: =========================== OUTGOING A-ABORT PDU ===========================
D: Abort Source: DUL service-user
D: Abort Reason: (no value available)
D: ============================= END A-ABORT PDU ==============================

Tried:

ae.add_requested_context(UID(""))

ae.add_requested_context(UID(""),ALL_TRANSFER_SYNTAXES)

ae.add_supported_context(UID(""))

ae.add_supported_context(UID(""), ALL_TRANSFER_SYNTAXES)

How do I accept images of all SOPClassUID s and write them to disk?


Solution

  • There are currently two ways to use private SOP classes with pynetdicom:

    1. Use _config.UNRESTRICTED_STORAGE_SERVICE.
    2. Patch the function as below:
    from pynetdicom import sop_class
    from pynetdicom.service_class import StorageServiceClass
    
    original_func = sop_class.uid_to_service_class
    
    def my_translator(uid):
        if uid == "1.3.46.670589.2.5.1.1":
            return StorageServiceClass
    
        return original_func(uid)
    
    sop_class.uid_to_service_class = my_translator
    

    In v2.1 you'll be able to use register_uid() instead:

    from pynetdicom import register_uid
    from pynetdicom.service_class import StorageServiceClass
    
    register_uid("1.3.46.670589.2.5.1.1", "MySOPClassName", StorageServiceClass)
    
    # and then either use the UID string directly, or import via
    from pynetdicom.sop_class import MySOPClassName