Package fabio :: Module brukerimage
[hide private]
[frames] | no frames]

Source Code for Module fabio.brukerimage

  1   
  2  ## Automatically adapted for numpy.oldnumeric Oct 05, 2007 by alter_code1.py 
  3   
  4  #!/usr/bin/env python 
  5  """ 
  6   
  7  Authors: Henning O. Sorensen & Erik Knudsen 
  8           Center for Fundamental Research: Metal Structures in Four Dimensions 
  9           Risoe National Laboratory 
 10           Frederiksborgvej 399 
 11           DK-4000 Roskilde 
 12           email:erik.knudsen@risoe.dk 
 13   
 14  Based on: openbruker,readbruker, readbrukerheader functions in the opendata 
 15           module of ImageD11 written by Jon Wright, ESRF, Grenoble, France 
 16   
 17  """ 
 18   
 19  import numpy as N, logging 
 20   
 21  from fabio.fabioimage import fabioimage 
 22  from fabio.readbytestream import readbytestream 
 23   
 24   
25 -class brukerimage(fabioimage):
26 """ 27 Read and eventually write ID11 bruker (eg smart6500) images 28 """ 29 30 # needed if you feel like writing - see ImageD11/scripts/edf2bruker.py 31 32 __headerstring__ = "" 33 34
35 - def _readheader(self, infile):
36 """ 37 the bruker format uses 80 char lines in key : value format 38 In the fisrt 512*5 bytes of the header there should be a 39 HDRBLKS key, whose value denotes how many 512 byte blocks 40 are in the total header. The header is always n*5*512 bytes, 41 otherwise it wont contain whole key: value pairs 42 """ 43 lump = infile.read(512 * 5) 44 self.__headerstring__ += lump 45 i = 80 46 self.header = {} 47 while i < 512 * 5: 48 if lump[i-80: i].find(":") > 0: 49 key, val = lump[i-80: i].split(":", 1) 50 key = key.strip() # remove the whitespace (why?) 51 val = val.strip() 52 if self.header.has_key(key): 53 # append lines if key already there 54 self.header[key] = self.header[key] + '\n' + val 55 else: 56 self.header[key] = val 57 self.header_keys.append(key) 58 i = i + 80 # next 80 characters 59 # we must have read this in the first 512 bytes. 60 nhdrblks = int(self.header['HDRBLKS']) 61 # Now read in the rest of the header blocks, appending 62 rest = infile.read(512 * (nhdrblks - 5)) 63 self.__headerstring__ += rest 64 lump = lump[i - 80: 512] + rest 65 i = 80 66 j = 512 * nhdrblks 67 while i < j : 68 if lump[i-80: i].find(":") > 0: # as for first 512 bytes of header 69 key, val = lump[i - 80: i].split(":", 1) 70 key = key.strip() 71 val = val.strip() 72 if self.header.has_key(key): 73 self.header[key] = self.header[key] + '\n' + val 74 else: 75 self.header[key] = val 76 self.header_keys.append(key) 77 i = i + 80 78 # make a (new) header item called "datastart" 79 self.header['datastart'] = infile.tell() 80 #set the image dimensions 81 self.dim1 = int(self.header['NROWS']) 82 self.dim2 = int(self.header['NCOLS'])
83
84 - def read(self, fname):
85 """ 86 Read in and unpack the pixels (including overflow table 87 """ 88 infile = self._open(fname, "rb") 89 try: 90 self._readheader(infile) 91 except: 92 raise 93 94 rows = self.dim1 95 cols = self.dim2 96 97 try: 98 # you had to read the Bruker docs to know this! 99 npixelb = int(self.header['NPIXELB']) 100 except: 101 errmsg = "length " + str(len(self.header['NPIXELB'])) + "\n" 102 for byt in self.header['NPIXELB']: 103 errmsg += "char: " + str(byt) + " " + str(ord(byt)) + "\n" 104 logging.warning(errmsg) 105 raise 106 107 self.data = readbytestream(infile, infile.tell(), 108 rows, cols, npixelb, 109 datatype="int", 110 signed='n', 111 swap='n') 112 113 #handle overflows 114 nov = int(self.header['NOVERFL']) 115 if nov > 0: # Read in the overflows 116 # need at least int32 sized data I guess - can reach 2^21 117 self.data = self.data.astype(N.uint32) 118 # 16 character overflows: 119 # 9 characters of intensity 120 # 7 character position 121 for i in range(nov): 122 ovfl = infile.read(16) 123 intensity = int(ovfl[0: 9]) 124 position = int(ovfl[9: 16]) 125 # relies on python style modulo being always + 126 row = position % rows 127 # relies on truncation down 128 col = position / rows 129 #print "Overflow ", r, c, intensity, position,\ 130 # self.data[r,c],self.data[c,r] 131 self.data[col, row] = intensity 132 infile.close() 133 134 self.resetvals() 135 self.pilimage = None 136 return self
137 138
139 - def write(self, fname):
140 """ 141 Writes the image as EDF 142 FIXME - this should call edfimage.write if that is wanted? 143 eg: obj = edfimage(data = self.data, header = self.header) 144 obj.write(fname) 145 or maybe something like: edfimage.write(self, fname) 146 """ 147 logging.warning("***warning***: call to unifinished " + \ 148 "brukerimage.write. This will write the file" + \ 149 fname + "as an edf-file") 150 151 152 outfile = self._open(fname, "wb") 153 outfile.write('{\n') 154 i = 4 155 for k in self.header_keys: 156 out = (("%s = %s;\n") % (k, self.header[k])) 157 i = i + len(out) 158 outfile.write(out) 159 out = (4096-i)*' ' 160 outfile.write(out) 161 outfile.write('}\n') 162 # Assumes a short-circuiting if / or ... 163 if not self.header.has_key("ByteOrder") or \ 164 self.header["ByteOrder"] == "LowByteFirst": 165 outfile.write(self.data.astype(N.uint16).tostring()) 166 else: 167 outfile.write(self.data.byteswap().astype( 168 N.uint16).tostring()) 169 outfile.close()
170
171 - def write2(self, fname):
172 """ FIXME: what is this? """ 173 pass
174 175 176
177 -def test():
178 """ a testcase """ 179 import sys, time 180 img = brukerimage() 181 start = time.clock() 182 for filename in sys.argv[1:]: 183 img.read(filename) 184 res = img.toPIL16() 185 img.rebin(2, 2) 186 print filename + (": max=%d, min=%d, mean=%.2e, stddev=%.2e") % ( 187 img.getmax(),img.getmin(), img.getmean(), img.getstddev()) 188 print 'integrated intensity (%d %d %d %d) =%.3f' % ( 189 10, 20, 20, 40, img.integrate_area((10, 20, 20, 40))) 190 end = time.clock() 191 print (end - start)
192 193 194 195 if __name__ == '__main__': 196 test() 197