Create a new private tags in a DICOM file

209 views Asked by At

I am currently trying to build a plug-in for Orthanc, an open-source server for DICOM Images.

That plug-in will be a viewer that will need some metadata of the images to work properly. Metadata that can't be stored on the "classic" tags (the ones with an even group number).

Disclaimer : we're not a medical organization and will simply use Dicom files to store our data. That means we won't be any problem with the privacy of our data.

I know that private creators are stored on these tags (gggg, 00xx) with (gggg is odd and >= 0x0009 and xx > 0x10) and that it books a block (gggg, xx00-xxff) for that private creator. I know there would be 240 private creators per group and each private creator has to be unique per group.

I'd like to know what I have to do :

  • Use an arbitrary Tag and write over any data if it exists (It doesn't seem wise, even if taking a completely random tag reduce the risk of it happening)
  • Use an arbitrary Tag, check if a private creator is already on it and throw an error in that case (What is the next step for that file?)
  • Use an arbitrary Tag and if it's already used, go the next one free (that means that 2 different DICOM files have a chance to not have the same Private Creator Tag, how do I handle it?)
  • Something else?

My use case is that people, unrelated to each other, will send/receive Dicom files and they should be able to view them with that plug-in without any problems.

Every tutorial that I've found (as this one), just add the private data without checking much.

What is the process I have to follow to be sure that there won't be any problem down the line?

As I am currently learning as much information as possible before starting developing that plug-in, I still don't know which programming language and library will be used (Either C++/DCMTK or Python/pydicom).

1

There are 1 answers

0
Broot On

Thanks to the explications of MrBeanBremen, I tested one complete use case myself with pydicom.

ds = dicom.Dataset()
block_1 = ds.private_block(0x1001, "Test", create=True)
block_1.add_new(0x01, VR.UL, 42)
block_1.add_new(0x02, VR.SH, "Hello World")
block_1.add_new(0x03, VR.UI, "1.2.3.4.5")

block_2 = ds.private_block(0x1001, "Test_bis", create=True)
block_2.add_new(0x01, VR.UL, 83)
block_2.add_new(0x02, VR.SH, "HelloWorld-bis")
block_2.add_new(0x03, VR.UI, "6.7.8.9")

block_3 = ds.private_block(0x1001, "Test", create=True)
block_3.add_new(0x01, VR.SH, "Changing the data completely")

ds.PixelSpacing = [0.1,0.1]

print(ds)

This is the result on the terminal :

(0028, 0030) Pixel Spacing                       DS: [0.1, 0.1]
(1001, 0010) Private Creator                     LO: 'Test'
(1001, 0011) Private Creator                     LO: 'Test_bis'
(1001, 1001) Private tag data                    SH: 'Changing the data completely'
(1001, 1002) Private tag data                    SH: 'Hello World'
(1001, 1003) Private tag data                    UI: 1.2.3.4.5
(1001, 1101) Private tag data                    UL: 83
(1001, 1102) Private tag data                    SH: 'HelloWorld-bis'
(1001, 1103) Private tag data                    UI: 6.7.8.9

That means block_1 creates the new private creator "Test" in the private group 0x1001. And add 3 tags at (1001, 1001), (1001, 1002) and (1001, 1003).

Block_2 as it is a new private Creator will add the tags at the next reserved block ( (1001, 1101), (1001, 1102), (1001, 1103))

Block_3 will not create a new block (as the private creator already exists inside that group) but will update the tags in that group.

That means that the framework will automatically place your private creator in your private group.

And just in case, I tried to add 241 different creators to see what happens. It simply throws an error.