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
orgui/app/qutils.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
from silx.gui import qt
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def messagebox_detailed_message(parent, title, text, detailed_text, icon, buttons=qt.QMessageBox.Ok):
|
|
36
|
+
diag = qt.QMessageBox(icon, title, text, buttons, parent)
|
|
37
|
+
diag.setDetailedText(detailed_text)
|
|
38
|
+
return diag.exec()
|
|
39
|
+
|
|
40
|
+
def critical_detailed_message(parent, title, text, detailed_text, buttons=qt.QMessageBox.Ok):
|
|
41
|
+
return messagebox_detailed_message(parent, title, text, detailed_text, qt.QMessageBox.Critical, buttons=buttons)
|
|
42
|
+
|
|
43
|
+
def warning_detailed_message(parent, title, text, detailed_text, buttons=qt.QMessageBox.Ok):
|
|
44
|
+
return messagebox_detailed_message(parent, title, text, detailed_text, qt.QMessageBox.Warning, buttons=buttons)
|
|
45
|
+
|
|
46
|
+
def information_detailed_message(parent, title, text, detailed_text, buttons=qt.QMessageBox.Ok):
|
|
47
|
+
return messagebox_detailed_message(parent, title, text, detailed_text, qt.QMessageBox.Information, buttons=buttons)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
__all__ = ['backends', 'scans']
|
|
@@ -0,0 +1,157 @@
|
|
|
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 numpy as np
|
|
33
|
+
|
|
34
|
+
from .scans import Scan
|
|
35
|
+
from datetime import datetime
|
|
36
|
+
import pytz
|
|
37
|
+
|
|
38
|
+
# --- parse h5node name and return the scan number and name ---
|
|
39
|
+
|
|
40
|
+
def parseCH5523(obj):
|
|
41
|
+
ddict = dict()
|
|
42
|
+
scanname = obj.local_name
|
|
43
|
+
scanno = int(scanname.split('_')[-1])
|
|
44
|
+
ddict['scanno'] = scanno
|
|
45
|
+
ddict['name'] = obj.local_name.strip('/')
|
|
46
|
+
return ddict
|
|
47
|
+
|
|
48
|
+
def parseP212H5(obj):
|
|
49
|
+
ddict = dict()
|
|
50
|
+
scanname = obj.basename
|
|
51
|
+
scanno, subscanno = scanname.split('.')
|
|
52
|
+
ddict['scanno'] = int(scanno)
|
|
53
|
+
ddict['name'] = obj.local_name
|
|
54
|
+
return ddict
|
|
55
|
+
|
|
56
|
+
def parseID31Bliss(obj):
|
|
57
|
+
ddict = dict()
|
|
58
|
+
scanname = obj.local_name
|
|
59
|
+
scansuffix = scanname.split('_')[-1]
|
|
60
|
+
scanname_nosuffix = '_'.join(scanname.split('_')[:-1])
|
|
61
|
+
scanno, subscanno = scansuffix.split('.')
|
|
62
|
+
ddict['scanno'] = int(scanno)
|
|
63
|
+
ddict['name'] = obj.local_name
|
|
64
|
+
return ddict
|
|
65
|
+
|
|
66
|
+
# orgui will search for these counters in the Scan object and copy them into the database, if available
|
|
67
|
+
auxillary_counters = ['current', 'potential', 'exposure_time', 'elapsed_time','time', 'srcur', 'mondio', 'epoch']
|
|
68
|
+
|
|
69
|
+
# assign the name parser to the beamtime identifiers:
|
|
70
|
+
|
|
71
|
+
scannoConverter = {'ch5523': parseCH5523,
|
|
72
|
+
'20190017': parseP212H5,
|
|
73
|
+
'ch5700': parseID31Bliss,
|
|
74
|
+
'20200028': parseP212H5,
|
|
75
|
+
'ch5918' : parseID31Bliss,
|
|
76
|
+
'P212_default' : parseP212H5,
|
|
77
|
+
'id31_default' : parseID31Bliss
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# --- dates of the beamtimes. Used to identify the beamtimes from the files ---
|
|
82
|
+
|
|
83
|
+
beamtimes = {'ch5523': (datetime(2018, 9, 22), datetime(2018, 10, 5)),
|
|
84
|
+
'20190017': (datetime(2019, 12, 8), datetime(2019, 12, 24)),
|
|
85
|
+
'ch5700': (datetime(2020, 11, 10), datetime(2020, 11, 27)),
|
|
86
|
+
'20200028': (datetime(2021, 4, 27), datetime(2021, 5, 10)),
|
|
87
|
+
'ch5918' : (datetime(2021, 7, 18), datetime(2021, 8, 1)),
|
|
88
|
+
'P212_default' : (datetime(1902, 7, 18), datetime(1903, 8, 1)),
|
|
89
|
+
'id31_default' : (datetime(2021, 8, 2), datetime(2500, 1, 1)) # all data after 2021/8/2 is automatically detected as ID31 data. You can change this behaviour by changing the beamtime dates.
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def localize(dt):
|
|
95
|
+
if dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None:
|
|
96
|
+
grenobletime = pytz.timezone('Europe/Paris')
|
|
97
|
+
return grenobletime.localize(dt)
|
|
98
|
+
else:
|
|
99
|
+
return dt
|
|
100
|
+
|
|
101
|
+
def getBeamtimeId(dt):
|
|
102
|
+
for bt in beamtimes:
|
|
103
|
+
start, end = beamtimes[bt]
|
|
104
|
+
if localize(start) <= localize(dt) <= localize(end):
|
|
105
|
+
return bt
|
|
106
|
+
else:
|
|
107
|
+
raise Exception("Didn't find matching beamtime for date %s" % dt.ctime())
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# add actual backends here, which perform the file reads:
|
|
111
|
+
# They must implement scans.Scan
|
|
112
|
+
|
|
113
|
+
from .beamline.id31_tools import BlissScan_EBS, Fastscan, BlissScan
|
|
114
|
+
from .beamline.P212_tools import H5Fastsweep
|
|
115
|
+
|
|
116
|
+
fscans = {'ch5523': BlissScan,
|
|
117
|
+
'20190017': H5Fastsweep, #probably doesn't work since image names are not saved
|
|
118
|
+
'ch5700': BlissScan_EBS,
|
|
119
|
+
'20200028': H5Fastsweep,
|
|
120
|
+
'ch5918' : BlissScan_EBS,
|
|
121
|
+
'P212_default' : H5Fastsweep,
|
|
122
|
+
'id31_default' : BlissScan_EBS
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def openScan(btid, ddict):
|
|
127
|
+
fscancls = fscans[btid]
|
|
128
|
+
|
|
129
|
+
# ideally, now the scan should only be opened with:
|
|
130
|
+
# fscan = fscancls(ddict['file'], ddict['scanno'])
|
|
131
|
+
# but this doesn't always work. So handle special cases here
|
|
132
|
+
|
|
133
|
+
if btid == 'ch5523':
|
|
134
|
+
fscan = fscancls(ddict['file'],ddict['name'])
|
|
135
|
+
|
|
136
|
+
if ddict['name'].startswith('ascan') and 'Pt111_3' in ddict['file']:
|
|
137
|
+
if fscan.axisname == 'mu':
|
|
138
|
+
mu = fscan.mu - 0.055 # misalignment!
|
|
139
|
+
fscan.axis = mu
|
|
140
|
+
fscan.mu = mu
|
|
141
|
+
print("Correct mu misalignment 0.055 deg, Pt111_3")
|
|
142
|
+
|
|
143
|
+
elif btid == '20190017' or btid == '20200028' or btid == 'P212_default':
|
|
144
|
+
fscan = fscancls(ddict['file'],ddict['scanno'])
|
|
145
|
+
elif btid == 'ch5700' or btid == 'ch5918' or btid == 'id31_default':
|
|
146
|
+
if 'node' in ddict:
|
|
147
|
+
fscan = fscancls(ddict['node'],ddict['scanno'], loadimg=False)
|
|
148
|
+
else:
|
|
149
|
+
fscan = fscancls(ddict['file'],ddict['scanno'], loadimg=False)
|
|
150
|
+
else:
|
|
151
|
+
try:
|
|
152
|
+
fscan = fscancls(ddict['file'], ddict['scanno'])
|
|
153
|
+
except Exception:
|
|
154
|
+
raise ValueError("Did not find matching scan in backends for beamtime id %s" % btid)
|
|
155
|
+
return fscan
|
|
156
|
+
|
|
157
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
"""ID31 beamline code.
|
|
4
|
+
|
|
5
|
+
Used for this software with permission from Jakub Drnec
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
class ID31DiffractLinTilt(object):
|
|
12
|
+
"""
|
|
13
|
+
ID31DiffractLinTilt: transforms linear motors into tilt motor (angular)
|
|
14
|
+
|
|
15
|
+
Some angular motors are mechanically moved through linear translations.
|
|
16
|
+
|
|
17
|
+
muoffset has to be set for each experiment since it is dependent on
|
|
18
|
+
the diffractometer alignment!
|
|
19
|
+
|
|
20
|
+
Adapted version from the ID31 beamline code.
|
|
21
|
+
"""
|
|
22
|
+
def __init__(self, *args, **kwargs):
|
|
23
|
+
self.config = {}
|
|
24
|
+
self.config['a'] = 938
|
|
25
|
+
self.config['b'] = 400
|
|
26
|
+
self.config['muoffset'] = -0.06442416994811659
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def a(self):
|
|
30
|
+
return self.config.get("a", float)
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def b(self):
|
|
34
|
+
return self.config.get("b", float)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def muoffset(self):
|
|
38
|
+
return self.config.get("muoffset", float)
|
|
39
|
+
|
|
40
|
+
def c(self, a=None, b=None):
|
|
41
|
+
a = self.a if a is None else a
|
|
42
|
+
b = self.b if b is None else b
|
|
43
|
+
return np.sqrt(np.square(a) + np.square(b))
|
|
44
|
+
|
|
45
|
+
def d(self, a=None, b=None):
|
|
46
|
+
a = self.a if a is None else a
|
|
47
|
+
b = self.b if b is None else b
|
|
48
|
+
return np.arctan(b / a)
|
|
49
|
+
|
|
50
|
+
def calc_from_real(self, positions_dict):
|
|
51
|
+
a, b = self.a, self.b
|
|
52
|
+
c, d = self.c(a, b), self.d(a, b)
|
|
53
|
+
a2, c2 = np.square(a), np.square(c)
|
|
54
|
+
linear = positions_dict["linear"]
|
|
55
|
+
bc2 = np.square(b + linear)
|
|
56
|
+
tilt = np.arccos((a2 + c2 - bc2) / (2 * a * c)) - d
|
|
57
|
+
return dict(tilt=np.rad2deg(tilt))
|
|
58
|
+
|
|
59
|
+
def calc_to_real(self, positions_dict):
|
|
60
|
+
a, b = self.a, self.b
|
|
61
|
+
c, d = self.c(a, b), self.d(a, b)
|
|
62
|
+
a2, c2 = np.square(a), np.square(c)
|
|
63
|
+
tilt = np.deg2rad(positions_dict["tilt"])
|
|
64
|
+
bc = np.sqrt(a2 + c2 - 2 * a * c * np.cos(tilt + d))
|
|
65
|
+
linear = bc - b
|
|
66
|
+
return dict(linear=linear)
|
|
67
|
+
|
|
68
|
+
def linai_to_mu(self,linai):
|
|
69
|
+
positions = {'linear' : linai}
|
|
70
|
+
tilt = self.calc_from_real(positions)
|
|
71
|
+
return tilt["tilt"] - self.muoffset
|
|
72
|
+
|
|
73
|
+
def mu_to_linai(self,mu):
|
|
74
|
+
ai = mu + self.muoffset #np.linspace(-1.0,1,11) + muoffset
|
|
75
|
+
tilts = {'tilt' : ai}
|
|
76
|
+
pos = self.calc_to_real(tilts)
|
|
77
|
+
return pos['linear']
|