如何获取在 C-MOVE 调用期间未成功检索的所有 SOP 实例的列表?

问题描述

我正在使用 PyNetDicom 从 PACS 服务器下载 (C-MOVE) 图像。我已经实现了一个向 PACS 发送 C-MOVE 请求的 SCU,以及一个接收 C-STORE 请求的 SCP。

我下载了整个研究,即一次下载几千张 DICOM 图像。出于某种原因,我未能收到其中的一些。我从 C-MOVE 请求中得到的响应显示了成功发送的图像数量和失败的图像数量(以及正在进行的图像数量以及任何警告)。

我不仅想知道有多少失败,还想知道哪些失败,这意味着我想获得失败的 SOP 实例 UID 列表。这是我的代码的相关部分:

# 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

这不起作用,标识符总是 None,即使 status.Status 显示操作失败。是我做错了什么,还是我关联的 PACS 不符合 DICOM 标准?

解决方法

当您充当 C-MOVE SCU 时,无法获取失败实例的标识符(SOP 实例 UID)。

  1. 您可以使用 C-MOVE SCP 单独获取详细信息/日志(从 DICOM 中获取)。
  2. 如果故障出在您的 C-STORE SCP,请检查那里的日志或详细信息。如果 C-STORE SCU(其他系统)出现故障,这可能无济于事,您需要再次使用它们。

不完全是解决方案,但是,您可以在 C-MOVE 之前执行 SERIES 级别查询 (C-FIND) 并提前获取要拉取的实例数 (NumberOfSeriesRelatedInstances)。但这只是一个计数;不是标识符。 STUDY 和 PATIENT 级别的查询也是如此。

Storage Commitment 在这种情况下可能没有用,因为同样,您的系统上不存在实例;你不知道标识符。

使用 IMAGE 级别查询 (C-FIND),您可以传递系列实例 UID 并获取该系列的实例列表。但是,我遇到了一些也强制 SOP 实例 UID 的系统。如果您的案例中的其他系统支持此功能,您可以执行以下操作:

  • 逐步进行患者、研究、系列和图像级别的查询 (C-FIND)。您可以参考this答案了解更多详情。
  • 将输出存储在某处(内存列表或数据库或其他)。
  • 执行您的常规 C-MOVE,并将收到的实例与您存储的列表进行比较。缺少的就是您要查找的列表。

回答您的评论:

我错过了 Failed SOP Instance UID List (0008,0058) 标签。

C.4.2.1.4.2 响应标识符结构
失败的 SOP 实例 UID 列表 (0008,0058) 指定了此 C-MOVE 操作失败的 C-STORE 子操作 SOP 实例的 UID 列表。 C-MOVE 响应中的标识符应有条件地包含基于 C-MOVE 响应状态值的失败 SOP 实例 UID 列表 (0008,0058)。如果没有 C-STORE 子操作失败,则失败的 SOP 实例 UID 列表 (0008,0058) 不存在,因此在 C-MOVE 响应中不应发送数据集。
参考:DICOM PS3.4 2020e - Service Class Specifications

看来它应该可以完成您的工作。但坦率地说,我从未遇到(或没有注意到)发送此类失败实例列表的 C-MOVE SCP。从您的代码中,您也没有收到数据。我建议不要依赖它。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...