Hello,
I'm trying to get data from my DICOM datasets as close to their original state as possible.
I have a list of items in a tag that are laid out as the following string:
0\0\0\0\0\0\0\0\0
How do I get it represented as such and not as a MultiString/MultiValue?
Knowing that for this specific tag, the DataElement is giving me the following data:
['0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0']
So, even when joining these, I end up with:
0.0\0.0\0.0\0.0\0.0\0.0\0.0\0.0\0.0
I've looked into the source code but didn't find an easy way to get any tag as a string as close as their original state as possible.
Thank you for your help!
Best,
Sylvain
Hi Sylvain,
All DS and IS types have a python attribute original_string. For a MultiValue, these are the separated strings for each individual element of the list, but you could join them back together:
>>> ds.PixelSpacing
['0.661468', '0.661468']
>>> ds.PixelSpacing[0].original_string
'0.661468'
>>> print("\\".join(x.original_string for x in ds.PixelSpacing))
0.661468\0.661468
Hello Darcy,
Thank you! I managed to get access to original_string on IS and DS types, and realized the multi-value VR I'm struggling with is a "FL".
Should we have an "original" value as well for this VR?
Thank you,
Sylvain
Hi Sylvain,
FL is not a string type - the values are stored as binary float numbers - so there can be no original string representation. The representation of the values is up to the application that displays them.
In this case, I would argue that the display of float values using the decimal separator is what I would expect, but it is up to you how to format the numbers.
Hello mrbean,
Thanks - that makes sense and in a normal setting I would expect such a behavior.
My intent is to display the content of the tag the way it was stored as a string (bytes), without any conversion (except as a string to display it or store it for reuse) - pretty much like an image viewer would do when displaying headers or a regular DICOM dumper.
I'm trying to wrap my head around that but I'm unfamiliar with the code deep down.
Well, as value types like FL, US, SS and a few more are stored binary and not as a string, you have to decide about the string represention yourself. Each DICOM dumper does the same - they do not show the original byte values, as this would be unreadable.
Would it be OK if you re-encoded the FL element or does it have to be the original encoded byte data? If you need the original encoded byte data then I think you're out of luck.
From pynetdicom3:
from pydicom.filebase import DicomBytesIO
from pydicom.filewriter import write_data_element
def encode_element(elem, is_little, is_implicit):
"""Encode a pydicom DataElement `elem` to a byte stream.
Parameters
----------
elem : pydicom.dataelem.DataElement
The element to encode
is_implicit : bool
The element encoding scheme.
is_little : bool
The byte ordering the element will be encoded in.
Returns
-------
bytes
The encoded element.
"""
fp = DicomBytesIO()
fp.is_implicit_VR = is_implicit
fp.is_little_endian = is_little
write_data_element(fp, elem)
bytestring = fp.parent.getvalue()
fp.close()
return bytestring
@mrbean-bremen Thank you! I'm afraid I'm not proficient enough to know where to intercept those values and how to use the representation I want (that is, the byte_string to characters without converting them to a float).
@scaramallion Thank you! I think I need the original byte data. Maybe my understanding of how these values are stored isn't deep enough.
I understand that the bytes need to be converted, although for that specific FL multivalue tag, I clearly see all dumps showing 0\0\0\0\0\0\0 (etc.), so I assume that the bytes stored are not 0.0\0.0\0.0\0.0 (etc.), and that each set of bytes can be converted to a set of characters instead of a float.
I'll deal with the data on the other end, that's fine too!
* Edit *: in my database, I've just realized that I actually have FL values represented as floats, so I did follow the DICOM standard there too. I guess I'll be fine :).
Thanks for your answers!