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

Source Code for Module fabio.dm3image

  1  """ 
  2  Authors: Henning O. Sorensen & Erik Knudsen 
  3           Center for Fundamental Research: Metal Structures in Four Dimensions 
  4           Risoe National Laboratory 
  5           Frederiksborgvej 399 
  6           DK-4000 Roskilde 
  7           email:erik.knudsen@risoe.dk 
  8   
  9          + Jon Wright, ESRF 
 10  """ 
 11  import logging 
 12  import numpy 
 13  from fabioimage import fabioimage 
 14  logger = logging.getLogger("dm3image") 
 15   
 16  DATA_TYPES = {  2     :  numpy.int16, 
 17                  4     :  numpy.uint16, 
 18                  3     :  numpy.int32, 
 19                  5     :  numpy.uint32, 
 20                  6     :  numpy.float32, 
 21                  7     :  numpy.float, 
 22                  8     :  numpy.int8, 
 23                  9     :  None, 
 24                  10    :  None, 
 25                  15    :  'Struct', 
 26                  18    :  None, 
 27                  20    :  None 
 28                  } 
 29   
 30  DATA_BYTES = {  2     :  2, 
 31                  4     :  2, 
 32                  3     :  4, 
 33                  5     :  4, 
 34                  6     :  4, 
 35                  7     :  8, 
 36                  8     :  1, 
 37                  9     :  None, 
 38                  10    :  None, 
 39                  15    :  'Struct', 
 40                  18    :  None, 
 41                  20    :  None 
 42                  } 
 43   
 44   
 45   
46 -class dm3image(fabioimage):
47 """ Read and try to write the dm3 data format """
48 - def __init__(self, *args, **kwargs):
49 fabioimage.__init__(self, *args, **kwargs) 50 self.encoded_datatype = None 51 self.no_data_elements = None 52 self.grouptag_is_sorted = None 53 self.grouptag_is_open = None 54 self.tag_encoded_type = None 55 self.tag_data_type = None 56 self.tag_is_data = None 57 self.grouptag_no_tags = None 58 self.bytes_in_file = None 59 self.tag_label_length = None 60 self.go_on = None
61
62 - def _readheader(self):
63 self.infile.seek(0) 64 file_format = self.readbytes(4, numpy.uint32)[0] # should be 3 65 assert file_format == 3, 'Wrong file type ' 66 self.bytes_in_file = self.readbytes(4, numpy.uint32)[0] 67 self.byte_order = self.readbytes(4, numpy.uint32)[0] # 0 = big, 1= little 68 print 'read dm3 file - file format ', file_format 69 print 'Bytes in file : ' , self.bytes_in_file 70 print 'Byte order :', self.byte_order, ' - 0 = bigEndian , 1 = littleEndian' 71 72 if self.byte_order == 0: 73 self.swap = True 74 elif self.byte_order == 1: 75 self.swap = False 76 else: 77 raise ValueError
78
79 - def read(self, fname, frame=None):
80 self.header = {} 81 self.resetvals() 82 self.infile = self._open(fname, "rb") 83 self._readheader() 84 self.go_on = True 85 print self.go_on 86 while self.go_on: 87 self.read_tag_group() 88 self.read_tag_entry() 89 if self.infile.tell() > self.bytes_in_file: break 90 91 while self.tag_is_data == 21: 92 self.read_tag_entry() 93 if self.infile.tell() > self.bytes_in_file: 94 self.go_on = False 95 96 (dim1_raw, dim2_raw) = self.header['Active Size (pixels)'].split() 97 (dim1_raw, dim2_raw) = (eval(dim1_raw), eval(dim2_raw)) 98 (dim1_binning, dim2_binning) = self.header['Binning'].split() 99 (dim1_binning, dim2_binning) = (eval(dim1_binning), eval(dim2_binning)) 100 self.dim1 = dim1_raw / dim1_binning 101 self.dim2 = dim2_raw / dim2_binning 102 #print dim1,dim2 103 if self.header.has_key('Data'): 104 self.data = self.header['Data'].reshape(self.dim1, self.dim2)
105
106 - def readbytes(self, bytes_to_read, format, swap=True):
107 raw = self.infile.read(bytes_to_read) 108 if format != None: 109 data = numpy.fromstring(raw, format) 110 else: 111 data = raw 112 if swap: 113 data = data.byteswap() 114 return data
115 116 117
118 - def read_tag_group(self):
119 120 self.grouptag_is_sorted = self.readbytes(1, numpy.uint8)[0] 121 self.grouptag_is_open = self.readbytes(1, numpy.uint8)[0] 122 self.grouptag_no_tags = self.readbytes(4, numpy.uint32)[0] 123 logger.debug('TagGroup is sorted? %s', self.grouptag_is_sorted) 124 logger.debug('TagGroup is open? %s', self.grouptag_is_open) 125 logger.debug('no of tags in TagGroup %s', self.grouptag_no_tags)
126
127 - def read_tag_entry(self):
128 129 self.tag_is_data = self.readbytes(1, numpy.uint8)[0] 130 self.tag_label_length = self.readbytes(2, numpy.uint16)[0] 131 logger.debug('does Tag have data ? %s - 20 = Tag group , 21 = data ', self.tag_is_data) 132 logger.debug('length of tag_label ', self.tag_label_length) 133 if self.tag_label_length != 0: 134 tag_label = self.infile.read(self.tag_label_length) 135 else: 136 tag_label = None 137 138 if self.tag_is_data == 21: 139 # This is data 140 self.header[tag_label] = self.read_tag_type() 141 logger.debug("%s: %s", tag_label, self.header[tag_label])
142 143
144 - def read_tag_type(self):
145 if self.infile.read(4) != '%%%%': 146 raise IOError 147 self.tag_data_type = self.readbytes(4, numpy.uint32)[0] 148 logger.debug('data is of type : %s - 1 = simple, 2= string, 3 = array, >3 structs', self.tag_data_type) 149 self.tag_encoded_type = self.readbytes(4, numpy.uint32)[0] 150 logger.debug('encode type: %s %s', self.tag_encoded_type, DATA_TYPES[ self.tag_encoded_type]) 151 if self.tag_data_type == 1: 152 # simple type 153 return self.readbytes(DATA_BYTES[ self.tag_encoded_type], 154 DATA_TYPES[ self.tag_encoded_type], 155 swap=self.swap)[0] 156 # are the data stored in a simple array? 157 if self.tag_encoded_type == 20 and self.tag_data_type == 3 : 158 self.data_type = self.readbytes(4, numpy.uint32)[0] 159 self.no_data_elements = self.readbytes(4, numpy.uint32)[0] 160 if self.data_type == 10: 161 logger.debug('skip bytes %s', self.no_data_elements) 162 dump = self.infile.read(self.no_data_elements) 163 return None 164 165 logger.debug('Data are stored as a simple a array -') 166 logger.debug('%s data elemets stored as %s', self.no_data_elements, self.data_type) 167 read_no_bytes = DATA_BYTES[self.data_type] * self.no_data_elements 168 format = DATA_TYPES[self.data_type] 169 return self.readbytes(read_no_bytes, format, swap=self.swap) 170 171 # are the data stored in a complex array ? 172 # print 'tag_type + data_type', self.tag_encoded_type,self.tag_data_type 173 174 #print self.tag_encoded_type , self.tag_data_type 175 if self.tag_encoded_type == 20 and self.tag_data_type > 3 : 176 self.tag_encoded_type = self.readbytes(4, numpy.uint32)[0] 177 logger.debug('found array - new tag_encoded_type %s', self.tag_encoded_type) 178 if self.tag_encoded_type == 15: # struct type 179 ###type = self.readbytes(4,numpy.int32) 180 struct_name_length = self.readbytes(4, numpy.int32)[0] 181 struct_number_fields = self.readbytes(4, numpy.int32)[0] 182 #print 'struct - name_length, number_field', struct_name_length,struct_number_fields 183 #print self.infile.read(struct_name_length) 184 field_info = [] 185 for i in range(struct_number_fields): 186 field_info.append([self.readbytes(4, numpy.int32)[0], self.readbytes(4, numpy.int32)[0]]) 187 #print field_info 188 self.no_data_elements = self.readbytes(4, numpy.int32)[0] 189 #print '%i data elemets stored as ' %self.no_data_elements 190 bytes_in_struct = 0 191 for i in range(struct_number_fields): 192 bytes_in_struct += DATA_BYTES[field_info[i][1]] 193 logger.debug('skip bytes %s', self.no_data_elements * bytes_in_struct) 194 dump = self.infile.read(self.no_data_elements * bytes_in_struct) 195 return None 196 197 198 if self.tag_encoded_type == 15: # struct type 199 ###type = self.readbytes(4,numpy.int32) 200 struct_name_length = self.readbytes(4, numpy.int32)[0] 201 struct_number_fields = self.readbytes(4, numpy.int32)[0] 202 #print 'struct - name_length, number_field', struct_name_length,struct_number_fields 203 #print self.infile.read(struct_name_length) 204 field_info = [] 205 for i in range(struct_number_fields): 206 field_info.append([self.readbytes(4, numpy.int32)[0], self.readbytes(4, numpy.int32)[0]]) 207 #print field_info 208 field_data = '' 209 for i in range(struct_number_fields): 210 #print type(i) 211 field_data = field_data + self.readbytes(field_info[i][0], None, swap=False) + ' ' 212 field_data = field_data + '%i ' % self.readbytes(DATA_BYTES[field_info[i][1]], 213 DATA_TYPES[field_info[i][1]], 214 swap=self.swap)[0] 215 return field_data
216
217 - def read_data(self):
218 self.encoded_datatype = numpy.fromstring(self.infile.read(4), numpy.uint32).byteswap()
219