pyTEMlib 0.2020.11.0__py3-none-any.whl → 0.2024.8.4__py3-none-any.whl
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.
Potentially problematic release.
This version of pyTEMlib might be problematic. Click here for more details.
- pyTEMlib/__init__.py +11 -11
- pyTEMlib/animation.py +631 -0
- pyTEMlib/atom_tools.py +240 -222
- pyTEMlib/config_dir.py +57 -29
- pyTEMlib/core_loss_widget.py +658 -0
- pyTEMlib/crystal_tools.py +1255 -0
- pyTEMlib/diffraction_plot.py +756 -0
- pyTEMlib/dynamic_scattering.py +293 -0
- pyTEMlib/eds_tools.py +609 -0
- pyTEMlib/eels_dialog.py +749 -486
- pyTEMlib/{interactive_eels.py → eels_dialog_utilities.py} +1199 -1524
- pyTEMlib/eels_tools.py +2031 -1731
- pyTEMlib/file_tools.py +1276 -491
- pyTEMlib/file_tools_qt.py +193 -0
- pyTEMlib/graph_tools.py +1166 -450
- pyTEMlib/graph_viz.py +449 -0
- pyTEMlib/image_dialog.py +158 -0
- pyTEMlib/image_dlg.py +146 -0
- pyTEMlib/image_tools.py +1399 -956
- pyTEMlib/info_widget.py +933 -0
- pyTEMlib/interactive_image.py +1 -0
- pyTEMlib/kinematic_scattering.py +1196 -0
- pyTEMlib/low_loss_widget.py +176 -0
- pyTEMlib/microscope.py +61 -78
- pyTEMlib/peak_dialog.py +1047 -350
- pyTEMlib/peak_dlg.py +286 -248
- pyTEMlib/probe_tools.py +653 -202
- pyTEMlib/sidpy_tools.py +153 -129
- pyTEMlib/simulation_tools.py +104 -87
- pyTEMlib/version.py +6 -3
- pyTEMlib/xrpa_x_sections.py +20972 -0
- {pyTEMlib-0.2020.11.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/LICENSE +21 -21
- pyTEMlib-0.2024.8.4.dist-info/METADATA +93 -0
- pyTEMlib-0.2024.8.4.dist-info/RECORD +37 -0
- {pyTEMlib-0.2020.11.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/WHEEL +6 -5
- {pyTEMlib-0.2020.11.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/entry_points.txt +0 -1
- pyTEMlib/KinsCat.py +0 -2685
- pyTEMlib/__version__.py +0 -2
- pyTEMlib/data/TEMlibrc +0 -68
- pyTEMlib/data/edges_db.csv +0 -189
- pyTEMlib/data/edges_db.pkl +0 -0
- pyTEMlib/data/fparam.txt +0 -103
- pyTEMlib/data/microscopes.csv +0 -7
- pyTEMlib/data/microscopes.xml +0 -167
- pyTEMlib/data/path.txt +0 -1
- pyTEMlib/defaults_parser.py +0 -86
- pyTEMlib/dm3_reader.py +0 -609
- pyTEMlib/edges_db.py +0 -76
- pyTEMlib/eels_dlg.py +0 -240
- pyTEMlib/hdf_utils.py +0 -481
- pyTEMlib/image_tools1.py +0 -2194
- pyTEMlib/info_dialog.py +0 -227
- pyTEMlib/info_dlg.py +0 -205
- pyTEMlib/nion_reader.py +0 -293
- pyTEMlib/nsi_reader.py +0 -165
- pyTEMlib/structure_tools.py +0 -316
- pyTEMlib-0.2020.11.0.dist-info/METADATA +0 -20
- pyTEMlib-0.2020.11.0.dist-info/RECORD +0 -42
- {pyTEMlib-0.2020.11.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/top_level.txt +0 -0
pyTEMlib/dm3_reader.py
DELETED
|
@@ -1,609 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: iso-8859-1 -*-
|
|
3
|
-
|
|
4
|
-
################################################################################
|
|
5
|
-
# Python class for reading GATAN DM3 (DigitalMicrograph) files
|
|
6
|
-
# and extracting all metadata
|
|
7
|
-
# --
|
|
8
|
-
# tested on EELS spectra, spectrum images and single-image files and image-stacks
|
|
9
|
-
# --
|
|
10
|
-
# based on the DM3_Reader plug-in (v 1.3.4) for ImageJ by Greg Jefferis <jefferis@stanford.edu>
|
|
11
|
-
# http://rsb.info.nih.gov/ij/plugins/DM3_Reader.html
|
|
12
|
-
# --
|
|
13
|
-
# Python adaptation: Pierre-Ivan Raynal <raynal@med.univ-tours.fr>
|
|
14
|
-
# http://microscopies.med.univ-tours.fr/
|
|
15
|
-
#
|
|
16
|
-
# Extended for EELS support by Gerd Duscher, UTK 2012
|
|
17
|
-
# Rewritten for integration of sidpy 2020
|
|
18
|
-
#
|
|
19
|
-
# Works for python 3
|
|
20
|
-
#
|
|
21
|
-
################################################################################
|
|
22
|
-
from __future__ import division, print_function, absolute_import, unicode_literals
|
|
23
|
-
|
|
24
|
-
import struct
|
|
25
|
-
import time
|
|
26
|
-
import numpy
|
|
27
|
-
|
|
28
|
-
import sys
|
|
29
|
-
import numpy as np
|
|
30
|
-
import os
|
|
31
|
-
|
|
32
|
-
import sidpy
|
|
33
|
-
|
|
34
|
-
version = '0.1beta'
|
|
35
|
-
|
|
36
|
-
debugLevel = 0 # 0=none, 1-3=basic, 4-5=simple, 6-10 verbose
|
|
37
|
-
|
|
38
|
-
if sys.version_info.major == 3:
|
|
39
|
-
unicode = str
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
# ### utility functions ###
|
|
43
|
-
|
|
44
|
-
# ## binary data reading functions ###
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def read_long(f):
|
|
48
|
-
"""Read 4 bytes as integer in file f"""
|
|
49
|
-
read_bytes = f.read(4)
|
|
50
|
-
return struct.unpack('>l', read_bytes)[0]
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def read_64_long(f):
|
|
54
|
-
read_bytes = f.read(8)
|
|
55
|
-
return struct.unpack('>Q', read_bytes)[0]
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def read_short(f):
|
|
59
|
-
"""Read 2 bytes as integer in file f"""
|
|
60
|
-
read_bytes = f.read(2)
|
|
61
|
-
return struct.unpack('>h', read_bytes)[0]
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def read_byte(f):
|
|
65
|
-
"""Read 1 byte as integer in file f"""
|
|
66
|
-
read_bytes = f.read(1)
|
|
67
|
-
return struct.unpack('>b', read_bytes)[0]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def read_bool(f):
|
|
71
|
-
"""Read 1 byte as boolean in file f"""
|
|
72
|
-
read_val = read_byte(f)
|
|
73
|
-
return read_val != 0
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def read_char(f):
|
|
77
|
-
"""Read 1 byte as char in file f"""
|
|
78
|
-
read_bytes = f.read(1)
|
|
79
|
-
return struct.unpack('c', read_bytes)[0]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def read_string(f, length=1):
|
|
83
|
-
"""Read len bytes as a string in file f"""
|
|
84
|
-
read_bytes = f.read(length)
|
|
85
|
-
str_fmt = '>' + str(length) + 's'
|
|
86
|
-
return struct.unpack(str_fmt, read_bytes)[0]
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def read_le_short(f):
|
|
90
|
-
"""Read 2 bytes as *little endian* integer in file f"""
|
|
91
|
-
read_bytes = f.read(2)
|
|
92
|
-
return struct.unpack('<h', read_bytes)[0]
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def read_le_long(f):
|
|
96
|
-
"""Read 4 bytes as *little endian* integer in file f"""
|
|
97
|
-
read_bytes = f.read(4)
|
|
98
|
-
return struct.unpack('<l', read_bytes)[0]
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def read_leu_short(f):
|
|
102
|
-
"""Read 2 bytes as *little endian* unsigned integer in file f"""
|
|
103
|
-
read_bytes = f.read(2)
|
|
104
|
-
return struct.unpack('<H', read_bytes)[0]
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def read_leu_long(f):
|
|
108
|
-
"""Read 4 bytes as *little endian* unsigned integer in file f"""
|
|
109
|
-
read_bytes = f.read(4)
|
|
110
|
-
return struct.unpack('<L', read_bytes)[0]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def read_le_float(f):
|
|
114
|
-
"""Read 4 bytes as *little endian* float in file f"""
|
|
115
|
-
read_bytes = f.read(4)
|
|
116
|
-
return struct.unpack('<f', read_bytes)[0]
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def read_le_double(f):
|
|
120
|
-
"""Read 8 bytes as *little endian* double in file f"""
|
|
121
|
-
read_bytes = f.read(8)
|
|
122
|
-
return struct.unpack('<d', read_bytes)[0]
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
# constants for encoded data types ##
|
|
126
|
-
SHORT = 2
|
|
127
|
-
LONG = 3
|
|
128
|
-
USHORT = 4
|
|
129
|
-
ULONG = 5
|
|
130
|
-
FLOAT = 6
|
|
131
|
-
DOUBLE = 7
|
|
132
|
-
BOOLEAN = 8
|
|
133
|
-
CHAR = 9
|
|
134
|
-
OCTET = 10
|
|
135
|
-
STRUCT = 15
|
|
136
|
-
STRING = 18
|
|
137
|
-
ARRAY = 20
|
|
138
|
-
|
|
139
|
-
# - association data type <--> reading function
|
|
140
|
-
readFunc = {
|
|
141
|
-
SHORT: read_le_short,
|
|
142
|
-
LONG: read_le_long,
|
|
143
|
-
USHORT: read_leu_short,
|
|
144
|
-
ULONG: read_leu_long,
|
|
145
|
-
FLOAT: read_le_float,
|
|
146
|
-
DOUBLE: read_le_double,
|
|
147
|
-
BOOLEAN: read_bool,
|
|
148
|
-
CHAR: read_char,
|
|
149
|
-
OCTET: read_char, # difference with char???
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
# other constants ##
|
|
153
|
-
IMGLIST = "root.ImageList."
|
|
154
|
-
OBJLIST = "root.DocumentObjectList."
|
|
155
|
-
MAXDEPTH = 64
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
# END constants ##
|
|
159
|
-
|
|
160
|
-
class DM3Reader(sidpy.Reader):
|
|
161
|
-
debugLevel = -1
|
|
162
|
-
|
|
163
|
-
"""
|
|
164
|
-
file_path: filepath to dm3 file.
|
|
165
|
-
|
|
166
|
-
warn('This Reader will eventually be moved to the ScopeReaders package'
|
|
167
|
-
'. Be prepared to change your import statements',
|
|
168
|
-
FutureWarning)
|
|
169
|
-
"""
|
|
170
|
-
|
|
171
|
-
def __init__(self, file_path, verbose=False):
|
|
172
|
-
super().__init__(file_path)
|
|
173
|
-
|
|
174
|
-
# initialize variables ##
|
|
175
|
-
self.verbose = verbose
|
|
176
|
-
self.__filename = file_path
|
|
177
|
-
self.__chosen_image = -1
|
|
178
|
-
|
|
179
|
-
# - open file for reading
|
|
180
|
-
try:
|
|
181
|
-
self.__f = open(self.__filename, 'rb')
|
|
182
|
-
except FileNotFoundError:
|
|
183
|
-
raise FileNotFoundError('File not found')
|
|
184
|
-
|
|
185
|
-
# - create Tags repositories
|
|
186
|
-
self.__stored_tags = {'DM': {}}
|
|
187
|
-
|
|
188
|
-
# check if this is valid DM3 file
|
|
189
|
-
is_dm = True
|
|
190
|
-
# read header (first 3 4-byte int)
|
|
191
|
-
# get version
|
|
192
|
-
file_version = read_long(self.__f)
|
|
193
|
-
|
|
194
|
-
# get indicated file size
|
|
195
|
-
if file_version == 3:
|
|
196
|
-
file_size = read_long(self.__f)
|
|
197
|
-
elif file_version == 4:
|
|
198
|
-
file_size = read_64_long(self.__f)
|
|
199
|
-
else:
|
|
200
|
-
is_dm = False
|
|
201
|
-
# get byte-ordering
|
|
202
|
-
le = read_long(self.__f)
|
|
203
|
-
little_endian = (le == 1)
|
|
204
|
-
|
|
205
|
-
if little_endian:
|
|
206
|
-
self.endian_str = '>'
|
|
207
|
-
else:
|
|
208
|
-
self.endian_str = '<'
|
|
209
|
-
|
|
210
|
-
# check file header, raise Exception if not DM3
|
|
211
|
-
if not is_dm:
|
|
212
|
-
raise TypeError("%s does not appear to be a DM3 or DM4 file." % os.path.split(self.__filename)[1])
|
|
213
|
-
elif self.verbose:
|
|
214
|
-
print("%s appears to be a DM3 file" % self.__filename)
|
|
215
|
-
self.file_version = file_version
|
|
216
|
-
self.file_size = file_size
|
|
217
|
-
|
|
218
|
-
if self.verbose:
|
|
219
|
-
print("Header info.:")
|
|
220
|
-
print("- file version:", file_version)
|
|
221
|
-
print("- le:", le)
|
|
222
|
-
print("- file size:", file_size, "bytes")
|
|
223
|
-
|
|
224
|
-
# don't read but close file
|
|
225
|
-
self.__f.close()
|
|
226
|
-
|
|
227
|
-
def read(self):
|
|
228
|
-
try:
|
|
229
|
-
self.__f = open(self.__filename, 'rb')
|
|
230
|
-
except FileNotFoundError:
|
|
231
|
-
raise FileNotFoundError('File not found')
|
|
232
|
-
|
|
233
|
-
t1 = time.time()
|
|
234
|
-
file_version = read_long(self.__f)
|
|
235
|
-
|
|
236
|
-
# get indicated file size
|
|
237
|
-
if file_version == 3:
|
|
238
|
-
file_size = read_long(self.__f)
|
|
239
|
-
elif file_version == 4:
|
|
240
|
-
file_size = read_64_long(self.__f)
|
|
241
|
-
else:
|
|
242
|
-
is_dm = False
|
|
243
|
-
# get byte-ordering
|
|
244
|
-
le = read_long(self.__f)
|
|
245
|
-
little_endian = (le == 1)
|
|
246
|
-
|
|
247
|
-
if little_endian:
|
|
248
|
-
self.endian_str = '>'
|
|
249
|
-
else:
|
|
250
|
-
self.endian_str = '<'
|
|
251
|
-
|
|
252
|
-
# ... then read it
|
|
253
|
-
|
|
254
|
-
self.__stored_tags = {'DM': {'file_version': file_version, 'file_size': file_size}}
|
|
255
|
-
|
|
256
|
-
self.__read_tag_group(self.__stored_tags)
|
|
257
|
-
|
|
258
|
-
if self.verbose:
|
|
259
|
-
print("-- %s Tags read --" % len(self.__stored_tags))
|
|
260
|
-
|
|
261
|
-
if self.verbose:
|
|
262
|
-
t2 = time.time()
|
|
263
|
-
print("| parse DM3 file: %.3g s" % (t2 - t1))
|
|
264
|
-
|
|
265
|
-
path, file_name = os.path.split(self.__filename)
|
|
266
|
-
basename, extension = os.path.splitext(file_name)
|
|
267
|
-
|
|
268
|
-
dataset = sidpy.Dataset.from_array(self.data_cube, name=basename)
|
|
269
|
-
self.__stored_tags['DM']['chosen_image'] = self.__chosen_image
|
|
270
|
-
dataset.original_metadata = self.get_tags()
|
|
271
|
-
|
|
272
|
-
dataset.quantity = 'intensity'
|
|
273
|
-
dataset.units = 'counts'
|
|
274
|
-
|
|
275
|
-
self.set_dimensions(dataset)
|
|
276
|
-
self.set_data_type(dataset)
|
|
277
|
-
|
|
278
|
-
dataset.title = basename
|
|
279
|
-
dataset.modality = 'generic'
|
|
280
|
-
dataset.source = 'DM3Reader'
|
|
281
|
-
dataset.original_metadata['DM']['full_file_name'] = self.__filename
|
|
282
|
-
|
|
283
|
-
return dataset
|
|
284
|
-
|
|
285
|
-
def set_data_type(self, dataset):
|
|
286
|
-
spectral_dim = False
|
|
287
|
-
# print(dataset._axes)
|
|
288
|
-
for dim, axis in dataset._axes.items():
|
|
289
|
-
if axis.dimension_type == sidpy.DimensionTypes.SPECTRAL:
|
|
290
|
-
spectral_dim = True
|
|
291
|
-
|
|
292
|
-
dataset.data_type = 'unknown'
|
|
293
|
-
if 'ImageTags' in dataset.original_metadata['ImageList'][str(self.__chosen_image)]:
|
|
294
|
-
image_tags = dataset.original_metadata['ImageList'][str(self.__chosen_image)]['ImageTags']
|
|
295
|
-
if 'SI' in image_tags:
|
|
296
|
-
if len(dataset.shape) == 3:
|
|
297
|
-
dataset.data_type = sidpy.DataTypes.SPECTRAL_IMAGE
|
|
298
|
-
else:
|
|
299
|
-
if spectral_dim:
|
|
300
|
-
dataset.data_type = sidpy.DataTypes.SPECTRAL_IMAGE # 'linescan'
|
|
301
|
-
else:
|
|
302
|
-
dataset.data_type = sidpy.DataTypes.IMAGE
|
|
303
|
-
dataset.metadata['image_type'] = 'survey image'
|
|
304
|
-
|
|
305
|
-
if dataset.data_type == sidpy.DataTypes.UNKNOWN:
|
|
306
|
-
if len(dataset.shape) > 3:
|
|
307
|
-
raise NotImplementedError('Data_type not implemented yet')
|
|
308
|
-
elif len(dataset.shape) == 3:
|
|
309
|
-
if spectral_dim:
|
|
310
|
-
dataset.data_type = sidpy.DataTypes.SPECTRAL_IMAGE
|
|
311
|
-
else:
|
|
312
|
-
dataset.data_type = 'image_stack'
|
|
313
|
-
elif len(dataset.shape) == 2:
|
|
314
|
-
if spectral_dim:
|
|
315
|
-
dataset.data_type = sidpy.DataTypes.SPECTRAL_IMAGE
|
|
316
|
-
else:
|
|
317
|
-
dataset.data_type = 'image'
|
|
318
|
-
elif len(dataset.shape) == 1:
|
|
319
|
-
if spectral_dim:
|
|
320
|
-
dataset.data_type = sidpy.DataTypes.SPECTRUM
|
|
321
|
-
else:
|
|
322
|
-
dataset.data_type = sidpy.DataTypes.LINE_PLOT
|
|
323
|
-
|
|
324
|
-
def set_dimensions(self, dataset):
|
|
325
|
-
dimensions_dict = dataset.original_metadata['ImageList'][str(self.__chosen_image)]['ImageData']['Calibrations'][
|
|
326
|
-
'Dimension']
|
|
327
|
-
|
|
328
|
-
reciprocal_name = 'u'
|
|
329
|
-
spatial_name = 'x'
|
|
330
|
-
|
|
331
|
-
for dim, dimension_tags in dimensions_dict.items():
|
|
332
|
-
# Fix annoying scale of spectrum_images in Zeiss and SEM images
|
|
333
|
-
if dimension_tags['Units'] == '�m':
|
|
334
|
-
dimension_tags['Units'] = 'nm'
|
|
335
|
-
dimension_tags['Scale'] *= 1000.0
|
|
336
|
-
|
|
337
|
-
if dimension_tags['Units'].strip() == '':
|
|
338
|
-
units = 'counts'
|
|
339
|
-
else:
|
|
340
|
-
units = dimension_tags['Units']
|
|
341
|
-
|
|
342
|
-
values = (np.arange(dataset.shape[int(dim)]) - dimension_tags['Origin']) * dimension_tags['Scale']
|
|
343
|
-
|
|
344
|
-
if 'eV' == units:
|
|
345
|
-
dataset.set_dimension(int(dim), sidpy.Dimension(values, name='energy_loss', units=units,
|
|
346
|
-
quantity='energy-loss',
|
|
347
|
-
dimension_type=sidpy.DimensionTypes.SPECTRAL))
|
|
348
|
-
elif 'eV' in units:
|
|
349
|
-
dataset.set_dimension(int(dim), sidpy.Dimension(values, name='energy', units=units,
|
|
350
|
-
quantity='energy',
|
|
351
|
-
dimension_type=sidpy.DimensionTypes.SPECTRAL))
|
|
352
|
-
elif '1/' in units or units in ['mrad', 'rad']:
|
|
353
|
-
dataset.set_dimension(int(dim), sidpy.Dimension(values, name=reciprocal_name, units=units,
|
|
354
|
-
quantity='reciprocal distance',
|
|
355
|
-
dimension_type=sidpy.DimensionTypes.RECIPROCAL))
|
|
356
|
-
reciprocal_name = chr(ord(reciprocal_name) + 1)
|
|
357
|
-
else:
|
|
358
|
-
units = 'counts'
|
|
359
|
-
dataset.set_dimension(int(dim), sidpy.Dimension(values, name=spatial_name, units=units,
|
|
360
|
-
quantity='distance',
|
|
361
|
-
dimension_type=sidpy.DimensionTypes.SPATIAL))
|
|
362
|
-
spatial_name = chr(ord(spatial_name) + 1)
|
|
363
|
-
|
|
364
|
-
# utility functions
|
|
365
|
-
|
|
366
|
-
def __read_tag_group(self, tags):
|
|
367
|
-
|
|
368
|
-
g_sorted = read_byte(self.__f)
|
|
369
|
-
# is the group open?
|
|
370
|
-
opened = read_byte(self.__f)
|
|
371
|
-
# number of Tags
|
|
372
|
-
if self.file_version == 3:
|
|
373
|
-
n_tags = read_long(self.__f)
|
|
374
|
-
else:
|
|
375
|
-
n_tags = read_64_long(self.__f)
|
|
376
|
-
|
|
377
|
-
# read Tags
|
|
378
|
-
for i in range(n_tags):
|
|
379
|
-
data = read_byte(self.__f)
|
|
380
|
-
is_data = (data == 21)
|
|
381
|
-
|
|
382
|
-
len_tag_label = read_short(self.__f)
|
|
383
|
-
|
|
384
|
-
if len_tag_label > 0:
|
|
385
|
-
tag_label = self.__f.read(len_tag_label).decode('latin-1')
|
|
386
|
-
else:
|
|
387
|
-
tag_label = '0'
|
|
388
|
-
for key in tags:
|
|
389
|
-
if key.isdigit():
|
|
390
|
-
tag_label = str(int(key) + 1)
|
|
391
|
-
if is_data:
|
|
392
|
-
value = self.__read_any_data()
|
|
393
|
-
tags[tag_label] = value
|
|
394
|
-
else:
|
|
395
|
-
tags[tag_label] = {}
|
|
396
|
-
self.__read_tag_group(tags[tag_label])
|
|
397
|
-
return 1
|
|
398
|
-
|
|
399
|
-
def __encoded_type_size(self, et):
|
|
400
|
-
# returns the size in bytes of the data type
|
|
401
|
-
if et == 0:
|
|
402
|
-
width = 0
|
|
403
|
-
elif et in (BOOLEAN, CHAR, OCTET):
|
|
404
|
-
width = 1
|
|
405
|
-
elif et in (SHORT, USHORT):
|
|
406
|
-
width = 2
|
|
407
|
-
elif et in (LONG, ULONG, FLOAT):
|
|
408
|
-
width = 4
|
|
409
|
-
elif et == DOUBLE:
|
|
410
|
-
width = 8
|
|
411
|
-
else:
|
|
412
|
-
# returns -1 for unrecognised types
|
|
413
|
-
width = -1
|
|
414
|
-
return width
|
|
415
|
-
|
|
416
|
-
def __read_any_data(self):
|
|
417
|
-
if self.file_version == 4:
|
|
418
|
-
tag_byte_length = struct.unpack_from('>Q', self.__f.read(8))[0]
|
|
419
|
-
# DM4 specifies this property as always big endian
|
|
420
|
-
|
|
421
|
-
delim = read_string(self.__f, 4)
|
|
422
|
-
if delim != b"%%%%":
|
|
423
|
-
raise Exception(hex(self.__f.tell()) + ": Tag Type delimiter not %%%%")
|
|
424
|
-
if self.file_version == 4:
|
|
425
|
-
n_in_tag = read_64_long(self.__f)
|
|
426
|
-
else:
|
|
427
|
-
n_in_tag = read_long(self.__f)
|
|
428
|
-
# higher level function dispatching to handling data types to other functions
|
|
429
|
-
# - get Type category (short, long, array...)
|
|
430
|
-
if self.file_version == 4:
|
|
431
|
-
encoded_type = read_64_long(self.__f)
|
|
432
|
-
else:
|
|
433
|
-
encoded_type = read_long(self.__f)
|
|
434
|
-
# - calc size of encoded_type
|
|
435
|
-
et_size = self.__encoded_type_size(encoded_type)
|
|
436
|
-
if et_size > 0:
|
|
437
|
-
data = self.__read_native_data(encoded_type, et_size)
|
|
438
|
-
elif encoded_type == STRING:
|
|
439
|
-
string_size = read_long(self.__f)
|
|
440
|
-
data = self.__read_string_data(string_size)
|
|
441
|
-
elif encoded_type == STRUCT:
|
|
442
|
-
struct_types = self.__read_struct_types()
|
|
443
|
-
data = self.__read_struct_data(struct_types)
|
|
444
|
-
elif encoded_type == ARRAY:
|
|
445
|
-
array_types = self.__read_array_types()
|
|
446
|
-
data = self.__read_array_data(array_types)
|
|
447
|
-
else:
|
|
448
|
-
raise Exception("rAnD, " + hex(self.__f.tell()) + ": Can't understand encoded type")
|
|
449
|
-
return data
|
|
450
|
-
|
|
451
|
-
def __read_native_data(self, encoded_type, et_size):
|
|
452
|
-
# reads ordinary data types
|
|
453
|
-
if encoded_type in readFunc.keys():
|
|
454
|
-
val = readFunc[encoded_type](self.__f)
|
|
455
|
-
else:
|
|
456
|
-
raise Exception("rND, " + hex(self.__f.tell()) + ": Unknown data type " + str(encoded_type))
|
|
457
|
-
return val
|
|
458
|
-
|
|
459
|
-
def __read_string_data(self, string_size):
|
|
460
|
-
# reads string data
|
|
461
|
-
if string_size <= 0:
|
|
462
|
-
r_string = ""
|
|
463
|
-
else:
|
|
464
|
-
# !!! *Unicode* string (UTF-16)... convert to Python unicode str
|
|
465
|
-
r_string = read_string(self.__f, string_size)
|
|
466
|
-
r_string = str(r_string, "utf_16_le")
|
|
467
|
-
return r_string
|
|
468
|
-
|
|
469
|
-
def __read_array_types(self):
|
|
470
|
-
# determines the data types in an array data type
|
|
471
|
-
array_type = read_long(self.__f)
|
|
472
|
-
item_types = []
|
|
473
|
-
if array_type == STRUCT:
|
|
474
|
-
item_types = self.__read_struct_types()
|
|
475
|
-
elif array_type == ARRAY:
|
|
476
|
-
item_types = self.__read_array_types()
|
|
477
|
-
else:
|
|
478
|
-
item_types.append(array_type)
|
|
479
|
-
return item_types
|
|
480
|
-
|
|
481
|
-
def __read_array_data(self, array_types):
|
|
482
|
-
# reads array data
|
|
483
|
-
array_size = read_long(self.__f)
|
|
484
|
-
item_size = 0
|
|
485
|
-
encoded_type = 0
|
|
486
|
-
for i in range(len(array_types)):
|
|
487
|
-
encoded_type = int(array_types[i])
|
|
488
|
-
et_size = self.__encoded_type_size(encoded_type)
|
|
489
|
-
item_size += et_size
|
|
490
|
-
buf_size = array_size * item_size
|
|
491
|
-
|
|
492
|
-
if len(array_types) == 1 and encoded_type == USHORT \
|
|
493
|
-
and array_size < 256:
|
|
494
|
-
# treat as string
|
|
495
|
-
val = self.__read_string_data(buf_size)
|
|
496
|
-
else:
|
|
497
|
-
# treat as binary data
|
|
498
|
-
# - store data size and offset as tags
|
|
499
|
-
val = self.__f.read(buf_size)
|
|
500
|
-
return val
|
|
501
|
-
|
|
502
|
-
def __read_struct_types(self):
|
|
503
|
-
# analyses data types in a struct
|
|
504
|
-
if self.file_version == 4:
|
|
505
|
-
struct_name_length = read_64_long(self.__f)
|
|
506
|
-
n_fields = read_64_long(self.__f)
|
|
507
|
-
else:
|
|
508
|
-
struct_name_length = read_long(self.__f)
|
|
509
|
-
n_fields = read_long(self.__f)
|
|
510
|
-
|
|
511
|
-
field_types = []
|
|
512
|
-
name_length = 0
|
|
513
|
-
for i in range(n_fields):
|
|
514
|
-
if self.file_version == 4:
|
|
515
|
-
name_length = read_64_long(self.__f)
|
|
516
|
-
field_type = read_64_long(self.__f)
|
|
517
|
-
else:
|
|
518
|
-
name_length = read_long(self.__f)
|
|
519
|
-
field_type = read_long(self.__f)
|
|
520
|
-
field_types.append(field_type)
|
|
521
|
-
return field_types
|
|
522
|
-
|
|
523
|
-
def __read_struct_data(self, struct_types):
|
|
524
|
-
# reads struct data based on type info in structType
|
|
525
|
-
data = []
|
|
526
|
-
for i in range(len(struct_types)):
|
|
527
|
-
encoded_type = struct_types[i]
|
|
528
|
-
et_size = self.__encoded_type_size(encoded_type)
|
|
529
|
-
# get data
|
|
530
|
-
data.append(self.__read_native_data(encoded_type, et_size))
|
|
531
|
-
return data
|
|
532
|
-
|
|
533
|
-
# ## END utility functions ###
|
|
534
|
-
|
|
535
|
-
def get_filename(self):
|
|
536
|
-
return self.__filename
|
|
537
|
-
|
|
538
|
-
filename = property(get_filename)
|
|
539
|
-
|
|
540
|
-
def get_tags(self):
|
|
541
|
-
return self.__stored_tags
|
|
542
|
-
|
|
543
|
-
tags = property(get_tags)
|
|
544
|
-
|
|
545
|
-
def get_raw(self):
|
|
546
|
-
"""Extracts data as np array"""
|
|
547
|
-
|
|
548
|
-
# DataTypes for image data <--> PIL decoders
|
|
549
|
-
data_types = {
|
|
550
|
-
1: '<u2', # 2 byte integer signed ("short")
|
|
551
|
-
2: '<f4', # 4 byte real (IEEE 754)
|
|
552
|
-
3: '<c8', # 8 byte complex (real, imaginary)
|
|
553
|
-
4: '', # ?
|
|
554
|
-
# 4 byte packed complex (see below)
|
|
555
|
-
5: (numpy.int16, {'real': (numpy.int8, 0), 'imaginary': (numpy.int8, 1)}),
|
|
556
|
-
6: '<u1', # 1 byte integer unsigned ("byte")
|
|
557
|
-
7: '<i4', # 4 byte integer signed ("long")
|
|
558
|
-
# I do not have any dm3 file with this format to test it.
|
|
559
|
-
8: '', # rgb view, 4 bytes/pixel, unused, red, green, blue?
|
|
560
|
-
9: '<i1', # byte integer signed
|
|
561
|
-
10: '<u2', # 2 byte integer unsigned
|
|
562
|
-
11: '<u4', # 4 byte integer unsigned
|
|
563
|
-
12: '<f8', # 8 byte real
|
|
564
|
-
13: '<c16', # byte complex
|
|
565
|
-
14: 'bool', # 1 byte binary (ie 0 or 1)
|
|
566
|
-
# Packed RGB. It must be a recent addition to the format because it does
|
|
567
|
-
# not appear in http://www.microscopy.cen.dtu.dk/~cbb/info/dmformat/
|
|
568
|
-
23: (numpy.float32,
|
|
569
|
-
{'R': ('<u1', 0), 'G': ('<u1', 1), 'B': ('<u1', 2), 'A': ('<u1', 3)}),
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
# find main image
|
|
573
|
-
for key in self.__stored_tags['ImageList']:
|
|
574
|
-
|
|
575
|
-
if key.isdigit():
|
|
576
|
-
if 'ImageData' in self.__stored_tags['ImageList'][key]:
|
|
577
|
-
if 'Data' in self.__stored_tags['ImageList'][key]['ImageData'] \
|
|
578
|
-
and 'DataType' in self.__stored_tags['ImageList'][key]['ImageData'] \
|
|
579
|
-
and 'Dimensions' in self.__stored_tags['ImageList'][key]['ImageData']:
|
|
580
|
-
if int(key) > self.__chosen_image:
|
|
581
|
-
self.__chosen_image = int(key)
|
|
582
|
-
if self.__chosen_image < 0:
|
|
583
|
-
raise IOError('Did not find data in file')
|
|
584
|
-
|
|
585
|
-
# get relevant Tags
|
|
586
|
-
byte_data = self.__stored_tags['ImageList'][str(self.__chosen_image)]['ImageData']['Data']
|
|
587
|
-
data_type = self.__stored_tags['ImageList'][str(self.__chosen_image)]['ImageData']['DataType']
|
|
588
|
-
dimensions = self.__stored_tags['ImageList'][str(self.__chosen_image)]['ImageData']['Dimensions']
|
|
589
|
-
|
|
590
|
-
# get shape from Dimensions
|
|
591
|
-
shape = []
|
|
592
|
-
for dim in dimensions:
|
|
593
|
-
shape.append(dimensions[dim])
|
|
594
|
-
|
|
595
|
-
# get data_type and reformat into numpy array
|
|
596
|
-
dt = data_types[data_type]
|
|
597
|
-
if dt == '':
|
|
598
|
-
raise TypeError('The datatype is not supported')
|
|
599
|
-
else:
|
|
600
|
-
raw_data = numpy.frombuffer(byte_data, dtype=dt, count=numpy.cumprod(shape)[-1]).reshape(shape, order='F')
|
|
601
|
-
# delete byte data in dictionary
|
|
602
|
-
self.__stored_tags['ImageList'][str(self.__chosen_image)]['ImageData']['Data'] = 'read'
|
|
603
|
-
return raw_data
|
|
604
|
-
|
|
605
|
-
data_cube = property(get_raw)
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
if __name__ == '__main__':
|
|
609
|
-
pass # print "DM3lib v.%s"%version
|
pyTEMlib/edges_db.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# Copyright © 2007 Francisco Javier de la Peña
|
|
3
|
-
#
|
|
4
|
-
# This file is part of EELSLab.
|
|
5
|
-
#
|
|
6
|
-
# EELSLab is free software; you can redistribute it and/or modify
|
|
7
|
-
# it under the terms of the GNU General Public License as published by
|
|
8
|
-
# the Free Software Foundation; either version 2 of the License, or
|
|
9
|
-
# (at your option) any later version.
|
|
10
|
-
#
|
|
11
|
-
# EELSLab is distributed in the hope that it will be useful,
|
|
12
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
-
# GNU General Public License for more details.
|
|
15
|
-
#
|
|
16
|
-
# You should have received a copy of the GNU General Public License
|
|
17
|
-
# along with EELSLab; if not, write to the Free Software
|
|
18
|
-
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
|
19
|
-
# USA
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
import csv
|
|
23
|
-
import os
|
|
24
|
-
|
|
25
|
-
from pyTEMlib.config_dir import config_path
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
file_path = os.path.join(config_path, 'edges_db.csv')
|
|
29
|
-
#print file_path
|
|
30
|
-
f = open(file_path, 'r')
|
|
31
|
-
reader = csv.reader(f)
|
|
32
|
-
edges_dict = {}
|
|
33
|
-
for row in reader:
|
|
34
|
-
twin_subshell = None
|
|
35
|
-
element, subshell = row[0].split('.')
|
|
36
|
-
Z = row[1]
|
|
37
|
-
if (element in edges_dict) is not True :
|
|
38
|
-
edges_dict[element]={}
|
|
39
|
-
edges_dict[element]['subshells'] = {}
|
|
40
|
-
edges_dict[element]['Z'] = Z
|
|
41
|
-
if row[3] is not '':
|
|
42
|
-
if subshell == "L3":
|
|
43
|
-
twin_subshell = "L2"
|
|
44
|
-
factor = 0.5
|
|
45
|
-
if subshell == "M3":
|
|
46
|
-
twin_subshell = "M2"
|
|
47
|
-
factor = 0.5
|
|
48
|
-
if subshell == "M5":
|
|
49
|
-
twin_subshell = "M4"
|
|
50
|
-
factor = 4/6.
|
|
51
|
-
if subshell == "N3":
|
|
52
|
-
twin_subshell = "N2"
|
|
53
|
-
factor = 2/4.
|
|
54
|
-
if subshell == "N5":
|
|
55
|
-
twin_subshell = "N4"
|
|
56
|
-
factor = 4/6.
|
|
57
|
-
if subshell == "N7":
|
|
58
|
-
twin_subshell = "N6"
|
|
59
|
-
factor = 6/8.
|
|
60
|
-
if subshell == "O5":
|
|
61
|
-
twin_subshell = "O4"
|
|
62
|
-
factor = 4/6.
|
|
63
|
-
|
|
64
|
-
edges_dict[element]['subshells'][subshell] = {}
|
|
65
|
-
edges_dict[element]['subshells'][subshell]['onset_energy'] = float(row[2])
|
|
66
|
-
edges_dict[element]['subshells'][subshell]['filename'] = row[0]
|
|
67
|
-
edges_dict[element]['subshells'][subshell]['relevance'] = row[4]
|
|
68
|
-
edges_dict[element]['subshells'][subshell]['factor'] = 1
|
|
69
|
-
|
|
70
|
-
if twin_subshell is not None :
|
|
71
|
-
edges_dict[element]['subshells'][twin_subshell] = {}
|
|
72
|
-
edges_dict[element]['subshells'][twin_subshell]['onset_energy'] = \
|
|
73
|
-
float(row[3])
|
|
74
|
-
edges_dict[element]['subshells'][twin_subshell]['filename'] = row[0]
|
|
75
|
-
edges_dict[element]['subshells'][twin_subshell]['relevance'] = row[4]
|
|
76
|
-
edges_dict[element]['subshells'][twin_subshell]['factor'] = factor
|