[Tutor] Problem with logic while extracting data from binary file
Bryan Fodness
bryan.fodness at gmail.com
Tue Mar 25 16:59:54 CET 2008
Here is my program. I am trying to extract values from a binary file for
use in a calculation. I am having trouble with the logic. Everything goes
well until I use the parseSequence function. If there is only one sequence
I seem fine, but if there is a sequence within a sequence everything seems
to fall apart. I don' t know if I have just looked at this so long that I
am not seeing the obvious fix. Any help would be appreciated.
I have attached the input file that I am using for a test. Also, here is
one of the strings that enters the parseSequence function, broken up to make
it more readable.
I would like to get parseDICOM(rawData)['\n0\x82'].
-----------------------------------------
('\n0', 'p\x00', 544,
'\xfe\xff\x00\xe0\x18\x02\x00\x00
\n0q\x00\x02\x00\x00\x001
\n0x\x00\x02\x00\x00\x0010
\n0\x80\x00\x02\x00\x00\x004
\n0\xa0\x00\x02\x00\x00\x000
\x0c0\x04\x00\xe8\x01\x00\x00
\xfe\xff\x00\xe0p\x00\x00\x00
*\n0\x82*\x002\x00\x00\x0042.9068704277562\\-
392.3545926477\\189.182112099444
\n0\x84\x00\x0c\x00\x00\x008.9617062e-1
\n0\x86\x00\x10\x00\x00\x00127.378510918301
\x0c0\x06\x00\x02\x00\x00\x001
\xfe\xff\x00\xe0p\x00\x00\x00
*\n0\x82*\x002\x00\x00\x0042.9068704277562\\-
392.3545926477\\189.182112099444
\n0\x84\x00\x0c\x00\x00\x001.629998e-1
\n0\x86\x00\x10\x00\x00\x0023.159729257873
\x0c0\x06\x00\x02\x00\x00\x004
\xfe\xff\x00\xe0t\x00\x00\x00
*\n0\x82*\x002\x00\x00\x0042.9068704277562\\-
392.3545926477\\189.182112099444
\n0\x84\x00\x10\x00\x00\x001.26285318894435
\n0\x86\x00\x10\x00\x00\x00227.690980638769
\x0c0\x06\x00\x02\x00\x00\x003
\xfe\xff\x00\xe0t\x00\x00\x00
\n0\x82\x002\x00\x00\x0042.9068704277562\\-
392.3545926477\\189.182112099444
\n0\x84\x00\x10\x00\x00\x001.52797639111557
\n0\x86\x00\x10\x00\x00\x00263.433384670643
\x0c0\x06\x00\x02\x00\x00\x002 ')
import struct
from time import *
print "Creating Variables...\n"
start=clock()
rawData = open('file.dcm', 'rb').read()
# Need to get Transfer Syntax UID (0002,0010) for encoding type
def parsePreamble(data):
preamble = data[:128]
dicm = data[128:132]
if dicm == 'DICM':
return preamble, 132
else:
raise NotAPreambleException
def parseMetaElementGL(data):
vl_field = data[138:140]
length = struct.unpack('h', vl_field)[0]
value = struct.unpack('hh',data[140:(140+length)])[0]
return value
def parseDataElement(data, start):
if start < (144+parseMetaElementGL(rawData)):
group_num = data[start:start+2]
element_num = data[start+2:start+4]
vr_field = data[start+4:start+6]
if vr_field == 'UN' or vr_field == 'SQ' or vr_field == 'OB' or
vr_field == 'OW':
unused = data[start+6:start+8]
vl_field = data[start+8:start+12]
length = struct.unpack('hh', vl_field)[0] # 4-byte
value = data[start+12:(start+12+length)]
pos = start+12+length
element = (group_num+element_num)
return element, pos, value, length
else:
vl_field = data[start+6:start+8]
length = struct.unpack('h', vl_field)[0] # 2-byte
value = data[start+8:(start+8+length)]
pos = start+8+length
element = (group_num+element_num)
return element, pos, value, length
else:
while start < len(data):
group_num = data[start:start+2]
element_num = data[start+2:start+4]
vl_field = data[start+4:start+8]
length = struct.unpack('hh', vl_field)[0]
value = data[start+8:(start+8+length)]
pos = start+8+length
element = (group_num+element_num)
return element, pos, value, length
else:
print "End of File"
def parseSequence(data, start):
group_num = data[start:start+2]
element_num = data[start+2:start+4]
vl_field = data[start+4:start+8]
length = struct.unpack('hh', vl_field)[0]
value = data[start+8:(start+8+length)]
pos = start+8+length
element = (group_num+element_num)
if element == '\xfe\xff\x00\xe0':
start = start+8
group_num = data[start:start+2]
element_num = data[start+2:start+4]
vl_field = data[start+4:start+8]
length = struct.unpack('hh', vl_field)[0]
value = data[start+8:(start+8+length)]
pos = start+8+length
element = (group_num+element_num)
if element == '\xfe\xff\x00\xe0':
start = start+8
group_num = data[start:start+2]
element_num = data[start+2:start+4]
vl_field = data[start+4:start+8]
length = struct.unpack('hh', vl_field)[0]
value = data[start+8:(start+8+length)]
pos = start+8+length
element = (group_num+element_num)
return element, pos, value
else:
return element, pos, value
else:
return element, pos, value
def parseDICOM(data):
elements = []
values = []
try:
preamble, next = parsePreamble(data)
except NotAPreambleException:
preamble, next = None, 0
while next < len(data):
element, next, value, length = parseDataElement(data, next)
if element == '\n0\x10\x00' or element == '\n0@\x00' or element ==
'\n0p\x00' or element == '\n0\xb0\x00':
start = 0
while start < length:
element, start, svalue = parseSequence(value, start)
elements.append(element)
values.append(svalue)
else:
elements.append(element)
values.append(value)
paired = zip(elements, values)
search = dict(paired)
return search
# Access variables for use in calculation
InstanceCreationDate = parseDICOM(rawData)['\x08\x00\x12\x00']
InstanceCreationTime = parseDICOM(rawData)['\x08\x00\x13\x00']
PatientsName = parseDICOM(rawData)['\x10\x00\x10\x00']
RTPlanLabel = parseDICOM(rawData)['\n0\x02\x00']
DoseReferenceDescription = parseDICOM(rawData)['\n0\x16\x00']
ToleranceTableLabel = parseDICOM(rawData)['\n0C\x00']
NumberOfBeams = int(parseDICOM(rawData)['\n0\x80\x00'])
BeamDoseSpecificationPoint = parseDICOM(rawData)['\n0\x82']
print "Instance Creation Date\t\t\t=\t%s" %InstanceCreationDate
print "Instance Creation Time\t\t\t=\t%s" %InstanceCreationTime
print "Patients Name\t\t\t\t=\t%s" %PatientsName
print "RT Plan Label\t\t\t\t=\t%s" %RTPlanLabel
print "DoseReference Description\t\t=\t%s" %DoseReferenceDescription
print "Tolerance Table Label\t\t\t=\t%s" %ToleranceTableLabel
print "Number Of Beams\t\t\t\t=\t%i" %NumberOfBeams
print "Beam Dose Specification Point\t\t=\t%s" %LeafJawPostions
end=clock()
time=end-start
print "\nVariables created in %.3f seconds\n" %time
--
"The game of science can accurately be described as a never-ending insult to
human intelligence." - João Magueijo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20080325/d0dacd8b/attachment-0001.htm
-------------- next part --------------
A non-text attachment was scrubbed...
Name: file.dcm
Type: application/octet-stream
Size: 13138 bytes
Desc: not available
Url : http://mail.python.org/pipermail/tutor/attachments/20080325/d0dacd8b/attachment-0001.obj
More information about the Tutor
mailing list