fabio 0.1.1__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Library/Python/2.7/site-packages/fabio/GEimage.py +334 -0
- Library/Python/2.7/site-packages/fabio/GEimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/GEimage_old.py +501 -0
- Library/Python/2.7/site-packages/fabio/GEimage_old.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/HiPiCimage.py +106 -0
- Library/Python/2.7/site-packages/fabio/HiPiCimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/OXDimage.py +442 -0
- Library/Python/2.7/site-packages/fabio/OXDimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/TiffIO.py +1197 -0
- Library/Python/2.7/site-packages/fabio/TiffIO.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/__init__.py +10 -0
- Library/Python/2.7/site-packages/fabio/__init__.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/adscimage.py +137 -0
- Library/Python/2.7/site-packages/fabio/adscimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/binaryimage.py +87 -0
- Library/Python/2.7/site-packages/fabio/binaryimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/bruker100image.py +96 -0
- Library/Python/2.7/site-packages/fabio/bruker100image.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/brukerimage.py +195 -0
- Library/Python/2.7/site-packages/fabio/brukerimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/byte_offset.so +0 -0
- Library/Python/2.7/site-packages/fabio/cbfimage.py +758 -0
- Library/Python/2.7/site-packages/fabio/cbfimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/cf_io.so +0 -0
- Library/Python/2.7/site-packages/fabio/compression.py +388 -0
- Library/Python/2.7/site-packages/fabio/compression.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/converters.py +54 -0
- Library/Python/2.7/site-packages/fabio/converters.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/datIO.py +60 -0
- Library/Python/2.7/site-packages/fabio/datIO.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/dm3image.py +219 -0
- Library/Python/2.7/site-packages/fabio/dm3image.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/edfimage.py +924 -0
- Library/Python/2.7/site-packages/fabio/edfimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fabioimage.py +556 -0
- Library/Python/2.7/site-packages/fabio/fabioimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fabioutils.py +491 -0
- Library/Python/2.7/site-packages/fabio/fabioutils.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/file_series.py +313 -0
- Library/Python/2.7/site-packages/fabio/file_series.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fit2dmaskimage.py +94 -0
- Library/Python/2.7/site-packages/fabio/fit2dmaskimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fit2dspreadsheetimage.py +85 -0
- Library/Python/2.7/site-packages/fabio/fit2dspreadsheetimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/kcdimage.py +131 -0
- Library/Python/2.7/site-packages/fabio/kcdimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/mar345_IO.so +0 -0
- Library/Python/2.7/site-packages/fabio/mar345image.py +320 -0
- Library/Python/2.7/site-packages/fabio/mar345image.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/marccdimage.py +309 -0
- Library/Python/2.7/site-packages/fabio/marccdimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/openimage.py +162 -0
- Library/Python/2.7/site-packages/fabio/openimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/pilatusimage.py +81 -0
- Library/Python/2.7/site-packages/fabio/pilatusimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/pnmimage.py +165 -0
- Library/Python/2.7/site-packages/fabio/pnmimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/readbytestream.py +86 -0
- Library/Python/2.7/site-packages/fabio/readbytestream.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/tifimage.py +283 -0
- Library/Python/2.7/site-packages/fabio/tifimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/xsdimage.py +134 -0
- Library/Python/2.7/site-packages/fabio/xsdimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/PKG-INFO +11 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/SOURCES.txt +114 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/dependency_links.txt +1 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/top_level.txt +4 -0
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
version = "0.1.1"
|
|
2
|
+
import logging
|
|
3
|
+
logging.basicConfig()
|
|
4
|
+
import fabioimage
|
|
5
|
+
import openimage
|
|
6
|
+
from fabioutils import filename_object, COMPRESSORS, jump_filename, \
|
|
7
|
+
previous_filename, next_filename, deconstruct_filename, \
|
|
8
|
+
extract_filenumber, getnum, construct_filename
|
|
9
|
+
from openimage import openimage as open
|
|
10
|
+
from openimage import openheader as openheader
|
|
Binary file
|
|
@@ -0,0 +1,137 @@
|
|
|
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()
|
|
Binary file
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
#coding: utf8
|
|
3
|
+
from __future__ import with_statement
|
|
4
|
+
__doc__ = """
|
|
5
|
+
Authors: Gael Goret, Jerome Kieffer, ESRF, France
|
|
6
|
+
Emails: gael.goret@esrf.fr, jerome.kieffer@esrf.fr
|
|
7
|
+
|
|
8
|
+
Binary files images are simple none-compressed 2D images only defined by their :
|
|
9
|
+
data-type, dimensions, byte order and offset
|
|
10
|
+
|
|
11
|
+
This simple library has been made for manipulating exotic/unknown files format.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__authors__ = ["Gaël Goret", "Jérôme Kieffer"]
|
|
15
|
+
__contact__ = "gael.goret@esrf.fr"#, jerome.kieffer@esrf.eu"
|
|
16
|
+
__license__ = "GPLv3+"
|
|
17
|
+
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
|
|
18
|
+
__version__ = "17 Apr 2012"
|
|
19
|
+
|
|
20
|
+
from fabioimage import fabioimage
|
|
21
|
+
import numpy, logging
|
|
22
|
+
logger = logging.getLogger("binaryimage")
|
|
23
|
+
|
|
24
|
+
class binaryimage(fabioimage):
|
|
25
|
+
"""
|
|
26
|
+
This simple library has been made for manipulating exotic/unknown files format.
|
|
27
|
+
|
|
28
|
+
Binary files images are simple none-compressed 2D images only defined by their :
|
|
29
|
+
data-type, dimensions, byte order and offset
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, *args, **kwargs):
|
|
33
|
+
fabioimage.__init__(self, *args, **kwargs)
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def swap_needed(endian):
|
|
37
|
+
"""
|
|
38
|
+
Decide if we need to byteswap
|
|
39
|
+
"""
|
|
40
|
+
if (endian == '<' and numpy.little_endian) or (endian == '>' and not numpy.little_endian):
|
|
41
|
+
return False
|
|
42
|
+
if (endian == '>' and numpy.little_endian) or (endian == '<' and not numpy.little_endian):
|
|
43
|
+
return True
|
|
44
|
+
|
|
45
|
+
def read(self, fname, dim1, dim2, offset=0, bytecode="int32", endian="<"):
|
|
46
|
+
"""
|
|
47
|
+
Read a binary image
|
|
48
|
+
Parameters : fname, dim1, dim2, offset, bytecode, endian
|
|
49
|
+
fname : file name : str
|
|
50
|
+
dim1,dim2 : image dimensions : int
|
|
51
|
+
offset : size of the : int
|
|
52
|
+
bytecode among : "int8","int16","int32","int64","uint8","uint16","uint32","uint64","float32","float64",...
|
|
53
|
+
endian among short or long endian ("<" or ">")
|
|
54
|
+
"""
|
|
55
|
+
self.filename = fname
|
|
56
|
+
self.dim1 = dim1
|
|
57
|
+
self.dim2 = dim2
|
|
58
|
+
self.bytecode = bytecode
|
|
59
|
+
f = open(self.filename, "rb")
|
|
60
|
+
dims = [dim2, dim1]
|
|
61
|
+
bpp = len(numpy.array(0, bytecode).tostring())
|
|
62
|
+
size = dims[0] * dims[1] * bpp
|
|
63
|
+
|
|
64
|
+
f.seek(offset)
|
|
65
|
+
rawData = f.read(size)
|
|
66
|
+
if self.swap_needed(endian):
|
|
67
|
+
data = numpy.fromstring(rawData, bytecode).byteswap().reshape(tuple(dims))
|
|
68
|
+
else:
|
|
69
|
+
data = numpy.fromstring(rawData, bytecode).reshape(tuple(dims))
|
|
70
|
+
self.data = data
|
|
71
|
+
return self
|
|
72
|
+
|
|
73
|
+
def estimate_offset_value(self, fname, dim1, dim2, bytecode="int32"):
|
|
74
|
+
"Estimates the size of a file"
|
|
75
|
+
with open(fname, "rb") as f:
|
|
76
|
+
bpp = len(numpy.array(0, bytecode).tostring())
|
|
77
|
+
size = dim1 * dim2 * bpp
|
|
78
|
+
totsize = len(f.read())
|
|
79
|
+
logger.info('total size (bytes): %s', totsize)
|
|
80
|
+
logger.info('expected data size given parameters (bytes): %s', size)
|
|
81
|
+
logger.info('estimation of the offset value (bytes): %s', totsize - size)
|
|
82
|
+
|
|
83
|
+
def write(self, fname):
|
|
84
|
+
with open(fname, mode="wb") as outfile:
|
|
85
|
+
outfile.write(self.data.tostring())
|
|
86
|
+
|
|
87
|
+
|
|
Binary file
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
import math
|
|
3
|
+
import logging
|
|
4
|
+
logger = logging.getLogger("bruker100image")
|
|
5
|
+
try:
|
|
6
|
+
import Image
|
|
7
|
+
except ImportError:
|
|
8
|
+
logger.warning("PIL is not installed ... trying to do without")
|
|
9
|
+
Image = None
|
|
10
|
+
|
|
11
|
+
from brukerimage import brukerimage
|
|
12
|
+
from readbytestream import readbytestream
|
|
13
|
+
|
|
14
|
+
class bruker100image(brukerimage):
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def toPIL16(self, filename=None):
|
|
18
|
+
if not Image:
|
|
19
|
+
raise RuntimeError("PIL is not installed !!! ")
|
|
20
|
+
|
|
21
|
+
if filename:
|
|
22
|
+
self.read(filename)
|
|
23
|
+
PILimage = Image.frombuffer("F",
|
|
24
|
+
(self.dim1, self.dim2),
|
|
25
|
+
self.data,
|
|
26
|
+
"raw",
|
|
27
|
+
"F;16", 0, -1)
|
|
28
|
+
return PILimage
|
|
29
|
+
|
|
30
|
+
def read(self, fname, frame=None):
|
|
31
|
+
f = open(fname, "rb")
|
|
32
|
+
try:
|
|
33
|
+
self._readheader(f)
|
|
34
|
+
except:
|
|
35
|
+
raise
|
|
36
|
+
|
|
37
|
+
rows = int(self.header['NROWS'])
|
|
38
|
+
cols = int(self.header['NCOLS'])
|
|
39
|
+
npixelb = int(self.header['NPIXELB'][0])
|
|
40
|
+
# you had to read the Bruker docs to know this!
|
|
41
|
+
|
|
42
|
+
# We are now at the start of the image - assuming
|
|
43
|
+
# readbrukerheader worked
|
|
44
|
+
# size = rows * cols * npixelb
|
|
45
|
+
self.data = readbytestream(f, f.tell(), rows, cols, npixelb,
|
|
46
|
+
datatype="int", signed='n', swap='n')
|
|
47
|
+
|
|
48
|
+
noverfl = self.header['NOVERFL'].split() # now process the overflows
|
|
49
|
+
#read the set of "underflow pixels" - these will be completely
|
|
50
|
+
# disregarded for now
|
|
51
|
+
data = self.data
|
|
52
|
+
k = 0
|
|
53
|
+
|
|
54
|
+
while k < 2:#for the time being things - are done in 16 bits
|
|
55
|
+
datatype = {'1' : numpy.uint8,
|
|
56
|
+
'2' : numpy.uint16,
|
|
57
|
+
'4' : numpy.uint32 }[("%d" % 2 ** k)]
|
|
58
|
+
ar = numpy.array(numpy.fromstring(f.read(int(noverfl[k]) * (2 ** k)),
|
|
59
|
+
datatype), numpy.uint16)
|
|
60
|
+
#insert the the overflow pixels in the image array:
|
|
61
|
+
#this is probably a memory intensive way of doing this -
|
|
62
|
+
# might be done in a more clever way
|
|
63
|
+
lim = 2 ** (8 * k) - 1
|
|
64
|
+
#generate an array comprising of the indices into data.ravel()
|
|
65
|
+
# where its value equals lim.
|
|
66
|
+
M = numpy.compress(numpy.equal(data.ravel(), lim), numpy.arange(rows * cols))
|
|
67
|
+
#now put values from ar into those indices
|
|
68
|
+
numpy.put(data.ravel(), M, ar)
|
|
69
|
+
padding = 16 * int(math.ceil(int(noverfl[k]) * (2 ** k) / 16.)) - \
|
|
70
|
+
int(noverfl[k]) * (2 ** k)
|
|
71
|
+
f.seek(padding, 1)
|
|
72
|
+
print noverfl[k] + " bytes read + %d bytes padding" % padding
|
|
73
|
+
k = k + 1
|
|
74
|
+
|
|
75
|
+
f.close()
|
|
76
|
+
|
|
77
|
+
(self.dim1, self.dim2) = (rows, cols)
|
|
78
|
+
print self.dim1, self.dim2
|
|
79
|
+
self.resetvals()
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
if __name__ == '__main__':
|
|
83
|
+
import sys, time
|
|
84
|
+
I = bruker100image()
|
|
85
|
+
b = time.clock()
|
|
86
|
+
while (sys.argv[1:]):
|
|
87
|
+
I.read(sys.argv[1])
|
|
88
|
+
r = I.toPIL16()
|
|
89
|
+
I.rebin(2, 2)
|
|
90
|
+
print sys.argv[1] + (": max=%d, min=%d, mean=%.2e, stddev=%.2e") % (
|
|
91
|
+
I.getmax(), I.getmin(), I.getmean(), I.getstddev())
|
|
92
|
+
print 'integrated intensity (%d %d %d %d) =%.3f' % (
|
|
93
|
+
10, 20, 20, 40, I.integrate_area((10, 20, 20, 40)))
|
|
94
|
+
sys.argv[1:] = sys.argv[2:]
|
|
95
|
+
e = time.clock()
|
|
96
|
+
print (e - b)
|
|
Binary file
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
Authors: Henning O. Sorensen & Erik Knudsen
|
|
5
|
+
Center for Fundamental Research: Metal Structures in Four Dimensions
|
|
6
|
+
Risoe National Laboratory
|
|
7
|
+
Frederiksborgvej 399
|
|
8
|
+
DK-4000 Roskilde
|
|
9
|
+
email:erik.knudsen@risoe.dk
|
|
10
|
+
|
|
11
|
+
Based on: openbruker,readbruker, readbrukerheader functions in the opendata
|
|
12
|
+
module of ImageD11 written by Jon Wright, ESRF, Grenoble, France
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import numpy, logging
|
|
17
|
+
logger = logging.getLogger("brukerimage")
|
|
18
|
+
from fabioimage import fabioimage
|
|
19
|
+
from readbytestream import readbytestream
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class brukerimage(fabioimage):
|
|
23
|
+
"""
|
|
24
|
+
Read and eventually write ID11 bruker (eg smart6500) images
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
# needed if you feel like writing - see ImageD11/scripts/edf2bruker.py
|
|
28
|
+
|
|
29
|
+
__headerstring__ = ""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _readheader(self, infile):
|
|
33
|
+
"""
|
|
34
|
+
the bruker format uses 80 char lines in key : value format
|
|
35
|
+
In the fisrt 512*5 bytes of the header there should be a
|
|
36
|
+
HDRBLKS key, whose value denotes how many 512 byte blocks
|
|
37
|
+
are in the total header. The header is always n*5*512 bytes,
|
|
38
|
+
otherwise it wont contain whole key: value pairs
|
|
39
|
+
"""
|
|
40
|
+
lump = infile.read(512 * 5)
|
|
41
|
+
self.__headerstring__ += lump
|
|
42
|
+
i = 80
|
|
43
|
+
self.header = {}
|
|
44
|
+
while i < 512 * 5:
|
|
45
|
+
if lump[i - 80: i].find(":") > 0:
|
|
46
|
+
key, val = lump[i - 80: i].split(":", 1)
|
|
47
|
+
key = key.strip() # remove the whitespace (why?)
|
|
48
|
+
val = val.strip()
|
|
49
|
+
if self.header.has_key(key):
|
|
50
|
+
# append lines if key already there
|
|
51
|
+
self.header[key] = self.header[key] + '\n' + val
|
|
52
|
+
else:
|
|
53
|
+
self.header[key] = val
|
|
54
|
+
self.header_keys.append(key)
|
|
55
|
+
i = i + 80 # next 80 characters
|
|
56
|
+
# we must have read this in the first 512 bytes.
|
|
57
|
+
nhdrblks = int(self.header['HDRBLKS'])
|
|
58
|
+
# Now read in the rest of the header blocks, appending
|
|
59
|
+
rest = infile.read(512 * (nhdrblks - 5))
|
|
60
|
+
self.__headerstring__ += rest
|
|
61
|
+
lump = lump[i - 80: 512] + rest
|
|
62
|
+
i = 80
|
|
63
|
+
j = 512 * nhdrblks
|
|
64
|
+
while i < j :
|
|
65
|
+
if lump[i - 80: i].find(":") > 0: # as for first 512 bytes of header
|
|
66
|
+
key, val = lump[i - 80: i].split(":", 1)
|
|
67
|
+
key = key.strip()
|
|
68
|
+
val = val.strip()
|
|
69
|
+
if self.header.has_key(key):
|
|
70
|
+
self.header[key] = self.header[key] + '\n' + val
|
|
71
|
+
else:
|
|
72
|
+
self.header[key] = val
|
|
73
|
+
self.header_keys.append(key)
|
|
74
|
+
i = i + 80
|
|
75
|
+
# make a (new) header item called "datastart"
|
|
76
|
+
self.header['datastart'] = infile.tell()
|
|
77
|
+
#set the image dimensions
|
|
78
|
+
self.dim1 = int(self.header['NROWS'])
|
|
79
|
+
self.dim2 = int(self.header['NCOLS'])
|
|
80
|
+
|
|
81
|
+
def read(self, fname, frame=None):
|
|
82
|
+
"""
|
|
83
|
+
Read in and unpack the pixels (including overflow table
|
|
84
|
+
"""
|
|
85
|
+
infile = self._open(fname, "rb")
|
|
86
|
+
try:
|
|
87
|
+
self._readheader(infile)
|
|
88
|
+
except:
|
|
89
|
+
raise
|
|
90
|
+
|
|
91
|
+
rows = self.dim1
|
|
92
|
+
cols = self.dim2
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
# you had to read the Bruker docs to know this!
|
|
96
|
+
npixelb = int(self.header['NPIXELB'])
|
|
97
|
+
except:
|
|
98
|
+
errmsg = "length " + str(len(self.header['NPIXELB'])) + "\n"
|
|
99
|
+
for byt in self.header['NPIXELB']:
|
|
100
|
+
errmsg += "char: " + str(byt) + " " + str(ord(byt)) + "\n"
|
|
101
|
+
logger.warning(errmsg)
|
|
102
|
+
raise
|
|
103
|
+
|
|
104
|
+
self.data = readbytestream(infile, infile.tell(),
|
|
105
|
+
rows, cols, npixelb,
|
|
106
|
+
datatype="int",
|
|
107
|
+
signed='n',
|
|
108
|
+
swap='n')
|
|
109
|
+
|
|
110
|
+
#handle overflows
|
|
111
|
+
nov = int(self.header['NOVERFL'])
|
|
112
|
+
if nov > 0: # Read in the overflows
|
|
113
|
+
# need at least int32 sized data I guess - can reach 2^21
|
|
114
|
+
self.data = self.data.astype(numpy.uint32)
|
|
115
|
+
# 16 character overflows:
|
|
116
|
+
# 9 characters of intensity
|
|
117
|
+
# 7 character position
|
|
118
|
+
for i in range(nov):
|
|
119
|
+
ovfl = infile.read(16)
|
|
120
|
+
intensity = int(ovfl[0: 9])
|
|
121
|
+
position = int(ovfl[9: 16])
|
|
122
|
+
# relies on python style modulo being always +
|
|
123
|
+
row = position % rows
|
|
124
|
+
# relies on truncation down
|
|
125
|
+
col = position / rows
|
|
126
|
+
#print "Overflow ", r, c, intensity, position,\
|
|
127
|
+
# self.data[r,c],self.data[c,r]
|
|
128
|
+
self.data[col, row] = intensity
|
|
129
|
+
infile.close()
|
|
130
|
+
|
|
131
|
+
self.resetvals()
|
|
132
|
+
self.pilimage = None
|
|
133
|
+
return self
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def write(self, fname):
|
|
137
|
+
"""
|
|
138
|
+
Writes the image as EDF
|
|
139
|
+
FIXME - this should call edfimage.write if that is wanted?
|
|
140
|
+
eg: obj = edfimage(data = self.data, header = self.header)
|
|
141
|
+
obj.write(fname)
|
|
142
|
+
or maybe something like: edfimage.write(self, fname)
|
|
143
|
+
"""
|
|
144
|
+
logger.warning("***warning***: call to unifinished " + \
|
|
145
|
+
"brukerimage.write. This will write the file" + \
|
|
146
|
+
fname + "as an edf-file")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
outfile = self._open(fname, "wb")
|
|
150
|
+
outfile.write('{\n')
|
|
151
|
+
i = 4
|
|
152
|
+
for k in self.header_keys:
|
|
153
|
+
out = (("%s = %s;\n") % (k, self.header[k]))
|
|
154
|
+
i = i + len(out)
|
|
155
|
+
outfile.write(out)
|
|
156
|
+
out = (4096 - i) * ' '
|
|
157
|
+
outfile.write(out)
|
|
158
|
+
outfile.write('}\n')
|
|
159
|
+
# Assumes a short-circuiting if / or ...
|
|
160
|
+
if not self.header.has_key("ByteOrder") or \
|
|
161
|
+
self.header["ByteOrder"] == "LowByteFirst":
|
|
162
|
+
outfile.write(self.data.astype(numpy.uint16).tostring())
|
|
163
|
+
else:
|
|
164
|
+
outfile.write(self.data.byteswap().astype(
|
|
165
|
+
numpy.uint16).tostring())
|
|
166
|
+
outfile.close()
|
|
167
|
+
|
|
168
|
+
def write2(self, fname):
|
|
169
|
+
""" FIXME: what is this? """
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test():
|
|
175
|
+
""" a testcase """
|
|
176
|
+
import sys, time
|
|
177
|
+
img = brukerimage()
|
|
178
|
+
start = time.clock()
|
|
179
|
+
for filename in sys.argv[1:]:
|
|
180
|
+
img.read(filename)
|
|
181
|
+
res = img.toPIL16()
|
|
182
|
+
img.rebin(2, 2)
|
|
183
|
+
print filename + (": max=%d, min=%d, mean=%.2e, stddev=%.2e") % (
|
|
184
|
+
img.getmax(), img.getmin(), img.getmean(), img.getstddev())
|
|
185
|
+
print 'integrated intensity (%d %d %d %d) =%.3f' % (
|
|
186
|
+
10, 20, 20, 40, img.integrate_area((10, 20, 20, 40)))
|
|
187
|
+
end = time.clock()
|
|
188
|
+
print (end - start)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
if __name__ == '__main__':
|
|
193
|
+
test()
|
|
194
|
+
|
|
195
|
+
|
|
Binary file
|
|
Binary file
|