Source code for fabio.adscimage

#!/usr/bin/env python
#coding: utf8
"""

Authors: Henning O. Sorensen & Erik Knudsen
         Center for Fundamental Research: Metal Structures in Four Dimensions
         Risoe National Laboratory
         Frederiksborgvej 399
         DK-4000 Roskilde
         email:erik.knudsen@risoe.dk

+ mods for fabio by JPW

"""

import numpy, logging
from fabioimage import fabioimage
logger = logging.getLogger("adscimage")

[docs]class adscimage(fabioimage): """ Read an image in ADSC format (quite similar to edf?) """ def __init__(self, *args, **kwargs): fabioimage.__init__(self, *args, **kwargs)
[docs] def read(self, fname, frame=None): """ read in the file """ infile = self._open(fname, "rb") try: self._readheader(infile) except: raise Exception("Error processing adsc header") # banned by bzip/gzip??? try: infile.seek(int(self.header['HEADER_BYTES']), 0) except TypeError: # Gzipped does not allow a seek and read header is not # promising to stop in the right place infile.close() infile = self._open(fname, "rb") infile.read(int(self.header['HEADER_BYTES'])) binary = infile.read() infile.close() #now read the data into the array self.dim1 = int(self.header['SIZE1']) self.dim2 = int(self.header['SIZE2']) if 'little' in self.header['BYTE_ORDER']: try: self.data = numpy.reshape( numpy.fromstring(binary, numpy.uint16), (self.dim2, self.dim1)) except ValueError: raise IOError, 'Size spec in ADSC-header does not match ' + \ 'size of image data field' self.bytecode = numpy.uint16 logger.info("adscimage read in using low byte first (x386-order)") else: try: self.data = numpy.reshape( numpy.fromstring(binary, numpy.uint16), (self.dim2, self.dim1)).byteswap() except ValueError: raise IOError, 'Size spec in ADSC-header does not match ' + \ 'size of image data field' self.bytecode = numpy.uint16 logger.info('adscimage using high byte first (network order)') self.resetvals() return self
def _readheader(self, infile): """ read an adsc header """ line = infile.readline() bytesread = len(line) while '}' not in line: if '=' in line: (key, val) = line.split('=') self.header_keys.append(key.strip()) self.header[key.strip()] = val.strip(' ;\n') line = infile.readline() bytesread = bytesread + len(line)
[docs] def write(self, fname): """ Write adsc format """ out = '{\n' for key in self.header_keys: out += "%s = %s;\n" % (key, self.header[key]) # FIXME ??? - made padding match header bytes keyword # the cbflib example image has exactly 512... if self.header.has_key("HEADER_BYTES"): pad = int(self.header["HEADER_BYTES"]) - len(out) - 2 else: # integer division # 1234567890123456789012 # HEADER_BYTES = 1234;\n hsize = ((len(out) + 23) / 512 + 1) * 512 out += "HEADER_BYTES=%d;\n" % (hsize) pad = hsize - len(out) - 2 out += pad * ' ' + "}\n" assert len(out) % 512 == 0 , "Header is not multiple of 512" outf = open(fname, "wb") outf.write(out) # it says "unsigned_short" ? ... jpw example has: # BYTE_ORDER=big_endian; # TYPE=unsigned_short; if "little" in self.header["BYTE_ORDER"]: outf.write(self.data.astype(numpy.uint16).tostring()) else: outf.write(self.data.byteswap().astype( numpy.uint16).tostring()) outf.close()
[docs]def test(): """ testcase """ import sys, time img = adscimage() begin = time.clock() while (sys.argv[1:]): img.read(sys.argv[1]) # rim = img.toPIL16() img.rebin(2, 2) img.write('jegErEnFil0000.img') print sys.argv[1] + ": max=%d, min=%d, mean=%.2e, stddev=%.2e" % (\ img.getmax(), img.getmin(), img.getmean(), img.getstddev()) print 'integrated intensity (%d %d %d %d) =%.3f' % (\ 10, 20, 20, 40, img.integrate_area((10, 20, 20, 40))) sys.argv[1:] = sys.argv[2:] end = time.clock() print end - begin
if __name__ == '__main__': test()