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