fabio.kcdimage

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

# Source Code for Module fabio.kcdimage

      1  #!/usr/bin/env python
      2  """
      3  Authors: Jerome Kieffer, ESRF
      4           email:jerome.kieffer@esrf.fr
      5
      6  kcd images are 2D images written by the old KappaCCD diffractometer built by Nonius in the 1990's
      7  Based on the edfimage.py parser.
      8  """
      9
     10  import numpy, logging
     11  import os, string
     12  from fabioimage import fabioimage
     13  logger = logging.getLogger("kcdimage")
     14
     15  DATA_TYPES = {"u16"  :  numpy.uint16 }
     16
     17  MINIMUM_KEYS = [
     18                  'ByteOrder',
     19                  'Data type',
     20                  'X dimension',
     21                  'Y dimension',
     22                  'Number of readouts']
     23
     24  DEFAULT_VALUES = { "Data type": "u16" }
     25
     26
     27
     28
     29 -class kcdimage(fabioimage):
     30      """
     31      Read the Nonius kcd data format """
     32
     33
     34 -    def _readheader(self, infile):
     35          """
     36          Read in a header in some KCD format from an already open file
     37          @
     38          """
     39          oneLine = infile.readline()
     40          alphanum = string.digits + string.letters + ". "
     41          asciiHeader = True
     42          for oneChar in oneLine.strip():
     43              if not oneChar in alphanum:
     44                  asciiHeader = False
     45
     46
     47          if asciiHeader is False:
     48              # This does not look like an edf file
     49              logger.warning("First line of %s does not seam to be ascii text!" % infile.name)
     50          endOfHeaders = False
     51          while not endOfHeaders:
     52              oneLine = infile.readline()
     53              if len(oneLine) > 100:
     54                  endOfHeaders = True
     55                  break
     56              if oneLine.strip() == "Binned mode":
     57                  oneLine = "Mode = Binned"
     58              try:
     59                  key, val = oneLine.split('=' , 1)
     60              except:
     61                  endOfHeaders = True
     62                  break
     63              key = key.strip()
     64              self.header_keys.append(key)
     65              self.header[key] = val.strip()
     66          missing = []
     67          for item in MINIMUM_KEYS:
     68              if item not in self.header_keys:
     69                  missing.append(item)
     70          if len(missing) > 0:
     71              logger.debug("KCD file misses the keys " + " ".join(missing))
     72
     73
     74 -    def read(self, fname, frame=None):
     75          """
     76          Read in header into self.header and
     77              the data   into self.data
     78          """
     79          self.header = {}
     80          self.resetvals()
     81          infile = self._open(fname, "rb")
     82          self._readheader(infile)
     83          # Compute image size
     84          try:
     85              self.dim1 = int(self.header['X dimension'])
     86              self.dim2 = int(self.header['Y dimension'])
     87          except:
     88              raise Exception("KCD file %s is corrupt, cannot read it" % fname)
     89          try:
     90              bytecode = DATA_TYPES[self.header['Data type']]
     91              self.bpp = len(numpy.array(0, bytecode).tostring())
     92          except KeyError:
     93              bytecode = numpy.uint16
     94              self.bpp = 2
     95              logger.warning("Defaulting type to uint16")
     96          try:
     97              nbReadOut = int(self.header['Number of readouts'])
     98          except KeyError:
     99              logger.warning("Defaulting number of ReadOut to 1")
    100              nbReadOut = 1
    101          fileSize = os.stat(fname)[6]
    102          expected_size = self.dim1 * self.dim2 * self.bpp * nbReadOut
    103          infile.seek(fileSize - expected_size)
    104          block = infile.read()
    105          assert len(block) == expected_size
    106          infile.close()
    107
    108          #now read the data into the array
    109          self.data = numpy.zeros((self.dim2, self.dim1))
    110          try:
    111              for i in range(nbReadOut):
    112                  self.data += numpy.reshape(numpy.fromstring(
    113                      block[i * expected_size / nbReadOut:(i + 1) * expected_size / nbReadOut], bytecode),
    114                      [self.dim2, self.dim1])
    115          except:
    116              print len(block), bytecode, self.bpp, self.dim2, self.dim1
    117              raise IOError, \
    118                'Size spec in kcd-header does not match size of image data field'
    119          self.bytecode = self.data.dtype.type
    120          self.resetvals()
    121          # ensure the PIL image is reset
    122          self.pilimage = None
    123          return self
    124
    125
    126      @staticmethod
    127 -    def checkData(data=None):
    128          if data is None:
    129              return None
    130          else:
    131              return data.astype(int)
    132