fabio 0.1.1__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Library/Python/2.7/site-packages/fabio/GEimage.py +334 -0
- Library/Python/2.7/site-packages/fabio/GEimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/GEimage_old.py +501 -0
- Library/Python/2.7/site-packages/fabio/GEimage_old.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/HiPiCimage.py +106 -0
- Library/Python/2.7/site-packages/fabio/HiPiCimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/OXDimage.py +442 -0
- Library/Python/2.7/site-packages/fabio/OXDimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/TiffIO.py +1197 -0
- Library/Python/2.7/site-packages/fabio/TiffIO.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/__init__.py +10 -0
- Library/Python/2.7/site-packages/fabio/__init__.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/adscimage.py +137 -0
- Library/Python/2.7/site-packages/fabio/adscimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/binaryimage.py +87 -0
- Library/Python/2.7/site-packages/fabio/binaryimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/bruker100image.py +96 -0
- Library/Python/2.7/site-packages/fabio/bruker100image.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/brukerimage.py +195 -0
- Library/Python/2.7/site-packages/fabio/brukerimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/byte_offset.so +0 -0
- Library/Python/2.7/site-packages/fabio/cbfimage.py +758 -0
- Library/Python/2.7/site-packages/fabio/cbfimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/cf_io.so +0 -0
- Library/Python/2.7/site-packages/fabio/compression.py +388 -0
- Library/Python/2.7/site-packages/fabio/compression.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/converters.py +54 -0
- Library/Python/2.7/site-packages/fabio/converters.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/datIO.py +60 -0
- Library/Python/2.7/site-packages/fabio/datIO.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/dm3image.py +219 -0
- Library/Python/2.7/site-packages/fabio/dm3image.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/edfimage.py +924 -0
- Library/Python/2.7/site-packages/fabio/edfimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fabioimage.py +556 -0
- Library/Python/2.7/site-packages/fabio/fabioimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fabioutils.py +491 -0
- Library/Python/2.7/site-packages/fabio/fabioutils.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/file_series.py +313 -0
- Library/Python/2.7/site-packages/fabio/file_series.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fit2dmaskimage.py +94 -0
- Library/Python/2.7/site-packages/fabio/fit2dmaskimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/fit2dspreadsheetimage.py +85 -0
- Library/Python/2.7/site-packages/fabio/fit2dspreadsheetimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/kcdimage.py +131 -0
- Library/Python/2.7/site-packages/fabio/kcdimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/mar345_IO.so +0 -0
- Library/Python/2.7/site-packages/fabio/mar345image.py +320 -0
- Library/Python/2.7/site-packages/fabio/mar345image.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/marccdimage.py +309 -0
- Library/Python/2.7/site-packages/fabio/marccdimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/openimage.py +162 -0
- Library/Python/2.7/site-packages/fabio/openimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/pilatusimage.py +81 -0
- Library/Python/2.7/site-packages/fabio/pilatusimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/pnmimage.py +165 -0
- Library/Python/2.7/site-packages/fabio/pnmimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/readbytestream.py +86 -0
- Library/Python/2.7/site-packages/fabio/readbytestream.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/tifimage.py +283 -0
- Library/Python/2.7/site-packages/fabio/tifimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio/xsdimage.py +134 -0
- Library/Python/2.7/site-packages/fabio/xsdimage.pyc +0 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/PKG-INFO +11 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/SOURCES.txt +114 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/dependency_links.txt +1 -0
- Library/Python/2.7/site-packages/fabio-0.1.1-py2.7.egg-info/top_level.txt +4 -0
|
@@ -0,0 +1,924 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf8 -*-
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
License: GPLv2+
|
|
6
|
+
|
|
7
|
+
Authors: Henning O. Sorensen & Erik Knudsen
|
|
8
|
+
Center for Fundamental Research: Metal Structures in Four Dimensions
|
|
9
|
+
Risoe National Laboratory
|
|
10
|
+
Frederiksborgvej 399
|
|
11
|
+
DK-4000 Roskilde
|
|
12
|
+
email:erik.knudsen@risoe.dk
|
|
13
|
+
|
|
14
|
+
+ Jon Wright, ESRF
|
|
15
|
+
|
|
16
|
+
2011-02-11: Mostly rewritten by Jérôme Kieffer (Jerome.Kieffer@esrf.eu)
|
|
17
|
+
European Synchrotron Radiation Facility
|
|
18
|
+
Grenoble (France)
|
|
19
|
+
2012-08-20: laisy read of data in EDF
|
|
20
|
+
"""
|
|
21
|
+
from __future__ import with_statement
|
|
22
|
+
import os, logging, types
|
|
23
|
+
logger = logging.getLogger("edfimage")
|
|
24
|
+
import numpy
|
|
25
|
+
from fabioimage import fabioimage
|
|
26
|
+
from fabioutils import isAscii, toAscii, nice_int
|
|
27
|
+
from compression import decBzip2, decGzip, decZlib
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
BLOCKSIZE = 512
|
|
31
|
+
DATA_TYPES = { "SignedByte" : numpy.int8,
|
|
32
|
+
"Signed8" : numpy.int8,
|
|
33
|
+
"UnsignedByte" : numpy.uint8,
|
|
34
|
+
"Unsigned8" : numpy.uint8,
|
|
35
|
+
"SignedShort" : numpy.int16,
|
|
36
|
+
"Signed16" : numpy.int16,
|
|
37
|
+
"UnsignedShort" : numpy.uint16,
|
|
38
|
+
"Unsigned16" : numpy.uint16,
|
|
39
|
+
"UnsignedShortInteger" : numpy.uint16,
|
|
40
|
+
"SignedInteger" : numpy.int32,
|
|
41
|
+
"Signed32" : numpy.int32,
|
|
42
|
+
"UnsignedInteger": numpy.uint32,
|
|
43
|
+
"Unsigned32" : numpy.uint32,
|
|
44
|
+
"SignedLong" : numpy.int32,
|
|
45
|
+
"UnsignedLong" : numpy.uint32,
|
|
46
|
+
"Signed64" : numpy.int64,
|
|
47
|
+
"Unsigned64" : numpy.uint64,
|
|
48
|
+
"FloatValue" : numpy.float32,
|
|
49
|
+
"FLOATVALUE" : numpy.float32,
|
|
50
|
+
"FLOAT" : numpy.float32, # fit2d
|
|
51
|
+
"Float" : numpy.float32, # fit2d
|
|
52
|
+
"FloatIEEE32" : numpy.float32,
|
|
53
|
+
"Float32" : numpy.float32,
|
|
54
|
+
"Double" : numpy.float64,
|
|
55
|
+
"DoubleValue" : numpy.float64,
|
|
56
|
+
"FloatIEEE64" : numpy.float64,
|
|
57
|
+
"DoubleIEEE64" : numpy.float64}
|
|
58
|
+
try:
|
|
59
|
+
DATA_TYPES["FloatIEEE128" ] = numpy.float128
|
|
60
|
+
DATA_TYPES["DoubleIEEE128" ] = numpy.float128
|
|
61
|
+
DATA_TYPES["QuadrupleValue" ] = numpy.float128
|
|
62
|
+
|
|
63
|
+
except AttributeError:
|
|
64
|
+
# not in your numpy
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
NUMPY_EDF_DTYPE = {"int8" :"SignedByte",
|
|
68
|
+
"int16" :"SignedShort",
|
|
69
|
+
"int32" :"SignedInteger",
|
|
70
|
+
"int64" :"Signed64",
|
|
71
|
+
"uint8" :"UnsignedByte",
|
|
72
|
+
"uint16" :"UnsignedShort",
|
|
73
|
+
"uint32" :"UnsignedInteger",
|
|
74
|
+
"uint64" :"Unsigned64",
|
|
75
|
+
"float32" :"FloatValue",
|
|
76
|
+
"float64" :"DoubleValue",
|
|
77
|
+
"float128" :"QuadrupleValue",
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
MINIMUM_KEYS = ['HEADERID',
|
|
81
|
+
'IMAGE',
|
|
82
|
+
'BYTEORDER',
|
|
83
|
+
'DATATYPE',
|
|
84
|
+
'DIM_1',
|
|
85
|
+
'DIM_2',
|
|
86
|
+
'SIZE'] # Size is thought to be essential for writing at least
|
|
87
|
+
|
|
88
|
+
DEFAULT_VALUES = {
|
|
89
|
+
# I do not define default values as they will be calculated at write time
|
|
90
|
+
# JK20110415
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
class Frame(object):
|
|
94
|
+
"""
|
|
95
|
+
A class representing a single frame in an EDF file
|
|
96
|
+
"""
|
|
97
|
+
def __init__(self, data=None, header=None, header_keys=None, number=None):
|
|
98
|
+
if header is None:
|
|
99
|
+
self.header = {}
|
|
100
|
+
else:
|
|
101
|
+
self.header = dict(header)
|
|
102
|
+
|
|
103
|
+
if header_keys is None:
|
|
104
|
+
self.header_keys = self.header.keys()
|
|
105
|
+
else:
|
|
106
|
+
self.header_keys = header_keys[:]
|
|
107
|
+
for key in header_keys:
|
|
108
|
+
if key not in self.header:
|
|
109
|
+
logger.warning("Header key %s, in header_keys is not in header dictionary, poping !!!" % key)
|
|
110
|
+
self.header_keys.remove(key)
|
|
111
|
+
|
|
112
|
+
self.capsHeader = {}
|
|
113
|
+
for key in self.header_keys:
|
|
114
|
+
try:
|
|
115
|
+
self.capsHeader[key.upper()] = key
|
|
116
|
+
except AttributeError:
|
|
117
|
+
logger.warning("Header key %s is not a string" % key)
|
|
118
|
+
self._data = data
|
|
119
|
+
self.dims = []
|
|
120
|
+
self.dim1 = 0
|
|
121
|
+
self.dim2 = 0
|
|
122
|
+
self.start = None # Position of start of raw data in file
|
|
123
|
+
self.size = None # size of raw data in file
|
|
124
|
+
self.file = None # opened file object with locking capabilities !!!
|
|
125
|
+
self.bpp = None
|
|
126
|
+
self._bytecode = None
|
|
127
|
+
if (number is not None) and isinstance(number, int):
|
|
128
|
+
self.iFrame = number
|
|
129
|
+
else:
|
|
130
|
+
self.iFrame = 0
|
|
131
|
+
|
|
132
|
+
def parseheader(self, block):
|
|
133
|
+
"""
|
|
134
|
+
Parse the header in some EDF format from an already open file
|
|
135
|
+
|
|
136
|
+
@param block: string representing the header block
|
|
137
|
+
@type block: string, should be full ascii
|
|
138
|
+
@return: size of the binary blob
|
|
139
|
+
"""
|
|
140
|
+
#reset values ...
|
|
141
|
+
self.header = {}
|
|
142
|
+
self.capsHeader = {}
|
|
143
|
+
self.header_keys = []
|
|
144
|
+
self.size = None
|
|
145
|
+
calcsize = 1
|
|
146
|
+
self.dims = []
|
|
147
|
+
|
|
148
|
+
for line in block.split(';'):
|
|
149
|
+
if '=' in line:
|
|
150
|
+
key, val = line.split('=' , 1)
|
|
151
|
+
# Why would someone put null bytes in a header?
|
|
152
|
+
key = key.replace("\x00"," ").strip()
|
|
153
|
+
self.header[key] = val.replace("\x00"," ").strip()
|
|
154
|
+
self.capsHeader[key.upper()] = key
|
|
155
|
+
self.header_keys.append(key)
|
|
156
|
+
|
|
157
|
+
# Compute image size
|
|
158
|
+
if "SIZE" in self.capsHeader:
|
|
159
|
+
try:
|
|
160
|
+
self.size = nice_int(self.header[self.capsHeader["SIZE"]])
|
|
161
|
+
except ValueError:
|
|
162
|
+
logger.warning("Unable to convert to integer : %s %s " % (self.capsHeader["SIZE"], self.header[self.capsHeader["SIZE"]]))
|
|
163
|
+
if "DIM_1" in self.capsHeader:
|
|
164
|
+
try:
|
|
165
|
+
dim1 = nice_int(self.header[self.capsHeader['DIM_1']])
|
|
166
|
+
except ValueError:
|
|
167
|
+
logger.error("Unable to convert to integer Dim_1: %s %s" % (self.capsHeader["DIM_1"], self.header[self.capsHeader["DIM_1"]]))
|
|
168
|
+
else:
|
|
169
|
+
calcsize *= dim1
|
|
170
|
+
self.dims.append(dim1)
|
|
171
|
+
else:
|
|
172
|
+
logger.error("No Dim_1 in headers !!!")
|
|
173
|
+
if "DIM_2" in self.capsHeader:
|
|
174
|
+
try:
|
|
175
|
+
dim2 = nice_int(self.header[self.capsHeader['DIM_2']])
|
|
176
|
+
except ValueError:
|
|
177
|
+
logger.error("Unable to convert to integer Dim_3: %s %s" % (self.capsHeader["DIM_2"], self.header[self.capsHeader["DIM_2"]]))
|
|
178
|
+
else:
|
|
179
|
+
calcsize *= dim2
|
|
180
|
+
self.dims.append(dim2)
|
|
181
|
+
else:
|
|
182
|
+
logger.error("No Dim_2 in headers !!!")
|
|
183
|
+
iDim = 3
|
|
184
|
+
# JON: this appears to be for nD images, but we don't treat those
|
|
185
|
+
while iDim is not None:
|
|
186
|
+
strDim = "DIM_%i" % iDim
|
|
187
|
+
if strDim in self.capsHeader:
|
|
188
|
+
try:
|
|
189
|
+
dim3 = nice_int(self.header[self.capsHeader[strDim]])
|
|
190
|
+
except ValueError:
|
|
191
|
+
logger.error("Unable to convert to integer %s: %s %s"
|
|
192
|
+
% (strDim, self.capsHeader[strDim], self.header[self.capsHeader[strDim]]))
|
|
193
|
+
dim3 = None
|
|
194
|
+
iDim = None
|
|
195
|
+
else:
|
|
196
|
+
if dim3 > 1:
|
|
197
|
+
# Otherwise treat dim3==1 as a 2D image
|
|
198
|
+
calcsize *= dim3
|
|
199
|
+
self.dims.append(dim3)
|
|
200
|
+
iDim += 1
|
|
201
|
+
|
|
202
|
+
else:
|
|
203
|
+
logger.debug("No Dim_3 -> it is a 2D image")
|
|
204
|
+
iDim = None
|
|
205
|
+
if self._bytecode is None:
|
|
206
|
+
if "DATATYPE" in self.capsHeader:
|
|
207
|
+
self._bytecode = DATA_TYPES[self.header[self.capsHeader['DATATYPE']]]
|
|
208
|
+
else:
|
|
209
|
+
self._bytecode = numpy.uint16
|
|
210
|
+
logger.warning("Defaulting type to uint16")
|
|
211
|
+
self.bpp = len(numpy.array(0, self._bytecode).tostring())
|
|
212
|
+
calcsize *= self.bpp
|
|
213
|
+
if (self.size is None):
|
|
214
|
+
self.size = calcsize
|
|
215
|
+
elif (self.size != calcsize):
|
|
216
|
+
if ("COMPRESSION" in self.capsHeader) and (self.header[self.capsHeader['COMPRESSION']].upper().startswith("NO")):
|
|
217
|
+
logger.info("Mismatch between the expected size %s and the calculated one %s" % (self.size, calcsize))
|
|
218
|
+
self.size = calcsize
|
|
219
|
+
|
|
220
|
+
for i, n in enumerate(self.dims):
|
|
221
|
+
setattr(self, "dim%i" % (i + 1), n)
|
|
222
|
+
|
|
223
|
+
return self.size
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def swap_needed(self):
|
|
227
|
+
"""
|
|
228
|
+
Decide if we need to byteswap
|
|
229
|
+
"""
|
|
230
|
+
if ('Low' in self.header[self.capsHeader['BYTEORDER']] and numpy.little_endian) or \
|
|
231
|
+
('High' in self.header[self.capsHeader['BYTEORDER']] and not numpy.little_endian):
|
|
232
|
+
return False
|
|
233
|
+
if ('High' in self.header[self.capsHeader['BYTEORDER']] and numpy.little_endian) or \
|
|
234
|
+
('Low' in self.header[self.capsHeader['BYTEORDER']] and not numpy.little_endian):
|
|
235
|
+
if self.bpp in [2, 4, 8]:
|
|
236
|
+
return True
|
|
237
|
+
else:
|
|
238
|
+
return False
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def getData(self):
|
|
242
|
+
"""
|
|
243
|
+
Unpack a binary blob according to the specification given in the header
|
|
244
|
+
|
|
245
|
+
@return: dataset as numpy.ndarray
|
|
246
|
+
"""
|
|
247
|
+
data = None
|
|
248
|
+
if self._data is not None:
|
|
249
|
+
data = self._data
|
|
250
|
+
elif self.file is None:
|
|
251
|
+
data = self._data
|
|
252
|
+
else:
|
|
253
|
+
if self._bytecode is None:
|
|
254
|
+
if "DATATYPE" in self.capsHeader:
|
|
255
|
+
self._bytecode = DATA_TYPES[self.header[self.capsHeader["DATATYPE"]]]
|
|
256
|
+
else:
|
|
257
|
+
self._bytecode = numpy.uint16
|
|
258
|
+
dims = self.dims[:]
|
|
259
|
+
dims.reverse()
|
|
260
|
+
with self.file.lock:
|
|
261
|
+
if self.file.closed:
|
|
262
|
+
logger.error("file: %s from %s is closed. Cannot read data." % (self.file, self.file.filename))
|
|
263
|
+
return
|
|
264
|
+
else:
|
|
265
|
+
self.file.seek(self.start)
|
|
266
|
+
fileData = self.file.read(self.size)
|
|
267
|
+
|
|
268
|
+
if ("COMPRESSION" in self.capsHeader):
|
|
269
|
+
compression = self.header[self.capsHeader["COMPRESSION"]].upper()
|
|
270
|
+
uncompressed_size = self.bpp
|
|
271
|
+
for i in dims:
|
|
272
|
+
uncompressed_size *= i
|
|
273
|
+
if "OFFSET" in compression :
|
|
274
|
+
try:
|
|
275
|
+
import byte_offset#IGNORE:F0401
|
|
276
|
+
except ImportError, error:
|
|
277
|
+
logger.error("Unimplemented compression scheme: %s (%s)" % (compression, error))
|
|
278
|
+
else:
|
|
279
|
+
myData = byte_offset.analyseCython(fileData, size=uncompressed_size)
|
|
280
|
+
rawData = myData.astype(self._bytecode).tostring()
|
|
281
|
+
self.size = uncompressed_size
|
|
282
|
+
elif compression == "NONE":
|
|
283
|
+
rawData = fileData
|
|
284
|
+
elif "GZIP" in compression:
|
|
285
|
+
rawData = decGzip(fileData)
|
|
286
|
+
self.size = uncompressed_size
|
|
287
|
+
elif "BZ" in compression :
|
|
288
|
+
rawData = decBzip2(fileData)
|
|
289
|
+
self.size = uncompressed_size
|
|
290
|
+
elif "Z" in compression :
|
|
291
|
+
rawData = decZlib(fileData)
|
|
292
|
+
self.size = uncompressed_size
|
|
293
|
+
else:
|
|
294
|
+
logger.warning("Unknown compression scheme %s" % compression)
|
|
295
|
+
rawData = fileData
|
|
296
|
+
|
|
297
|
+
else:
|
|
298
|
+
rawData = fileData
|
|
299
|
+
|
|
300
|
+
expected = self.size
|
|
301
|
+
obtained = len(rawData)
|
|
302
|
+
if expected > obtained:
|
|
303
|
+
logger.error("Data stream is incomplete: %s < expected %s bytes" % (obtained, expected))
|
|
304
|
+
rawData += "\x00" * (expected - obtained)
|
|
305
|
+
elif expected < len(rawData):
|
|
306
|
+
logger.info("Data stream contains trailing junk : %s > expected %s bytes" % (obtained, expected))
|
|
307
|
+
rawData = rawData[:expected]
|
|
308
|
+
if self.swap_needed():
|
|
309
|
+
data = numpy.fromstring(rawData, self._bytecode).byteswap().reshape(tuple(dims))
|
|
310
|
+
else:
|
|
311
|
+
data = numpy.fromstring(rawData, self._bytecode).reshape(tuple(dims))
|
|
312
|
+
self._data = data
|
|
313
|
+
self._bytecode = data.dtype.type
|
|
314
|
+
return data
|
|
315
|
+
def setData(self, npa=None):
|
|
316
|
+
"""Setter for data in edf frame"""
|
|
317
|
+
self._data = npa
|
|
318
|
+
data = property(getData, setData, "property: (edf)frame.data, uncompress the datablock when needed")
|
|
319
|
+
def getByteCode(self):
|
|
320
|
+
if self._bytecode is None:
|
|
321
|
+
self._bytecode = self.data.dtype.type
|
|
322
|
+
|
|
323
|
+
return self._bytecode
|
|
324
|
+
def setByteCode(self, _iVal):
|
|
325
|
+
self._bytecode = _iVal
|
|
326
|
+
bytecode = property(getByteCode, setByteCode)
|
|
327
|
+
|
|
328
|
+
def getEdfBlock(self, force_type=None, fit2dMode=False):
|
|
329
|
+
"""
|
|
330
|
+
@param force_type: type of the dataset to be enforced like "float64" or "uint16"
|
|
331
|
+
@type force_type: string or numpy.dtype
|
|
332
|
+
@param fit2dMode: enforce compatibility with fit2d and starts countimg number of images at 1
|
|
333
|
+
@type fit2dMode: boolean
|
|
334
|
+
@return: ascii header block
|
|
335
|
+
@rtype: python string with the concatenation of the ascii header and the binary data block
|
|
336
|
+
"""
|
|
337
|
+
if force_type is not None:
|
|
338
|
+
data = self.data.astype(force_type)
|
|
339
|
+
else:
|
|
340
|
+
data = self.data
|
|
341
|
+
fit2dMode = bool(fit2dMode)
|
|
342
|
+
for key in self.header:
|
|
343
|
+
KEY = key.upper()
|
|
344
|
+
if KEY not in self.capsHeader:
|
|
345
|
+
self.capsHeader[KEY] = key
|
|
346
|
+
if key not in self.header_keys:
|
|
347
|
+
self.header_keys.append(key)
|
|
348
|
+
|
|
349
|
+
header = self.header.copy()
|
|
350
|
+
header_keys = self.header_keys[:]
|
|
351
|
+
capsHeader = self.capsHeader.copy()
|
|
352
|
+
|
|
353
|
+
listHeader = ["{\n"]
|
|
354
|
+
# First of all clean up the headers:
|
|
355
|
+
for i in capsHeader:
|
|
356
|
+
if "DIM_" in i:
|
|
357
|
+
header.pop(capsHeader[i])
|
|
358
|
+
header_keys.remove(capsHeader[i])
|
|
359
|
+
for KEY in ["SIZE", "EDF_BINARYSIZE", "EDF_HEADERSIZE", "BYTEORDER", "DATATYPE", "HEADERID", "IMAGE"]:
|
|
360
|
+
if KEY in capsHeader:
|
|
361
|
+
header.pop(capsHeader[KEY])
|
|
362
|
+
header_keys.remove(capsHeader[KEY])
|
|
363
|
+
if "EDF_DATABLOCKID" in capsHeader:
|
|
364
|
+
header_keys.remove(capsHeader["EDF_DATABLOCKID"])
|
|
365
|
+
#but do not remove the value from dict, instead reset the key ...
|
|
366
|
+
if capsHeader["EDF_DATABLOCKID"] != "EDF_DataBlockID":
|
|
367
|
+
header["EDF_DataBlockID"] = header.pop(capsHeader["EDF_DATABLOCKID"])
|
|
368
|
+
capsHeader["EDF_DATABLOCKID"] = "EDF_DataBlockID"
|
|
369
|
+
|
|
370
|
+
# Then update static headers freshly deleted
|
|
371
|
+
header_keys.insert(0, "Size")
|
|
372
|
+
header["Size"] = len(data.tostring())
|
|
373
|
+
header_keys.insert(0, "HeaderID")
|
|
374
|
+
header["HeaderID"] = "EH:%06d:000000:000000" % (self.iFrame + fit2dMode)
|
|
375
|
+
header_keys.insert(0, "Image")
|
|
376
|
+
header["Image"] = str(self.iFrame + fit2dMode)
|
|
377
|
+
|
|
378
|
+
dims = list(data.shape)
|
|
379
|
+
nbdim = len(dims)
|
|
380
|
+
for i in dims:
|
|
381
|
+
key = "Dim_%i" % nbdim
|
|
382
|
+
header[key] = i
|
|
383
|
+
header_keys.insert(0, key)
|
|
384
|
+
nbdim -= 1
|
|
385
|
+
header_keys.insert(0, "DataType")
|
|
386
|
+
header["DataType"] = NUMPY_EDF_DTYPE[str(numpy.dtype(data.dtype))]
|
|
387
|
+
header_keys.insert(0, "ByteOrder")
|
|
388
|
+
if numpy.little_endian:
|
|
389
|
+
header["ByteOrder"] = "LowByteFirst"
|
|
390
|
+
else:
|
|
391
|
+
header["ByteOrder"] = "HighByteFirst"
|
|
392
|
+
approxHeaderSize = 100
|
|
393
|
+
for key in header:
|
|
394
|
+
approxHeaderSize += 7 + len(key) + len(str(header[key]))
|
|
395
|
+
approxHeaderSize = BLOCKSIZE * (approxHeaderSize // BLOCKSIZE + 1)
|
|
396
|
+
header_keys.insert(0, "EDF_HeaderSize")
|
|
397
|
+
header["EDF_HeaderSize"] = str(BLOCKSIZE * (approxHeaderSize // BLOCKSIZE + 1))
|
|
398
|
+
header_keys.insert(0, "EDF_BinarySize")
|
|
399
|
+
header["EDF_BinarySize"] = len(data.tostring())
|
|
400
|
+
header_keys.insert(0, "EDF_DataBlockID")
|
|
401
|
+
if not "EDF_DataBlockID" in header:
|
|
402
|
+
header["EDF_DataBlockID"] = "%i.Image.Psd" % (self.iFrame + fit2dMode)
|
|
403
|
+
preciseSize = 4 #2 before {\n 2 after }\n
|
|
404
|
+
for key in header_keys:
|
|
405
|
+
#Escape keys or values that are no ascii
|
|
406
|
+
strKey = str(key)
|
|
407
|
+
if not isAscii(strKey, listExcluded=["}", "{"]):
|
|
408
|
+
logger.warning("Non ascii key %s, skipping" % strKey)
|
|
409
|
+
continue
|
|
410
|
+
strValue = str(header[key])
|
|
411
|
+
if not isAscii(strValue, listExcluded=["}", "{"]):
|
|
412
|
+
logger.warning("Non ascii value %s, skipping" % strValue)
|
|
413
|
+
continue
|
|
414
|
+
line = strKey + " = " + strValue + " ;\n"
|
|
415
|
+
preciseSize += len(line)
|
|
416
|
+
listHeader.append(line)
|
|
417
|
+
if preciseSize > approxHeaderSize:
|
|
418
|
+
logger.error("I expected the header block only at %s in fact it is %s" % (approxHeaderSize, preciseSize))
|
|
419
|
+
for idx, line in enumerate(listHeader[:]):
|
|
420
|
+
if line.startswith("EDF_HeaderSize"):
|
|
421
|
+
headerSize = BLOCKSIZE * (preciseSize // BLOCKSIZE + 1)
|
|
422
|
+
newline = "EDF_HeaderSize = %s ;\n" % headerSize
|
|
423
|
+
delta = len(newline) - len(line)
|
|
424
|
+
if (preciseSize // BLOCKSIZE) != ((preciseSize + delta) // BLOCKSIZE):
|
|
425
|
+
headerSize = BLOCKSIZE * ((preciseSize + delta) // BLOCKSIZE + 1)
|
|
426
|
+
newline = "EDF_HeaderSize = %s ;\n" % headerSize
|
|
427
|
+
preciseSize = preciseSize + delta
|
|
428
|
+
listHeader[idx] = newline
|
|
429
|
+
break
|
|
430
|
+
else:
|
|
431
|
+
headerSize = approxHeaderSize
|
|
432
|
+
listHeader.append(" "*(headerSize - preciseSize) + "}\n")
|
|
433
|
+
return "".join(listHeader) + data.tostring()
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
class edfimage(fabioimage):
|
|
438
|
+
""" Read and try to write the ESRF edf data format """
|
|
439
|
+
|
|
440
|
+
def __init__(self, data=None , header=None, header_keys=None, frames=None):
|
|
441
|
+
self.currentframe = 0
|
|
442
|
+
self.filesize = None
|
|
443
|
+
try:
|
|
444
|
+
dim = len(data.shape)
|
|
445
|
+
except Exception, error: #IGNORE:W0703
|
|
446
|
+
logger.debug("Data don't look like a numpy array (%s), resetting all!!" % error)
|
|
447
|
+
data = None
|
|
448
|
+
dim = 0
|
|
449
|
+
fabioimage.__init__(self, data, header)
|
|
450
|
+
if dim == 2:
|
|
451
|
+
fabioimage.__init__(self, data, header)
|
|
452
|
+
elif dim == 1 :
|
|
453
|
+
data.shape = (0, len(data))
|
|
454
|
+
fabioimage.__init__(self, data, header)
|
|
455
|
+
elif dim == 3 :
|
|
456
|
+
fabioimage.__init__(self, data[0, :, :], header)
|
|
457
|
+
elif dim == 4 :
|
|
458
|
+
fabioimage.__init__(self, data[0, 0, :, :], header)
|
|
459
|
+
elif dim == 5 :
|
|
460
|
+
fabioimage.__init__(self, data[0, 0, 0, :, :], header)
|
|
461
|
+
|
|
462
|
+
if frames is None:
|
|
463
|
+
frame = Frame(data=self.data, header=self.header,
|
|
464
|
+
header_keys=header_keys ,
|
|
465
|
+
number=self.currentframe)
|
|
466
|
+
self.__frames = [frame]
|
|
467
|
+
else:
|
|
468
|
+
self.__frames = frames
|
|
469
|
+
|
|
470
|
+
@staticmethod
|
|
471
|
+
def checkHeader(header=None):
|
|
472
|
+
"""
|
|
473
|
+
Empty for fabioimage but may be populated by others classes
|
|
474
|
+
"""
|
|
475
|
+
if type(header) != types.DictionaryType:
|
|
476
|
+
return {}
|
|
477
|
+
new = {}
|
|
478
|
+
for key, value in header.items():
|
|
479
|
+
new[toAscii(key, ";{}")] = toAscii(value, ";{}")
|
|
480
|
+
return new
|
|
481
|
+
|
|
482
|
+
@staticmethod
|
|
483
|
+
def _readHeaderBlock(infile):
|
|
484
|
+
"""
|
|
485
|
+
Read in a header in some EDF format from an already open file
|
|
486
|
+
|
|
487
|
+
@param infile: file object open in read mode
|
|
488
|
+
@return: string (or None if no header was found.
|
|
489
|
+
"""
|
|
490
|
+
|
|
491
|
+
block = infile.read(BLOCKSIZE)
|
|
492
|
+
if len(block) < BLOCKSIZE:
|
|
493
|
+
logger.debug("Under-short header: only %i bytes in %s" % (len(block), infile.name))
|
|
494
|
+
return
|
|
495
|
+
if (block.find("{") < 0) :
|
|
496
|
+
# This does not look like an edf file
|
|
497
|
+
logger.warning("no opening {. Corrupt header of EDF file %s" % infile.name)
|
|
498
|
+
return
|
|
499
|
+
while '}' not in block:
|
|
500
|
+
block = block + infile.read(BLOCKSIZE)
|
|
501
|
+
if len(block) > BLOCKSIZE * 20:
|
|
502
|
+
logger.warning("Runaway header in EDF file")
|
|
503
|
+
return
|
|
504
|
+
start = block.find("{") + 1
|
|
505
|
+
end = block.find("}")
|
|
506
|
+
|
|
507
|
+
# Now it is essential to go to the start of the binary part
|
|
508
|
+
if block[end: end + 3] == "}\r\n":
|
|
509
|
+
offset = end + 3 - len(block)
|
|
510
|
+
elif block[end: end + 2] == "}\n":
|
|
511
|
+
offset = end + 2 - len(block)
|
|
512
|
+
else:
|
|
513
|
+
logger.error("Unable to locate start of the binary section")
|
|
514
|
+
offset = None
|
|
515
|
+
if offset is not None:
|
|
516
|
+
infile.seek(offset, os.SEEK_CUR)
|
|
517
|
+
return block[start:end]
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def _readheader(self, infile):
|
|
521
|
+
"""
|
|
522
|
+
Read all headers in a file and populate self.header
|
|
523
|
+
data is not yet populated
|
|
524
|
+
@type infile: file object open in read mode
|
|
525
|
+
"""
|
|
526
|
+
self.__frames = []
|
|
527
|
+
bContinue = True
|
|
528
|
+
while bContinue:
|
|
529
|
+
block = self._readHeaderBlock(infile)
|
|
530
|
+
if block is None:
|
|
531
|
+
bContinue = False
|
|
532
|
+
break
|
|
533
|
+
frame = Frame(number=self.nframes)
|
|
534
|
+
size = frame.parseheader(block)
|
|
535
|
+
frame.file = infile
|
|
536
|
+
frame.start = infile.tell()
|
|
537
|
+
frame.size = size
|
|
538
|
+
self.__frames += [frame]
|
|
539
|
+
try:
|
|
540
|
+
infile.seek(size, os.SEEK_CUR)
|
|
541
|
+
except Exception, error:
|
|
542
|
+
logger.warning("infile is %s" % infile)
|
|
543
|
+
logger.warning("Position is %s" % infile.tell())
|
|
544
|
+
logger.warning("size is %s" % size)
|
|
545
|
+
logger.error("It seams this error occurs under windows when reading a (large-) file over network: %s ", error)
|
|
546
|
+
raise Exception(error)
|
|
547
|
+
|
|
548
|
+
if frame.start + size > infile.size:
|
|
549
|
+
logger.warning("Non complete datablock: got %s, expected %s" % (infile.size - frame.start, size))
|
|
550
|
+
bContinue = False
|
|
551
|
+
break
|
|
552
|
+
|
|
553
|
+
for i, frame in enumerate(self.__frames):
|
|
554
|
+
missing = []
|
|
555
|
+
for item in MINIMUM_KEYS:
|
|
556
|
+
if item not in frame.capsHeader:
|
|
557
|
+
missing.append(item)
|
|
558
|
+
if len(missing) > 0:
|
|
559
|
+
logger.info("EDF file %s frame %i misses mandatory keys: %s " % (self.filename, i, " ".join(missing)))
|
|
560
|
+
self.currentframe = 0
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
def read(self, fname, frame=None):
|
|
564
|
+
"""
|
|
565
|
+
Read in header into self.header and
|
|
566
|
+
the data into self.data
|
|
567
|
+
"""
|
|
568
|
+
self.resetvals()
|
|
569
|
+
self.filename = fname
|
|
570
|
+
|
|
571
|
+
infile = self._open(fname, "rb")
|
|
572
|
+
self._readheader(infile)
|
|
573
|
+
if frame is None:
|
|
574
|
+
pass
|
|
575
|
+
elif frame < self.nframes:
|
|
576
|
+
self = self.getframe(frame)
|
|
577
|
+
else:
|
|
578
|
+
logger.error("Reading file %s You requested frame %s but only %s frames are available", fname, frame, self.nframes)
|
|
579
|
+
self.resetvals()
|
|
580
|
+
# ensure the PIL image is reset
|
|
581
|
+
self.pilimage = None
|
|
582
|
+
return self
|
|
583
|
+
|
|
584
|
+
def swap_needed(self):
|
|
585
|
+
"""
|
|
586
|
+
Decide if we need to byteswap
|
|
587
|
+
"""
|
|
588
|
+
if ('Low' in self.header[self.capsHeader['BYTEORDER']] and numpy.little_endian) or \
|
|
589
|
+
('High' in self.header[self.capsHeader['BYTEORDER']] and not numpy.little_endian):
|
|
590
|
+
return False
|
|
591
|
+
if ('High' in self.header[self.capsHeader['BYTEORDER']] and numpy.little_endian) or \
|
|
592
|
+
('Low' in self.header[self.capsHeader['BYTEORDER']] and not numpy.little_endian):
|
|
593
|
+
if self.bpp in [2, 4, 8]:
|
|
594
|
+
return True
|
|
595
|
+
else:
|
|
596
|
+
return False
|
|
597
|
+
|
|
598
|
+
def unpack(self):
|
|
599
|
+
"""
|
|
600
|
+
Unpack a binary blob according to the specification given in the header and return the dataset
|
|
601
|
+
|
|
602
|
+
@return: dataset as numpy.ndarray
|
|
603
|
+
"""
|
|
604
|
+
return self.__frames[self.currentframe].getData()
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
def getframe(self, num):
|
|
608
|
+
""" returns the file numbered 'num' in the series as a fabioimage """
|
|
609
|
+
newImage = None
|
|
610
|
+
if self.nframes == 1:
|
|
611
|
+
logger.debug("Single frame EDF; having fabioimage default behavour: %s" % num)
|
|
612
|
+
newImage = fabioimage.getframe(self, num)
|
|
613
|
+
elif num in xrange(self.nframes):
|
|
614
|
+
logger.debug("Multi frame EDF; having edfimage specific behavour: %s/%s" % (num, self.nframes))
|
|
615
|
+
newImage = edfimage(frames=self.__frames)
|
|
616
|
+
newImage.currentframe = num
|
|
617
|
+
newImage.filename = self.filename
|
|
618
|
+
else:
|
|
619
|
+
txt = "Cannot access frame: %s/%s" % (num, self.nframes)
|
|
620
|
+
logger.error(txt)
|
|
621
|
+
raise ValueError("edfimage.getframe:" + txt)
|
|
622
|
+
return newImage
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
def previous(self):
|
|
626
|
+
""" returns the previous file in the series as a fabioimage """
|
|
627
|
+
newImage = None
|
|
628
|
+
if self.nframes == 1:
|
|
629
|
+
newImage = fabioimage.previous(self)
|
|
630
|
+
else:
|
|
631
|
+
newFrameId = self.currentframe - 1
|
|
632
|
+
newImage = self.getframe(newFrameId)
|
|
633
|
+
return newImage
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def next(self):
|
|
637
|
+
""" returns the next file in the series as a fabioimage """
|
|
638
|
+
newImage = None
|
|
639
|
+
if self.nframes == 1:
|
|
640
|
+
newImage = fabioimage.next(self)
|
|
641
|
+
else:
|
|
642
|
+
newFrameId = self.currentframe + 1
|
|
643
|
+
newImage = self.getframe(newFrameId)
|
|
644
|
+
return newImage
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
def write(self, fname, force_type=None, fit2dMode=False):
|
|
648
|
+
"""
|
|
649
|
+
Try to write a file
|
|
650
|
+
check we can write zipped also
|
|
651
|
+
mimics that fabian was writing uint16 (we sometimes want floats)
|
|
652
|
+
|
|
653
|
+
@param force_type: can be numpy.uint16 or simply "float"
|
|
654
|
+
@return: None
|
|
655
|
+
|
|
656
|
+
"""
|
|
657
|
+
|
|
658
|
+
outfile = self._open(fname, mode="wb")
|
|
659
|
+
for i, frame in enumerate(self.__frames):
|
|
660
|
+
frame.iFrame = i
|
|
661
|
+
outfile.write(frame.getEdfBlock(force_type=force_type, fit2dMode=fit2dMode))
|
|
662
|
+
outfile.close()
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def appendFrame(self, frame=None, data=None, header=None):
|
|
666
|
+
"""
|
|
667
|
+
Method used add a frame to an EDF file
|
|
668
|
+
@param frame: frame to append to edf image
|
|
669
|
+
@type frame: instance of Frame
|
|
670
|
+
@return: None
|
|
671
|
+
"""
|
|
672
|
+
if isinstance(frame, Frame):
|
|
673
|
+
self.__frames.append(frame)
|
|
674
|
+
else:
|
|
675
|
+
self.__frames.append(Frame(data, header))
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
def deleteFrame(self, frameNb=None):
|
|
679
|
+
"""
|
|
680
|
+
Method used to remove a frame from an EDF image. by default the last one is removed.
|
|
681
|
+
@param frameNb: frame number to remove, by default the last.
|
|
682
|
+
@type frameNb: integer
|
|
683
|
+
@return: None
|
|
684
|
+
"""
|
|
685
|
+
if frameNb is None:
|
|
686
|
+
self.__frames.pop()
|
|
687
|
+
else:
|
|
688
|
+
self.__frames.pop(frameNb)
|
|
689
|
+
|
|
690
|
+
def fastReadData(self, filename=None):
|
|
691
|
+
"""
|
|
692
|
+
This is a special method that will read and return the data from another file ...
|
|
693
|
+
The aim is performances, ... but only supports uncompressed files.
|
|
694
|
+
|
|
695
|
+
@return: data from another file using positions from current edfimage
|
|
696
|
+
"""
|
|
697
|
+
if (filename is None) or not os.path.isfile(filename):
|
|
698
|
+
raise RuntimeError("edfimage.fastReadData is only valid with another file: %s does not exist" % (filename))
|
|
699
|
+
data = None
|
|
700
|
+
frame = self.__frames[self.currentframe]
|
|
701
|
+
with open(filename, "rb")as f:
|
|
702
|
+
f.seek(frame.start)
|
|
703
|
+
raw = f.read(frame.size)
|
|
704
|
+
try:
|
|
705
|
+
data = numpy.fromstring(raw, dtype=self.bytecode)
|
|
706
|
+
data.shape = self.data.shape
|
|
707
|
+
except Exception, err :
|
|
708
|
+
logger.error("unable to convert file content to numpy array: %s", err)
|
|
709
|
+
return data
|
|
710
|
+
|
|
711
|
+
def fastReadROI(self, filename, coords=None):
|
|
712
|
+
"""
|
|
713
|
+
Method reading Region of Interest of another file based on metadata available in current edfimage.
|
|
714
|
+
The aim is performances, ... but only supports uncompressed files.
|
|
715
|
+
|
|
716
|
+
@return: ROI-data from another file using positions from current edfimage
|
|
717
|
+
@rtype: numpy 2darray
|
|
718
|
+
"""
|
|
719
|
+
if (filename is None) or not os.path.isfile(filename):
|
|
720
|
+
raise RuntimeError("edfimage.fastReadData is only valid with another file: %s does not exist" % (filename))
|
|
721
|
+
data = None
|
|
722
|
+
frame = self.__frames[self.currentframe]
|
|
723
|
+
|
|
724
|
+
if len(coords) == 4:
|
|
725
|
+
slice1 = self.make_slice(coords)
|
|
726
|
+
elif len(coords) == 2 and isinstance(coords[0], slice) and \
|
|
727
|
+
isinstance(coords[1], slice):
|
|
728
|
+
slice1 = coords
|
|
729
|
+
else:
|
|
730
|
+
logger.warning('readROI: Unable to understand Region Of Interest: got %s', coords)
|
|
731
|
+
return
|
|
732
|
+
d1 = self.data.shape[-1]
|
|
733
|
+
start0 = slice1[0].start
|
|
734
|
+
start1 = slice1[1].start
|
|
735
|
+
slice2 = (slice(0, slice1[0].stop - start0, slice1[0].step),
|
|
736
|
+
slice(0, slice1[1].stop - start1, slice1[1].step))
|
|
737
|
+
start = frame.start + self.bpp * (d1 * start0 + start1)
|
|
738
|
+
size = self.bpp * ((slice2[0].stop) * d1)
|
|
739
|
+
with open(filename, "rb")as f:
|
|
740
|
+
f.seek(start)
|
|
741
|
+
raw = f.read(size)
|
|
742
|
+
try:
|
|
743
|
+
data = numpy.fromstring(raw, dtype=self.bytecode)
|
|
744
|
+
data.shape = -1, d1
|
|
745
|
+
except Exception, err :
|
|
746
|
+
logger.error("unable to convert file content to numpy array: %s", err)
|
|
747
|
+
return data[slice2]
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
################################################################################
|
|
751
|
+
# Properties definition for header, data, header_keys and capsHeader
|
|
752
|
+
################################################################################
|
|
753
|
+
def getNbFrames(self):
|
|
754
|
+
"""
|
|
755
|
+
Getter for number of frames
|
|
756
|
+
"""
|
|
757
|
+
return len(self.__frames)
|
|
758
|
+
def setNbFrames(self, val):
|
|
759
|
+
"""
|
|
760
|
+
Setter for number of frames ... should do nothing. Here just to avoid bugs
|
|
761
|
+
"""
|
|
762
|
+
if val != len(self.__frames):
|
|
763
|
+
logger.warning("trying to set the number of frames ")
|
|
764
|
+
nframes = property(getNbFrames, setNbFrames, "property: number of frames in EDF file")
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
def getHeader(self):
|
|
768
|
+
"""
|
|
769
|
+
Getter for the headers. used by the property header,
|
|
770
|
+
"""
|
|
771
|
+
return self.__frames[self.currentframe].header
|
|
772
|
+
def setHeader(self, _dictHeader):
|
|
773
|
+
"""
|
|
774
|
+
Enforces the propagation of the header to the list of frames
|
|
775
|
+
"""
|
|
776
|
+
try:
|
|
777
|
+
self.__frames[self.currentframe].header = _dictHeader
|
|
778
|
+
except AttributeError:
|
|
779
|
+
self.__frames = [Frame(header=_dictHeader)]
|
|
780
|
+
except IndexError:
|
|
781
|
+
if self.currentframe < len(self.__frames):
|
|
782
|
+
self.__frames.append(Frame(header=_dictHeader))
|
|
783
|
+
def delHeader(self):
|
|
784
|
+
"""
|
|
785
|
+
Deleter for edf header
|
|
786
|
+
"""
|
|
787
|
+
self.__frames[self.currentframe].header = {}
|
|
788
|
+
header = property(getHeader, setHeader, delHeader, "property: header of EDF file")
|
|
789
|
+
|
|
790
|
+
def getHeaderKeys(self):
|
|
791
|
+
"""
|
|
792
|
+
Getter for edf header_keys
|
|
793
|
+
"""
|
|
794
|
+
return self.__frames[self.currentframe].header_keys
|
|
795
|
+
def setHeaderKeys(self, _listtHeader):
|
|
796
|
+
"""
|
|
797
|
+
Enforces the propagation of the header_keys to the list of frames
|
|
798
|
+
@param _listtHeader: list of the (ordered) keys in the header
|
|
799
|
+
@type _listtHeader: python list
|
|
800
|
+
"""
|
|
801
|
+
try:
|
|
802
|
+
self.__frames[self.currentframe].header_keys = _listtHeader
|
|
803
|
+
except AttributeError:
|
|
804
|
+
self.__frames = [Frame(header_keys=_listtHeader)]
|
|
805
|
+
except IndexError:
|
|
806
|
+
if self.currentframe < len(self.__frames):
|
|
807
|
+
self.__frames.append(Frame(header_keys=_listtHeader))
|
|
808
|
+
def delHeaderKeys(self):
|
|
809
|
+
"""
|
|
810
|
+
Deleter for edf header_keys
|
|
811
|
+
"""
|
|
812
|
+
self.__frames[self.currentframe].header_keys = []
|
|
813
|
+
header_keys = property(getHeaderKeys, setHeaderKeys, delHeaderKeys, "property: header_keys of EDF file")
|
|
814
|
+
|
|
815
|
+
def getData(self):
|
|
816
|
+
"""
|
|
817
|
+
getter for edf Data
|
|
818
|
+
@return: data for current frame
|
|
819
|
+
@rtype: numpy.ndarray
|
|
820
|
+
"""
|
|
821
|
+
npaData = None
|
|
822
|
+
try:
|
|
823
|
+
npaData = self.__frames[self.currentframe].data
|
|
824
|
+
except AttributeError:
|
|
825
|
+
self.__frames = [Frame()]
|
|
826
|
+
npaData = self.__frames[self.currentframe].data
|
|
827
|
+
except IndexError:
|
|
828
|
+
if self.currentframe < len(self.__frames):
|
|
829
|
+
self.__frames.append(Frame())
|
|
830
|
+
npaData = self.__frames[self.currentframe].data
|
|
831
|
+
return npaData
|
|
832
|
+
|
|
833
|
+
def setData(self, _data):
|
|
834
|
+
"""
|
|
835
|
+
Enforces the propagation of the data to the list of frames
|
|
836
|
+
@param _data: numpy array representing data
|
|
837
|
+
"""
|
|
838
|
+
try:
|
|
839
|
+
self.__frames[self.currentframe].data = _data
|
|
840
|
+
except AttributeError:
|
|
841
|
+
self.__frames = [Frame(data=_data)]
|
|
842
|
+
except IndexError:
|
|
843
|
+
if self.currentframe < len(self.__frames):
|
|
844
|
+
self.__frames.append(Frame(data=_data))
|
|
845
|
+
def delData(self):
|
|
846
|
+
"""
|
|
847
|
+
deleter for edf Data
|
|
848
|
+
"""
|
|
849
|
+
self.__frames[self.currentframe].data = None
|
|
850
|
+
data = property(getData, setData, delData, "property: data of EDF file")
|
|
851
|
+
|
|
852
|
+
def getCapsHeader(self):
|
|
853
|
+
"""
|
|
854
|
+
getter for edf headers keys in upper case
|
|
855
|
+
@return: data for current frame
|
|
856
|
+
@rtype: dict
|
|
857
|
+
"""
|
|
858
|
+
return self.__frames[self.currentframe].capsHeader
|
|
859
|
+
def setCapsHeader(self, _data):
|
|
860
|
+
"""
|
|
861
|
+
Enforces the propagation of the header_keys to the list of frames
|
|
862
|
+
@param _data: numpy array representing data
|
|
863
|
+
"""
|
|
864
|
+
self.__frames[self.currentframe].capsHeader = _data
|
|
865
|
+
def delCapsHeader(self):
|
|
866
|
+
"""
|
|
867
|
+
deleter for edf capsHeader
|
|
868
|
+
"""
|
|
869
|
+
self.__frames[self.currentframe].capsHeader = {}
|
|
870
|
+
capsHeader = property(getCapsHeader, setCapsHeader, delCapsHeader, "property: capsHeader of EDF file, i.e. the keys of the header in UPPER case.")
|
|
871
|
+
|
|
872
|
+
def getDim1(self):
|
|
873
|
+
return self.__frames[self.currentframe].dim1
|
|
874
|
+
def setDim1(self, _iVal):
|
|
875
|
+
try:
|
|
876
|
+
self.__frames[self.currentframe].dim1 = _iVal
|
|
877
|
+
except AttributeError:
|
|
878
|
+
self.__frames = [Frame()]
|
|
879
|
+
except IndexError:
|
|
880
|
+
if self.currentframe < len(self.__frames):
|
|
881
|
+
self.__frames.append(Frame())
|
|
882
|
+
self.__frames[self.currentframe].dim1 = _iVal
|
|
883
|
+
dim1 = property(getDim1, setDim1)
|
|
884
|
+
def getDim2(self):
|
|
885
|
+
return self.__frames[self.currentframe].dim2
|
|
886
|
+
def setDim2(self, _iVal):
|
|
887
|
+
try:
|
|
888
|
+
self.__frames[self.currentframe].dim2 = _iVal
|
|
889
|
+
except AttributeError:
|
|
890
|
+
self.__frames = [Frame()]
|
|
891
|
+
except IndexError:
|
|
892
|
+
if self.currentframe < len(self.__frames):
|
|
893
|
+
self.__frames.append(Frame())
|
|
894
|
+
self.__frames[self.currentframe].dim2 = _iVal
|
|
895
|
+
dim2 = property(getDim2, setDim2)
|
|
896
|
+
|
|
897
|
+
def getDims(self):
|
|
898
|
+
return self.__frames[self.currentframe].dims
|
|
899
|
+
dims = property(getDims)
|
|
900
|
+
def getByteCode(self):
|
|
901
|
+
return self.__frames[self.currentframe].bytecode
|
|
902
|
+
def setByteCode(self, _iVal):
|
|
903
|
+
try:
|
|
904
|
+
self.__frames[self.currentframe].bytecode = _iVal
|
|
905
|
+
except AttributeError:
|
|
906
|
+
self.__frames = [Frame()]
|
|
907
|
+
except IndexError:
|
|
908
|
+
if self.currentframe < len(self.__frames):
|
|
909
|
+
self.__frames.append(Frame())
|
|
910
|
+
self.__frames[self.currentframe].bytecode = _iVal
|
|
911
|
+
bytecode = property(getByteCode, setByteCode)
|
|
912
|
+
def getBpp(self):
|
|
913
|
+
return self.__frames[self.currentframe].bpp
|
|
914
|
+
def setBpp(self, _iVal):
|
|
915
|
+
try:
|
|
916
|
+
self.__frames[self.currentframe].bpp = _iVal
|
|
917
|
+
except AttributeError:
|
|
918
|
+
self.__frames = [Frame()]
|
|
919
|
+
except IndexError:
|
|
920
|
+
if self.currentframe < len(self.__frames):
|
|
921
|
+
self.__frames.append(Frame())
|
|
922
|
+
self.__frames[self.currentframe].bpp = _iVal
|
|
923
|
+
bpp = property(getBpp, setBpp)
|
|
924
|
+
|