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

Source Code for Module fabio.mar345image

  1  #!/usr/bin/env python 
  2  """ 
  3   
  4  Authors: Henning O. Sorensen & Erik Knudsen 
  5           Center for Fundamental Research: Metal Structures in Four Dimensions 
  6           Risoe National Laboratory 
  7           Frederiksborgvej 399 
  8           DK-4000 Roskilde 
  9           email:erik.knudsen@risoe.dk 
 10            + 
 11           Jon Wright, ESRF, France 
 12  """ 
 13   
 14  from fabioimage import fabioimage 
 15  import numpy, struct, string 
 16   
17 -class mar345image(fabioimage):
18 _need_a_real_file = True
19 - def read(self, fname):
20 """ Read a mar345 image""" 21 self.filename = fname 22 f = self._open(self.filename, "rb") 23 self._readheader(f) 24 25 try: 26 import mar345_io 27 except: 28 print 'error importing the mar345_io backend - ' + \ 29 'generating empty 1x1 picture' 30 f.close() 31 self.dim1 = 1 32 self.dim2 = 1 33 self.bytecode = numpy.int # 34 self.data = numpy.resize(numpy.array([0], numpy.int), [1, 1]) 35 return self 36 37 if 'compressed' in self.header['Format']: 38 self.data = mar345_io.unpack(f, self.dim1, self.dim2, self.numhigh) 39 else: 40 print "error: cannot handle these formats yet " + \ 41 "due to lack of documentation" 42 return None 43 self.bytecode = numpy.uint 44 f.close() 45 return self
46
47 - def _readheader(self, infile=None):
48 """ Read a mar345 image header """ 49 # clip was not used anywhere - commented out 50 # clip = '\x00' 51 #using a couple of local variables inside this function 52 f = infile 53 h = {} 54 55 #header is 4096 bytes long 56 l = f.read(64) 57 #the contents of the mar345 header is taken to be as 58 # described in 59 # http://www.mar-usa.com/support/downloads/mar345_formats.pdf 60 #the first 64 bytes are 4-byte integers (but in the CBFlib 61 # example image it seems to 128 bytes?) 62 #first 4-byte integer is a marker to check endianness 63 # TODO: turn this into a real check 64 if (l[0:4] == '1234'): 65 fs = 'I' 66 # unsigned integer, was using unsigned long (64 bit?) 67 fs = 'i' 68 #image dimensions 69 self.dim1 = self.dim2 = int(struct.unpack(fs, l[4:8])[0]) 70 #number of high intensity pixels 71 self.numhigh = struct.unpack(fs, l[2 * 4 : (2 + 1) * 4])[0] 72 h['NumHigh'] = self.numhigh 73 #Image format 74 i = struct.unpack(fs, l[3 * 4 : (3 + 1) * 4])[0] 75 if i == 1: 76 h['Format'] = 'compressed' 77 elif i == 2: 78 h['Format'] = 'spiral' 79 else: 80 h['Format'] = 'compressed' 81 print "warning: image format could not be detetermined" + \ 82 "- assuming compressed mar345" 83 #collection mode 84 h['Mode'] = {0:'Dose', 1: 'Time'}[struct.unpack(fs, l[4 * 4:(4 + 1) * 4])[0]] 85 #total number of pixels 86 self.numpixels = struct.unpack(fs, l[5 * 4:(5 + 1) * 4])[0] 87 h['NumPixels'] = str(self.numpixels) 88 #pixel dimensions (length,height) in mm 89 h['PixelLength'] = struct.unpack(fs, l[6 * 4:(6 + 1) * 4])[0] / 1000.0 90 h['PixelHeight'] = struct.unpack(fs, l[7 * 4:(7 + 1) * 4])[0] / 1000.0 91 #x-ray wavelength in AA 92 h['Wavelength'] = struct.unpack(fs, l[8 * 4:(8 + 1) * 4])[0] / 1000000.0 93 #used distance 94 h['Distance'] = struct.unpack(fs, l[9 * 4:(9 + 1) * 4])[0] / 1000.0 95 #starting and ending phi 96 h['StartPhi'] = struct.unpack(fs, l[10 * 4:11 * 4])[0] / 1000.0 97 h['EndPhi'] = struct.unpack(fs, l[11 * 4:12 * 4])[0] / 1000.0 98 #starting and ending omega 99 h['StartOmega'] = struct.unpack(fs, l[12 * 4:13 * 4])[0] / 1000.0 100 h['EndOmega'] = struct.unpack(fs, l[13 * 4:14 * 4])[0] / 1000.0 101 #Chi and Twotheta angles 102 h['Chi'] = struct.unpack(fs, l[14 * 4:15 * 4])[0] / 1000.0 103 h['TwoTheta'] = struct.unpack(fs, l[15 * 4:16 * 4])[0] / 1000.0 104 105 #the rest of the header is ascii 106 # TODO: validate these values against the binaries already read 107 l = f.read(128) 108 if not 'mar research' in l: 109 print "warning: the string \"mar research\" should be in " + \ 110 "bytes 65-76 of the header but was not" 111 l = string.strip(f.read(4096 - 128 - 64)) 112 for m in l.splitlines(): 113 if m == 'END OF HEADER': break 114 n = m.split(' ', 1) 115 if n[0] == '': 116 continue 117 if n[0] in ('PROGRAM', 'DATE', 'SCANNER', 'HIGH', 'MULTIPLIER', 118 'GAIN', 'WAVELENGTH', 'DISTANCE', 'RESOLUTION', 119 'CHI', 'TWOTHETA', 'MODE', 'TIME', 'GENERATOR', 120 'MONOCHROMATOR', 'REMARK'): 121 h[n[0]] = n[1].strip() 122 continue 123 if n[0] in ('FORMAT'): 124 (h['DIM'], h['FORMAT_TYPE'], h['NO_PIXELS']) = n[1].split() 125 continue 126 if n[0] in ('PIXEL', 'OFFSET', 'PHI', 'OMEGA', 'COUNTS', 127 'CENTER', 'INTENSITY', 'HISTOGRAM', 'COLLIMATOR'): 128 n = m.split() 129 h.update([(n[0] + '_' + n[j], n[j + 1]) for j in range(1, len(n), 2)]) 130 continue 131 self.header = h 132 return h
133
134 - def write(self):
135 pass
136