首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >pynetdicom C_GET失败,无演示上下文用于'CT图像存储‘已被对等成员接受为SCP角色

pynetdicom C_GET失败,无演示上下文用于'CT图像存储‘已被对等成员接受为SCP角色
EN

Stack Overflow用户
提问于 2020-12-29 00:05:28
回答 1查看 531关注 0票数 1

我是第一次尝试使用pynetdicom。我已经在我的PC上安装了它和ConQuest DICOM服务器。我能够让pynetdicom echo示例正常工作,但是当我尝试pynetdicom Storage SCU示例(https://pydicom.github.io/pynetdicom/stable/examples/storage.html)时,它失败了,出现以下错误:

代码语言:javascript
运行
复制
No presentation context for 'CT Image Storage' has been accepted by the peer for the SCP role

问题是,据我所知,该示例已经协商了CT图像存储上下文。以下是日志记录:

代码语言:javascript
运行
复制
pydev debugger: starting (pid: 39132)
I: Requesting Association
D: Request Parameters:
D: ======================= OUTGOING A-ASSOCIATE-RQ PDU ========================
D: Our Implementation Class UID:      1.2.826.0.1.3680043.9.3811.1.5.3
D: Our Implementation Version Name:   PYNETDICOM_153
D: Application Context Name:    1.2.840.10008.3.1.1.1
D: Calling Application Name:    PYNETDICOM      
D: Called Application Name:     ANY-SCP         
D: Our Max PDU Receive Size:    16382
D: Presentation Contexts:
D:   Context ID:        1 (Proposed)
D:     Abstract Syntax: =Patient Root Query/Retrieve Information Model - GET
D:     Proposed SCP/SCU Role: Default
D:     Proposed Transfer Syntaxes:
D:       =Implicit VR Little Endian
D:       =Explicit VR Little Endian
D:       =Deflated Explicit VR Little Endian
D:       =Explicit VR Big Endian
D:   Context ID:        3 (Proposed)
D:     Abstract Syntax: =CT Image Storage
D:     Proposed SCP/SCU Role: SCP
D:     Proposed Transfer Syntaxes:
D:       =Implicit VR Little Endian
D:       =Explicit VR Little Endian
D:       =Deflated Explicit VR Little Endian
D:       =Explicit VR Big Endian
D: Requested Extended Negotiation: None
D: Requested Common Extended Negotiation: None
D: Requested Asynchronous Operations Window Negotiation: None
D: Requested User Identity Negotiation: None
D: ========================== END A-ASSOCIATE-RQ PDU ==========================
D: Accept Parameters:
D: ======================= INCOMING A-ASSOCIATE-AC PDU ========================
D: Their Implementation Class UID:    1.2.826.0.1.3680043.2.135.1066.101
D: Their Implementation Version Name: 1.5.0/WIN32
D: Application Context Name:    1.2.840.10008.3.1.1.1
D: Calling Application Name:    PYNETDICOM      
D: Called Application Name:     ANY-SCP         
D: Their Max PDU Receive Size:  32768
D: Presentation Contexts:
D:   Context ID:        1 (Accepted)
D:     Abstract Syntax: =Patient Root Query/Retrieve Information Model - GET
D:     Accepted SCP/SCU Role: Default
D:     Accepted Transfer Syntax: =Implicit VR Little Endian
D:   Context ID:        3 (Accepted)
D:     Abstract Syntax: =CT Image Storage
D:     Accepted SCP/SCU Role: Default
D:     Accepted Transfer Syntax: =Implicit 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 ==========================
I: Association Accepted
I: Sending Get Request: MsgID 1
I: 
I: # Request Identifier
I: (0008,0052) CS [PATIENT]                                # 1 QueryRetrieveLevel
I: (0010,0010) PN [Wrench, Fred]                           # 1 PatientName
I: 
D: ========================== OUTGOING DIMSE MESSAGE ==========================
D: Message Type                  : C-GET RQ
D: Message ID                    : 1
D: Affected SOP Class UID        : Patient Root Query/Retrieve Information Model - GET
D: Identifier                    : Present
D: Priority                      : Low
D: ============================ END DIMSE MESSAGE =============================
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                    : 59647
D: Affected SOP Class UID        : CT Image Storage
D: Affected SOP Instance UID     : 1.3.6.1.4.1.33997.3232235894.19152.1608672548.1.1.1
D: Move Originator               : PYNETDICOM
D: Data Set                      : Present
D: Priority                      : Medium
D: ============================ END DIMSE MESSAGE =============================
E: No presentation context for 'CT Image Storage' has been accepted by the peer for the SCP role
D: pydicom.read_dataset() TransferSyntax="Little Endian Implicit"
D: ========================== INCOMING DIMSE MESSAGE ==========================
D: Message Type                  : C-GET RSP
D: Presentation Context ID       : 1
D: Message ID Being Responded To : 1
D: Affected SOP Class UID        : Patient Root Query/Retrieve Information Model - GET
D: Remaining Sub-operations      : 0
D: Completed Sub-operations      : 0
D: Failed Sub-operations         : 5
D: Warning Sub-operations        : 0
D: Identifier                    : None
D: Status                        : 0xFE00
D: ============================ END DIMSE MESSAGE =============================
D: 
I: Get SCP Result: 0xFE00 (Cancel)
I: Sub-Operations Remaining: 0, Completed: 0, Failed: 5, Warning: 0
D: pydicom.read_dataset() TransferSyntax="Little Endian Implicit"
C-GET query status: 0xfe00
I: Releasing Association

因此,日志显示CT Image Storage上下文已被接受,但带有SCP/SCU Role: Default,无论这意味着什么。当我通过pynetdicom处理进行调试时,我看到有一个CT上下文,但仅用于SCP角色。ConQuest显示它已经发送了DICOM文件,然后断开了连接。

当然还有代码(对pynetdicom示例只做了很小的改动:

代码语言:javascript
运行
复制
from pydicom.dataset import Dataset

from pynetdicom import AE, evt, build_role, debug_logger
from pynetdicom.sop_class import (
    PatientRootQueryRetrieveInformationModelGet,
    CTImageStorage
)

debug_logger()

# Implement the handler for evt.EVT_C_STORE
def handle_store(event):
    """Handle a C-STORE request event."""
    ds = event.dataset
    ds.file_meta = event.file_meta

    # Save the dataset using the SOP Instance UID as the filename
    ds.save_as(ds.SOPInstanceUID, write_like_original=False)

    # Return a 'Success' status
    return 0x0000

handlers = [(evt.EVT_C_STORE, handle_store)]

# Initialise the Application Entity
ae = AE()

# Add the requested presentation contexts (QR SCU)
ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
# Add the requested presentation context (Storage SCP)
ae.add_requested_context(CTImageStorage)

# Create an SCP/SCU Role Selection Negotiation item for CT Image Storage
role = build_role(CTImageStorage, scp_role=True)

# Create our Identifier (query) dataset
# We need to supply a Unique Key Attribute for each level above the
#   Query/Retrieve level
ds = Dataset()
ds.QueryRetrieveLevel = 'PATIENT'
ds.PatientName = 'Wrench, Fred'

# Associate with peer AE at IP 127.0.0.1 and port 11112
assoc = ae.associate('127.0.0.1', 5679, ext_neg=[role], evt_handlers=handlers)

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

    # Release the association
    assoc.release()
else:
    print('Association rejected, aborted or never connected')

我一遍又一遍地搜索,直到我的搜索者感到疼痛。

EN

回答 1

Stack Overflow用户

发布于 2021-01-04 06:50:33

在DICOM C-GET中,关联请求者必须发送为每个SOP类(SCU、SCP或SCU/SCP)建议特定角色的SCP/SCU role selection项。然后,关联接受者用它自己的角色选择项进行响应,这些项指示它接受哪个建议的角色。

问题似乎是,当Conquest充当关联接受者时,它不会发送任何预期的响应,因此pynetdicom假定您正在获取默认角色,因为这是DICOM标准在未收到响应时所要求的角色

如果协会-接受者未返回SCP/SCU角色选择项,则协会-请求者的角色应为SCU,协会-接受者的角色应为SCP

这在调试日志中可见,其中声明了接受的SCP/SCU角色(它将使用SCP而不是默认角色):

代码语言:javascript
运行
复制
D:   Context ID:        3 (Accepted)
D:     Abstract Syntax: =CT Image Storage
D:     Accepted SCP/SCU Role: Default
D:     Accepted Transfer Syntax: =Implicit VR Little Endian

这也是为什么您会收到一个异常,声明CT Image Storage没有接受任何SCP角色。

这看起来与this issue的问题相同,并且可以由forcing pynetdicom to treat the context以类似于支持SCP角色的方式解决:

代码语言:javascript
运行
复制
if assoc.is_established:
    for cx in assoc.accepted_contexts:
        cx._as_scp = True

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

    # Release the association
    assoc.release()
else:
    print('Association rejected, aborted or never connected')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65480481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档