1 """
2 Authors: Henning O. Sorensen & Erik Knudsen
3 Center for Fundamental Research: Metal Structures in Four Dimensions
4 Risoe National Laboratory
5 Frederiksborgvej 399
6 DK-4000 Roskilde
7 email:erik.knudsen@risoe.dk
8
9 + Jon Wright, ESRF
10 """
11 import logging
12 import numpy
13 from fabioimage import fabioimage
14 logger = logging.getLogger("dm3image")
15
16 DATA_TYPES = { 2 : numpy.int16,
17 4 : numpy.uint16,
18 3 : numpy.int32,
19 5 : numpy.uint32,
20 6 : numpy.float32,
21 7 : numpy.float,
22 8 : numpy.int8,
23 9 : None,
24 10 : None,
25 15 : 'Struct',
26 18 : None,
27 20 : None
28 }
29
30 DATA_BYTES = { 2 : 2,
31 4 : 2,
32 3 : 4,
33 5 : 4,
34 6 : 4,
35 7 : 8,
36 8 : 1,
37 9 : None,
38 10 : None,
39 15 : 'Struct',
40 18 : None,
41 20 : None
42 }
43
44
45
47 """ Read and try to write the dm3 data format """
49 fabioimage.__init__(self, *args, **kwargs)
50 self.encoded_datatype = None
51 self.no_data_elements = None
52 self.grouptag_is_sorted = None
53 self.grouptag_is_open = None
54 self.tag_encoded_type = None
55 self.tag_data_type = None
56 self.tag_is_data = None
57 self.grouptag_no_tags = None
58 self.bytes_in_file = None
59 self.tag_label_length = None
60 self.go_on = None
61
63 self.infile.seek(0)
64 file_format = self.readbytes(4, numpy.uint32)[0]
65 assert file_format == 3, 'Wrong file type '
66 self.bytes_in_file = self.readbytes(4, numpy.uint32)[0]
67 self.byte_order = self.readbytes(4, numpy.uint32)[0]
68 print 'read dm3 file - file format ', file_format
69 print 'Bytes in file : ' , self.bytes_in_file
70 print 'Byte order :', self.byte_order, ' - 0 = bigEndian , 1 = littleEndian'
71
72 if self.byte_order == 0:
73 self.swap = True
74 elif self.byte_order == 1:
75 self.swap = False
76 else:
77 raise ValueError
78
79 - def read(self, fname, frame=None):
80 self.header = {}
81 self.resetvals()
82 self.infile = self._open(fname, "rb")
83 self._readheader()
84 self.go_on = True
85 print self.go_on
86 while self.go_on:
87 self.read_tag_group()
88 self.read_tag_entry()
89 if self.infile.tell() > self.bytes_in_file: break
90
91 while self.tag_is_data == 21:
92 self.read_tag_entry()
93 if self.infile.tell() > self.bytes_in_file:
94 self.go_on = False
95
96 (dim1_raw, dim2_raw) = self.header['Active Size (pixels)'].split()
97 (dim1_raw, dim2_raw) = (eval(dim1_raw), eval(dim2_raw))
98 (dim1_binning, dim2_binning) = self.header['Binning'].split()
99 (dim1_binning, dim2_binning) = (eval(dim1_binning), eval(dim2_binning))
100 self.dim1 = dim1_raw / dim1_binning
101 self.dim2 = dim2_raw / dim2_binning
102
103 if self.header.has_key('Data'):
104 self.data = self.header['Data'].reshape(self.dim1, self.dim2)
105
106 - def readbytes(self, bytes_to_read, format, swap=True):
107 raw = self.infile.read(bytes_to_read)
108 if format != None:
109 data = numpy.fromstring(raw, format)
110 else:
111 data = raw
112 if swap:
113 data = data.byteswap()
114 return data
115
116
117
119
120 self.grouptag_is_sorted = self.readbytes(1, numpy.uint8)[0]
121 self.grouptag_is_open = self.readbytes(1, numpy.uint8)[0]
122 self.grouptag_no_tags = self.readbytes(4, numpy.uint32)[0]
123 logger.debug('TagGroup is sorted? %s', self.grouptag_is_sorted)
124 logger.debug('TagGroup is open? %s', self.grouptag_is_open)
125 logger.debug('no of tags in TagGroup %s', self.grouptag_no_tags)
126
127 - def read_tag_entry(self):
128
129 self.tag_is_data = self.readbytes(1, numpy.uint8)[0]
130 self.tag_label_length = self.readbytes(2, numpy.uint16)[0]
131 logger.debug('does Tag have data ? %s - 20 = Tag group , 21 = data ', self.tag_is_data)
132 logger.debug('length of tag_label ', self.tag_label_length)
133 if self.tag_label_length != 0:
134 tag_label = self.infile.read(self.tag_label_length)
135 else:
136 tag_label = None
137
138 if self.tag_is_data == 21:
139
140 self.header[tag_label] = self.read_tag_type()
141 logger.debug("%s: %s", tag_label, self.header[tag_label])
142
143
145 if self.infile.read(4) != '%%%%':
146 raise IOError
147 self.tag_data_type = self.readbytes(4, numpy.uint32)[0]
148 logger.debug('data is of type : %s - 1 = simple, 2= string, 3 = array, >3 structs', self.tag_data_type)
149 self.tag_encoded_type = self.readbytes(4, numpy.uint32)[0]
150 logger.debug('encode type: %s %s', self.tag_encoded_type, DATA_TYPES[ self.tag_encoded_type])
151 if self.tag_data_type == 1:
152
153 return self.readbytes(DATA_BYTES[ self.tag_encoded_type],
154 DATA_TYPES[ self.tag_encoded_type],
155 swap=self.swap)[0]
156
157 if self.tag_encoded_type == 20 and self.tag_data_type == 3 :
158 self.data_type = self.readbytes(4, numpy.uint32)[0]
159 self.no_data_elements = self.readbytes(4, numpy.uint32)[0]
160 if self.data_type == 10:
161 logger.debug('skip bytes %s', self.no_data_elements)
162 dump = self.infile.read(self.no_data_elements)
163 return None
164
165 logger.debug('Data are stored as a simple a array -')
166 logger.debug('%s data elemets stored as %s', self.no_data_elements, self.data_type)
167 read_no_bytes = DATA_BYTES[self.data_type] * self.no_data_elements
168 format = DATA_TYPES[self.data_type]
169 return self.readbytes(read_no_bytes, format, swap=self.swap)
170
171
172
173
174
175 if self.tag_encoded_type == 20 and self.tag_data_type > 3 :
176 self.tag_encoded_type = self.readbytes(4, numpy.uint32)[0]
177 logger.debug('found array - new tag_encoded_type %s', self.tag_encoded_type)
178 if self.tag_encoded_type == 15:
179
180 struct_name_length = self.readbytes(4, numpy.int32)[0]
181 struct_number_fields = self.readbytes(4, numpy.int32)[0]
182
183
184 field_info = []
185 for i in range(struct_number_fields):
186 field_info.append([self.readbytes(4, numpy.int32)[0], self.readbytes(4, numpy.int32)[0]])
187
188 self.no_data_elements = self.readbytes(4, numpy.int32)[0]
189
190 bytes_in_struct = 0
191 for i in range(struct_number_fields):
192 bytes_in_struct += DATA_BYTES[field_info[i][1]]
193 logger.debug('skip bytes %s', self.no_data_elements * bytes_in_struct)
194 dump = self.infile.read(self.no_data_elements * bytes_in_struct)
195 return None
196
197
198 if self.tag_encoded_type == 15:
199
200 struct_name_length = self.readbytes(4, numpy.int32)[0]
201 struct_number_fields = self.readbytes(4, numpy.int32)[0]
202
203
204 field_info = []
205 for i in range(struct_number_fields):
206 field_info.append([self.readbytes(4, numpy.int32)[0], self.readbytes(4, numpy.int32)[0]])
207
208 field_data = ''
209 for i in range(struct_number_fields):
210
211 field_data = field_data + self.readbytes(field_info[i][0], None, swap=False) + ' '
212 field_data = field_data + '%i ' % self.readbytes(DATA_BYTES[field_info[i][1]],
213 DATA_TYPES[field_info[i][1]],
214 swap=self.swap)[0]
215 return field_data
216
218 self.encoded_datatype = numpy.fromstring(self.infile.read(4), numpy.uint32).byteswap()
219