fabio.adscimage

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

# Source Code for Module fabio.adscimage

      1  #!/usr/bin/env python
      2  #coding: utf8
      3  """
      4
      5  Authors: Henning O. Sorensen & Erik Knudsen
      6           Center for Fundamental Research: Metal Structures in Four Dimensions
      7           Risoe National Laboratory
      8           Frederiksborgvej 399
      9           DK-4000 Roskilde
     10           email:erik.knudsen@risoe.dk
     11
     12  + mods for fabio by JPW
     13
     14  """
     15
     16  import numpy, logging
     17  from fabioimage import fabioimage
     18  logger = logging.getLogger("adscimage")
     19
     20 -class adscimage(fabioimage):
     21      """ Read an image in ADSC format (quite similar to edf?) """
     22 -    def __init__(self, *args, **kwargs):
     23          fabioimage.__init__(self, *args, **kwargs)
     24
     25 -    def read(self, fname, frame=None):
     26          """ read in the file """
     27          infile = self._open(fname, "rb")
     28          try:
     29              self._readheader(infile)
     30          except:
     31              raise Exception("Error processing adsc header")
     32          # banned by bzip/gzip???
     33          try:
     34              infile.seek(int(self.header['HEADER_BYTES']), 0)
     35          except TypeError:
     36              # Gzipped does not allow a seek and read header is not
     37              # promising to stop in the right place
     38              infile.close()
     39              infile = self._open(fname, "rb")
     40              infile.read(int(self.header['HEADER_BYTES']))
     41          binary = infile.read()
     42          infile.close()
     43
     44          #now read the data into the array
     45          self.dim1 = int(self.header['SIZE1'])
     46          self.dim2 = int(self.header['SIZE2'])
     47          if 'little' in self.header['BYTE_ORDER']:
     48              try:
     49                  self.data = numpy.reshape(
     50                      numpy.fromstring(binary, numpy.uint16),
     51                      (self.dim2, self.dim1))
     52              except ValueError:
     53                  raise IOError, 'Size spec in ADSC-header does not match ' + \
     54                      'size of image data field'
     55              self.bytecode = numpy.uint16
     56              logger.info("adscimage read in using low byte first (x386-order)")
     57          else:
     58              try:
     59                  self.data = numpy.reshape(
     60                      numpy.fromstring(binary, numpy.uint16),
     61                      (self.dim2, self.dim1)).byteswap()
     62              except ValueError:
     63                  raise IOError, 'Size spec in ADSC-header does not match ' + \
     64                      'size of image data field'
     65              self.bytecode = numpy.uint16
     66              logger.info('adscimage using high byte first (network order)')
     67          self.resetvals()
     68          return self
     69
     70
     71 -    def _readheader(self, infile):
     72          """ read an adsc header """
     73          line = infile.readline()
     74          bytesread = len(line)
     75          while '}' not in line:
     76              if '=' in line:
     77                  (key, val) = line.split('=')
     78                  self.header_keys.append(key.strip())
     79                  self.header[key.strip()] = val.strip(' ;\n')
     80              line = infile.readline()
     81              bytesread = bytesread + len(line)
     82
     83
     84 -    def write(self, fname):
     85          """
     86          Write adsc format
     87          """
     88          out = '{\n'
     89          for key in self.header_keys:
     90              out += "%s = %s;\n" % (key, self.header[key])
     91          # FIXME ??? - made padding match header bytes keyword
     92          #        the cbflib example image has exactly 512...
     93          if self.header.has_key("HEADER_BYTES"):
     94              pad = int(self.header["HEADER_BYTES"]) - len(out) - 2
     95          else:
     96              # integer division
     97              # 1234567890123456789012
     98              # HEADER_BYTES = 1234;\n
     99              hsize = ((len(out) + 23) / 512 + 1) * 512
    100              out += "HEADER_BYTES=%d;\n" % (hsize)
    101              pad = hsize - len(out) - 2
    102          out += pad * ' ' + "}\n"
    103          assert len(out) % 512 == 0 , "Header is not multiple of 512"
    104          outf = open(fname, "wb")
    105          outf.write(out)
    106          # it says "unsigned_short" ? ... jpw example has:
    107          # BYTE_ORDER=big_endian;
    108          # TYPE=unsigned_short;
    109          if "little" in self.header["BYTE_ORDER"]:
    110              outf.write(self.data.astype(numpy.uint16).tostring())
    111          else:
    112              outf.write(self.data.byteswap().astype(
    113                      numpy.uint16).tostring())
    114          outf.close()
    115
    116
    117 -def test():
    118      """ testcase """
    119      import sys, time
    120      img = adscimage()
    121      begin = time.clock()
    122      while (sys.argv[1:]):
    123          img.read(sys.argv[1])
    124  #        rim = img.toPIL16()
    125          img.rebin(2, 2)
    126          img.write('jegErEnFil0000.img')
    127          print sys.argv[1] + ": max=%d, min=%d, mean=%.2e, stddev=%.2e" % (\
    128                img.getmax(), img.getmin(), img.getmean(), img.getstddev())
    129          print 'integrated intensity (%d %d %d %d) =%.3f' % (\
    130                10, 20, 20, 40, img.integrate_area((10, 20, 20, 40)))
    131          sys.argv[1:] = sys.argv[2:]
    132      end = time.clock()
    133      print end - begin
    134
    135
    136  if __name__ == '__main__':
    137      test()
    138