1
2 """
3 Authors: Jerome Kieffer, ESRF
4 email:jerome.kieffer@esrf.fr
5
6 kcd images are 2D images written by the old KappaCCD diffractometer built by Nonius in the 1990's
7 Based on the edfimage.py parser.
8 """
9
10 import numpy as np, logging
11 import os, string
12 from fabio.fabioimage import fabioimage
13
14
15 DATA_TYPES = {
16
17
18 "u16" : np.uint16,
19
20
21
22
23
24
25
26
27
28 }
29
30 MINIMUM_KEYS = [
31 'ByteOrder',
32 'Data type',
33 'X dimension',
34 'Y dimension',
35 'Number of readouts']
36
37 DEFAULT_VALUES = {
38 "Data type": "u16"
39 }
40
41
42
43
45 """
46 Read the Nonius kcd data format """
47
48
50 """
51 Read in a header in some KCD format from an already open file
52 @
53 """
54 oneLine = infile.readline()
55 alphanum = string.digits + string.letters + ". "
56 asciiHeader = True
57 for oneChar in oneLine.strip():
58 if not oneChar in alphanum:
59 asciiHeader = False
60
61
62 if asciiHeader is False:
63
64 logging.warning("First line of %s does not seam to be ascii text!" % infile.name)
65 endOfHeaders = False
66 while not endOfHeaders:
67 oneLine = infile.readline()
68 if len(oneLine) > 100:
69 endOfHeaders = True
70 break
71 if oneLine.strip() == "Binned mode":
72 oneLine = "Mode = Binned"
73 try:
74 key, val = oneLine.split('=' , 1)
75 except:
76 endOfHeaders = True
77 break
78 key = key.strip()
79 self.header_keys.append(key)
80 self.header[key] = val.strip()
81 missing = []
82 for item in MINIMUM_KEYS:
83 if item not in self.header_keys:
84 missing.append(item)
85 if len(missing) > 0:
86 logging.debug("KCD file misses the keys " + " ".join(missing))
87
88
89 - def read(self, fname):
90 """
91 Read in header into self.header and
92 the data into self.data
93 """
94 self.header = {}
95 self.resetvals()
96 infile = self._open(fname, "rb")
97 self._readheader(infile)
98
99 try:
100 self.dim1 = int(self.header['X dimension'])
101 self.dim2 = int(self.header['Y dimension'])
102 except:
103 raise Exception("KCD file %s is corrupt, cannot read it" % fname)
104 try:
105 bytecode = DATA_TYPES[self.header['Data type']]
106 self.bpp = len(np.array(0, bytecode).tostring())
107 except KeyError:
108 bytecode = np.uint16
109 self.bpp = 2
110 logging.warning("Defaulting type to uint16")
111 try:
112 nbReadOut = int(self.header['Number of readouts'])
113 except KeyError:
114 logging.warning("Defaulting number of ReadOut to 1")
115 nbReadOut = 1
116 fileSize = os.stat(fname)[6]
117 expected_size = self.dim1 * self.dim2 * self.bpp * nbReadOut
118 infile.seek(fileSize - expected_size)
119 block = infile.read()
120 assert len(block) == expected_size
121 infile.close()
122
123
124 self.data = np.zeros((self.dim2, self.dim1))
125 try:
126 for i in range(nbReadOut):
127 self.data += np.reshape(np.fromstring(
128 block[i * expected_size / nbReadOut:(i + 1) * expected_size / nbReadOut], bytecode),
129 [self.dim2, self.dim1])
130 except:
131 print len(block), bytecode, self.bpp, self.dim2, self.dim1
132 raise IOError, \
133 'Size spec in kcd-header does not match size of image data field'
134 self.bytecode = self.data.dtype.type
135 self.resetvals()
136
137 self.pilimage = None
138 return self
139