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 as N, logging
17
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):
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 logging.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(N.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 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 logging.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
160 if not self.header.has_key("ByteOrder") or \
161 self.header["ByteOrder"] == "LowByteFirst":
162 outfile.write(self.data.astype(N.uint16).tostring())
163 else:
164 outfile.write(self.data.byteswap().astype(
165 N.uint16).tostring())
166 outfile.close()
167
169 """ FIXME: what is this? """
170 pass
171
172
173
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