How to generate SOPInstance UID for DICOM file?

Question:

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.

Asked By: mtoloo

||

Answers:

According to the DICOM standard (PS 3.5-2011 Page 61), you need an orgroot and a suffix. Examples can be found here (PS 3.5-2011 Page 83).

Also do not forget that UI Fields have to be padded (if they do not have an even length) with ‘’ bytes and not with spaces.

I would suggest to create the UID like this:

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

Beware that the limit is 64 chars!

Answered By: Gogorrr

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);
}
Answered By: Victor Derks

I would really suggest you go away from implementing it yourself. Most language do provide a UUID library these days, do not reinvent the wheel. Esp. if you are going to write code to extract MAC adress, this can be very complex writing it in portable C.

UUID do not exactly fit the DICOM definition, so you need to register your own Organisation Root UID, then simply pad with a generated UUID which bring spatial and time uniqueness condition.

YOUR_ORG_ROOT.CONVERTED_UUID

Pay attention that you have 64 bytes (that’s plenty already, see here) for storage in Value Representation UI:

  • Convert Hexadecimal notation of UUID to VR: UI definition ([0-9.]+)
  • Trim with extreme care (you may introduce redundancy during this operation)
  • Choose a short Org Root
  • Pad with (0 binary) if needed.

Finally since you are using python, use uuid lib python-uuid.


The above should be considered an alternate implementation to what is officially defined in the standard:

When converting directly a UUID to a UID, one must use the “2.25.” root.

Answered By: malat

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.
Answered By: Amit Joshi

DICOM UIDs
These identifiers together serve to present different information about the generating devices, the patient, the individual meeting and the files that make up the study. Moving on, each image within a study contains several different UIDs to link that single image to the rest of the series, the exam, and the overall patient encounter (the hierarchy being: Patient > Study > Series > Image). The UIDs generated as part of the process must be globally unique, and there are numerous issuance registries, which seek to avoid duplication by assigning batches to manufacturers and individuals or locations as needed.

All UIDs generated for DICOM services start with the first dig ¬1.2.840.10008[…] allowing for easy recognition among wider network traffic.

Answered By: Carlos Queiroz