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
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
#coding: utf8
|
|
3
|
+
from __future__ import with_statement
|
|
4
|
+
__doc__ = """
|
|
5
|
+
|
|
6
|
+
Authors: Henning O. Sorensen & Erik Knudsen
|
|
7
|
+
Center for Fundamental Research: Metal Structures in Four Dimensions
|
|
8
|
+
Risoe National Laboratory
|
|
9
|
+
Frederiksborgvej 399
|
|
10
|
+
DK-4000 Roskilde
|
|
11
|
+
email:erik.knudsen@risoe.dk
|
|
12
|
+
+
|
|
13
|
+
Jon Wright, Jerome Kieffer, Gael Goret ESRF, France
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from fabioimage import fabioimage
|
|
17
|
+
import numpy, struct, time, sys
|
|
18
|
+
import logging
|
|
19
|
+
logger = logging.getLogger("mar345image")
|
|
20
|
+
from compression import compPCK, decPCK
|
|
21
|
+
|
|
22
|
+
class mar345image(fabioimage):
|
|
23
|
+
_need_a_real_file = True
|
|
24
|
+
def __init__(self, *args, **kwargs):
|
|
25
|
+
fabioimage.__init__(self, *args, **kwargs)
|
|
26
|
+
self.numhigh = None
|
|
27
|
+
self.numpixels = None
|
|
28
|
+
|
|
29
|
+
def read(self, fname, frame=None):
|
|
30
|
+
""" Read a mar345 image"""
|
|
31
|
+
self.filename = fname
|
|
32
|
+
f = self._open(self.filename, "rb")
|
|
33
|
+
self._readheader(f)
|
|
34
|
+
if 'compressed' in self.header['Format']:
|
|
35
|
+
try:
|
|
36
|
+
self.data = decPCK(f, self.dim1, self.dim2, self.numhigh)
|
|
37
|
+
except Exception, error:
|
|
38
|
+
logger.error('%s. importing the mar345_io backend: generate an empty 1x1 picture' % error)
|
|
39
|
+
f.close()
|
|
40
|
+
self.dim1 = 1
|
|
41
|
+
self.dim2 = 1
|
|
42
|
+
self.bytecode = numpy.int #
|
|
43
|
+
self.data = numpy.resize(numpy.array([0], numpy.int), [1, 1])
|
|
44
|
+
return self
|
|
45
|
+
|
|
46
|
+
else:
|
|
47
|
+
logger.error("cannot handle these formats yet " + \
|
|
48
|
+
"due to lack of documentation")
|
|
49
|
+
return None
|
|
50
|
+
self.bytecode = numpy.uint
|
|
51
|
+
f.close()
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
def _readheader(self, infile=None):
|
|
55
|
+
""" Read a mar345 image header """
|
|
56
|
+
# clip was not used anywhere - commented out
|
|
57
|
+
# clip = '\x00'
|
|
58
|
+
#using a couple of local variables inside this function
|
|
59
|
+
f = infile
|
|
60
|
+
h = {}
|
|
61
|
+
|
|
62
|
+
#header is 4096 bytes long
|
|
63
|
+
l = f.read(64)
|
|
64
|
+
#the contents of the mar345 header is taken to be as
|
|
65
|
+
# described in
|
|
66
|
+
# http://www.mar-usa.com/support/downloads/mar345_formats.pdf
|
|
67
|
+
#the first 64 bytes are 4-byte integers (but in the CBFlib
|
|
68
|
+
# example image it seems to 128 bytes?)
|
|
69
|
+
#first 4-byte integer is a marker to check endianness
|
|
70
|
+
if struct.unpack("<i", l[0:4])[0] == 1234:
|
|
71
|
+
fs = '<i'
|
|
72
|
+
else:
|
|
73
|
+
fs = '>i'
|
|
74
|
+
|
|
75
|
+
#image dimensions
|
|
76
|
+
self.dim1 = self.dim2 = int(struct.unpack(fs, l[4:8])[0])
|
|
77
|
+
#number of high intensity pixels
|
|
78
|
+
self.numhigh = struct.unpack(fs, l[2 * 4 : (2 + 1) * 4])[0]
|
|
79
|
+
h['NumHigh'] = self.numhigh
|
|
80
|
+
#Image format
|
|
81
|
+
i = struct.unpack(fs, l[3 * 4 : (3 + 1) * 4])[0]
|
|
82
|
+
if i == 1:
|
|
83
|
+
h['Format'] = 'compressed'
|
|
84
|
+
elif i == 2:
|
|
85
|
+
h['Format'] = 'spiral'
|
|
86
|
+
else:
|
|
87
|
+
h['Format'] = 'compressed'
|
|
88
|
+
logger.warning("image format could not be detetermined" + \
|
|
89
|
+
"- assuming compressed mar345")
|
|
90
|
+
#collection mode
|
|
91
|
+
h['Mode'] = {0:'Dose', 1: 'Time'}[struct.unpack(fs, l[4 * 4:(4 + 1) * 4])[0]]
|
|
92
|
+
#total number of pixels
|
|
93
|
+
self.numpixels = struct.unpack(fs, l[5 * 4:(5 + 1) * 4])[0]
|
|
94
|
+
h['NumPixels'] = str(self.numpixels)
|
|
95
|
+
#pixel dimensions (length,height) in mm
|
|
96
|
+
h['PixelLength'] = struct.unpack(fs, l[6 * 4:(6 + 1) * 4])[0] / 1000.0
|
|
97
|
+
h['PixelHeight'] = struct.unpack(fs, l[7 * 4:(7 + 1) * 4])[0] / 1000.0
|
|
98
|
+
#x-ray wavelength in AA
|
|
99
|
+
h['Wavelength'] = struct.unpack(fs, l[8 * 4:(8 + 1) * 4])[0] / 1000000.0
|
|
100
|
+
#used distance
|
|
101
|
+
h['Distance'] = struct.unpack(fs, l[9 * 4:(9 + 1) * 4])[0] / 1000.0
|
|
102
|
+
#starting and ending phi
|
|
103
|
+
h['StartPhi'] = struct.unpack(fs, l[10 * 4:11 * 4])[0] / 1000.0
|
|
104
|
+
h['EndPhi'] = struct.unpack(fs, l[11 * 4:12 * 4])[0] / 1000.0
|
|
105
|
+
#starting and ending omega
|
|
106
|
+
h['StartOmega'] = struct.unpack(fs, l[12 * 4:13 * 4])[0] / 1000.0
|
|
107
|
+
h['EndOmega'] = struct.unpack(fs, l[13 * 4:14 * 4])[0] / 1000.0
|
|
108
|
+
#Chi and Twotheta angles
|
|
109
|
+
h['Chi'] = struct.unpack(fs, l[14 * 4:15 * 4])[0] / 1000.0
|
|
110
|
+
h['TwoTheta'] = struct.unpack(fs, l[15 * 4:16 * 4])[0] / 1000.0
|
|
111
|
+
|
|
112
|
+
#the rest of the header is ascii
|
|
113
|
+
# TODO: validate these values against the binaries already read
|
|
114
|
+
l = f.read(128)
|
|
115
|
+
if not 'mar research' in l:
|
|
116
|
+
logger.warning("the string \"mar research\" should be in " + \
|
|
117
|
+
"bytes 65-76 of the header but was not")
|
|
118
|
+
start = 128
|
|
119
|
+
else:
|
|
120
|
+
start = l.index('mar research')
|
|
121
|
+
f.seek(64 + start)
|
|
122
|
+
l = f.read(4096 - start - 64).strip()
|
|
123
|
+
for m in l.splitlines():
|
|
124
|
+
if m == 'END OF HEADER':
|
|
125
|
+
break
|
|
126
|
+
n = m.split(' ', 1)
|
|
127
|
+
if n[0] == '':
|
|
128
|
+
continue
|
|
129
|
+
if n[0] in ('PROGRAM', 'DATE', 'SCANNER', 'HIGH', 'MULTIPLIER',
|
|
130
|
+
'GAIN', 'WAVELENGTH', 'DISTANCE', 'RESOLUTION',
|
|
131
|
+
'CHI', 'TWOTHETA', 'MODE', 'TIME', 'GENERATOR',
|
|
132
|
+
'MONOCHROMATOR', 'REMARK'):
|
|
133
|
+
logger.debug("reading: %s %s", n[0], n[1])
|
|
134
|
+
h[n[0]] = n[1].strip()
|
|
135
|
+
continue
|
|
136
|
+
if n[0] in ('FORMAT'):
|
|
137
|
+
(h['DIM'], h['FORMAT_TYPE'], h['NO_PIXELS']) = n[1].split()
|
|
138
|
+
continue
|
|
139
|
+
if n[0] in ('PIXEL', 'OFFSET', 'PHI', 'OMEGA', 'COUNTS',
|
|
140
|
+
'CENTER', 'INTENSITY', 'HISTOGRAM', 'COLLIMATOR'):
|
|
141
|
+
n = m.split()
|
|
142
|
+
h.update([(n[0] + '_' + n[j], n[j + 1]) for j in range(1, len(n), 2)])
|
|
143
|
+
continue
|
|
144
|
+
self.header = h
|
|
145
|
+
return h
|
|
146
|
+
|
|
147
|
+
def write(self, fname):
|
|
148
|
+
"""Try to write mar345 file. This is still in beta version.
|
|
149
|
+
It uses CCP4 (LGPL) PCK1 algo from JPA"""
|
|
150
|
+
headers = self._writeheader()
|
|
151
|
+
hotpixels = self._high_intensity_pixel_records()
|
|
152
|
+
compressed_stream = compPCK(self.data)
|
|
153
|
+
try:
|
|
154
|
+
outfile = self._open(fname, mode="wb")
|
|
155
|
+
outfile.write(headers)
|
|
156
|
+
outfile.write(hotpixels)
|
|
157
|
+
outfile.write(compressed_stream)
|
|
158
|
+
outfile.close()
|
|
159
|
+
except Exception, error:
|
|
160
|
+
logger.error("Error in writing file %s: %s" % (fname, error))
|
|
161
|
+
|
|
162
|
+
def _writeheader(self, linesep="\n", size=4096):#the standard padding does not inclued
|
|
163
|
+
"""
|
|
164
|
+
@param linesep: end of line separator
|
|
165
|
+
@return string/bytes containing the mar345 header
|
|
166
|
+
"""
|
|
167
|
+
try:
|
|
168
|
+
version = sys.modules["fabio"].version
|
|
169
|
+
except (KeyError, AttributeError):
|
|
170
|
+
version = "0.1.1"
|
|
171
|
+
lnsep = len(linesep)
|
|
172
|
+
|
|
173
|
+
self.header["HIGH"] = str(self.nb_overflow_pixels())
|
|
174
|
+
binheader = numpy.zeros(16, "int32")
|
|
175
|
+
binheader[:4] = numpy.array([1234, self.dim1, int(self.header["HIGH"]), 1])
|
|
176
|
+
binheader[4] = (self.header.get("MODE", "TIME") == "TIME")
|
|
177
|
+
binheader[5] = self.dim1 * self.dim2
|
|
178
|
+
binheader[6] = int(self.header.get("PIXEL_LENGTH", 1))
|
|
179
|
+
binheader[7] = int(self.header.get("PIXEL_HEIGHT", 1))
|
|
180
|
+
binheader[8] = int(float(self.header.get("WAVELENGTH", 1)) * 1e6)
|
|
181
|
+
binheader[9] = int(float(self.header.get("DISTANCE", 1)) * 1e3)
|
|
182
|
+
binheader[10] = int(float(self.header.get("PHI_START", 1)) * 1e3)
|
|
183
|
+
binheader[11] = int(float(self.header.get("PHI_END", 1)) * 1e3)
|
|
184
|
+
binheader[12] = int(float(self.header.get("OMEGA_START", 1)) * 1e3)
|
|
185
|
+
binheader[13] = int(float(self.header.get("OMEGA_END", 1)) * 1e3)
|
|
186
|
+
binheader[14] = int(float(self.header.get("CHI", 1)) * 1e3)
|
|
187
|
+
binheader[15] = int(float(self.header.get("TWOTHETA", 1)) * 1e3)
|
|
188
|
+
lstout = [binheader.tostring() + 'mar research'.ljust(64 - lnsep)]
|
|
189
|
+
lstout.append("PROGRAM".ljust(15) + (str(self.header.get("PROGRAM", "FabIO Version %s" % (version))).ljust(49 - lnsep)))
|
|
190
|
+
lstout.append("DATE".ljust(15) + (str(self.header.get("DATE", time.ctime()))).ljust(49 - lnsep))
|
|
191
|
+
key = "SCANNER"
|
|
192
|
+
if key in self.header:
|
|
193
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
194
|
+
key = "FORMAT_TYPE"
|
|
195
|
+
if key in self.header:
|
|
196
|
+
lstout.append("FORMAT".ljust(15) + ("%s %s %s" % (self.dim1, self.header[key], self.dim1 * self.dim2)).ljust(49 - lnsep))
|
|
197
|
+
key = "HIGH"
|
|
198
|
+
if key in self.header:
|
|
199
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
200
|
+
key1 = "PIXEL_LENGTH"
|
|
201
|
+
key2 = "PIXEL_HEIGHT"
|
|
202
|
+
if (key1 in self.header) and (key2 in self.header):
|
|
203
|
+
lstout.append("PIXEL".ljust(15) + ("LENGTH %s HEIGHT %s" % (self.header[key1], self.header[key2])).ljust(49 - lnsep))
|
|
204
|
+
key1 = "OFFSET_ROFF"
|
|
205
|
+
key2 = "OFFSET_TOFF"
|
|
206
|
+
if key1 in self.header and key2 in self.header:
|
|
207
|
+
lstout.append("OFFSET".ljust(15) + ("ROFF %s TOFF %s" % (self.header[key1], self.header[key2])).ljust(49 - lnsep))
|
|
208
|
+
key = "MULTIPLIER"
|
|
209
|
+
if key in self.header:
|
|
210
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
211
|
+
key = "GAIN"
|
|
212
|
+
if key in self.header:
|
|
213
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
214
|
+
key = "WAVELENGTH"
|
|
215
|
+
if key in self.header:
|
|
216
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
217
|
+
key = "DISTANCE"
|
|
218
|
+
if key in self.header:
|
|
219
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
220
|
+
key = "RESOLUTION"
|
|
221
|
+
if key in self.header:
|
|
222
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
223
|
+
key1 = "PHI_START"
|
|
224
|
+
key2 = "PHI_END"
|
|
225
|
+
key3 = "PHI_OSC"
|
|
226
|
+
if (key1 in self.header) and (key2 in self.header) and (key3 in self.header):
|
|
227
|
+
lstout.append("PHI".ljust(15) + ("START %s END %s OSC %s" % (self.header[key1], self.header[key2], self.header[key3])).ljust(49 - lnsep))
|
|
228
|
+
key1 = "OMEGA_START"
|
|
229
|
+
key2 = "OMEGA_END"
|
|
230
|
+
key3 = "OMEGA_OSC"
|
|
231
|
+
if (key1 in self.header) and (key2 in self.header) and (key3 in self.header):
|
|
232
|
+
lstout.append("OMEGA".ljust(15) + ("START %s END %s OSC %s" % (self.header[key1], self.header[key2], self.header[key3])).ljust(49 - lnsep))
|
|
233
|
+
key = "CHI"
|
|
234
|
+
if key in self.header:
|
|
235
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
236
|
+
key = "TWOTHETA"
|
|
237
|
+
if key in self.header:
|
|
238
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
239
|
+
key1 = "CENTER_X"
|
|
240
|
+
key2 = "CENTER_Y"
|
|
241
|
+
if (key1 in self.header) and (key2 in self.header):
|
|
242
|
+
lstout.append("CENTER".ljust(15) + ("X %s Y %s" % (self.header[key1], self.header[key2])).ljust(49 - lnsep))
|
|
243
|
+
key = "MODE"
|
|
244
|
+
if key in self.header:
|
|
245
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
246
|
+
key = "TIME"
|
|
247
|
+
if key in self.header:
|
|
248
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
249
|
+
key1 = "COUNTS_START"
|
|
250
|
+
key2 = "COUNTS_END"
|
|
251
|
+
key3 = "COUNTS_NMEAS"
|
|
252
|
+
if key1 in self.header and key2 in self.header and key3 in self.header:
|
|
253
|
+
lstout.append("COUNTS".ljust(15) + ("START %s END %s NMEAS %s" % (self.header[key1], self.header[key2], self.header[key3])).ljust(49 - lnsep))
|
|
254
|
+
key1 = "COUNTS_MIN"
|
|
255
|
+
key2 = "COUNTS_MAX"
|
|
256
|
+
if key1 in self.header and key2 in self.header:
|
|
257
|
+
lstout.append("COUNTS".ljust(15) + ("MIN %s MAX %s" % (self.header[key1], self.header[key2])).ljust(49 - lnsep))
|
|
258
|
+
key1 = "COUNTS_AVE"
|
|
259
|
+
key2 = "COUNTS_SIG"
|
|
260
|
+
if key1 in self.header and key2 in self.header:
|
|
261
|
+
lstout.append("COUNTS".ljust(15) + ("AVE %s SIG %s" % (self.header[key1], self.header[key2])).ljust(49 - lnsep))
|
|
262
|
+
key1 = "INTENSITY_MIN"
|
|
263
|
+
key2 = "INTENSITY_MAX"
|
|
264
|
+
key3 = "INTENSITY_AVE"
|
|
265
|
+
key4 = "INTENSITY_SIG"
|
|
266
|
+
if key1 in self.header and key2 in self.header and key3 in self.header and key4 in self.header:
|
|
267
|
+
lstout.append("INTENSITY".ljust(15) + ("MIN %s MAX %s AVE %s SIG %s" % (self.header[key1], self.header[key2], self.header[key3], self.header[key4])).ljust(49 - lnsep))
|
|
268
|
+
key1 = "HISTOGRAM_START"
|
|
269
|
+
key2 = "HISTOGRAM_END"
|
|
270
|
+
key3 = "HISTOGRAM_MAX"
|
|
271
|
+
if key1 in self.header and key2 in self.header and key3 in self.header:
|
|
272
|
+
lstout.append("HISTOGRAM".ljust(15) + ("START %s END %s MAX %s" % (self.header[key1], self.header[key2], self.header[key3])).ljust(49 - lnsep))
|
|
273
|
+
key = "GENERATOR"
|
|
274
|
+
if key in self.header:
|
|
275
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
276
|
+
key = "MONOCHROMATOR"
|
|
277
|
+
if key in self.header:
|
|
278
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
279
|
+
key1 = "COLLIMATOR_WIDTH"
|
|
280
|
+
key2 = "COLLIMATOR_HEIGHT"
|
|
281
|
+
if key1 in self.header and key2 in self.header:
|
|
282
|
+
lstout.append("COLLIMATOR".ljust(15) + ("WIDTH %s HEIGHT %s" % (self.header[key1], self.header[key2])).ljust(49 - lnsep))
|
|
283
|
+
key = "REMARK"
|
|
284
|
+
if key in self.header:
|
|
285
|
+
lstout.append(key.ljust(15) + str(self.header[key]).ljust(49 - lnsep))
|
|
286
|
+
else:
|
|
287
|
+
lstout.append(key.ljust(64 - lnsep))
|
|
288
|
+
key = "END OF HEADER"
|
|
289
|
+
lstout.append(key)
|
|
290
|
+
return linesep.join(lstout).ljust(size)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def _high_intensity_pixel_records(self):
|
|
294
|
+
flt_data = self.data.flatten()
|
|
295
|
+
pix_location = numpy.where(flt_data > 65535)[0]
|
|
296
|
+
nb_pix = pix_location.size
|
|
297
|
+
if nb_pix % 8 == 0:
|
|
298
|
+
tmp = numpy.zeros((nb_pix, 2), dtype="int32")
|
|
299
|
+
else:
|
|
300
|
+
tmp = numpy.zeros(((nb_pix // 8 + 1) * 8, 2), dtype="int32")
|
|
301
|
+
tmp[:nb_pix, 0] = pix_location + 1
|
|
302
|
+
tmp[:nb_pix, 1] = flt_data[pix_location]
|
|
303
|
+
return tmp.tostring()
|
|
304
|
+
|
|
305
|
+
def nb_overflow_pixels(self):
|
|
306
|
+
return (self.data > 65535).sum()
|
|
307
|
+
|
|
308
|
+
@staticmethod
|
|
309
|
+
def checkData(data=None):
|
|
310
|
+
if data is None:
|
|
311
|
+
return None
|
|
312
|
+
else:
|
|
313
|
+
# enforce square image
|
|
314
|
+
shape = data.shape
|
|
315
|
+
assert len(shape) == 2, "image has 2 dimensions"
|
|
316
|
+
mshape = max(shape)
|
|
317
|
+
z = numpy.zeros((mshape, mshape), dtype=int)
|
|
318
|
+
z[:shape[0], :shape[1]] = data
|
|
319
|
+
return z
|
|
320
|
+
|
|
Binary file
|
|
@@ -0,0 +1,309 @@
|
|
|
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:henning.sorensen@risoe.dk
|
|
10
|
+
|
|
11
|
+
+ (mods for fabio) Jon Wright, ESRF
|
|
12
|
+
marccdimage can read MarCCD and MarMosaic images including header info.
|
|
13
|
+
|
|
14
|
+
JPW : Use a parser in case of typos (sorry?)
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Base this on the tifimage (as marccd seems to be tiff with a
|
|
20
|
+
# special header
|
|
21
|
+
|
|
22
|
+
from tifimage import tifimage
|
|
23
|
+
import logging
|
|
24
|
+
logger = logging.getLogger("marccdimage")
|
|
25
|
+
|
|
26
|
+
# Now for the c definition (found on mar webpage)
|
|
27
|
+
# The following string is therefore copyrighted by Mar I guess
|
|
28
|
+
|
|
29
|
+
CDEFINITION = """
|
|
30
|
+
typedef struct frame_header_type {
|
|
31
|
+
/* File/header format parameters (256 bytes) */
|
|
32
|
+
UINT32 header_type; /* flag for header type
|
|
33
|
+
(can be used as magic number) */
|
|
34
|
+
char header_name[16]; /* header name (MMX) */
|
|
35
|
+
UINT32 header_major_version; /* header_major_version (n.) */
|
|
36
|
+
UINT32 header_minor_version; /* header_minor_version (.n) */
|
|
37
|
+
UINT32 header_byte_order;/* BIG_ENDIAN (Motorola,MIPS);
|
|
38
|
+
LITTLE_ENDIAN (DEC, Intel) */
|
|
39
|
+
UINT32 data_byte_order; /* BIG_ENDIAN (Motorola,MIPS);
|
|
40
|
+
LITTLE_ENDIAN (DEC, Intel) */
|
|
41
|
+
UINT32 header_size; /* in bytes */
|
|
42
|
+
UINT32 frame_type; /* flag for frame type */
|
|
43
|
+
UINT32 magic_number; /* to be used as a flag -
|
|
44
|
+
usually to indicate new file */
|
|
45
|
+
UINT32 compression_type; /* type of image compression */
|
|
46
|
+
UINT32 compression1; /* compression parameter 1 */
|
|
47
|
+
UINT32 compression2; /* compression parameter 2 */
|
|
48
|
+
UINT32 compression3; /* compression parameter 3 */
|
|
49
|
+
UINT32 compression4; /* compression parameter 4 */
|
|
50
|
+
UINT32 compression5; /* compression parameter 4 */
|
|
51
|
+
UINT32 compression6; /* compression parameter 4 */
|
|
52
|
+
UINT32 nheaders; /* total number of headers */
|
|
53
|
+
UINT32 nfast; /* number of pixels in one line */
|
|
54
|
+
UINT32 nslow; /* number of lines in image */
|
|
55
|
+
UINT32 depth; /* number of bytes per pixel */
|
|
56
|
+
UINT32 record_length; /* number of pixels between
|
|
57
|
+
succesive rows */
|
|
58
|
+
UINT32 signif_bits; /* true depth of data, in bits */
|
|
59
|
+
UINT32 data_type; /* (signed,unsigned,float...) */
|
|
60
|
+
UINT32 saturated_value; /* value marks pixel as saturated */
|
|
61
|
+
UINT32 sequence; /* TRUE or FALSE */
|
|
62
|
+
UINT32 nimages; /* total number of images - size of
|
|
63
|
+
each is nfast*(nslow/nimages) */
|
|
64
|
+
UINT32 origin; /* corner of origin */
|
|
65
|
+
UINT32 orientation; /* direction of fast axis */
|
|
66
|
+
UINT32 view_direction; /* direction to view frame */
|
|
67
|
+
UINT32 overflow_location;/* FOLLOWING_HEADER, FOLLOWING_DATA */
|
|
68
|
+
UINT32 over_8_bits; /* # of pixels with counts 255 */
|
|
69
|
+
UINT32 over_16_bits; /* # of pixels with count 65535 */
|
|
70
|
+
UINT32 multiplexed; /* multiplex flag */
|
|
71
|
+
UINT32 nfastimages; /* # of images in fast direction */
|
|
72
|
+
UINT32 nslowimages; /* # of images in slow direction */
|
|
73
|
+
UINT32 background_applied;/* flags correction has been applied
|
|
74
|
+
hold magic number ? */
|
|
75
|
+
UINT32 bias_applied; /* flags correction has been applied
|
|
76
|
+
hold magic number ? */
|
|
77
|
+
UINT32 flatfield_applied;/* flags correction has been applied -
|
|
78
|
+
hold magic number ? */
|
|
79
|
+
UINT32 distortion_applied;/*flags correction has been applied -
|
|
80
|
+
hold magic number ? */
|
|
81
|
+
UINT32 original_header_type; /* Header/frame type from file
|
|
82
|
+
that frame is read from */
|
|
83
|
+
UINT32 file_saved; /* Flag that file has been saved,
|
|
84
|
+
should be zeroed if modified */
|
|
85
|
+
char reserve1[(64-40)*sizeof(INT32)-16];
|
|
86
|
+
|
|
87
|
+
/* Data statistics (128) */
|
|
88
|
+
UINT32 total_counts[2]; /* 64 bit integer range = 1.85E19*/
|
|
89
|
+
UINT32 special_counts1[2];
|
|
90
|
+
UINT32 special_counts2[2];
|
|
91
|
+
UINT32 min;
|
|
92
|
+
UINT32 max;
|
|
93
|
+
UINT32 mean;
|
|
94
|
+
UINT32 rms;
|
|
95
|
+
UINT32 p10;
|
|
96
|
+
UINT32 p90;
|
|
97
|
+
UINT32 stats_uptodate;
|
|
98
|
+
UINT32 pixel_noise[MAXIMAGES]; /*1000*base noise value (ADUs) */
|
|
99
|
+
char reserve2[(32-13-MAXIMAGES)*sizeof(INT32)];
|
|
100
|
+
|
|
101
|
+
/* More statistics (256) */
|
|
102
|
+
UINT16 percentile[128];
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
/* Goniostat parameters (128 bytes) */
|
|
106
|
+
INT32 xtal_to_detector; /* 1000*distance in millimeters */
|
|
107
|
+
INT32 beam_x; /* 1000*x beam position (pixels) */
|
|
108
|
+
INT32 beam_y; /* 1000*y beam position (pixels) */
|
|
109
|
+
INT32 integration_time; /* integration time in milliseconds */
|
|
110
|
+
INT32 exposure_time; /* exposure time in milliseconds */
|
|
111
|
+
INT32 readout_time; /* readout time in milliseconds */
|
|
112
|
+
INT32 nreads; /* number of readouts to get this image */
|
|
113
|
+
INT32 start_twotheta; /* 1000*two_theta angle */
|
|
114
|
+
INT32 start_omega; /* 1000*omega angle */
|
|
115
|
+
INT32 start_chi; /* 1000*chi angle */
|
|
116
|
+
INT32 start_kappa; /* 1000*kappa angle */
|
|
117
|
+
INT32 start_phi; /* 1000*phi angle */
|
|
118
|
+
INT32 start_delta; /* 1000*delta angle */
|
|
119
|
+
INT32 start_gamma; /* 1000*gamma angle */
|
|
120
|
+
INT32 start_xtal_to_detector; /* 1000*distance in mm (dist in um)*/
|
|
121
|
+
INT32 end_twotheta; /* 1000*two_theta angle */
|
|
122
|
+
INT32 end_omega; /* 1000*omega angle */
|
|
123
|
+
INT32 end_chi; /* 1000*chi angle */
|
|
124
|
+
INT32 end_kappa; /* 1000*kappa angle */
|
|
125
|
+
INT32 end_phi; /* 1000*phi angle */
|
|
126
|
+
INT32 end_delta; /* 1000*delta angle */
|
|
127
|
+
INT32 end_gamma; /* 1000*gamma angle */
|
|
128
|
+
INT32 end_xtal_to_detector; /* 1000*distance in mm (dist in um)*/
|
|
129
|
+
INT32 rotation_axis; /* active rotation axis */
|
|
130
|
+
INT32 rotation_range; /* 1000*rotation angle */
|
|
131
|
+
INT32 detector_rotx; /* 1000*rotation of detector around X */
|
|
132
|
+
INT32 detector_roty; /* 1000*rotation of detector around Y */
|
|
133
|
+
INT32 detector_rotz; /* 1000*rotation of detector around Z */
|
|
134
|
+
char reserve3[(32-28)*sizeof(INT32)];
|
|
135
|
+
|
|
136
|
+
/* Detector parameters (128 bytes) */
|
|
137
|
+
INT32 detector_type; /* detector type */
|
|
138
|
+
INT32 pixelsize_x; /* pixel size (nanometers) */
|
|
139
|
+
INT32 pixelsize_y; /* pixel size (nanometers) */
|
|
140
|
+
INT32 mean_bias; /* 1000*mean bias value */
|
|
141
|
+
INT32 photons_per_100adu; /* photons / 100 ADUs */
|
|
142
|
+
INT32 measured_bias[MAXIMAGES];/* 1000*mean bias value for each image*/
|
|
143
|
+
INT32 measured_temperature[MAXIMAGES]; /* Temperature of each
|
|
144
|
+
detector in milliKelvins */
|
|
145
|
+
INT32 measured_pressure[MAXIMAGES]; /* Pressure of each chamber
|
|
146
|
+
in microTorr */
|
|
147
|
+
/* Retired reserve4 when MAXIMAGES set to 9 from 16 and
|
|
148
|
+
two fields removed, and temp and pressure added
|
|
149
|
+
char reserve4[(32-(5+3*MAXIMAGES))*sizeof(INT32)]
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
/* X-ray source and optics parameters (128 bytes) */
|
|
153
|
+
/* X-ray source parameters (8*4 bytes) */
|
|
154
|
+
INT32 source_type; /* (code) - target, synch. etc */
|
|
155
|
+
INT32 source_dx; /* Optics param. - (size microns) */
|
|
156
|
+
INT32 source_dy; /* Optics param. - (size microns) */
|
|
157
|
+
INT32 source_wavelength; /* wavelength (femtoMeters) */
|
|
158
|
+
INT32 source_power; /* (Watts) */
|
|
159
|
+
INT32 source_voltage; /* (Volts) */
|
|
160
|
+
INT32 source_current; /* (microAmps) */
|
|
161
|
+
INT32 source_bias; /* (Volts) */
|
|
162
|
+
INT32 source_polarization_x; /* () */
|
|
163
|
+
INT32 source_polarization_y; /* () */
|
|
164
|
+
char reserve_source[4*sizeof(INT32)];
|
|
165
|
+
|
|
166
|
+
/* X-ray optics_parameters (8*4 bytes) */
|
|
167
|
+
INT32 optics_type; /* Optics type (code)*/
|
|
168
|
+
INT32 optics_dx; /* Optics param. - (size microns) */
|
|
169
|
+
INT32 optics_dy; /* Optics param. - (size microns) */
|
|
170
|
+
INT32 optics_wavelength; /* Optics param. - (size microns) */
|
|
171
|
+
INT32 optics_dispersion; /* Optics param. - (*10E6) */
|
|
172
|
+
INT32 optics_crossfire_x; /* Optics param. - (microRadians) */
|
|
173
|
+
INT32 optics_crossfire_y; /* Optics param. - (microRadians) */
|
|
174
|
+
INT32 optics_angle; /* Optics param. - (monoch.
|
|
175
|
+
2theta - microradians) */
|
|
176
|
+
INT32 optics_polarization_x; /* () */
|
|
177
|
+
INT32 optics_polarization_y; /* () */
|
|
178
|
+
char reserve_optics[4*sizeof(INT32)];
|
|
179
|
+
|
|
180
|
+
char reserve5[((32-28)*sizeof(INT32))];
|
|
181
|
+
|
|
182
|
+
/* File parameters (1024 bytes) */
|
|
183
|
+
char filetitle[128]; /* Title */
|
|
184
|
+
char filepath[128]; /* path name for data file */
|
|
185
|
+
char filename[64]; /* name of data file */
|
|
186
|
+
char acquire_timestamp[32]; /* date and time of acquisition */
|
|
187
|
+
char header_timestamp[32]; /* date and time of header update */
|
|
188
|
+
char save_timestamp[32]; /* date and time file saved */
|
|
189
|
+
char file_comments[512]; /* comments, use as desired */
|
|
190
|
+
char reserve6[1024-(128+128+64+(3*32)+512)];
|
|
191
|
+
|
|
192
|
+
/* Dataset parameters (512 bytes) */
|
|
193
|
+
char dataset_comments[512]; /* comments, used as desired */
|
|
194
|
+
/* pad out to 3072 bytes */
|
|
195
|
+
char pad[3072-(256+128+256+(3*128)+1024+512)];
|
|
196
|
+
|
|
197
|
+
} frame_header;
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
import struct
|
|
201
|
+
|
|
202
|
+
# Convert mar c header file types to python struct module types
|
|
203
|
+
C_TO_STRUCT = {
|
|
204
|
+
"INT32" : "i",
|
|
205
|
+
"UINT32" : "I",
|
|
206
|
+
"char" : "c",
|
|
207
|
+
"UINT16" : "H"
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
# Sizes (bytes) of mar c header objects
|
|
211
|
+
C_SIZES = {
|
|
212
|
+
"INT32" : 4,
|
|
213
|
+
"UINT32" : 4,
|
|
214
|
+
"char" : 1,
|
|
215
|
+
"UINT16" : 2
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
# This was worked out by trial and error from a trial image I think
|
|
219
|
+
MAXIMAGES = 9
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def make_format(c_def_string):
|
|
223
|
+
"""
|
|
224
|
+
Reads the header definition in c and makes the format
|
|
225
|
+
string to pass to struct.unpack
|
|
226
|
+
"""
|
|
227
|
+
lines = c_def_string.split("\n")
|
|
228
|
+
fmt = ""
|
|
229
|
+
names = []
|
|
230
|
+
expected = 0
|
|
231
|
+
for line in lines:
|
|
232
|
+
if line.find(";") == -1:
|
|
233
|
+
continue
|
|
234
|
+
decl = line.split(";")[0].lstrip().rstrip()
|
|
235
|
+
try:
|
|
236
|
+
[typ, name] = decl.split()
|
|
237
|
+
except ValueError:
|
|
238
|
+
logger.debug("skipping: %s" , line)
|
|
239
|
+
continue
|
|
240
|
+
|
|
241
|
+
if name.find("[") > -1:
|
|
242
|
+
# repeated ... times
|
|
243
|
+
try:
|
|
244
|
+
num = name.split("[")[1].split("]")[0]
|
|
245
|
+
num = num.replace("MAXIMAGES", str(MAXIMAGES))
|
|
246
|
+
num = num.replace("sizeof(INT32)", "4")
|
|
247
|
+
times = eval(num)
|
|
248
|
+
except Exception, error:
|
|
249
|
+
logger.error("%s Please decode %s", error, decl)
|
|
250
|
+
raise error
|
|
251
|
+
else:
|
|
252
|
+
times = 1
|
|
253
|
+
try:
|
|
254
|
+
fmt += C_TO_STRUCT[typ] * times
|
|
255
|
+
names += [name] * times
|
|
256
|
+
expected += C_SIZES[typ] * times
|
|
257
|
+
except KeyError:
|
|
258
|
+
continue
|
|
259
|
+
return names, fmt
|
|
260
|
+
|
|
261
|
+
# Make these be compiled on loading module
|
|
262
|
+
HEADER_NAMES, HEADER_FORMAT = make_format(CDEFINITION)
|
|
263
|
+
|
|
264
|
+
def interpret_header(header, fmt, names):
|
|
265
|
+
"""
|
|
266
|
+
given a format and header interpret it
|
|
267
|
+
"""
|
|
268
|
+
values = struct.unpack(fmt, header)
|
|
269
|
+
hdr = {}
|
|
270
|
+
i = 0
|
|
271
|
+
for name in names:
|
|
272
|
+
if hdr.has_key(name):
|
|
273
|
+
if type(values[i]) == type("string"):
|
|
274
|
+
hdr[name] = hdr[name] + values[i]
|
|
275
|
+
else:
|
|
276
|
+
try:
|
|
277
|
+
hdr[name].append(values[i])
|
|
278
|
+
except AttributeError:
|
|
279
|
+
hdr[name] = [hdr[name], values[i]]
|
|
280
|
+
else:
|
|
281
|
+
hdr[name] = values[i]
|
|
282
|
+
i = i + 1
|
|
283
|
+
|
|
284
|
+
return hdr
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
class marccdimage(tifimage):
|
|
288
|
+
""" Read in data in mar ccd format, also
|
|
289
|
+
MarMosaic images, including header info """
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _readheader(self, infile):
|
|
293
|
+
"""
|
|
294
|
+
Parser based approach
|
|
295
|
+
Gets all entries
|
|
296
|
+
"""
|
|
297
|
+
infile.seek(1024)
|
|
298
|
+
hstr = infile.read(3072)
|
|
299
|
+
self.header = interpret_header(hstr, HEADER_FORMAT, HEADER_NAMES)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def _read(self, fname):
|
|
304
|
+
"""
|
|
305
|
+
inherited from tifimage
|
|
306
|
+
... a marccd image *is a* tif image
|
|
307
|
+
just with a header
|
|
308
|
+
"""
|
|
309
|
+
return tifimage.read(self, fname)
|
|
Binary file
|