[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