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, logging
11 import os, string
12 from fabioimage import fabioimage
13 logger = logging.getLogger("kcdimage")
14
15 DATA_TYPES = {"u16" : numpy.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" }
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 @
38 """
39 oneLine = infile.readline()
40 alphanum = string.digits + string.letters + ". "
41 asciiHeader = True
42 for oneChar in oneLine.strip():
43 if not oneChar in alphanum:
44 asciiHeader = False
45
46
47 if asciiHeader is False:
48
49 logger.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 logger.debug("KCD file misses the keys " + " ".join(missing))
72
73
74 - def read(self, fname, frame=None):
75 """
76 Read in header into self.header and
77 the data into self.data
78 """
79 self.header = {}
80 self.resetvals()
81 infile = self._open(fname, "rb")
82 self._readheader(infile)
83
84 try:
85 self.dim1 = int(self.header['X dimension'])
86 self.dim2 = int(self.header['Y dimension'])
87 except:
88 raise Exception("KCD file %s is corrupt, cannot read it" % fname)
89 try:
90 bytecode = DATA_TYPES[self.header['Data type']]
91 self.bpp = len(numpy.array(0, bytecode).tostring())
92 except KeyError:
93 bytecode = numpy.uint16
94 self.bpp = 2
95 logger.warning("Defaulting type to uint16")
96 try:
97 nbReadOut = int(self.header['Number of readouts'])
98 except KeyError:
99 logger.warning("Defaulting number of ReadOut to 1")
100 nbReadOut = 1
101 fileSize = os.stat(fname)[6]
102 expected_size = self.dim1 * self.dim2 * self.bpp * nbReadOut
103 infile.seek(fileSize - expected_size)
104 block = infile.read()
105 assert len(block) == expected_size
106 infile.close()
107
108
109 self.data = numpy.zeros((self.dim2, self.dim1))
110 try:
111 for i in range(nbReadOut):
112 self.data += numpy.reshape(numpy.fromstring(
113 block[i * expected_size / nbReadOut:(i + 1) * expected_size / nbReadOut], bytecode),
114 [self.dim2, self.dim1])
115 except:
116 print len(block), bytecode, self.bpp, self.dim2, self.dim1
117 raise IOError, \
118 'Size spec in kcd-header does not match size of image data field'
119 self.bytecode = self.data.dtype.type
120 self.resetvals()
121
122 self.pilimage = None
123 return self
124
125
126 @staticmethod
128 if data is None:
129 return None
130 else:
131 return data.astype(int)
132