fabio.dm3image

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