Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error : a bytes-like object is required, not 'MultiValue' #1412

Closed
nizarbabu opened this issue Jun 16, 2021 · 9 comments · Fixed by #1413
Closed

Error : a bytes-like object is required, not 'MultiValue' #1412

nizarbabu opened this issue Jun 16, 2021 · 9 comments · Fixed by #1413
Labels

Comments

@nizarbabu
Copy link

nizarbabu commented Jun 16, 2021

Hello,

I am getting following error while updating the tag LongTrianglePointIndexList (0066,0040),
TypeError: a bytes-like object is required, not 'MultiValue'

I noticed that the error gets produced only when the VR is given as "OL" , works fine with "OB", "OF" etc.

sample code (assume 'lineSeq' is the dicom dataset sequence):

import pydicom
import array
data=list(range(1,10))
data=array.array('H', indexData).tostring()  # to convert to unsigned short
lineSeq.add_new(0x00660040, 'OL', data)   
ds.save_as("mydicom")

outcome: TypeError: a bytes-like object is required, not 'MultiValue'

using version - 2.0.0.0

Any help is appreciated.

Thank you

@nizarbabu
Copy link
Author

Also tried following code to get the byte string, but same error.

  1. data=array.array('L', indexData).tostring() # to convert to long -> same error
  2. data=array.array('Q', indexData).tostring() # to convert to long long -> same error

@scaramallion
Copy link
Member

scaramallion commented Jun 16, 2021

O* VRs should be bytes. Use array.tobytes() instead of tostring()?

Also, in the future if have an issue it's much more helpful if you post the full traceback rather than the error since we can look at it to figure out where in the code the exception is occurring.

It would also help if you posted the version of Python you're using.

This works fine for me with Python 3.9 and pydicom 2.1.2:

from pydicom import Dataset
import array

arr = array.array('H', range(10))
ds = Dataset()
ds.is_little_endian = True
ds.is_implicit_VR = False
ds.LongTrianglePointIndexList = arr.tobytes()
print(ds["LongTrianglePointIndexList"].VR)  # 'OL'
ds.save_as('temp.dcm')

This also works fine:

ds = Dataset()
ds.add_new(0x00660040, 'OL', arr.tobytes())

@nizarbabu
Copy link
Author

nizarbabu commented Jun 16, 2021

Thank you for the answer.
Unfortunately the error still persists with above code.
Please find the attached detailed error.
error.txt

One more information is that the 'ds' is actually read from a file in the disk (ds=pydicom.read_file(filename)).
and this byte array is stored under the following sequence
ds[0x0066,0x0002][0][0x0066,0x0013][0][0x0066,0x0028][0][0x0066,0x0040] = arr.tobytes()

pydicom - 2.0.0.0
python - 3.6.4

Thank you.

@scaramallion
Copy link
Member

scaramallion commented Jun 16, 2021

Could you post a minimal code sample that reproduces the issue please?

If you're using something like this:
ds[0x0066,0x0002][0][0x0066,0x0013][0][0x0066,0x0028][0][0x0066,0x0040] = arr.tobytes()

Then you're missing the .value assignment:
ds[0x0066,0x0002][0][0x0066,0x0013][0][0x0066,0x0028][0][0x0066,0x0040].value = arr.tobytes()

@nizarbabu
Copy link
Author

nizarbabu commented Jun 16, 2021

Hello,
above code line I just mentioned to give an idea where the actual data is stored (tree level).

Please find the actual code used below,

import pydicom
from pydicom.sequence import Sequence
from pydicom.dataelem import DataElement
from pydicom.dataset import Dataset

ds = pydicom.read_file(filename)
surfaceSeq= ds[0x0066,0x0002]

#// read existing sequence items in the dataset
seqlist=[]
for n in surfaceSeq:
    seqlist.append(n)

newDs = Dataset()
 
surfaceMeshPrimitiveSq = Dataset()
lineSeq = Dataset()
indexData = list(range(1,100))
indexData = array.array('H', indexData)
indexData = indexData.tobytes()
lineSeq.add_new(0x00660040, 'OL', indexData) 
surfaceMeshPrimitiveSq.add_new(0x00660028, 'SQ', [lineSeq])
newDs.add_new(0x00660013, 'SQ', [surfaceMeshPrimitiveSq])

#add the new sequnce item to the list
seqlist.append(newDs)
ds[0x0066,0x0002] = DataElement(0x00660002,"SQ",seqlist)
ds.save_as(filename)

@scaramallion
Copy link
Member

scaramallion commented Jun 16, 2021

OK, I can reproduce with:

import array

from pydicom import Dataset
from pydicom.uid import ExplicitVRLittleEndian

ds = Dataset()
ds.file_meta = Dataset()
ds.file_meta.TransferSyntaxUID = ExplicitVRLittleEndian

b = array.array('H', range(100)).tobytes()

ds.LongPrimitivePointIndexList = b
ds.save_as('1421.dcm')

And print(ds) gives:

(0066, 0040) Long Primitive Point Index List     OL: [b'\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\t\x00\n\x00\x0b\x00\x0c\x00\r\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00 \x00!\x00"\x00#\x00$\x00%\x00&\x00\'\x00(\x00)\x00*\x00+\x00,\x00-\x00.\x00/\x000\x001\x002\x003\x004\x005\x006\x007\x008\x009\x00:\x00;\x00<\x00=\x00>\x00?\x00@\x00A\x00B\x00C\x00D\x00E\x00F\x00G\x00H\x00I\x00J\x00K\x00L\x00M\x00N\x00O\x00P\x00Q\x00R\x00S\x00T\x00U\x00V\x00W\x00X\x00Y\x00Z\x00[\x00', b'\x00]\x00^\x00_\x00`\x00a\x00b\x00c\x00']

I think this is because the byte value is hitting the hex for the backslash character during assignment. Ouch, that's kinda nasty.

@scaramallion scaramallion added bug and removed question labels Jun 16, 2021
@scaramallion
Copy link
Member

scaramallion commented Jun 16, 2021

As a workaround you can do the equivalent of:

b = array.array('H', range(100)).tobytes()
ds.LongPrimitivePointIndexList = None
# Bypass the value check and set it directly
ds["LongPrimitivePointIndexList"]._value = b

The problem arises because elements with a VR of OL (and OD and OV) aren't being excluded from the backslash check. Thanks, we'll have a fix in for the next release.

@nizarbabu
Copy link
Author

Thank you.
The workaround works!

@scaramallion
Copy link
Member

We really should have a checklist or something for what needs to be changed when we add new VRs...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants