fabio.xsdimage

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

# Source Code for Module fabio.xsdimage

      1  #!/usr/bin/env python
      2  # coding: utf8
      3  """
      4  Authors: Jérôme Kieffer, ESRF
      5           email:jerome.kieffer@esrf.fr
      6
      7  XSDimge are XML files containing numpy arrays
      8  """
      9  __author__ = "Jérôme Kieffer"
     10  __contact__ = "jerome.kieffer@esrf.eu"
     11  __license__ = "GPLv3+"
     12  __copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
     13
     14  import logging, numpy
     15  logger = logging.getLogger("xsdimage")
     16  from fabioimage import fabioimage
     17  import base64, hashlib
     18  try:
     19      from lxml import etree
     20  except ImportError:
     21      logger.warning("lxml library is probably not part of your python installation: disabling xsdimage format")
     22      etree = None
     23
     24 -class xsdimage(fabioimage):
     25      """
     26      Read the XSDataImage XML File data format
     27      """
     28 -    def __init__(self, data=None, header=None, fname=None):
     29          """
     30          Constructor of the class XSDataImage.
     31
     32          @param _strFilename: the name of the file to open
     33          @type  _strFilename: string
     34          """
     35          fabioimage.__init__(self, data=data, header=header)
     36          self.dims = []
     37          self.size = None
     38          self.coding = None
     39          self.dtype = None
     40          self.rawData = None
     41          self.md5 = None
     42          if fname is not None:
     43              self.filename = fname
     44              self.read(fname)
     45
     46 -    def read(self, fname, frame=None):
     47          """
     48          """
     49          self.header = {}
     50          self.resetvals()
     51          self.filename = fname
     52          infile = self._open(fname, "rb")
     53          self._readheader(infile)
     54
     55          try:
     56              self.dim1, self.dim2 = self.dims[:2]
     57          except:
     58              raise IOError("XSD file %s is corrupt, no dimensions in it" % fname)
     59          try:
     60              self.bytecode = numpy.dtype(self.dtype).type
     61              self.bpp = len(numpy.array(0, self.bytecode).tostring())
     62          except TypeError:
     63              self.bytecode = numpy.int32
     64              self.bpp = 32
     65              logger.warning("Defaulting type to int32")
     66
     67          exp_size = 1
     68          for i in self.dims:
     69              exp_size *= i
     70          assert exp_size == self.size
     71
     72          decData = None
     73          if self.coding == "base64":
     74              decData = base64.b64decode(self.rawData)
     75          elif self.coding == "base32":
     76              decData = base64.b32decode(self.rawData)
     77          elif self.coding == "base16":
     78              decData = base64.b16decode(self.rawData)
     79          else:
     80              logger.warning("Unable to recognize the encoding of the data !!! got %s, expected base64, base32 or base16, I assume it is base64 " % self.coding)
     81              decData = base64.b64decode(self.rawData)
     82          if self.md5:
     83              assert  hashlib.md5(decData).hexdigest() == self.md5
     84
     85
     86          self.data = numpy.fromstring(decData, dtype=self.bytecode).reshape(tuple(self.dims))
     87          if not numpy.little_endian: #by default little endian
     88              self.data.byteswap(inplace=True)
     89          self.resetvals()
     90  #        # ensure the PIL image is reset
     91          self.pilimage = None
     92          return self
     93
     94 -    def _readheader(self, infile):
     95          """
     96          Read all headers in a file and populate self.header
     97          data is not yet populated
     98          @type infile: file object open in read mode
     99          """
    100          xml = etree.parse(infile)
    101          self.dims = []
    102          for i in xml.xpath("//shape"):
    103              try:
    104                  self.dims.append(int(i.text))
    105              except ValueError, error:
    106                  logger.warning("%s Shape: Unable to convert %s to integer in %s" % (error, i.text, i))
    107          for i in xml.xpath("//size"):
    108              try:
    109                  self.size = int(i.text)
    110              except Exception, error:#IGNORE:W0703
    111                  logger.warning("%s Size: Unable to convert %s to integer in %s" % (error, i.text, i))
    112          self.dtype = None
    113          for i in xml.xpath("//dtype"):
    114              self.dtype = i.text
    115          self.coding = None
    116          for i in xml.xpath("//coding"):
    117              j = i.find("value")
    118              if j is not None:
    119                  self.coding = j.text
    120          self.rawData = None
    121          for i in xml.xpath("//data"):
    122              self.rawData = i.text
    123          self.md5 = None
    124          for i in xml.xpath("//md5sum"):
    125              j = i.find("value")
    126              if j is not None:
    127                  self.md5 = j.text
    128
    129  if etree is None:
    130      xsdimage = None
    131