mxcubecore 1.382.0__py3-none-any.whl → 1.384.0__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 mxcubecore might be problematic. Click here for more details.
- mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py +235 -197
- mxcubecore/HardwareObjects/ICATLIMS.py +351 -300
- mxcubecore/HardwareObjects/MiniDiff.py +8 -5
- mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +4 -0
- {mxcubecore-1.382.0.dist-info → mxcubecore-1.384.0.dist-info}/METADATA +1 -1
- {mxcubecore-1.382.0.dist-info → mxcubecore-1.384.0.dist-info}/RECORD +9 -11
- mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py +0 -40
- mxcubecore/HardwareObjects/ESRF/ID29EnergyScan.py +0 -77
- {mxcubecore-1.382.0.dist-info → mxcubecore-1.384.0.dist-info}/COPYING +0 -0
- {mxcubecore-1.382.0.dist-info → mxcubecore-1.384.0.dist-info}/COPYING.LESSER +0 -0
- {mxcubecore-1.382.0.dist-info → mxcubecore-1.384.0.dist-info}/WHEEL +0 -0
|
@@ -1,16 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Project name: MXCuBE
|
|
4
|
+
# https://github.com/mxcube.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of MXCuBE software.
|
|
7
|
+
#
|
|
8
|
+
# MXCuBE is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# MXCuBE is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU Lesser General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Lesser Public License
|
|
19
|
+
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
Example xml_ configuration:
|
|
23
|
+
|
|
24
|
+
.. code-block:: xml
|
|
25
|
+
|
|
26
|
+
<object class="ESRF.ESRFXRFSpectrum">
|
|
27
|
+
<object href="/bliss" role="controller"/>
|
|
28
|
+
<cfgfile>/users/blissadm/local/beamline_configuration/misc/15keV.cfg</cfgfile>
|
|
29
|
+
<default_integration_time>3</default_integration_time>
|
|
30
|
+
<default_energy_range>[2.0, 15]</default_energy_range>
|
|
31
|
+
<cfg_energies>[15]</cfg_energies>
|
|
32
|
+
</object>
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
__copyright__ = """ Copyright © by the MXCuBE collaboration """
|
|
36
|
+
__license__ = "LGPLv3+"
|
|
37
|
+
|
|
6
38
|
|
|
7
|
-
|
|
8
|
-
# to run chooch in shell
|
|
39
|
+
import logging
|
|
9
40
|
import subprocess
|
|
10
41
|
import time
|
|
42
|
+
from datetime import datetime as dt
|
|
43
|
+
from pathlib import Path
|
|
44
|
+
from shutil import copy2
|
|
45
|
+
from zoneinfo import ZoneInfo
|
|
11
46
|
|
|
12
|
-
import
|
|
13
|
-
import
|
|
47
|
+
import numpy as np
|
|
48
|
+
from gevent import event, spawn
|
|
14
49
|
|
|
15
50
|
from mxcubecore import HardwareRepository as HWR
|
|
16
51
|
from mxcubecore.HardwareObjects.abstract.AbstractEnergyScan import AbstractEnergyScan
|
|
@@ -24,9 +59,9 @@ class GetStaticParameters:
|
|
|
24
59
|
self.pars_dict = self._read_from_file(config_file)
|
|
25
60
|
|
|
26
61
|
def _read_from_file(self, config_file):
|
|
27
|
-
with open(
|
|
62
|
+
with Path(config_file).open("r") as fp:
|
|
28
63
|
array = []
|
|
29
|
-
for line in
|
|
64
|
+
for line in fp:
|
|
30
65
|
if not line.startswith("#") and self.element in line:
|
|
31
66
|
array = line.split()
|
|
32
67
|
break
|
|
@@ -39,16 +74,15 @@ class GetStaticParameters:
|
|
|
39
74
|
|
|
40
75
|
if "K" in self.edge:
|
|
41
76
|
th_energy = float(array[3]) / 1000.0
|
|
77
|
+
elif "1" in self.edge:
|
|
78
|
+
# L1
|
|
79
|
+
th_energy = float(array[6]) / 1000.0
|
|
80
|
+
elif "2" in self.edge:
|
|
81
|
+
# L2
|
|
82
|
+
th_energy = float(array[7]) / 1000.0
|
|
42
83
|
else:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
th_energy = float(array[6]) / 1000.0
|
|
46
|
-
elif "2" in self.edge:
|
|
47
|
-
# L2
|
|
48
|
-
th_energy = float(array[7]) / 1000.0
|
|
49
|
-
else:
|
|
50
|
-
# L or L3
|
|
51
|
-
th_energy = float(array[8]) / 1000.0
|
|
84
|
+
# L or L3
|
|
85
|
+
th_energy = float(array[8]) / 1000.0
|
|
52
86
|
|
|
53
87
|
# all the values are in keV
|
|
54
88
|
static_pars["edgeEnergy"] = th_energy
|
|
@@ -56,16 +90,15 @@ class GetStaticParameters:
|
|
|
56
90
|
static_pars["endEnergy"] = th_energy + 0.05
|
|
57
91
|
static_pars["findattEnergy"] = th_energy + 0.03
|
|
58
92
|
static_pars["remoteEnergy"] = th_energy + 1
|
|
59
|
-
|
|
60
|
-
except Exception as err:
|
|
61
|
-
print(err)
|
|
93
|
+
except TypeError:
|
|
62
94
|
return {}
|
|
95
|
+
return static_pars
|
|
96
|
+
return {}
|
|
63
97
|
|
|
64
98
|
|
|
65
99
|
class ESRFEnergyScan(AbstractEnergyScan):
|
|
66
100
|
def __init__(self, name):
|
|
67
101
|
super().__init__(name)
|
|
68
|
-
# self._tunable_bl = tunable_bl
|
|
69
102
|
self.ctrl = None
|
|
70
103
|
|
|
71
104
|
def execute_command(self, command_name, *args, **kwargs):
|
|
@@ -74,41 +107,44 @@ class ESRFEnergyScan(AbstractEnergyScan):
|
|
|
74
107
|
return cmd_obj(*args, wait=wait)
|
|
75
108
|
|
|
76
109
|
def init(self):
|
|
77
|
-
self.energy_obj = HWR.beamline.energy
|
|
78
|
-
self.beamsize = self.get_object_by_role("beamsize")
|
|
79
110
|
self.ctrl = self.get_object_by_role("controller")
|
|
80
|
-
self.ready_event =
|
|
111
|
+
self.ready_event = event.Event()
|
|
81
112
|
if HWR.beamline.lims is None:
|
|
82
113
|
logging.getLogger("HWR").warning(
|
|
83
114
|
"EnergyScan: you should specify the database hardware object"
|
|
84
115
|
)
|
|
85
|
-
self.scanInfo = None
|
|
86
|
-
# self._tunable_bl.energy_obj = self.energy_obj
|
|
87
116
|
|
|
88
117
|
def is_connected(self):
|
|
89
118
|
return True
|
|
90
119
|
|
|
91
|
-
def get_static_parameters(self, config_file, element, edge):
|
|
120
|
+
def get_static_parameters(self, config_file: str, element: str, edge: str) -> dict:
|
|
121
|
+
"""Get the static parameters for form the config file.
|
|
122
|
+
Args:
|
|
123
|
+
config_file(str): File to read the configuration from (full path).
|
|
124
|
+
element(str): Element acronym as in the periodic table of elements.
|
|
125
|
+
edge(str): edge line (K, L1, L2, L3)
|
|
126
|
+
"""
|
|
92
127
|
pars = GetStaticParameters(config_file, element, edge).pars_dict
|
|
93
128
|
|
|
94
|
-
|
|
95
|
-
pars["startEnergy"] +=
|
|
96
|
-
pars["endEnergy"] +=
|
|
129
|
+
offset_kev = self.get_property("offset_keV")
|
|
130
|
+
pars["startEnergy"] += offset_kev
|
|
131
|
+
pars["endEnergy"] += offset_kev
|
|
97
132
|
pars["element"] = element
|
|
98
133
|
|
|
99
134
|
return pars
|
|
100
135
|
|
|
101
136
|
def escan_prepare(self):
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
137
|
+
"""Set the nesessary equipment in position for the scan."""
|
|
138
|
+
self.ctrl.detcover.set_in()
|
|
139
|
+
self.ctrl.diffractometer.fldet_in()
|
|
140
|
+
self.ctrl.diffractometer.set_phase("DataCollection")
|
|
106
141
|
|
|
107
142
|
def escan_postscan(self):
|
|
143
|
+
"""Actions done after the scan finished."""
|
|
108
144
|
self.ctrl.diffractometer.fldet_out()
|
|
109
|
-
# self.ctrl.fluodet.OUT
|
|
110
145
|
|
|
111
146
|
def escan_cleanup(self):
|
|
147
|
+
"""Cleanup actions."""
|
|
112
148
|
self.close_fast_shutter()
|
|
113
149
|
HWR.beamline.safety_shutter.close()
|
|
114
150
|
self.emit("energyScanFailed", ())
|
|
@@ -124,12 +160,12 @@ class ESRFEnergyScan(AbstractEnergyScan):
|
|
|
124
160
|
"""Called by queue_entry.py. To be removed"""
|
|
125
161
|
self.escan_cleanup()
|
|
126
162
|
|
|
127
|
-
def
|
|
163
|
+
def store_energy_scan(self):
|
|
128
164
|
if HWR.beamline.lims is None:
|
|
129
165
|
return
|
|
130
166
|
try:
|
|
131
167
|
int(self.energy_scan_parameters["sessionId"])
|
|
132
|
-
except
|
|
168
|
+
except (TypeError, KeyError):
|
|
133
169
|
return
|
|
134
170
|
|
|
135
171
|
# remove unnecessary for ISPyB fields:
|
|
@@ -141,75 +177,66 @@ class ESRFEnergyScan(AbstractEnergyScan):
|
|
|
141
177
|
self.energy_scan_parameters.pop("directory")
|
|
142
178
|
self.energy_scan_parameters.pop("atomic_nb")
|
|
143
179
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
180
|
+
spawn(store_energy_scan_thread, HWR.beamline.lims, self.energy_scan_parameters)
|
|
181
|
+
|
|
182
|
+
def do_chooch(
|
|
183
|
+
self, elt: str, edge: str, directory: str, archive_directory: str, prefix: str
|
|
184
|
+
):
|
|
185
|
+
"""Execute peak and IP calculation with chooch.
|
|
186
|
+
Args:
|
|
187
|
+
elt(str): Element acrony as in the periodic table of elements.
|
|
188
|
+
edge(str): Edge like (K, L1, L2, L3).
|
|
189
|
+
directory(str): raw data directory (fill path).
|
|
190
|
+
archive_director(str): archive data directory (fill path).
|
|
191
|
+
prefix(str): File root prefix.
|
|
192
|
+
"""
|
|
149
193
|
self.energy_scan_parameters["endTime"] = time.strftime("%Y-%m-%d %H:%M:%S")
|
|
150
194
|
|
|
151
|
-
raw_data_file =
|
|
195
|
+
raw_data_file = Path(directory) / "data.raw"
|
|
152
196
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
raw_arch_file = os.path.join(archive_directory, (archive_prefix + "1" + ".raw"))
|
|
197
|
+
archive_prefix = f"{prefix}_{elt}_{edge}"
|
|
198
|
+
raw_scan_file = Path(directory) / (archive_prefix + ".raw")
|
|
199
|
+
efs_scan_file = raw_scan_file.with_suffix(".efs")
|
|
200
|
+
raw_arch_file = Path(archive_directory) / (archive_prefix + "1" + ".raw")
|
|
158
201
|
|
|
159
202
|
i = 0
|
|
160
|
-
while
|
|
203
|
+
while Path(raw_arch_file).is_file():
|
|
161
204
|
i += 1
|
|
162
|
-
raw_arch_file =
|
|
163
|
-
|
|
164
|
-
|
|
205
|
+
raw_arch_file = Path(archive_directory) / (archive_prefix + str(i) + ".raw")
|
|
206
|
+
|
|
207
|
+
png_scan_file = raw_scan_file.with_suffix(".png")
|
|
208
|
+
png_arch_file = raw_arch_file.with_suffix(".png")
|
|
165
209
|
|
|
166
|
-
|
|
167
|
-
|
|
210
|
+
if not Path(archive_directory).exists():
|
|
211
|
+
Path(archive_directory).mkdir(parents=True)
|
|
168
212
|
|
|
169
|
-
if not os.path.exists(archive_directory):
|
|
170
|
-
os.makedirs(archive_directory)
|
|
171
213
|
try:
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
self.emit("energyScanFailed", ())
|
|
176
|
-
return
|
|
177
|
-
else:
|
|
178
|
-
scan_data = []
|
|
179
|
-
try:
|
|
180
|
-
with open(raw_data_file, "r") as raw_file:
|
|
214
|
+
with Path(raw_scan_file).open("w") as fp:
|
|
215
|
+
scan_data = []
|
|
216
|
+
with Path(raw_data_file).open("r") as raw_file:
|
|
181
217
|
for line in raw_file.readlines()[2:]:
|
|
182
218
|
try:
|
|
183
|
-
|
|
184
|
-
except
|
|
185
|
-
|
|
219
|
+
x, y = line.split("\t")
|
|
220
|
+
except (AttributeError, ValueError):
|
|
221
|
+
x, y = line.split()
|
|
186
222
|
x = float(x.strip())
|
|
187
223
|
y = float(y.strip())
|
|
188
224
|
scan_data.append((x, y))
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
225
|
+
fp.write("%f,%f\r\n" % (x, y))
|
|
226
|
+
except IOError:
|
|
227
|
+
self.store_energy_scan()
|
|
228
|
+
self.emit("energyScanFailed", ())
|
|
229
|
+
return ()
|
|
230
|
+
|
|
231
|
+
# create the gallery directory
|
|
232
|
+
g_dir = Path(directory).parent / "gallery"
|
|
233
|
+
if not Path(g_dir).exists():
|
|
234
|
+
Path(g_dir).mkdir(parents=True)
|
|
235
|
+
|
|
236
|
+
copy2(raw_scan_file, raw_arch_file)
|
|
237
|
+
copy2(raw_scan_file, g_dir / raw_arch_file.name)
|
|
197
238
|
self.energy_scan_parameters["scanFileFullPath"] = raw_arch_file
|
|
198
239
|
|
|
199
|
-
"""
|
|
200
|
-
result = PyChooch.calc(scan_data, elt, edge, efs_scan_file)
|
|
201
|
-
# PyChooch occasionally returns an error and the result
|
|
202
|
-
# the sleep command assures that we get the result
|
|
203
|
-
time.sleep(1)
|
|
204
|
-
print(result[0])
|
|
205
|
-
pk = result[0] / 1000.0
|
|
206
|
-
fppPeak = result[1]
|
|
207
|
-
fpPeak = result[2]
|
|
208
|
-
ip = result[3] / 1000.0
|
|
209
|
-
fppInfl = result[4]
|
|
210
|
-
fpInfl = result[5]
|
|
211
|
-
chooch_graph_data = result[6]
|
|
212
|
-
"""
|
|
213
240
|
# while waiting for chooch to work...
|
|
214
241
|
subprocess.call(
|
|
215
242
|
[
|
|
@@ -226,68 +253,60 @@ class ESRFEnergyScan(AbstractEnergyScan):
|
|
|
226
253
|
]
|
|
227
254
|
)
|
|
228
255
|
time.sleep(5)
|
|
229
|
-
with open(
|
|
256
|
+
with Path(efs_scan_file).open("r") as fp:
|
|
230
257
|
for _ in range(3):
|
|
231
|
-
next(
|
|
232
|
-
nparr =
|
|
233
|
-
|
|
234
|
-
idx =
|
|
258
|
+
next(fp)
|
|
259
|
+
nparr = np.array([list(map(float, line.split())) for line in fp])
|
|
260
|
+
fpp_peak = nparr[:, 1].max()
|
|
261
|
+
idx = np.where(nparr[:, 1] == fpp_peak)
|
|
235
262
|
pk = nparr[:, 0][idx][0] / 1000.0
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
idx =
|
|
263
|
+
fp_peak = nparr[:, 2][idx][0]
|
|
264
|
+
fpp_infl = nparr[:, 2].min()
|
|
265
|
+
idx = np.where(nparr[:, 2] == fpp_infl)
|
|
239
266
|
ip = nparr[:, 0][idx][0] / 1000.0
|
|
240
|
-
|
|
241
|
-
|
|
267
|
+
fp_infl = nparr[:, 1][idx][0]
|
|
268
|
+
# get the threshold from the theoretical edge [keV]
|
|
269
|
+
th_t = self.get_property("theoritical_edge_threshold", 0.03)
|
|
270
|
+
rm = pk + th_t
|
|
242
271
|
|
|
243
|
-
comm = ""
|
|
244
272
|
th_edge = float(self.energy_scan_parameters["edgeEnergy"])
|
|
245
273
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
)
|
|
274
|
+
msg = f"Chooch results: pk = {pk}, ip = {ip}. rm = {rm}.\n"
|
|
275
|
+
msg += f"Theoretical edge: {th_edge}."
|
|
276
|
+
logging.getLogger("HWR").info(msg)
|
|
250
277
|
|
|
251
278
|
# +- shift from the theoretical edge [eV]
|
|
252
|
-
edge_shift =
|
|
253
|
-
calc_shift = (th_edge -
|
|
254
|
-
if
|
|
255
|
-
rm = th_edge +
|
|
256
|
-
comm = "
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
logging.getLogger("user_level_log").info(
|
|
263
|
-
"EnergyScan: %s Check your scan and choose the energies manually" % comm
|
|
264
|
-
)
|
|
279
|
+
edge_shift = 50
|
|
280
|
+
calc_shift = (th_edge - pk) * 1000
|
|
281
|
+
if abs(calc_shift) > edge_shift:
|
|
282
|
+
rm = th_edge + th_t
|
|
283
|
+
comm = "below" if calc_shift > edge_shift else "above"
|
|
284
|
+
msg = f"Calculated peak {pk} is more than {edge_shift} eV {comm} "
|
|
285
|
+
msg += f"the theoretical value {th_edge}. "
|
|
286
|
+
self.energy_scan_parameters["comments"] = msg
|
|
287
|
+
msg += "Check your scan and choose the energies manually"
|
|
288
|
+
logging.getLogger("user_level_log").info(msg)
|
|
265
289
|
pk = 0
|
|
266
290
|
ip = 0
|
|
267
291
|
|
|
268
|
-
efs_arch_file = raw_arch_file.
|
|
269
|
-
if
|
|
270
|
-
|
|
292
|
+
efs_arch_file = raw_arch_file.with_suffix(".efs")
|
|
293
|
+
if Path(efs_scan_file).is_file():
|
|
294
|
+
copy2(efs_scan_file, efs_arch_file)
|
|
295
|
+
copy2(efs_scan_file, g_dir / efs_arch_file.name)
|
|
271
296
|
else:
|
|
272
|
-
self.
|
|
297
|
+
self.store_energy_scan()
|
|
273
298
|
self.emit("energyScanFailed", ())
|
|
274
|
-
return
|
|
299
|
+
return ()
|
|
275
300
|
|
|
276
|
-
self.energy_scan_parameters["filename"] = raw_arch_file.
|
|
301
|
+
self.energy_scan_parameters["filename"] = raw_arch_file.name
|
|
277
302
|
self.energy_scan_parameters["peakEnergy"] = pk
|
|
278
303
|
self.energy_scan_parameters["inflectionEnergy"] = ip
|
|
279
304
|
self.energy_scan_parameters["remoteEnergy"] = rm
|
|
280
|
-
self.energy_scan_parameters["peakFPrime"] =
|
|
281
|
-
self.energy_scan_parameters["peakFDoublePrime"] =
|
|
282
|
-
self.energy_scan_parameters["inflectionFPrime"] =
|
|
283
|
-
self.energy_scan_parameters["inflectionFDoublePrime"] =
|
|
284
|
-
self.energy_scan_parameters["comments"] = comm
|
|
305
|
+
self.energy_scan_parameters["peakFPrime"] = fp_peak
|
|
306
|
+
self.energy_scan_parameters["peakFDoublePrime"] = fpp_peak
|
|
307
|
+
self.energy_scan_parameters["inflectionFPrime"] = fp_infl
|
|
308
|
+
self.energy_scan_parameters["inflectionFDoublePrime"] = fpp_infl
|
|
285
309
|
|
|
286
|
-
"""
|
|
287
|
-
chooch_graph_x, chooch_graph_y1, chooch_graph_y2 = zip(*chooch_graph_data)
|
|
288
|
-
chooch_graph_x = list(chooch_graph_x)
|
|
289
|
-
chooch_graph_x = [x / 1000.0 for x in chooch_graph_x]
|
|
290
|
-
"""
|
|
291
310
|
logging.getLogger("HWR").info("Saving png")
|
|
292
311
|
# prepare to save png files
|
|
293
312
|
title = "%10s %6s %6s\n%10s %6.2f %6.2f\n%10s %6.2f %6.2f" % (
|
|
@@ -295,90 +314,109 @@ class ESRFEnergyScan(AbstractEnergyScan):
|
|
|
295
314
|
"f'",
|
|
296
315
|
"f''",
|
|
297
316
|
pk,
|
|
298
|
-
|
|
299
|
-
|
|
317
|
+
fp_peak,
|
|
318
|
+
fpp_peak,
|
|
300
319
|
ip,
|
|
301
|
-
|
|
302
|
-
|
|
320
|
+
fp_infl,
|
|
321
|
+
fpp_infl,
|
|
303
322
|
)
|
|
304
|
-
if
|
|
305
|
-
|
|
323
|
+
if Path(png_scan_file).is_file():
|
|
324
|
+
copy2(png_scan_file, png_arch_file)
|
|
325
|
+
copy2(png_scan_file, g_dir / png_arch_file.name)
|
|
306
326
|
else:
|
|
307
|
-
self.
|
|
327
|
+
self.store_energy_scan()
|
|
308
328
|
self.emit("energyScanFailed", ())
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
fig = Figure(figsize=(15, 11))
|
|
312
|
-
ax = fig.add_subplot(211)
|
|
313
|
-
ax.set_title("%s\n%s" % (efs_scan_file, title))
|
|
314
|
-
ax.grid(True)
|
|
315
|
-
ax.plot(*(zip(*scan_data)), **{"color": "black"})
|
|
316
|
-
ax.set_xlabel("Energy")
|
|
317
|
-
ax.set_ylabel("MCA counts")
|
|
318
|
-
ax2 = fig.add_subplot(212)
|
|
319
|
-
ax2.grid(True)
|
|
320
|
-
ax2.set_xlabel("Energy")
|
|
321
|
-
ax2.set_ylabel("")
|
|
322
|
-
handles = []
|
|
323
|
-
handles.append(ax2.plot(chooch_graph_x, chooch_graph_y1, color="blue"))
|
|
324
|
-
handles.append(ax2.plot(chooch_graph_x, chooch_graph_y2, color="red"))
|
|
325
|
-
canvas = FigureCanvasAgg(fig)
|
|
326
|
-
"""
|
|
329
|
+
return ()
|
|
330
|
+
|
|
327
331
|
self.energy_scan_parameters["jpegChoochFileFullPath"] = str(png_arch_file)
|
|
328
|
-
|
|
329
|
-
try:
|
|
330
|
-
logging.getLogger("HWR").info(
|
|
331
|
-
"Rendering energy scan and Chooch graphs to PNG file : %s",
|
|
332
|
-
png_scan_file,
|
|
333
|
-
)
|
|
334
|
-
canvas.print_figure(png_scan_file, dpi=80)
|
|
335
|
-
except Exception:
|
|
336
|
-
logging.getLogger("HWR").exception("could not print figure")
|
|
337
|
-
try:
|
|
338
|
-
logging.getLogger("HWR").info(
|
|
339
|
-
"Saving energy scan to archive directory for ISPyB : %s", png_arch_file
|
|
340
|
-
)
|
|
341
|
-
canvas.print_figure(png_arch_file, dpi=80)
|
|
342
|
-
except Exception:
|
|
343
|
-
logging.getLogger("HWR").exception("could not save figure")
|
|
344
|
-
"""
|
|
345
|
-
self.storeEnergyScan()
|
|
332
|
+
self.store_energy_scan()
|
|
346
333
|
|
|
347
334
|
self.emit(
|
|
348
335
|
"chooch_finished",
|
|
349
336
|
(
|
|
350
337
|
pk,
|
|
351
|
-
|
|
352
|
-
|
|
338
|
+
fpp_peak,
|
|
339
|
+
fp_peak,
|
|
353
340
|
ip,
|
|
354
|
-
|
|
355
|
-
|
|
341
|
+
fpp_infl,
|
|
342
|
+
fp_infl,
|
|
356
343
|
rm,
|
|
357
|
-
# chooch_graph_x,
|
|
358
|
-
# chooch_graph_y1,
|
|
359
|
-
# chooch_graph_y2,
|
|
360
344
|
title,
|
|
361
345
|
),
|
|
362
346
|
)
|
|
363
347
|
return (
|
|
364
348
|
pk,
|
|
365
|
-
|
|
366
|
-
|
|
349
|
+
fpp_peak,
|
|
350
|
+
fp_peak,
|
|
367
351
|
ip,
|
|
368
|
-
|
|
369
|
-
|
|
352
|
+
fpp_infl,
|
|
353
|
+
fp_infl,
|
|
370
354
|
rm,
|
|
371
355
|
[],
|
|
372
356
|
[],
|
|
373
357
|
[],
|
|
374
|
-
# chooch_graph_x,
|
|
375
|
-
# chooch_graph_y1,
|
|
376
|
-
# chooch_graph_y2,
|
|
377
358
|
title,
|
|
378
359
|
)
|
|
379
360
|
|
|
361
|
+
def energy_scan_hook(self, energy_scan_parameters: dict):
|
|
362
|
+
"""
|
|
363
|
+
Execute actions, required before running the raw scan(like changing
|
|
364
|
+
undulator gaps, move to a given energy... These are in general
|
|
365
|
+
beamline specific actions.
|
|
366
|
+
"""
|
|
367
|
+
if self.energy_scan_parameters["findattEnergy"]:
|
|
368
|
+
HWR.beamline.energy.set_value(energy_scan_parameters["findattEnergy"])
|
|
369
|
+
|
|
370
|
+
def set_mca_roi(self, eroi_min, eroi_max):
|
|
371
|
+
self.energy_scan_parameters["fluorescenceDetector"] = "KETEK_AXAS-A"
|
|
372
|
+
# check if roi in eV or keV
|
|
373
|
+
if eroi_min > 1000:
|
|
374
|
+
eroi_min /= 1000.0
|
|
375
|
+
eroi_max /= 1000.0
|
|
376
|
+
self.ctrl.mca.set_roi(
|
|
377
|
+
eroi_min,
|
|
378
|
+
eroi_max,
|
|
379
|
+
channel=1,
|
|
380
|
+
element=self.energy_scan_parameters["element"],
|
|
381
|
+
atomic_nb=self.energy_scan_parameters["atomic_nb"],
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
def choose_attenuation(self):
|
|
385
|
+
"""Choose the appropriate attenuation to execute the scan"""
|
|
386
|
+
eroi_min = self.energy_scan_parameters["eroi_min"]
|
|
387
|
+
eroi_max = self.energy_scan_parameters["eroi_max"]
|
|
388
|
+
self.ctrl.detcover.set_in()
|
|
389
|
+
mcafile = Path(self.energy_scan_parameters["directory"]) / "mca.raw"
|
|
390
|
+
self.ctrl.find_max_attenuation(
|
|
391
|
+
ctime=2, roi=[eroi_min, eroi_max], datafile=mcafile
|
|
392
|
+
)
|
|
393
|
+
self.energy_scan_parameters["transmissionFactor"] = (
|
|
394
|
+
HWR.beamline.transmission.get_value()
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
def execute_energy_scan(self, energy_scan_parameters: dict):
|
|
398
|
+
"""
|
|
399
|
+
Execute the raw scan sequence. Here is where you pass whatever
|
|
400
|
+
parameters you need to run the raw scan (e.g start/end energy,
|
|
401
|
+
counting time, energy step...).
|
|
402
|
+
"""
|
|
403
|
+
start_en = energy_scan_parameters["startEnergy"]
|
|
404
|
+
end_en = energy_scan_parameters["endEnergy"]
|
|
405
|
+
dd = dt.now(tz=ZoneInfo("Europe/Paris"))
|
|
406
|
+
fname = "%s/%s_%s_%s_%s.scan" % (
|
|
407
|
+
energy_scan_parameters["directory"],
|
|
408
|
+
energy_scan_parameters["prefix"],
|
|
409
|
+
dt.datetime.strftime(dd, "%d"),
|
|
410
|
+
dt.datetime.strftime(dd, "%b"),
|
|
411
|
+
dt.datetime.strftime(dd, "%Y"),
|
|
412
|
+
)
|
|
413
|
+
self.ctrl.energy_scan.do_energy_scan(start_en, end_en, datafile=fname)
|
|
414
|
+
self.energy_scan_parameters["exposureTime"] = (
|
|
415
|
+
self.ctrl.energy_scan.exposure_time
|
|
416
|
+
)
|
|
417
|
+
|
|
380
418
|
|
|
381
|
-
def
|
|
419
|
+
def store_energy_scan_thread(db_conn, scan_info):
|
|
382
420
|
scan_info = dict(scan_info)
|
|
383
421
|
blsample_id = scan_info["blSampleId"]
|
|
384
422
|
scan_info.pop("blSampleId")
|
|
@@ -393,5 +431,5 @@ def StoreEnergyScanThread(db_conn, scan_info):
|
|
|
393
431
|
else:
|
|
394
432
|
asso = {"blSampleId": blsample_id, "energyScanId": escan_id}
|
|
395
433
|
db_conn.associate_bl_sample_and_energy_scan(asso)
|
|
396
|
-
except Exception
|
|
397
|
-
|
|
434
|
+
except Exception:
|
|
435
|
+
logging.getLogger("HWR").exception("Could not store energy")
|