pydicom reports SOPClassUID '1.2.840.10008.5.1.4.1.1.4' instead of 'MR Image Storage'

468 views
Skip to first unread message

Dimitri

unread,
Feb 26, 2014, 12:42:02 PM2/26/14
to pyd...@googlegroups.com
Dear all,

The value associated to SOPClassUID is displayed by pydicom as '1.2.840.10008.5.1.4.1.1.4'. I would like to display 'MR Image Storage' instead:
 
>>> import dicom
>>> 
>>> dataset = dicom.read_file('20130209153005958.MR.dic')
>>> dataset.SOPClassUID
'1.2.840.10008.5.1.4.1.1.4'
>>> 
>>> dataset[0x0008,0x0016].value
'1.2.840.10008.5.1.4.1.1.4'
>>> 
>>> dataset[0x0008,0x0016]
(0008, 0016) SOP Class UID                       UI: MR Image Storage
>>> 
>>> dataset[0x0008,0x0016].repval
'MR Image Storage'
>>> 

What is the proper way to display 'MR Image Storage'? Do I have to use the DICOM tag number (0008,0016) and repval or can it be done using the keyword SOPClassUID which I find easier to read in my code?

Dimitri

Darcy Mason

unread,
Feb 26, 2014, 2:29:31 PM2/26/14
to pyd...@googlegroups.com
Hi Dimitri,

If you try:
>>> print dataset.SOPClassUID,
I think you should see 'MR Image Storage'.
pydicom overrides the __str__ method to display the human-readable name of UIDs, but the __repr__ method (which is used when displaying objects at the interpreter line without a 'print') shows the original value.

Darcy

Darcy Mason

unread,
Feb 26, 2014, 2:39:53 PM2/26/14
to pyd...@googlegroups.com
... I should have added that str(ds.SOPClassUID) will also work, and can be used in python code in addition to the interpreter.  In the latter case, though, the equality test (__eq__) has also been overridden for UIDs, so in addition to the dotted numbers, one can compare ds.SOPClassUID directly to the string value,. e.g. ds.SOPClassUID == 'MR Image Storage' will test correctly.

Dimitri

unread,
Feb 26, 2014, 4:33:19 PM2/26/14
to pyd...@googlegroups.com
Darcy,

Thank you for your explanations. Here is what happenned.

The following piece of code does not work as I was expecting it to work:

import dicom

ACCEPT = { 'MR Image Storage', 'Enhanced MR Image Storage' }

dataset = dicom.read_file('/neurospin/imagen/FU2/RAW/MANUAL_FTP/PARIS/070000150817FU/ImageData/EPI_MID_FU/20130209153005958.MR.dic')
print '<' + dataset.SOPClassUID + '>'
if dataset.SOPClassUID in ACCEPT:
    print 'ACCEPT!'

I turned to the interactive shell to investigate and got mixed up. The code works as intended if slightly changed to:

if str(dataset.SOPClassUID) in ACCEPT:
    print 'ACCEPT!'

instead of:

if dataset.SOPClassUID in ACCEPT:
    print 'ACCEPT!'

Once again, I'm sorry for the noise.

Dimitri

Darcy Mason

unread,
Feb 26, 2014, 8:26:05 PM2/26/14
to pyd...@googlegroups.com
Hi Dimitri,

I was also surprised your original code did not work.  It does work if you use a list instead of a set:
ACCEPT = [...]

After scratching my head for a minute, I believe this is because the "contains" operation of a set will not call __eq__. Since sets contain unique values, they probably simply check for a hash of the value in the set, like what is used with dictionary keys, rather than comparing the values themselves, which makes for much faster operations.  In fact I'm pretry sure I have read this somewhere before.

I suppose there is a way to modify pydicom's UID class to add a __hash__ function, but it hurts my brain a little to think through the consequences of that. In fact I think we could not reliably get both comparisons (by name and by dotted number) to work.

And ... don't worry about the "noise" ... these were interesting questions that did point out a weakness we didn't know existed.

Darcy

Dimitri

unread,
Feb 27, 2014, 2:38:06 AM2/27/14
to pyd...@googlegroups.com
Darcy,

I wouldn't change __hash__ because its usual purpose is to be efficient, not to return a nice readable string. Additionnally as you point out some users might be interested in the tag number and others in the keyword.

Dimitri
Reply all
Reply to author
Forward
0 new messages