1
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
23 """
24 Read and eventually write ID11 bruker (eg smart6500) images
25 """
26
27
28
29 __headerstring__ = ""
30
31
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()
48 val = val.strip()
49 if self.header.has_key(key):
50
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
56
57 nhdrblks = int(self.header['HDRBLKS'])
58
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:
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
76 self.header['datastart'] = infile.tell()
77
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
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
111 nov = int(self.header['NOVERFL'])
112 if nov > 0:
113
114 self.data = self.data.astype(numpy.uint32)
115
116
117
118 for i in range(nov):
119 ovfl = infile.read(16)
120 intensity = int(ovfl[0: 9])
121 position = int(ovfl[9: 16])
122
123 row = position % rows
124
125 col = position / rows
126
127
128 self.data[col, row] = intensity
129 infile.close()
130
131 self.resetvals()
132 self.pilimage = None
133 return self
134
135
137 """
138 Writes the image as EDF
139
140 FIXME: this should call edfimage.write if that is wanted?
141 obj = edfimage(data = self.data, header = self.header)
142 obj.write(fname)
143 or maybe something like: edfimage.write(self, fname)
144
145 """
146 logger.warning("***warning***: call to unifinished " + \
147 "brukerimage.write. This will write the file" + \
148 fname + "as an edf-file")
149
150
151 outfile = self._open(fname, "wb")
152 outfile.write('{\n')
153 i = 4
154 for k in self.header_keys:
155 out = (("%s = %s;\n") % (k, self.header[k]))
156 i = i + len(out)
157 outfile.write(out)
158 out = (4096 - i) * ' '
159 outfile.write(out)
160 outfile.write('}\n')
161
162 if not self.header.has_key("ByteOrder") or \
163 self.header["ByteOrder"] == "LowByteFirst":
164 outfile.write(self.data.astype(numpy.uint16).tostring())
165 else:
166 outfile.write(self.data.byteswap().astype(
167 numpy.uint16).tostring())
168 outfile.close()
169
170
171
172
174 """ a testcase """
175 import sys, time
176 img = brukerimage()
177 start = time.clock()
178 for filename in sys.argv[1:]:
179 img.read(filename)
180 res = img.toPIL16()
181 img.rebin(2, 2)
182 print filename + (": max=%d, min=%d, mean=%.2e, stddev=%.2e") % (
183 img.getmax(), img.getmin(), img.getmean(), img.getstddev())
184 print 'integrated intensity (%d %d %d %d) =%.3f' % (
185 10, 20, 20, 40, img.integrate_area((10, 20, 20, 40)))
186 end = time.clock()
187 print (end - start)
188
189
190
191 if __name__ == '__main__':
192 test()
193