orGUI 1.0.1__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.
- orGUI-1.0.1.dist-info/LICENSE +21 -0
- orGUI-1.0.1.dist-info/METADATA +147 -0
- orGUI-1.0.1.dist-info/RECORD +83 -0
- orGUI-1.0.1.dist-info/WHEEL +5 -0
- orGUI-1.0.1.dist-info/entry_points.txt +2 -0
- orGUI-1.0.1.dist-info/top_level.txt +1 -0
- orgui/__init__.py +36 -0
- orgui/app/ArrayTableDialog.py +433 -0
- orgui/app/QReflectionSelector.py +538 -0
- orgui/app/QScanSelector.py +692 -0
- orgui/app/QUBCalculator.py +1210 -0
- orgui/app/__init__.py +36 -0
- orgui/app/database.py +487 -0
- orgui/app/orGUI.py +2613 -0
- orgui/app/qutils.py +51 -0
- orgui/backend/__init__.py +32 -0
- orgui/backend/backends.py +157 -0
- orgui/backend/beamline/ID31DiffractLinTilt.py +77 -0
- orgui/backend/beamline/P212_tools.py +577 -0
- orgui/backend/beamline/__init__.py +36 -0
- orgui/backend/beamline/fio_reader.py +110 -0
- orgui/backend/beamline/id31_tools.py +651 -0
- orgui/backend/scans.py +95 -0
- orgui/backend/udefaults.py +163 -0
- orgui/backend/universalScanLoader.py +105 -0
- orgui/datautils/__init__.py +32 -0
- orgui/datautils/util.py +705 -0
- orgui/datautils/xrayutils/CTRcalc.py +3022 -0
- orgui/datautils/xrayutils/CTRopt.py +623 -0
- orgui/datautils/xrayutils/CTRplotutil.py +904 -0
- orgui/datautils/xrayutils/DetectorCalibration.py +685 -0
- orgui/datautils/xrayutils/HKLVlieg.py +1360 -0
- orgui/datautils/xrayutils/ReciprocalNavigation.py +401 -0
- orgui/datautils/xrayutils/_CTRcalc_accel.py +181 -0
- orgui/datautils/xrayutils/__init__.py +46 -0
- orgui/datautils/xrayutils/element_data.py +213 -0
- orgui/datautils/xrayutils/test/__init__.py +57 -0
- orgui/datautils/xrayutils/test/test_CTRcalc.py +152 -0
- orgui/datautils/xrayutils/test/test_DetectorCalibration.py +336 -0
- orgui/datautils/xrayutils/test/test_HKLcalc.py +88 -0
- orgui/datautils/xrayutils/unitcells/Fe3O4(100).bul +59 -0
- orgui/datautils/xrayutils/unitcells/Pt100.bul +7 -0
- orgui/datautils/xrayutils/unitcells/Pt100_small.bul +5 -0
- orgui/datautils/xrayutils/unitcells/Pt110.bul +5 -0
- orgui/datautils/xrayutils/unitcells/Pt111.bul +6 -0
- orgui/datautils/xrayutils/unitcells/Pt310.bul +13 -0
- orgui/datautils/xrayutils/unitcells/Pt3O4(100).bul +19 -0
- orgui/datautils/xrayutils/unitcells/PtO(001).bul +9 -0
- orgui/datautils/xrayutils/unitcells/PtO(010).bul +9 -0
- orgui/datautils/xrayutils/unitcells/PtO(100).bul +9 -0
- orgui/datautils/xrayutils/unitcells/__init__.py +67 -0
- orgui/datautils/xrayutils/unitcells/a-PtO2(0001).bul +6 -0
- orgui/main.py +101 -0
- orgui/resources/__init__.py +40 -0
- orgui/resources/icons/alpha.png +0 -0
- orgui/resources/icons/alpha.svg +67 -0
- orgui/resources/icons/diffractometer_v3.png +0 -0
- orgui/resources/icons/disable-image.png +0 -0
- orgui/resources/icons/disable-image.svg +68 -0
- orgui/resources/icons/document-nx-open.png +0 -0
- orgui/resources/icons/document-nx-open.svg +152 -0
- orgui/resources/icons/document-nx-save.png +0 -0
- orgui/resources/icons/document-nx-save.svg +73 -0
- orgui/resources/icons/logo.png +0 -0
- orgui/resources/icons/logo.svg +808 -0
- orgui/resources/icons/max_image.png +0 -0
- orgui/resources/icons/max_image.svg +77 -0
- orgui/resources/icons/max_image2.png +0 -0
- orgui/resources/icons/max_image2.svg +83 -0
- orgui/resources/icons/search-image.png +0 -0
- orgui/resources/icons/search-image.svg +94 -0
- orgui/resources/icons/search-reflection.png +0 -0
- orgui/resources/icons/search-reflection.svg +126 -0
- orgui/resources/icons/search.png +0 -0
- orgui/resources/icons/search.svg +91 -0
- orgui/resources/icons/select-image.png +0 -0
- orgui/resources/icons/select-image.svg +60 -0
- orgui/resources/icons/set-reflection.png +0 -0
- orgui/resources/icons/set-reflection.svg +91 -0
- orgui/resources/icons/sum_image.png +0 -0
- orgui/resources/icons/sum_image.svg +63 -0
- orgui/resources/icons/sum_image2.png +0 -0
- orgui/resources/icons/sum_image2.svg +75 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# /*##########################################################################
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020-2024 Timo Fuchs
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
|
14
|
+
# all copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
# THE SOFTWARE.
|
|
23
|
+
#
|
|
24
|
+
# ###########################################################################*/
|
|
25
|
+
__author__ = "Timo Fuchs"
|
|
26
|
+
__copyright__ = "Copyright 2020-2024 Timo Fuchs"
|
|
27
|
+
__license__ = "MIT License"
|
|
28
|
+
__version__ = "1.0.0"
|
|
29
|
+
__maintainer__ = "Timo Fuchs"
|
|
30
|
+
__email__ = "fuchs@physik.uni-kiel.de"
|
|
31
|
+
|
|
32
|
+
import unittest
|
|
33
|
+
|
|
34
|
+
from .. import DetectorCalibration
|
|
35
|
+
import pyFAI
|
|
36
|
+
|
|
37
|
+
import numpy as np
|
|
38
|
+
import os
|
|
39
|
+
import warnings
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
from silx.io import dictdump
|
|
43
|
+
silx_avail = True
|
|
44
|
+
except:
|
|
45
|
+
silx_avail = False
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class TestRWDetector2D_SXRD(unittest.TestCase):
|
|
49
|
+
|
|
50
|
+
def setUp(self):
|
|
51
|
+
self.sxrddet = DetectorCalibration.Detector2D_SXRD()
|
|
52
|
+
self.sxrddet.detector = pyFAI.detector_factory('Pilatus 2M CdTe')
|
|
53
|
+
self.sxrddet.poni1 = 0.1
|
|
54
|
+
self.sxrddet.poni2 = 0.1
|
|
55
|
+
self.sxrddet.rot1 = np.pi/20
|
|
56
|
+
self.sxrddet.rot2 = -np.pi/20
|
|
57
|
+
self.sxrddet.rot3 = 0
|
|
58
|
+
self.sxrddet.dist = 1.5
|
|
59
|
+
self.sxrddet.setAzimuthalReference(np.deg2rad(90.))
|
|
60
|
+
self.sxrddet.setPolarization(np.deg2rad(90.), 0.75)
|
|
61
|
+
|
|
62
|
+
def test_from_to_dict(self):
|
|
63
|
+
nxdict = self.sxrddet.toNXdict()
|
|
64
|
+
othersxrddet = DetectorCalibration.Detector2D_SXRD()
|
|
65
|
+
othersxrddet.fromNXdict(nxdict)
|
|
66
|
+
self.check_sxrd_equal(othersxrddet)
|
|
67
|
+
|
|
68
|
+
def check_sxrd_equal(self, other):
|
|
69
|
+
self.assertDictEqual(self.sxrddet.getPyFAI(), other.getPyFAI())
|
|
70
|
+
self.assertEqual(self.sxrddet._polFactor, other._polFactor)
|
|
71
|
+
self.assertEqual(self.sxrddet._polAxis, other._polAxis)
|
|
72
|
+
self.assertEqual(self.sxrddet._deltaChi, other._deltaChi)
|
|
73
|
+
|
|
74
|
+
@unittest.skipUnless(silx_avail, "silx not available")
|
|
75
|
+
def test_write_nx(self):
|
|
76
|
+
self._nxfilename = "./detcal_test.nx"
|
|
77
|
+
self.addCleanup(self._destruct_file, self._nxfilename)
|
|
78
|
+
|
|
79
|
+
nxdict = self.sxrddet.toNXdict()
|
|
80
|
+
dictdump.dicttonx(nxdict, self._nxfilename)
|
|
81
|
+
self.assertTrue(os.path.isfile(self._nxfilename))
|
|
82
|
+
os.remove(self._nxfilename)
|
|
83
|
+
|
|
84
|
+
@unittest.skipUnless(silx_avail, "silx not available")
|
|
85
|
+
def test_read_write_nx(self):
|
|
86
|
+
self._nxfilename = "./detcal_test.nx"
|
|
87
|
+
self.addCleanup(self._destruct_file, self._nxfilename)
|
|
88
|
+
|
|
89
|
+
nxdict = self.sxrddet.toNXdict()
|
|
90
|
+
dictdump.dicttonx(nxdict, self._nxfilename)
|
|
91
|
+
|
|
92
|
+
read_dict = dictdump.nxtodict(self._nxfilename)
|
|
93
|
+
othersxrddet = DetectorCalibration.Detector2D_SXRD()
|
|
94
|
+
othersxrddet.fromNXdict(read_dict)
|
|
95
|
+
self.check_sxrd_equal(othersxrddet)
|
|
96
|
+
|
|
97
|
+
othersxrddet = DetectorCalibration.loadNXdict(read_dict)
|
|
98
|
+
self.check_sxrd_equal(othersxrddet)
|
|
99
|
+
|
|
100
|
+
os.remove(self._nxfilename)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _destruct_file(self, filename):
|
|
104
|
+
if os.path.exists(filename):
|
|
105
|
+
os.remove(self._nxfilename)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class TestAnglePixelConversion(unittest.TestCase):
|
|
109
|
+
|
|
110
|
+
def setUp(self):
|
|
111
|
+
self.sxrddet = DetectorCalibration.Detector2D_SXRD()
|
|
112
|
+
self.sxrddet.detector = pyFAI.detector_factory('Pilatus 2M CdTe')
|
|
113
|
+
self.sxrddet.poni1 = 0.1
|
|
114
|
+
self.sxrddet.poni2 = 0.1
|
|
115
|
+
self.sxrddet.rot1 = np.pi/20
|
|
116
|
+
self.sxrddet.rot2 = -np.pi/20
|
|
117
|
+
self.sxrddet.rot3 = 0
|
|
118
|
+
self.sxrddet.dist = 1.5
|
|
119
|
+
self.sxrddet.setAzimuthalReference(np.deg2rad(90.))
|
|
120
|
+
self.sxrddet.setPolarization(np.deg2rad(90.), 0.75)
|
|
121
|
+
|
|
122
|
+
self.p1 = np.arange(self.sxrddet.detector.shape[1] ) + 0.5 # pixel center
|
|
123
|
+
self.p2 = np.arange(self.sxrddet.detector.shape[0] ) + 0.5
|
|
124
|
+
self.p12 = np.moveaxis(np.array(np.meshgrid(self.p1,self.p2)),0, -1)[:,:,::-1]
|
|
125
|
+
|
|
126
|
+
self.mu = np.deg2rad(0.1) # should be differed, but probably ok
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def assertPixelErrorSurfaceAnglesLessThan(self, abserr=1e-3, msg=""):
|
|
130
|
+
gamma, delta = self.sxrddet.surfaceAngles(self.mu)
|
|
131
|
+
p12_conv = self.sxrddet.pixelsSurfaceAngles(gamma, delta, self.mu)
|
|
132
|
+
maxerror = np.nanmax(np.abs(self.p12 - p12_conv))
|
|
133
|
+
if maxerror > abserr:
|
|
134
|
+
warnings.warn("too large error: %.5f pixel coord from surface angles, %s" % (maxerror, msg))
|
|
135
|
+
#self.assertLessEqual(maxerror, abserr, "too large error pixel coord from surface angles, %s" % msg)
|
|
136
|
+
|
|
137
|
+
def assertPixelErrorTthChiLessThan(self, abserr=1e-3, msg=""):
|
|
138
|
+
tth = self.sxrddet.twoThetaArray()
|
|
139
|
+
chi = self.sxrddet.chiArray()
|
|
140
|
+
p12_conv = self.sxrddet.pixelsTthChi(tth, chi)
|
|
141
|
+
maxerror = np.nanmax(np.abs(self.p12 - p12_conv))
|
|
142
|
+
if maxerror > abserr:
|
|
143
|
+
warnings.warn("too large error: %.5f pixel coord from tth and chi, %s" % (maxerror, msg))
|
|
144
|
+
#self.assertLessEqual(maxerror, abserr, "too large error pixel coord from tth and chi, %s" % msg)
|
|
145
|
+
|
|
146
|
+
def assertGamDelRangeErrorLessThan(self, abserr=1e-3, msg=""):
|
|
147
|
+
exact = self.sxrddet._rangegamdel_p_full_det
|
|
148
|
+
corner = self.sxrddet.rangegamdel_p
|
|
149
|
+
|
|
150
|
+
diff = np.array(exact) - np.array(corner)
|
|
151
|
+
max_rel_diff = np.amax(np.abs(diff))
|
|
152
|
+
if max_rel_diff > abserr:
|
|
153
|
+
warnings.warn("too large error: %.5f approx det corners, %s" % (max_rel_diff, msg))
|
|
154
|
+
#self.assertLessEqual(max_rel_diff, abserr, "too large error approx det corners, %s" % msg)
|
|
155
|
+
|
|
156
|
+
def test_poni1(self):
|
|
157
|
+
for p1 in np.linspace(-3,3,5):
|
|
158
|
+
self.sxrddet.poni1 = p1
|
|
159
|
+
msg="poni1 = %s" % p1
|
|
160
|
+
self.assertPixelErrorSurfaceAnglesLessThan(msg=msg)
|
|
161
|
+
self.assertPixelErrorTthChiLessThan(msg=msg)
|
|
162
|
+
self.assertGamDelRangeErrorLessThan(msg=msg)
|
|
163
|
+
self.sxrddet.poni1 = 0.1
|
|
164
|
+
|
|
165
|
+
def test_poni2(self):
|
|
166
|
+
for p1 in np.linspace(-3,3,5):
|
|
167
|
+
self.sxrddet.poni2 = p1
|
|
168
|
+
msg="poni2 = %s" % p1
|
|
169
|
+
self.assertPixelErrorSurfaceAnglesLessThan(msg=msg)
|
|
170
|
+
self.assertPixelErrorTthChiLessThan(msg=msg)
|
|
171
|
+
self.assertGamDelRangeErrorLessThan(msg=msg)
|
|
172
|
+
self.sxrddet.poni2 = 0.1
|
|
173
|
+
|
|
174
|
+
def test_rot1(self):
|
|
175
|
+
for p1 in np.linspace(0,np.pi,8):
|
|
176
|
+
self.sxrddet.rot1 = p1
|
|
177
|
+
msg="rot1 = %s" % p1
|
|
178
|
+
self.assertPixelErrorSurfaceAnglesLessThan(msg=msg)
|
|
179
|
+
self.assertPixelErrorTthChiLessThan(msg=msg)
|
|
180
|
+
self.assertGamDelRangeErrorLessThan(msg=msg)
|
|
181
|
+
self.sxrddet.rot1 = np.pi/20
|
|
182
|
+
|
|
183
|
+
def test_rot2(self):
|
|
184
|
+
for p1 in np.linspace(0,np.pi,8):
|
|
185
|
+
self.sxrddet.rot2 = p1
|
|
186
|
+
msg="rot2 = %s" % p1
|
|
187
|
+
self.assertPixelErrorSurfaceAnglesLessThan(msg=msg)
|
|
188
|
+
self.assertPixelErrorTthChiLessThan(msg=msg)
|
|
189
|
+
self.assertGamDelRangeErrorLessThan(msg=msg)
|
|
190
|
+
self.sxrddet.rot2 = -np.pi/20
|
|
191
|
+
|
|
192
|
+
def test_rot3(self):
|
|
193
|
+
for p1 in np.linspace(0,np.pi,8):
|
|
194
|
+
self.sxrddet.rot3 = p1
|
|
195
|
+
msg="rot3 = %s" % p1
|
|
196
|
+
self.assertPixelErrorSurfaceAnglesLessThan(msg=msg)
|
|
197
|
+
self.assertPixelErrorTthChiLessThan(msg=msg)
|
|
198
|
+
self.assertGamDelRangeErrorLessThan(msg=msg)
|
|
199
|
+
self.sxrddet.rot3 = 0
|
|
200
|
+
|
|
201
|
+
def test_dist(self):
|
|
202
|
+
for d in np.linspace(0.01,10,5):
|
|
203
|
+
self.sxrddet.dist = d
|
|
204
|
+
msg="dist = %s" % d
|
|
205
|
+
self.assertPixelErrorSurfaceAnglesLessThan(msg=msg)
|
|
206
|
+
self.assertPixelErrorTthChiLessThan(msg=msg)
|
|
207
|
+
self.assertGamDelRangeErrorLessThan(msg=msg)
|
|
208
|
+
self.sxrddet.dist = 1.5
|
|
209
|
+
|
|
210
|
+
"""
|
|
211
|
+
def test_del_gam_range():
|
|
212
|
+
sxrddet = Detector2D_SXRD()
|
|
213
|
+
sxrddet.detector = pyFAI.detector_factory('Pilatus 2M CdTe')
|
|
214
|
+
sxrddet.poni1 = 0.1
|
|
215
|
+
sxrddet.poni2 = 0.1
|
|
216
|
+
sxrddet.rot1 = np.pi/4
|
|
217
|
+
sxrddet.rot2 = np.pi/5
|
|
218
|
+
sxrddet.rot3 = np.pi/6
|
|
219
|
+
sxrddet.dist = 1.5
|
|
220
|
+
sxrddet.setAzimuthalReference(np.deg2rad(90.))
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def checkRange():
|
|
224
|
+
exact = sxrddet._rangegamdel_p_full_det
|
|
225
|
+
corner = sxrddet.rangegamdel_p
|
|
226
|
+
#print("Exact: ", exact)
|
|
227
|
+
#print("Corner: ", corner)
|
|
228
|
+
diff = np.array(exact) - np.array(corner)
|
|
229
|
+
max_rel_diff = np.amax(np.abs(diff))
|
|
230
|
+
return max_rel_diff, diff
|
|
231
|
+
#print("Difference:", np.array(exact) - np.array(corner))
|
|
232
|
+
|
|
233
|
+
sxrddet.poni2 = 0.0
|
|
234
|
+
for p1 in np.linspace(-5,5,20):
|
|
235
|
+
sxrddet.poni1 = p1
|
|
236
|
+
maxerr, diff = checkRange()
|
|
237
|
+
print(f"Max numerical error at poni1 = {p1} m: {maxerr}")
|
|
238
|
+
|
|
239
|
+
sxrddet.poni1 = 0.0
|
|
240
|
+
for p2 in np.linspace(-5,5,20):
|
|
241
|
+
sxrddet.poni2 = p2
|
|
242
|
+
maxerr, diff = checkRange()
|
|
243
|
+
print(f"Max numerical error at poni2 = {p2} m: {maxerr}")
|
|
244
|
+
|
|
245
|
+
# test rot1:
|
|
246
|
+
for r1 in np.linspace(0,np.pi,8):
|
|
247
|
+
sxrddet.rot1 = r1
|
|
248
|
+
maxerr, diff = checkRange()
|
|
249
|
+
print(f"Max numerical error at rot1 = {np.rad2deg(r1)} deg: {maxerr}")
|
|
250
|
+
sxrddet.rot1 = np.pi/4
|
|
251
|
+
for r2 in np.linspace(0,np.pi,8):
|
|
252
|
+
sxrddet.rot2 = r2
|
|
253
|
+
maxerr, diff = checkRange()
|
|
254
|
+
print(f"Max numerical error at rot2 = {np.rad2deg(r2)} deg: {maxerr}")
|
|
255
|
+
|
|
256
|
+
sxrddet.rot2 = np.pi/4
|
|
257
|
+
for r3 in np.linspace(0,np.pi,8):
|
|
258
|
+
sxrddet.rot3 = r3
|
|
259
|
+
maxerr, diff = checkRange()
|
|
260
|
+
print(f"Max numerical error at rot3 = {np.rad2deg(r3)} deg: {maxerr}")
|
|
261
|
+
sxrddet.rot3 = np.pi/4
|
|
262
|
+
|
|
263
|
+
for d in np.linspace(0.001,10,5):
|
|
264
|
+
sxrddet.dist = d
|
|
265
|
+
maxerr, diff = checkRange()
|
|
266
|
+
print(f"Max numerical error at dist = {d} m: {maxerr}")
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def testPixelConversion():
|
|
270
|
+
sxrddet = Detector2D_SXRD()
|
|
271
|
+
sxrddet.detector = pyFAI.detector_factory('Pilatus 2M CdTe')
|
|
272
|
+
sxrddet.poni1 = 0.1
|
|
273
|
+
sxrddet.poni2 = 0.1
|
|
274
|
+
sxrddet.rot1 = np.pi/4
|
|
275
|
+
sxrddet.rot2 = np.pi/5
|
|
276
|
+
sxrddet.rot3 = np.pi/6
|
|
277
|
+
sxrddet.dist = 1.5
|
|
278
|
+
sxrddet.setAzimuthalReference(np.deg2rad(90.))
|
|
279
|
+
|
|
280
|
+
# pixel coordinates:
|
|
281
|
+
p1 = np.arange(sxrddet.detector.shape[1] ) + 0.5 # pixel center
|
|
282
|
+
p2 = np.arange(sxrddet.detector.shape[0] ) + 0.5
|
|
283
|
+
p12 = np.moveaxis(np.array(np.meshgrid(p1,p2)),0, -1)[:,:,::-1]
|
|
284
|
+
# this seems to be overcomplicated... is there a better method?
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def checkPixel_sxrd():
|
|
288
|
+
gamma, delta = sxrddet.surfaceAngles(np.deg2rad(0.1))
|
|
289
|
+
p12_conv = sxrddet.pixelsSurfaceAngles(gamma, delta, np.deg2rad(0.1))
|
|
290
|
+
return np.nanmax(np.abs(p12 - p12_conv))
|
|
291
|
+
#return np.allclose(p12, p12_conv, atol=1e-5)
|
|
292
|
+
|
|
293
|
+
def checkPixel_tth():
|
|
294
|
+
tth = sxrddet.twoThetaArray()
|
|
295
|
+
chi = sxrddet.chiArray()
|
|
296
|
+
p12_conv = sxrddet.pixelsTthChi(tth, chi)
|
|
297
|
+
return np.nanmax(np.abs(p12 - p12_conv))
|
|
298
|
+
|
|
299
|
+
checkPixel = checkPixel_sxrd
|
|
300
|
+
|
|
301
|
+
sxrddet.poni2 = 0.0
|
|
302
|
+
for p1 in np.linspace(-5,5,20):
|
|
303
|
+
sxrddet.poni1 = p1
|
|
304
|
+
maxerr = checkPixel()
|
|
305
|
+
print(f"Max numerical error at poni1 = {p1} m: {maxerr}")
|
|
306
|
+
sxrddet.poni1 = 0.0
|
|
307
|
+
for p2 in np.linspace(-5,5,20):
|
|
308
|
+
sxrddet.poni2 = p2
|
|
309
|
+
maxerr = checkPixel()
|
|
310
|
+
print(f"Max numerical error at poni2 = {p2} m: {maxerr}")
|
|
311
|
+
|
|
312
|
+
# test rot1:
|
|
313
|
+
for r1 in np.linspace(0,np.pi,8):
|
|
314
|
+
sxrddet.rot1 = r1
|
|
315
|
+
maxerr = checkPixel()
|
|
316
|
+
print(f"Max numerical error at rot1 = {np.rad2deg(r1)} deg: {maxerr}")
|
|
317
|
+
sxrddet.rot1 = np.pi/4
|
|
318
|
+
for r2 in np.linspace(0,np.pi,8):
|
|
319
|
+
sxrddet.rot2 = r2
|
|
320
|
+
maxerr = checkPixel()
|
|
321
|
+
print(f"Max numerical error at rot2 = {np.rad2deg(r2)} deg: {maxerr}")
|
|
322
|
+
|
|
323
|
+
sxrddet.rot2 = np.pi/4
|
|
324
|
+
for r3 in np.linspace(0,np.pi,8):
|
|
325
|
+
sxrddet.rot3 = r3
|
|
326
|
+
maxerr = checkPixel()
|
|
327
|
+
print(f"Max numerical error at rot3 = {np.rad2deg(r3)} deg: {maxerr}")
|
|
328
|
+
sxrddet.rot3 = np.pi/4
|
|
329
|
+
|
|
330
|
+
for d in np.linspace(0.001,10,5):
|
|
331
|
+
sxrddet.dist = d
|
|
332
|
+
maxerr = checkPixel()
|
|
333
|
+
print(f"Max numerical error at dist = {d} m: {maxerr}")
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
"""
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# /*##########################################################################
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020-2024 Timo Fuchs
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
|
14
|
+
# all copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
# THE SOFTWARE.
|
|
23
|
+
#
|
|
24
|
+
# ###########################################################################*/
|
|
25
|
+
__author__ = "Timo Fuchs"
|
|
26
|
+
__copyright__ = "Copyright 2020-2024 Timo Fuchs"
|
|
27
|
+
__license__ = "MIT License"
|
|
28
|
+
__version__ = "1.0.0"
|
|
29
|
+
__maintainer__ = "Timo Fuchs"
|
|
30
|
+
__email__ = "fuchs@physik.uni-kiel.de"
|
|
31
|
+
|
|
32
|
+
import unittest
|
|
33
|
+
|
|
34
|
+
from .. import HKLVlieg
|
|
35
|
+
from ... import util
|
|
36
|
+
|
|
37
|
+
import numpy as np
|
|
38
|
+
import os
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TestLattice(unittest.TestCase):
|
|
42
|
+
|
|
43
|
+
def testCreateLattice(self):
|
|
44
|
+
lat = HKLVlieg.Lattice([3.9242, 3.9242, 3.9242] ,[90.0000 ,90.0000, 120.0000])
|
|
45
|
+
self.assertTrue(np.allclose([3.9242, 3.9242, 3.9242], lat.a))
|
|
46
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 120.0000]), lat.alpha))
|
|
47
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 60.0000]), lat.beta))
|
|
48
|
+
self.assertTrue(np.allclose([1.84883478, 1.84883478, 1.60113789], lat.b))
|
|
49
|
+
|
|
50
|
+
lat.setLattice([3.9242, 3.9242, 3.9242] ,[90.0000 ,90.0000, 120.0000])
|
|
51
|
+
self.assertTrue(np.allclose([3.9242, 3.9242, 3.9242], lat.a))
|
|
52
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 120.0000]), lat.alpha))
|
|
53
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 60.0000]), lat.beta))
|
|
54
|
+
self.assertTrue(np.allclose([1.84883478, 1.84883478, 1.60113789], lat.b))
|
|
55
|
+
|
|
56
|
+
lat.a = [3.9242, 3.9242, 3.9242]
|
|
57
|
+
self.assertTrue(np.allclose([3.9242, 3.9242, 3.9242], lat.a))
|
|
58
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 120.0000]), lat.alpha))
|
|
59
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 60.0000]), lat.beta))
|
|
60
|
+
self.assertTrue(np.allclose([1.84883478, 1.84883478, 1.60113789], lat.b))
|
|
61
|
+
|
|
62
|
+
lat.alpha = np.deg2rad([90.0000 ,90.0000, 120.0000])
|
|
63
|
+
self.assertTrue(np.allclose([3.9242, 3.9242, 3.9242], lat.a))
|
|
64
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 120.0000]), lat.alpha))
|
|
65
|
+
self.assertTrue(np.allclose(np.deg2rad([90.0000 ,90.0000, 60.0000]), lat.beta))
|
|
66
|
+
self.assertTrue(np.allclose([1.84883478, 1.84883478, 1.60113789], lat.b))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def testIsReciprocal(self):
|
|
70
|
+
|
|
71
|
+
lat = HKLVlieg.Lattice([3.9242, 6.9242, 2.9242] ,[100.0000 ,90.0000, 120.0000])
|
|
72
|
+
|
|
73
|
+
xyz_rel = (np.arange(100*3).reshape((3,100)) - 150) / 10.
|
|
74
|
+
hkl = (np.arange(100*3).reshape((3,100)) - 150) / 10.
|
|
75
|
+
|
|
76
|
+
phase = 2*np.pi * np.sum(xyz_rel*hkl,axis=0)
|
|
77
|
+
|
|
78
|
+
xyz_cart = lat.directVectorCart(xyz_rel.T)
|
|
79
|
+
self.assertTrue(np.allclose(xyz_cart, lat.R_mat @ xyz_rel))
|
|
80
|
+
|
|
81
|
+
Q_cart = lat.reciprocalVectorCart(hkl.T)
|
|
82
|
+
self.assertTrue(np.allclose(Q_cart, lat.B_mat @ hkl))
|
|
83
|
+
|
|
84
|
+
phase_lat = np.sum(xyz_cart*Q_cart,axis=0)
|
|
85
|
+
|
|
86
|
+
self.assertTrue(np.allclose(phase_lat, phase))
|
|
87
|
+
|
|
88
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Fe3O4(001)
|
|
2
|
+
return
|
|
3
|
+
8.397 8.397 8.397 90.0 90.0 90.0
|
|
4
|
+
O 0.98789 0.48789 0.754 0.7 0.7 1
|
|
5
|
+
O 0.26211 0.76211 0.754 0.7 0.7 1
|
|
6
|
+
O 0.48789 0.98789 0.754 0.7 0.7 1
|
|
7
|
+
O 0.76211 0.26211 0.754 0.7 0.7 1
|
|
8
|
+
Fe 0.5 0.75 0.75 0.678 0.678 1
|
|
9
|
+
Fe 0.25 0 0.75 0.678 0.678 1
|
|
10
|
+
Fe 0 0.25 0.75 0.678 0.678 1
|
|
11
|
+
Fe 0.75 0.5 0.75 0.678 0.678 1
|
|
12
|
+
O 0.23789 0.23789 0.746 0.7 0.7 1
|
|
13
|
+
O 0.01211 0.01211 0.746 0.7 0.7 1
|
|
14
|
+
O 0.51211 0.51211 0.746 0.7 0.7 1
|
|
15
|
+
O 0.73789 0.73789 0.746 0.7 0.7 1
|
|
16
|
+
Fe 0.625 0.125 0.625 0.583 0.583 1
|
|
17
|
+
Fe 0.125 0.625 0.625 0.583 0.583 1
|
|
18
|
+
O 0.51211 0.73789 0.504 0.7 0.7 1
|
|
19
|
+
O 0.01211 0.23789 0.504 0.7 0.7 1
|
|
20
|
+
O 0.73789 0.51211 0.504 0.7 0.7 1
|
|
21
|
+
O 0.23789 0.01211 0.504 0.7 0.7 1
|
|
22
|
+
Fe 0.75 0.75 0.5 0.678 0.678 1
|
|
23
|
+
Fe 0.25 0.25 0.5 0.678 0.678 1
|
|
24
|
+
Fe 0.5 0.5 0.5 0.678 0.678 1
|
|
25
|
+
Fe 0 0 0.5 0.678 0.678 1
|
|
26
|
+
O 0.76211 0.98789 0.496 0.7 0.7 1
|
|
27
|
+
O 0.26211 0.48789 0.496 0.7 0.7 1
|
|
28
|
+
O 0.98789 0.76211 0.496 0.7 0.7 1
|
|
29
|
+
O 0.48789 0.26211 0.496 0.7 0.7 1
|
|
30
|
+
Fe 0.875 0.375 0.375 0.583 0.583 1
|
|
31
|
+
Fe 0.375 0.875 0.375 0.583 0.583 1
|
|
32
|
+
O 0.48789 0.48789 0.254 0.7 0.7 1
|
|
33
|
+
O 0.76211 0.76211 0.254 0.7 0.7 1
|
|
34
|
+
O 0.98789 0.98789 0.254 0.7 0.7 1
|
|
35
|
+
O 0.26211 0.26211 0.254 0.7 0.7 1
|
|
36
|
+
Fe 0.5 0.25 0.25 0.678 0.678 1
|
|
37
|
+
Fe 0.75 0 0.25 0.678 0.678 1
|
|
38
|
+
Fe 0.25 0.5 0.25 0.678 0.678 1
|
|
39
|
+
Fe 0 0.75 0.25 0.678 0.678 1
|
|
40
|
+
O 0.01211 0.51211 0.246 0.7 0.7 1
|
|
41
|
+
O 0.51211 0.01211 0.246 0.7 0.7 1
|
|
42
|
+
O 0.73789 0.23789 0.246 0.7 0.7 1
|
|
43
|
+
O 0.23789 0.73789 0.246 0.7 0.7 1
|
|
44
|
+
Fe 0.125 0.125 0.125 0.583 0.583 1
|
|
45
|
+
Fe 0.625 0.625 0.125 0.583 0.583 1
|
|
46
|
+
O 0.01211 0.73789 0.004 0.7 0.7 1
|
|
47
|
+
O 0.73789 0.01211 0.004 0.7 0.7 1
|
|
48
|
+
O 0.23789 0.51211 0.004 0.7 0.7 1
|
|
49
|
+
O 0.51211 0.23789 0.004 0.7 0.7 1
|
|
50
|
+
Fe 0 0.5 0 0.678 0.678 1
|
|
51
|
+
Fe 0.75 0.25 0 0.678 0.678 1
|
|
52
|
+
Fe 0.25 0.75 0 0.678 0.678 1
|
|
53
|
+
Fe 0.5 0 0 0.678 0.678 1
|
|
54
|
+
O 0.98789 0.26211 -0.004 0.7 0.7 1
|
|
55
|
+
O 0.26211 0.98789 -0.004 0.7 0.7 1
|
|
56
|
+
O 0.48789 0.76211 -0.004 0.7 0.7 1
|
|
57
|
+
O 0.76211 0.48789 -0.004 0.7 0.7 1
|
|
58
|
+
Fe 0.375 0.375 -0.125 0.583 0.583 1
|
|
59
|
+
Fe 0.875 0.875 -0.125 0.583 0.583 1
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Pt(100) larger unit cell for compatibility
|
|
2
|
+
return
|
|
3
|
+
3.9242 3.9242 3.9242 90.0000 90.0000 90.0000
|
|
4
|
+
Pt 0.00000 0.00000 -1.00000 0.4353 0.4353 1.0000
|
|
5
|
+
Pt 0.50000 0.50000 -1.00000 0.4353 0.4353 1.0000
|
|
6
|
+
Pt 0.50000 0.00000 -0.50000 0.4353 0.4353 1.0000
|
|
7
|
+
Pt 0.00000 0.50000 -0.50000 0.4353 0.4353 1.0000
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Pt(310)
|
|
2
|
+
return
|
|
3
|
+
6.2047 3.9242 6.2047 90.000 90.000 90.000
|
|
4
|
+
Pt 0.0000 0.0000 0.0 0.4489 0.4489 1
|
|
5
|
+
Pt 0.3000 0.5000 -0.1 0.4489 0.4489 1
|
|
6
|
+
Pt 0.6000 0.0000 -0.2 0.4489 0.4489 1
|
|
7
|
+
Pt 0.9000 0.5000 -0.3 0.4489 0.4489 1
|
|
8
|
+
Pt 0.2000 0.0000 -0.4 0.4489 0.4489 1
|
|
9
|
+
Pt 0.5000 0.5000 -0.5 0.4489 0.4489 1
|
|
10
|
+
Pt 0.8000 0.0000 -0.6 0.4489 0.4489 1
|
|
11
|
+
Pt 0.1000 0.5000 -0.7 0.4489 0.4489 1
|
|
12
|
+
Pt 0.4000 0.0000 -0.8 0.4489 0.4489 1
|
|
13
|
+
Pt 0.7000 0.5000 -0.9 0.4489 0.4489 1
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Pt3O4(100) simple cubic version
|
|
2
|
+
// Muller, Olaf ; Roy, Rustum: Formation and stability of the platinum and rhodium oxides at high oxygen pressures and the structures of Pt3O4, β-PtO2 and RhO2. In: Journal of The Less-Common Metals Bd. 16 (1968), Nr. 2, S. 129–146
|
|
3
|
+
// Nomiyama, Ricardo K. ; Piotrowski, Maurício J. ; Da Silva, Juarez L.F.: Bulk structures of PtO and PtO2 from density functional calculations. In: Physical Review B - Condensed Matter and Materials Physics Bd. 84 (2011), Nr. 10, S. 2–5
|
|
4
|
+
return
|
|
5
|
+
5.5580 5.5580 5.5580 90.0000 90.0000 90.0000
|
|
6
|
+
Pt 0.50000 0.25000 0.00000000 0.4353 0.4353 1.0000
|
|
7
|
+
Pt 0.50000 0.75000 0.00000000 0.4353 0.4353 1.0000
|
|
8
|
+
Pt 0.00000 0.50000 0.75000000 0.4353 0.4353 1.0000
|
|
9
|
+
Pt 0.00000 0.50000 0.25000000 0.4353 0.4353 1.0000
|
|
10
|
+
Pt 0.75000 0.00000 0.50000000 0.4353 0.4353 1.0000
|
|
11
|
+
Pt 0.25000 0.00000 0.50000000 0.4353 0.4353 1.0000
|
|
12
|
+
O 0.75000 0.25000 0.25000000 0.4353 0.4353 1.0000
|
|
13
|
+
O 0.25000 0.25000 0.75000000 0.4353 0.4353 1.0000
|
|
14
|
+
O 0.25000 0.75000 0.25000000 0.4353 0.4353 1.0000
|
|
15
|
+
O 0.75000 0.75000 0.75000000 0.4353 0.4353 1.0000
|
|
16
|
+
O 0.25000 0.75000 0.75000000 0.4353 0.4353 1.0000
|
|
17
|
+
O 0.75000 0.75000 0.25000000 0.4353 0.4353 1.0000
|
|
18
|
+
O 0.25000 0.25000 0.25000000 0.4353 0.4353 1.0000
|
|
19
|
+
O 0.75000 0.25000 0.75000000 0.4353 0.4353 1.0000
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// PtO(001) tetragonal "PtS"
|
|
2
|
+
// from McBride, J. R. ; Graham, G. W. ; Peters, C. R. ; Weber, W. H.: Growth and characterization of reactively sputtered thin-film platinum oxides. In: Journal of Applied Physics Bd. 69 (1991), Nr. 3, S. 1596–1604
|
|
3
|
+
// Moore, Walter J. ; Pauling, Linus: The Crystal Structures of the Tetragonal Monoxides of Lead, Tin, Palladium, and Platinum. In: Journal of the American Chemical Society Bd. 63 (1941), Nr. 5, S. 1392–1394
|
|
4
|
+
return
|
|
5
|
+
3.0777 3.0777 5.3400 90.0000 90.0000 90.0000
|
|
6
|
+
O2- 0.00000 0.00000 -0.75000 0.4353 0.4353 1.0000
|
|
7
|
+
Pt2+ 0.00000 0.50000 -0.50000 0.4353 0.4353 1.0000
|
|
8
|
+
O2- 0.00000 0.00000 -0.25000 0.4353 0.4353 1.0000
|
|
9
|
+
Pt2+ 0.50000 0.00000 0.00000 0.4353 0.4353 1.0000
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// PtO(010) tetragonal "PtS"
|
|
2
|
+
// from McBride, J. R. ; Graham, G. W. ; Peters, C. R. ; Weber, W. H.: Growth and characterization of reactively sputtered thin-film platinum oxides. In: Journal of Applied Physics Bd. 69 (1991), Nr. 3, S. 1596–1604
|
|
3
|
+
// Moore, Walter J. ; Pauling, Linus: The Crystal Structures of the Tetragonal Monoxides of Lead, Tin, Palladium, and Platinum. In: Journal of the American Chemical Society Bd. 63 (1941), Nr. 5, S. 1392–1394
|
|
4
|
+
return
|
|
5
|
+
3.0777 5.3400 3.0777 90.0000 90.0000 90.0000
|
|
6
|
+
O2- 0.00000 0.75000 0.00000 0.4353 0.4353 1.0000
|
|
7
|
+
Pt2+ 0.50000 0.50000 0.00000 0.4353 0.4353 1.0000
|
|
8
|
+
O2- 0.00000 0.25000 0.00000 0.4353 0.4353 1.0000
|
|
9
|
+
Pt4+ 0.00000 0.00000 -0.50000 0.4353 0.4353 1.0000
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// PtO(001) tetragonal "PtS"
|
|
2
|
+
// from McBride, J. R. ; Graham, G. W. ; Peters, C. R. ; Weber, W. H.: Growth and characterization of reactively sputtered thin-film platinum oxides. In: Journal of Applied Physics Bd. 69 (1991), Nr. 3, S. 1596–1604
|
|
3
|
+
// Moore, Walter J. ; Pauling, Linus: The Crystal Structures of the Tetragonal Monoxides of Lead, Tin, Palladium, and Platinum. In: Journal of the American Chemical Society Bd. 63 (1941), Nr. 5, S. 1392–1394
|
|
4
|
+
return
|
|
5
|
+
5.3400 3.0777 3.0777 90.0000 90.0000 90.0000
|
|
6
|
+
O2- 0.75000 0.50000 -0.50000 0.4353 0.4353 1.0000
|
|
7
|
+
Pt2+ 0.50000 0.50000 0.00000 0.4353 0.4353 1.0000
|
|
8
|
+
O2- 0.25000 0.50000 -0.50000 0.4353 0.4353 1.0000
|
|
9
|
+
Pt2+ 0.00000 0.0000 -0.50000 0.4353 0.4353 1.0000
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# /*##########################################################################
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020-2024 Timo Fuchs
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
|
14
|
+
# all copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
# THE SOFTWARE.
|
|
23
|
+
#
|
|
24
|
+
# ###########################################################################*/
|
|
25
|
+
__author__ = "Timo Fuchs"
|
|
26
|
+
__copyright__ = "Copyright 2020-2024 Timo Fuchs"
|
|
27
|
+
__license__ = "MIT License"
|
|
28
|
+
__version__ = "1.0.0"
|
|
29
|
+
__maintainer__ = "Timo Fuchs"
|
|
30
|
+
__email__ = "fuchs@physik.uni-kiel.de"
|
|
31
|
+
|
|
32
|
+
import os
|
|
33
|
+
import glob
|
|
34
|
+
|
|
35
|
+
_uc_path = os.path.dirname(__file__)
|
|
36
|
+
|
|
37
|
+
_files_bulk = glob.glob(os.path.join(_uc_path,"*.bul"))
|
|
38
|
+
_files_surf = glob.glob(os.path.join(_uc_path,"*.sur"))
|
|
39
|
+
_files_xtal = glob.glob(os.path.join(_uc_path,"*.xtal"))
|
|
40
|
+
|
|
41
|
+
availablebulk = [os.path.splitext(os.path.basename(bf))[0] for bf in _files_bulk]
|
|
42
|
+
availablesur = [os.path.splitext(os.path.basename(bf))[0] for bf in _files_surf]
|
|
43
|
+
availablextal = [os.path.splitext(os.path.basename(bf))[0] for bf in _files_xtal]
|
|
44
|
+
|
|
45
|
+
BULFILES = dict( (os.path.splitext(os.path.basename(bf))[0].lower(), bf) for bf in _files_bulk)
|
|
46
|
+
SURFILES = dict( (os.path.splitext(os.path.basename(bf))[0].lower(), bf) for bf in _files_surf)
|
|
47
|
+
XTALFILES = dict( (os.path.splitext(os.path.basename(bf))[0].lower(), bf) for bf in _files_xtal)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def unitcell(name: str):
|
|
51
|
+
from .. import CTRcalc
|
|
52
|
+
name = name.lower()
|
|
53
|
+
if name in BULFILES:
|
|
54
|
+
return CTRcalc.UnitCell.fromBULfile(BULFILES[name])
|
|
55
|
+
elif name in SURFILES:
|
|
56
|
+
return CTRcalc.UnitCell.fromSURfile(SURFILES[name])
|
|
57
|
+
else:
|
|
58
|
+
raise ValueError("Unit cell %s is not available." % name)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def crystal(name: str):
|
|
62
|
+
from .. import CTRcalc
|
|
63
|
+
name = name.lower()
|
|
64
|
+
if name in XTALFILES:
|
|
65
|
+
return CTRcalc.SXRDCrystal.fromFile(XTALFILES[name])
|
|
66
|
+
else:
|
|
67
|
+
raise ValueError("Crystal %s is not available." % name)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// alpha-PtO2(0001). A single O-Pt-O trilayer with Pt at 000.
|
|
2
|
+
return
|
|
3
|
+
3.1000 3.1000 4.1600 90.0000 90.0000 120.0000
|
|
4
|
+
O2- 0.33333 0.66666 0.25000 0.4350 0.4350 1.0000
|
|
5
|
+
Pt4+ 0.00000 0.00000 0.00000 0.4350 0.4350 1.0000
|
|
6
|
+
O2- 0.66666 0.33333 -0.25000 0.4350 0.4350 1.0000
|