Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate SOPInstance UID for DICOM file?

I am developing a system which will be able to create structured report for PACS.

Obviously in order to create a DICOM instance (file containing Report data), I need three UIDs for Study, Series and Instance. StudyUID and SeriesUID must be the same as that of study and series that report is created for. But for SOPInstanceUID, I need to generate new UID.

I have seen getNewSOPInstanceUID method in Pixelmed documentation, but I am not familiar with the Pixelmed source. I need an algorithm or Python source.

like image 407
mtoloo Avatar asked Apr 24 '12 10:04

mtoloo


2 Answers

There are 2 ways in DICOM to create UIDs. One based on a registered UID root and one based on a UUID. The later method was added to the DICOM standard with CP-1156 in 2012. UIDs for things like Study UID, Series UID, SOP Instance UID can be created by converting a UUID to a DICOM UID.

Most programming languages have build in support to create a UUID. The sample code code below creates a valid DICOM UID in C# based on a GUID value.

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);
}

The following method does the same but is about 5 times faster:

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);
}
like image 150
Victor Derks Avatar answered Oct 04 '22 12:10

Victor Derks


Refer this answer for more details about DICOM UID.

A] Increment the counters [Not Recommended]

One simple logic is to get your SeriesInstanceUID and increment it by 1. So say your SeriesInstanceUID is "1.1.1.1.1" then your SOPInstanceUID may be "1.1.1.1.2" or "1.1.1.1.1.1".

Problems:

  • When the instance is deleted and next instance is created, the earlier counter should not be used.
  • In multi-threaded environment, enough care should be taken.
  • Does not guarantee uniqueness across different systems/applications.

B] Date Time [Not Recommended]

Other technique generally used is to append time stamp (with ticks) to organization root.

Problems:

  • Multi-threaded environment is an issue.
  • System clock may go off.
  • Uniqueness across different systems/applications cannot be guaranteed.

C] More Complex [RECOMMENDED]

1.2.840.xxxxx.30.152.99999.235.20.100.yyyyMMddHHmmss.zzzzzz

Where:

1.2.840.xxxxx: Organization Root
30: Application ID
152: Application Version
99999: Installation/Location ID
235: Study ID
20: Series Number
100: Image Number
yyyyMMddHHmmss: Date Time
zzzzzz: Thread safe counter/Random Number

Problems:

  • Algorithm may fail in case system clock goes off; this is protected by thread safe counter/random number further. Remote possibility; need to take little care.

D] UUID Derived UID [RECOMMENDED]

UID may be generated from the root "2.25." followed by a decimal representation of a Universally Unique Identifier (UUID).

Problems:

  • This may be appropriate for dynamically created UIDs, such as SOP Instance UIDs, but is not appropriate for UIDs determined during design, such as private SOP Class or Transfer Syntax UIDs, or Implementation Class UIDs.
  • UID is restricted to only 128 bits. DICOM UID support wider range.
like image 29
Amit Joshi Avatar answered Oct 04 '22 12:10

Amit Joshi