Package gmisclib :: Module read_dicom
[frames] | no frames]

Source Code for Module gmisclib.read_dicom

  1  #!/usr/bin/env python 
  2   
  3  import g_exec 
  4  import re 
  5  import Num 
  6   
  7   
8 -def _rm_bkt(s):
9 s = s.strip() 10 if s.startswith('[') and s.endswith(']'): 11 return s[1:-1] 12 return s
13
14 -def _sq(s):
15 return ''.join( [ q.capitalize() for q in s.split() ] )
16 17
18 -def read_header(f):
19 pass1 = re.compile(r'[(]([0-9a-fA-F]+),([0-9a-fA-F]+)[)]\s+[A-Z]+.[0-9].\s+([a-zA-Z0-9_]+):\s*(.*)\s*[(]\s*[0-9]+ bytes\s*[)]$') 20 pass2gel = re.compile(r'([a-zA-Z0-9_]+)\s+[(][0-9]+[)]:\s*([x0-9a-fA-F]+)') 21 pass2e = re.compile(r'(.*)\s*:\s*(.*)') 22 gnpat = re.compile(r'(.*)\s+-\s+Group\s+([x0-9a-fA-F]+)') 23 defer = {} 24 gnames = {} 25 caught = set() 26 ipass = 0 27 lip = 0 28 p2g = None 29 p2e = None 30 gname = None 31 for s in g_exec.getiter_raw('medcon', ['medcon', '-f', f]): 32 s = s.rstrip() 33 34 # print '#', s 35 if s.startswith('Pass #1: through DICOM reader'): 36 ipass = 1 37 continue 38 elif s.startswith('Pass #2: through Acr/Nema reader'): 39 ipass = 2 40 continue 41 elif gnpat.match(s): 42 m = gnpat.match(s) 43 gname = m.group(1) 44 gnames[ int(m.group(2),16) ] = gname 45 continue 46 47 if ipass == 1: 48 m = pass1.match(s) 49 if not m: 50 continue 51 k1, k2, k, v = m.groups() 52 if k != 'Unknown': 53 caught.add( (int(k1,16), int(k2,16)) ) 54 yield (k, _rm_bkt(v)) 55 else: 56 defer[ (int(k1,16),int(k2,16)) ] = _rm_bkt(v) 57 elif ipass == 2: 58 if s.startswith('----'): 59 continue 60 m = pass2gel.match(s) 61 if m: 62 if m.group(1) == 'Group': 63 p2g = m.group(2) 64 elif m.group(1) == 'Element': 65 p2e = m.group(2) 66 lip += 1 67 continue 68 m = pass2e.match(s) 69 if not m: 70 continue 71 if p2g is None or p2e is None: 72 continue 73 k1 = int(p2g, 16) 74 k2 = int(p2e, 16) 75 if (k1, k2) in caught: 76 continue 77 k, v = m.groups() 78 if v.strip() == '<not printed>': 79 continue 80 if k.strip() == 'Unknown Element': 81 continue 82 if (k1,k2) in defer: 83 del defer[ (k1,k2) ] 84 caught.add( (k1, k2) ) 85 p2g = None 86 p2e = None 87 yield (_sq(gname) + '.' + _sq(k), v) 88 for ((k1,k2),v) in defer.items(): 89 if k1 in gnames: 90 yield ('%s.%#x' % (_sq(gnames[k1]),k2), v) 91 else: 92 yield ('CODE%#x.%#x' % (k1,k2), v)
93 94
95 -class img_with_mx(object):
96 """This is a way of reading in a 2-D image when you don't 97 know the final size. It keeps a larger image around 98 and keeps track of the area that has been set. 99 """ 100
101 - def __init__(self, i, j):
102 """Create an image that contains pixel (i,j).""" 103 assert i>=0 and j>=0 104 self.img = Num.zeros((2*i+1,2*j+1), Num.Float) 105 self.mi = i 106 self.mj = j
107
108 - def resize(self, inxt, jnxt):
109 tmp = Num.zeros((inxt,jnxt), Num.Float) 110 tmp[:self.mi+1, :self.mj+1] = self.img[:self.mi+1, :self.mj+1] 111 self.img = tmp
112
113 - def set(self, i, j, val):
114 """Set a pixel, expanding the allocated space as needed.""" 115 assert i>=0 and j>=0 116 117 try: 118 self.img[i,j] = val 119 except IndexError: 120 if i >= self.img.shape[0]: 121 inxt = 2*i+2 122 else: 123 inxt = max(i, self.mi) + 1 124 125 if j >= self.img.shape[1]: 126 jnxt = 2*j+2 127 else: 128 jnxt = max(j, self.mj) + 1 129 self.img.resize(inxt, jnxt) 130 self.img[i,j] = val 131 132 if i > self.mi: 133 self.mi = i 134 if j > self.mj: 135 self.mj = j
136
137 - def get(self):
138 """Get the image, trimming it to show 139 the area that has been set. 140 """ 141 return self.img[self.mi:0:-1, :self.mj]
142 143
144 -def _set(imgs, iimg, i, j, val):
145 assert i>=0 and j>=0 146 try: 147 img = imgs[iimg] 148 except KeyError: 149 img = img_with_mx(i, j) 150 imgs[iimg] = img 151 img.set(i, j, val)
152 153
154 -def read_body(f):
155 pix = re.compile('\s*P[(]\s*([0-9]+),\s*([0-9]+)\s*[)]') 156 imgs = {} 157 for s in g_exec.getiter_raw('medcon', ['medcon', '-pa', '-f', f]): 158 if not s.startswith('#'): 159 # print 'Not hash', s 160 continue 161 a = s.split(':') 162 if len(a) != 8: 163 # print 'Not 8:', s 164 continue 165 assert a[0] == '#' and a[2]=='S' and a[4]=='I' 166 m = pix.match(a[6]) 167 assert m 168 i = int(m.group(1)) - 1 169 j = int(m.group(2)) - 1 170 iimg = int(a[1]) - 1 171 sl = float(a[3]) 172 intercept = float(a[5]) 173 val = sl*float(a[7]) + intercept 174 _set(imgs, iimg, j, i, val) 175 o = [] 176 imgl = imgs.items() 177 imgl.sort() 178 for (j,img) in imgl: 179 o.append(img.get()) 180 return o
181 182
183 -def read_imgs(f):
184 import gpkimgclass 185 h = dict(read_header(f)) 186 b = read_body(f) 187 return [gpkimgclass.gpk_img(h.copy(), bi) for bi in b]
188 189 if __name__ == '__main__': 190 import sys 191 try: 192 import psyco 193 psyco.full() 194 except ImportError: 195 pass 196 arglist = sys.argv[1:] 197 if arglist[0] == '-o': 198 arglist.pop(0) 199 o = arglist.pop(0) 200 tmp = read_imgs(arglist[0]) 201 assert len(tmp) == 1 202 tmp[0].write(o) 203 else: 204 for (k,v) in read_header(arglist[0]): 205 print '%s = %s' % (k, v) 206