Как тестировать PACS через dcmtk: практическое руководство

dcmtk — это набор утилит для работы с протоколом DICOM, идеально подходящий для тестирования PACS, шлюзов и модальностей. В этой статье — практические шаги, как быстро проверить доступность, поиск, отправку и получение через PACS, с примерами команд.

Что вы сможете протестировать

  • Связность и доступность (C-ECHO)
  • Отправку объектов (C-STORE)
  • Поиск в базе (C-FIND, включая Q/R и MWL)
  • Забор исследований (C-MOVE и C-GET)
  • Шифрование канала (TLS, при необходимости)
  • Диагностику проблем (логи, таймауты, контексты представления)

Подготовка окружения

Установка

  • Debian/Ubuntu:
    sudo apt-get update && sudo apt-get install -y dcmtk
  • RHEL/CentOS/Rocky/Alma:
    sudo dnf install -y dcmtk
  • Windows: скачайте готовые сборки с сайта OFFIS (dcmtk) и добавьте в PATH.

Проверьте версию:

echoscu --version

Базовая проверка сети

Перед DICOM-проверками убедитесь, что порт PACS доступен.

  • Linux/macOS:
    nc -vz 10.0.0.10 104
  • Windows PowerShell:
    Test-NetConnection 10.0.0.10 -Port 104

Примечание: порт 104 (стандартный DICOM) часто закрыт брандмауэрами и на Unix-системах требует прав root для прослушивания. Многие PACS и тестовые приёмники используют 11112.

AE Titles и параметры сессии

Для всех команд dcmtk важны:

  • -aet — ваш AE Title (Calling AE)
  • -aec — AE Title удалённой системы (Called AE)
  • IP и порт сервера PACS

Примерная матрица значений вам выдаётся администратором PACS (или вы настраиваете их сами на стороне PACS).

C-ECHO: проверка доступности PACS

Самый быстрый «DICOM ping» — команда echoscu:

echoscu -v -aet TESTSCU -aec PACS_AE 10.0.0.10 104

Ожидаемый результат — успешная ассоциация и статус Success. Если есть отказ — смотрите причину в выводе (AE Title не распознан, нет ответа, таймаут и т.п.).

C-STORE: отправка DICOM-объектов в PACS

1) Отправка одного файла

storescu -v -aet TESTSCU -aec PACS_STORE 10.0.0.10 104 /data/dicom/img1.dcm

2) Отправка каталога (Linux)

for f in /data/dicom/*.dcm; do \
  storescu -v -aet TESTSCU -aec PACS_STORE 10.0.0.10 104 "$f"; \
done

2a) Отправка каталога (Windows PowerShell)

Get-ChildItem C:\dicom -Recurse -Filter *.dcm | ForEach-Object {
  storescu.exe -v -aet TESTSCU -aec PACS_STORE 10.0.0.10 104 $_.FullName
}

3) Если PACS не принимает компрессию

  • Декомпрессия JPEG/J2K:
    dcmdjpeg in.dcm out_uncompressed.dcm
  • Смена синтаксиса передачи (пример):
    dcmconv --write-xfer-little in.dcm out_explicit_le.dcm

Затем повторите storescu с получившимся файлом.

C-FIND: поиск в PACS (Query/Retrieve)

Проверим поиск по модели Patient/Study Root. На стороне PACS должна быть включена служба Q/R для вашего AE.

Поиск исследований по PatientName и дате (Study Root)

findscu -v -S -aet QRYSCU -aec PACS_QR 10.0.0.10 104 \
  -k 0008,0052=STUDY \
  -k 0010,0010=IVAN* \
  -k 0008,0020=20240101-20241231

Ответ приходит в stdout. Перенаправьте в файл для анализа:

findscu ... > find_response.txt

Поиск с известным StudyInstanceUID

findscu -v -S -aet QRYSCU -aec PACS_QR 10.0.0.10 104 \
  -k 0008,0052=STUDY \
  -k 0020,000D=1.2.840.113619.2.55.3.283116435.781.1457952743.467

Modality Worklist (MWL)

MWL использует отдельный класс C-FIND (SOP Class: Modality Worklist Information Model). Многие системы ожидают ключи внутри последовательности ScheduledProcedureStepSequence (0040,0100). Удобнее собирать ключевой набор в DICOM-файл и передавать его findscu.

Пример: запрос MWL на КТ за дату

  1. Подготовьте текстовый ключевой набор (примерный, может отличаться в зависимости от версии dcmtk и словаря):
    # mwl_keys.txt (упрощённый пример)
    (0010,0010) PN [DOE^*]
    (0008,0060) CS [CT]
    (0040,0100) SQ (1)
      (fffe,e000) na (Содержимое первого SPS-Item)
        (0040,0002) DA [20260101-20260131] # ScheduledProcedureStepStartDate
      (fffe,e00d) na (Конец SPS-Item)
    (fffe,e0dd) na (Конец SPS-Sequence)

    Синтаксис текстового файла для dump2dcm/keys может отличаться по версиям dcmtk. Проверьте справку вашей версии.

  2. Сконвертируйте ключи в DICOM:
    dump2dcm mwl_keys.txt mwl_query.dcm
  3. Выполните запрос:
    findscu -v -W -aet MWLSCU -aec PACS_MWL 10.0.0.10 104 -f mwl_query.dcm

C-MOVE и C-GET: забор объектов из PACS

Вариант 1: C-MOVE (PACS «пушит» к вам)

  1. Поднимите локальный приёмник:
    storescp -v -aet STORE 11112 -od ./inbox
  2. Убедитесь, что в конфигурации PACS добавлен маршрут AE=STORE, IP=ваш_хост, Порт=11112.
  3. Инициируйте перемещение:
    movescu -v -S -aet MOVE -aec PACS_QR -aem STORE 10.0.0.10 104 \
      -k QueryRetrieveLevel=STUDY \
      -k StudyInstanceUID=1.2.840.113619.2.55.3.283116435.781.1457952743.467

Файлы должны появиться в ./inbox на вашей машине.

Вариант 2: C-GET (PACS «шлёт» в тот же канал)

C-GET не требует предварительной маршрутизации AE на PACS, так как приём ведётся тем же соединением, что и запрос.

getscu -v -S -aet GET -aec PACS_QR 10.0.0.10 104 \
  -k QueryRetrieveLevel=STUDY \
  -k StudyInstanceUID=1.2.840.113619.2.55.3.283116435.781.1457952743.467 \
  -od ./inbox

Опция вывода директорий для getscu может отличаться по версиям. Проверьте getscu --help в вашей сборке.

TLS/SSL (шифрование)

Если PACS требует TLS, dcmtk поддерживает защищённые ассоциации. Набор опций для сертификатов и алгоритмов шифрования менялся между версиями 3.6.x. Общая идея:

  • Указать ключ и сертификат клиента
  • Включить/предложить TLS при установке ассоциации

Проверьте доступные опции конкретной утилиты: echoscu --help | find "TLS". В средах с жёсткими требованиями можно использовать внешний терминатор TLS (например, stunnel) между dcmtk и PACS.

Логи и отладка

  • Включайте подробный вывод: добавляйте -v, а при необходимости — отладку -d.
  • Сохраняйте логи:
    echoscu ... -v -d 2>&1 | tee echo.log
  • Для анализа на сетевом уровне используйте Wireshark (диссектор DICOM).

Практические советы

  • Всегда уточняйте у владельца PACS: AE Titles, IP/порт, разрешённые узлы, поддерживаемые SOP-классы и синтаксисы передачи.
  • Для C-MOVE предварительно настраивайте в PACS ваш AE-приёмник (AE/IP/порт).
  • Не тестируйте на реальных ПД с PHI: деидентифицируйте данные.
  • Если поиск возвращает пусто — сократите фильтры (оставьте только QueryRetrieveLevel и один ключ), затем постепенно сужайте.
  • При проблемах с компрессией — декомпрессируйте файлы перед отправкой.
  • На Windows аккуратно экранируйте символы подстановки в ключах поиска (например, используйте кавычки вокруг значений с *).

Типичные ошибки и подводные камни

  • AE Title не распознан на PACS: ассоциация отклонена. Проверьте -aec и список разрешённых AE на сервере.
  • Firewall/NAT: C-MOVE падает, потому что PACS не может подключиться к вашему storescp. Разрешите входящие на порт приёмника и проверьте маршрут.
  • Несовместимый синтаксис передачи: PACS отклоняет C-STORE. Декомпрессируйте или конвертируйте Transfer Syntax.
  • Недостаточные ключи для MWL: сервер возвращает пусто. Запросите минимально необходимые поля и правильную вложенность SPS Sequence.
  • Порты ниже 1024 на Unix: для прослушивания (storescp на 104) нужны права root. Используйте 11112 на тестах.
  • Таймауты: увеличьте сетевые таймауты утилитам dcmtk (флаги зависят от версии) или проверяйте задержки в сети.

Вывод

dcmtk — надёжный инструмент для проверки PACS на всех уровнях DICOM: от простого C-ECHO до полного цикла Q/R и MWL. Используйте приведённые команды как «чек-лист» диагностики, а при расхождениях по опциям — сверяйтесь с --help вашей версии dcmtk и документацией PACS.

Прокрутить вверх