Как сгенерировать UID SOPInstance для файла DICOM?

Я разрабатываю систему, которая сможет создавать структурированный отчет для PACS.

Очевидно, что для создания экземпляра DICOM (файла, содержащего данные отчета) мне нужны три UID для исследования, серии и экземпляра. StudyUID и SeriesUID должны быть такими же, как у исследования и серии, для которых создается отчет. Но для SOPInstanceUID мне нужно сгенерировать новый UID.

Я видел getNewSOPInstanceUID метод в документации Pixelmed, но я не знаком с источником Pixelmed. Мне нужен алгоритм или исходный код Python.


person mtoloo    schedule 24.04.2012    source источник
comment
Вам понадобится больше, чем просто алгоритм. DICOM UID должны быть глобально уникальными, поэтому вам необходимо зарегистрироваться в одном из назначенных органов, чтобы получить корневую основу, которая будет использоваться для всех UID, которые вы создаете.   -  person Matt    schedule 24.04.2012


Ответы (4)


Я бы действительно посоветовал вам отказаться от реализации этого самостоятельно. В наши дни большинство языков предоставляют библиотеки UUID, не изобретайте велосипед. Esp. если вы собираетесь написать код для извлечения MAC-адреса, это может быть очень сложно написать на портативном C.

UUID не совсем соответствуют определению DICOM, поэтому вам необходимо зарегистрировать собственный корневой каталог организации UID, затем просто заполните сгенерированным UUID, который создает условие пространственной и временной уникальности.

YOUR_ORG_ROOT.CONVERTED_UUID

Обратите внимание, что у вас есть 64 байта (этого уже достаточно, см. здесь) для хранилище в пользовательском интерфейсе представления значений:

  • Преобразование шестнадцатеричного представления UUID в VR: определение пользовательского интерфейса ([0-9.]+)
  • Обрезайте с особой осторожностью (во время этой операции вы можете создать избыточность)
  • Выберите короткий Org Root
  • При необходимости добавьте \0 (0 двоичный).

Наконец, поскольку вы используете python, используйте uuid lib python-uuid.


Вышеупомянутое следует рассматривать как альтернативную реализацию того, что официально определено в стандарте:

При прямом преобразовании UUID в UID необходимо использовать "2.25." корень.

person malat    schedule 07.01.2013
comment
Совет создавать не свой собственный алгоритм UUID очень здравый. Действия по преобразованию UUID в DICOM UID неверны. В стандарте DICOM есть определенные правила для этого преобразования (см. Часть 5, параграф b.2). - person Victor Derks; 17.12.2018

В DICOM есть два способа создания UID. Один основан на зарегистрированном корне UID, а другой - на UUID. Более поздний метод был добавлен к стандарту DICOM в CP-1156 в 2012 году. UID для таких вещей, как Study UID, Series UID, SOP Instance UID, могут быть созданы путем преобразования UUID в DICOM UID.

Большинство языков программирования имеют встроенную поддержку для создания UUID. В приведенном ниже примере кода кода создается действительный DICOM UID в C # на основе значения GUID.

public static string GuidToUidStringUsingStringAndParse(Guid value)
{
    var guidBytes = string.Format("0{0:N}", value);
    var bigInteger = BigInteger.Parse(guidBytes, NumberStyles.HexNumber);
    return string.Format(CultureInfo.InvariantCulture, "2.25.{0}", bigInteger);
}

Следующий метод делает то же самое, но примерно в 5 раз быстрее:

public static string ConvertGuidToUuidInteger(ref Guid value)
{
    // ISO/IEC 9834-8, paragraph 6.3 (referenced by DICOM PS 3.5, B.2) defines how
    // to convert a UUID to a single integer value that can be converted back into a UUID.

    // The Guid.ToByteArray Method returns the array in a strange order (see .NET docs),
    // BigInteger expects the input array in little endian order.
    // The last byte controls the sign, add an additional zero to ensure
    // the array is parsed as a positive number.
    var octets = value.ToByteArray();
    var littleEndianOrder = new byte[]
    { octets[15], octets[14], octets[13], octets[12], octets[11], octets[10], octets[9], octets[8],
        octets[6], octets[7], octets[4], octets[5], octets[0], octets[1], octets[2], octets[3], 0 };

    return "2.25." + new BigInteger(littleEndianOrder).ToString(CultureInfo.InvariantCulture);
}
person Victor Derks    schedule 04.01.2013
comment
Хотя мне нравится простота этого ответа, следует отметить, что вы ограничиваете (так сказать) себя только 128-битной частью UUID. Хотя DICOM UID обеспечивает гораздо более широкий диапазон ... - person malat; 12.09.2016
comment
Стандарт DICOM требует, чтобы при использовании UUID для DICOM UID использовался формат, указанный в части 5, параграф B.2. В этом есть смысл, 128-битный UUID уже статически уникален (см. Википедию), и добавление дополнительных байтов не делает его значительно более уникальным. Добавление дополнительных байтов также проблематично для других систем, которые хотят извлечь часть UUID из DICOM UID из объектов DICOM, которые они получают. - person Victor Derks; 16.12.2018
comment
@VictorDerks: я упомянул первый блок кода в своем другом ответе здесь. Основная логика такая же; только некоторые улучшения и добавлены пояснения. - person Amit Joshi; 19.09.2019

См. этот ответ для получения дополнительных сведений о DICOM UID.

A] Увеличьте счетчики [не рекомендуется]

Одна простая логика - получить ваш SeriesInstanceUID и увеличить его на 1. Так, скажем, ваш SeriesInstanceUID - «1.1.1.1.1», тогда ваш SOPInstanceUID может быть «1.1.1.1. 2» или «1.1.1.1» .1. 1 ".

Проблемы:

  • Когда экземпляр удаляется и создается следующий экземпляр, более ранний счетчик не должен использоваться.
  • В многопоточной среде следует соблюдать осторожность.
  • Не гарантирует уникальность для разных систем / приложений.

B] Дата и время [не рекомендуется]

Другой обычно используемый метод - это добавление отметки времени (с отметками) к корню организации.

Проблемы:

  • Многопоточная среда представляет собой проблему.
  • Системные часы могут отключиться.
  • Уникальность для разных систем / приложений не может быть гарантирована.

C] Более сложный [РЕКОМЕНДУЕТСЯ]

1.2.840.xxxxx.30.152.99999.235.20.100.yyyyMMddHHmmss.zzzzzz

Где:

1.2.840.xxxxx: корневой каталог организации
30: идентификатор приложения
152: версия приложения
99999 : Идентификатор места установки / места
235: Идентификатор исследования
20: Серийный номер
100: Изображение Число
yyyyMMddHHmmss: Дата Время
zzzzzz: Поточно-безопасный счетчик / Случайное число

Проблемы:

  • Алгоритм может дать сбой при отключении системных часов; это дополнительно защищено поточно-безопасным счетчиком / случайным числом. Удаленная возможность; нужно немного заботиться.

D] Производный UUID [РЕКОМЕНДУЕТСЯ]

UID может быть сгенерирован из корня «2.25». за которым следует десятичное представление универсального уникального идентификатора (UUID).

Проблемы:

  • Это может быть подходящим для динамически создаваемых UID, таких как UID экземпляра SOP, но не подходит для UID, определенных во время проектирования, таких как частный класс SOP или UID синтаксиса передачи или UID класса реализации.
  • UID ограничен 128 битами. DICOM UID поддерживает более широкий диапазон.
person Amit Joshi    schedule 20.09.2017
comment
Стандарт DICOM позволяет использовать UID, производные от UUID, для разработки UID, таких как синтаксис передачи, но использование корневого формата организации является предпочтительным, поскольку это значительно упрощает определение того, кто разработал этот новый синтаксис передачи. Программным инженерам нужно время, чтобы создать такой новый UID, для работающего приложения нужны только динамически созданные UID. - person Victor Derks; 17.12.2018

Согласно стандарту DICOM (PS 3.5-2011, стр. 61) вам понадобится оргроот и суффикс . Примеры можно найти здесь (ПУ 3.5-2011, стр. 83).

Также не забывайте, что поля пользовательского интерфейса должны быть дополнены (если они не имеют четной длины) байтами '\ 0', а не пробелами.

Я бы предложил создать такой UID:

YOUR_ORGROOT.Year.Month.Day.Hour.Minute.Second.Milliseconds.StaticCounter

Помните, что ограничение составляет 64 символа!

person Gogorrr    schedule 25.04.2012
comment
Вам не хватает пространственного условия перед временной уникальностью, см. RFC 4122. Должно быть больше похоже на: YOUR_ORGROOT.SPATIAL.TIME - person malat; 07.01.2013