DefDAP 1.2.2__tar.gz → 1.3.0__tar.gz
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.
- {defdap-1.2.2 → defdap-1.3.0}/DefDAP.egg-info/PKG-INFO +2 -1
- {defdap-1.2.2 → defdap-1.3.0}/DefDAP.egg-info/requires.txt +1 -0
- {defdap-1.2.2 → defdap-1.3.0}/PKG-INFO +2 -1
- defdap-1.3.0/defdap/_version.py +1 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/file_readers.py +156 -12
- {defdap-1.2.2 → defdap-1.3.0}/pyproject.toml +3 -2
- defdap-1.2.2/defdap/_version.py +0 -1
- {defdap-1.2.2 → defdap-1.3.0}/DefDAP.egg-info/SOURCES.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/DefDAP.egg-info/dependency_links.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/DefDAP.egg-info/top_level.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/LICENSE +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/README.md +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/__init__.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/_accelerated.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/base.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/crystal.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/crystal_utils.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/ebsd.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/experiment.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/file_writers.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/hrdic.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/inspector.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/plotting.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/quat.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/slip_systems/cubic_bcc.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/slip_systems/cubic_bcc_110only.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/slip_systems/cubic_fcc.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/slip_systems/cubic_fcc_damask.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/slip_systems/hexagonal_noca.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/slip_systems/hexagonal_withca.txt +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/defdap/utils.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/docs/source/conf.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/setup.cfg +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/tests/test_ebsd.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/tests/test_hrdic.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/tests/test_io.py +0 -0
- {defdap-1.2.2 → defdap-1.3.0}/tests/test_quat.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DefDAP
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: A python library for correlating EBSD and HRDIC data.
|
|
5
5
|
Author: Rhys Thomas, João Quinta da Fonseca
|
|
6
6
|
Author-email: "Michael D. Atkinson" <michael.atkinson@ukaea.uk>
|
|
@@ -34,6 +34,7 @@ Requires-Dist: peakutils
|
|
|
34
34
|
Requires-Dist: matplotlib_scalebar
|
|
35
35
|
Requires-Dist: networkx
|
|
36
36
|
Requires-Dist: numba
|
|
37
|
+
Requires-Dist: h5py
|
|
37
38
|
Provides-Extra: testing
|
|
38
39
|
Requires-Dist: pytest<8; extra == "testing"
|
|
39
40
|
Requires-Dist: coverage; extra == "testing"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DefDAP
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: A python library for correlating EBSD and HRDIC data.
|
|
5
5
|
Author: Rhys Thomas, João Quinta da Fonseca
|
|
6
6
|
Author-email: "Michael D. Atkinson" <michael.atkinson@ukaea.uk>
|
|
@@ -34,6 +34,7 @@ Requires-Dist: peakutils
|
|
|
34
34
|
Requires-Dist: matplotlib_scalebar
|
|
35
35
|
Requires-Dist: networkx
|
|
36
36
|
Requires-Dist: numba
|
|
37
|
+
Requires-Dist: h5py
|
|
37
38
|
Provides-Extra: testing
|
|
38
39
|
Requires-Dist: pytest<8; extra == "testing"
|
|
39
40
|
Requires-Dist: coverage; extra == "testing"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '1.3.0'
|
|
@@ -13,15 +13,16 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
import numpy as np
|
|
17
|
-
from numpy.lib.recfunctions import structured_to_unstructured
|
|
18
|
-
import pandas as pd
|
|
19
16
|
from abc import ABC, abstractmethod
|
|
20
17
|
import pathlib
|
|
21
18
|
import re
|
|
22
|
-
|
|
23
19
|
from typing import TextIO, Dict, List, Callable, Any, Type, Optional
|
|
24
20
|
|
|
21
|
+
import h5py
|
|
22
|
+
import numpy as np
|
|
23
|
+
from numpy.lib.recfunctions import structured_to_unstructured
|
|
24
|
+
import pandas as pd
|
|
25
|
+
|
|
25
26
|
from defdap.crystal import Phase
|
|
26
27
|
from defdap.quat import Quat
|
|
27
28
|
from defdap.utils import Datastore
|
|
@@ -56,11 +57,14 @@ class EBSDDataLoader(ABC):
|
|
|
56
57
|
self.data_format = None
|
|
57
58
|
|
|
58
59
|
@staticmethod
|
|
59
|
-
def get_loader(
|
|
60
|
+
def get_loader(
|
|
61
|
+
data_type: str, file_name: pathlib.Path
|
|
62
|
+
) -> 'Type[EBSDDataLoader]':
|
|
60
63
|
if data_type is None:
|
|
61
64
|
data_type = {
|
|
62
65
|
'.crc': 'oxfordbinary',
|
|
63
66
|
'.cpr': 'oxfordbinary',
|
|
67
|
+
'.h5oina': 'oxfordh5',
|
|
64
68
|
'.ctf': 'oxfordtext',
|
|
65
69
|
'.ang': 'edaxang',
|
|
66
70
|
}.get(file_name.suffix, 'oxfordbinary')
|
|
@@ -70,6 +74,7 @@ class EBSDDataLoader(ABC):
|
|
|
70
74
|
loader = {
|
|
71
75
|
'oxfordbinary': OxfordBinaryLoader,
|
|
72
76
|
'oxfordtext': OxfordTextLoader,
|
|
77
|
+
'oxfordh5': Oxfordh5Loader,
|
|
73
78
|
'edaxang': EdaxAngLoader,
|
|
74
79
|
'pythondict': PythonDictLoader,
|
|
75
80
|
}[data_type]
|
|
@@ -234,6 +239,134 @@ class OxfordTextLoader(EBSDDataLoader):
|
|
|
234
239
|
self.check_data()
|
|
235
240
|
|
|
236
241
|
|
|
242
|
+
class Oxfordh5Loader(EBSDDataLoader):
|
|
243
|
+
def load(self, file_name: pathlib.Path, dataset = None) -> None:
|
|
244
|
+
"""Read an Oxford Instruments ``.h5oina`` orientation file.
|
|
245
|
+
|
|
246
|
+
Parameters
|
|
247
|
+
----------
|
|
248
|
+
file_name : pathlib.Path
|
|
249
|
+
Path to file.
|
|
250
|
+
dataset : str (raw or processed), optional
|
|
251
|
+
Dataset to load. If None, defaults to raw data.
|
|
252
|
+
|
|
253
|
+
"""
|
|
254
|
+
# Open data file and read in metadata
|
|
255
|
+
if not file_name.is_file():
|
|
256
|
+
raise FileNotFoundError(f"Cannot open file {file_name}")
|
|
257
|
+
|
|
258
|
+
file = h5py.File(file_name)
|
|
259
|
+
|
|
260
|
+
# This header contains all the information in the map that does not
|
|
261
|
+
# change with processing
|
|
262
|
+
raw_header = file['1']['EBSD']['Header']
|
|
263
|
+
shape = (int(raw_header['Y Cells'][0]), int(raw_header['X Cells'][0]))
|
|
264
|
+
self.loaded_metadata['shape'] = shape
|
|
265
|
+
self.loaded_metadata['step_size'] = float(raw_header['X Step'][0])
|
|
266
|
+
self.loaded_metadata['acquisition_rotation'] = Quat.from_euler_angles(
|
|
267
|
+
*raw_header['Specimen Orientation Euler'][0]
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
# Check if `Data Processing` dataset exists in the h5
|
|
271
|
+
if 'Data' in file['1']['Data Processing'] and dataset is None:
|
|
272
|
+
print('\n\tMultiple datasets in h5 file, defaulting to raw data.')
|
|
273
|
+
print(
|
|
274
|
+
'\tProcessed data can be accessed by passing `processed` to '
|
|
275
|
+
'the `dataset` argument.'
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
# Handle `raw` or `processed` selection
|
|
279
|
+
if dataset is None or dataset == 'raw':
|
|
280
|
+
root = file['1']['EBSD']
|
|
281
|
+
if dataset == 'processed':
|
|
282
|
+
if 'Data Processing' not in file['1']:
|
|
283
|
+
raise ValueError('No processed data in h5 file.')
|
|
284
|
+
if 'Data' not in file['1']['Data Processing']:
|
|
285
|
+
raise ValueError('No processed data in h5 file.')
|
|
286
|
+
root = file['1']['Data Processing']
|
|
287
|
+
|
|
288
|
+
# Phase data from relevant dataset
|
|
289
|
+
for phase_data in root['Header']['Phases'].values():
|
|
290
|
+
phase = Phase(
|
|
291
|
+
phase_data['Phase Name'][0].decode(),
|
|
292
|
+
phase_data['Laue Group'][0],
|
|
293
|
+
phase_data['Space Group'][0],
|
|
294
|
+
np.concatenate([
|
|
295
|
+
phase_data['Lattice Dimensions'][0],
|
|
296
|
+
phase_data['Lattice Angles'][0]
|
|
297
|
+
]))
|
|
298
|
+
self.loaded_metadata['phases'].append(phase)
|
|
299
|
+
|
|
300
|
+
self.check_metadata()
|
|
301
|
+
|
|
302
|
+
# Some data is only available and relevant for the raw data, for
|
|
303
|
+
# example band contrast
|
|
304
|
+
if dataset == 'raw':
|
|
305
|
+
raw_data = root['Data']
|
|
306
|
+
self.loaded_data.add(
|
|
307
|
+
'band_contrast',
|
|
308
|
+
np.array(raw_data['Band Contrast']).reshape(shape),
|
|
309
|
+
unit='', type='map', order=0,
|
|
310
|
+
plot_params={
|
|
311
|
+
'plot_colour_bar': True,
|
|
312
|
+
'cmap': 'gray',
|
|
313
|
+
'clabel': 'Band contrast',
|
|
314
|
+
}
|
|
315
|
+
)
|
|
316
|
+
self.loaded_data.add(
|
|
317
|
+
'band_slope',
|
|
318
|
+
np.array(raw_data['Band Slope']).reshape(shape),
|
|
319
|
+
unit='', type='map', order=0,
|
|
320
|
+
plot_params={
|
|
321
|
+
'plot_colour_bar': True,
|
|
322
|
+
'cmap': 'gray',
|
|
323
|
+
'clabel': 'Band slope',
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
self.loaded_data.add(
|
|
327
|
+
'mean_angular_deviation',
|
|
328
|
+
np.array(raw_data['Mean Angular Deviation']).reshape(shape),
|
|
329
|
+
unit='', type='map', order=0,
|
|
330
|
+
plot_params={
|
|
331
|
+
'plot_colour_bar': True,
|
|
332
|
+
'clabel': 'Mean angular deviation',
|
|
333
|
+
}
|
|
334
|
+
)
|
|
335
|
+
self.loaded_data.add(
|
|
336
|
+
'pattern_quality',
|
|
337
|
+
np.array(raw_data['Pattern Quality']).reshape(shape),
|
|
338
|
+
unit='', type='map', order=0,
|
|
339
|
+
plot_params={
|
|
340
|
+
'plot_colour_bar': True,
|
|
341
|
+
'clabel': 'Pattern quality',
|
|
342
|
+
}
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
# If pattern matching is performed, the cross correlation coefficient
|
|
346
|
+
# is useful
|
|
347
|
+
if dataset == 'processed' and 'Pattern Matching' in root:
|
|
348
|
+
pattern_data = root['Pattern Matching']['Data']
|
|
349
|
+
self.loaded_data.add(
|
|
350
|
+
'pattern_quality',
|
|
351
|
+
np.array(
|
|
352
|
+
pattern_data['Cross Correlation Coefficient']
|
|
353
|
+
).reshape(shape),
|
|
354
|
+
unit='', type='map', order=0,
|
|
355
|
+
plot_params={
|
|
356
|
+
'plot_colour_bar': True,
|
|
357
|
+
'clabel': 'Cross Correlation Coefficient',
|
|
358
|
+
}
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
# Get Euler angles from relevant dataset
|
|
362
|
+
self.loaded_data.phase = np.array(root['Data']['Phase']).reshape(shape)
|
|
363
|
+
self.loaded_data.euler_angle = (
|
|
364
|
+
root['Data']['Euler'][:].reshape(shape + (3,)).transpose((2, 0, 1))
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
self.check_data()
|
|
368
|
+
|
|
369
|
+
|
|
237
370
|
class EdaxAngLoader(EBSDDataLoader):
|
|
238
371
|
def load(self, file_name: pathlib.Path) -> None:
|
|
239
372
|
""" Read an EDAX .ang file.
|
|
@@ -327,7 +460,9 @@ class EdaxAngLoader(EBSDDataLoader):
|
|
|
327
460
|
)
|
|
328
461
|
add_phase = 1 if data['phase'].min() == 0 else 0
|
|
329
462
|
self.loaded_data.phase = data['phase'].reshape(shape) + add_phase
|
|
330
|
-
self.loaded_data['phase', 'plot_params']['vmax'] = len(
|
|
463
|
+
self.loaded_data['phase', 'plot_params']['vmax'] = len(
|
|
464
|
+
self.loaded_metadata['phases']
|
|
465
|
+
)
|
|
331
466
|
|
|
332
467
|
# flatten the structured dtype
|
|
333
468
|
euler_angle = structured_to_unstructured(
|
|
@@ -424,8 +559,10 @@ class OxfordBinaryLoader(EBSDDataLoader):
|
|
|
424
559
|
|
|
425
560
|
group_name = group_pat.match(line.strip()).group(1)
|
|
426
561
|
group_dict = dict()
|
|
427
|
-
read_until_string(
|
|
428
|
-
|
|
562
|
+
read_until_string(
|
|
563
|
+
cpr_file, '[', comment_char=comment_char,
|
|
564
|
+
line_process=lambda l: parse_line(l, group_dict)
|
|
565
|
+
)
|
|
429
566
|
metadata[group_name] = group_dict
|
|
430
567
|
|
|
431
568
|
# Create phase objects and move metadata to object metadata dict
|
|
@@ -549,7 +686,8 @@ class OxfordBinaryLoader(EBSDDataLoader):
|
|
|
549
686
|
data[['ph1', 'phi', 'ph2']].reshape(shape)).transpose((2, 0, 1))
|
|
550
687
|
|
|
551
688
|
if self.loaded_metadata['edx']['Count'] > 0:
|
|
552
|
-
EDXFields = [key for key in data.dtype.fields.keys()
|
|
689
|
+
EDXFields = [key for key in data.dtype.fields.keys()
|
|
690
|
+
if key.startswith('EDX')]
|
|
553
691
|
for field in EDXFields:
|
|
554
692
|
self.loaded_data.add(
|
|
555
693
|
field,
|
|
@@ -590,7 +728,9 @@ class PythonDictLoader(EBSDDataLoader):
|
|
|
590
728
|
unit='', type='map', order=0
|
|
591
729
|
)
|
|
592
730
|
self.loaded_data.phase = data_dict['phase']
|
|
593
|
-
self.loaded_data['phase', 'plot_params']['vmax'] = len(
|
|
731
|
+
self.loaded_data['phase', 'plot_params']['vmax'] = len(
|
|
732
|
+
self.loaded_metadata['phases']
|
|
733
|
+
)
|
|
594
734
|
self.loaded_data.euler_angle = data_dict['euler_angle']
|
|
595
735
|
self.check_data()
|
|
596
736
|
|
|
@@ -819,8 +959,12 @@ class OpenPivBinaryLoader(DICDataLoader):
|
|
|
819
959
|
|
|
820
960
|
# if y descending, flip
|
|
821
961
|
if np.all(np.diff(data['y'][:,0])) > 0:
|
|
822
|
-
self.loaded_data.coordinate = np.array(
|
|
823
|
-
|
|
962
|
+
self.loaded_data.coordinate = np.array(
|
|
963
|
+
[data['x'][::-1], data['y'][::-1]]
|
|
964
|
+
)
|
|
965
|
+
self.loaded_data.displacement = np.array(
|
|
966
|
+
[data['u'][::-1], data['v'][::-1]]
|
|
967
|
+
)
|
|
824
968
|
else:
|
|
825
969
|
self.loaded_data.coordinate = np.array([data['x'], data['y']])
|
|
826
970
|
self.loaded_data.displacement = np.array([data['u'], data['v']])
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "DefDAP"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.3.0"
|
|
8
8
|
authors = [
|
|
9
9
|
{name = "Michael D. Atkinson", email = "michael.atkinson@ukaea.uk"},
|
|
10
10
|
{name = "Rhys Thomas"},
|
|
@@ -41,6 +41,7 @@ dependencies = [
|
|
|
41
41
|
"matplotlib_scalebar",
|
|
42
42
|
"networkx",
|
|
43
43
|
"numba",
|
|
44
|
+
"h5py"
|
|
44
45
|
]
|
|
45
46
|
|
|
46
47
|
[project.urls]
|
|
@@ -75,7 +76,7 @@ defdap = ["slip_systems/*.txt"]
|
|
|
75
76
|
|
|
76
77
|
[tool.commitizen]
|
|
77
78
|
name = "cz_conventional_commits"
|
|
78
|
-
version = "1.
|
|
79
|
+
version = "1.3.0"
|
|
79
80
|
tag_format = "v$version"
|
|
80
81
|
version_files = [
|
|
81
82
|
"pyproject.toml:version",
|
defdap-1.2.2/defdap/_version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '1.2.2'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|