Compare commits
117 Commits
refactor/r
...
refactor/i
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d63be7e04 | |||
| 63ee870c89 | |||
| 36a2e55474 | |||
| 19d117619a | |||
| 447a9c3924 | |||
|
|
17e525689c | ||
| 4907c5db27 | |||
| 0dfcedc47f | |||
| 8f2335396b | |||
| 8a7a005b56 | |||
| e19ce733a2 | |||
|
|
ccaf996512 | ||
|
|
83de8b75db | ||
|
|
829bdc11c1 | ||
|
|
cbb3f9e8bc | ||
|
|
5f819d9835 | ||
|
|
8f55b6dbcb | ||
| b2095f8d7b | |||
|
|
9186853faf | ||
| 4d241d26f3 | |||
| f47ca6e174 | |||
| e86e6ba63c | |||
| 7ff2f7dc1b | |||
| ef1ab749a9 | |||
|
|
ec53bb7000 | ||
|
|
5f1449365d | ||
|
|
9699b39a7e | ||
| 4fa81ddc5c | |||
|
|
79f63b84fc | ||
|
|
5f9f2c8762 | ||
|
|
58960944f8 | ||
|
|
dfb4fa75d9 | ||
| 70b196403b | |||
| f14a5f220e | |||
| a4077be379 | |||
| cf96658625 | |||
| c21d6cf3c6 | |||
| 4f22de66f6 | |||
| dadee3efc1 | |||
|
|
19ac208f73 | ||
| a327d0ccaa | |||
|
|
9107b1f14b | ||
|
|
bb8bf3a072 | ||
| 9c331c13e0 | |||
|
|
8a1951766b | ||
|
|
a70c4588a0 | ||
|
|
55aa7128e2 | ||
| b31a1ea996 | |||
| 820b673144 | |||
| 805d4b5a13 | |||
|
|
011955ca38 | ||
| 04f123ab2b | |||
| 372205957b | |||
|
|
41d574253e | ||
|
|
c9536d9380 | ||
| 831ace2533 | |||
|
|
20a4f4d0bc | ||
|
|
3ae62c8ff9 | ||
|
|
40c460d120 | ||
|
|
0d66d2d364 | ||
|
|
2e3ed9f6f0 | ||
|
|
fff0b8ce41 | ||
|
|
d7308a8b81 | ||
|
|
86e71ca255 | ||
|
|
d3c86b07a0 | ||
|
|
af2a2df55f | ||
|
|
d2e4a8c703 | ||
|
|
a8cc2bcbe0 | ||
|
|
cb16dcfb4c | ||
|
|
4282d4ead6 | ||
|
|
a07a56822f | ||
|
|
07543755d9 | ||
|
|
793eedb3f4 | ||
|
|
dbae426a87 | ||
|
|
9e84c1570c | ||
|
|
2002f2fabf | ||
|
|
fb49295a92 | ||
|
|
85ecf8b55f | ||
|
|
a1eacdf54b | ||
|
|
c9a1fd1cd6 | ||
|
|
54b9a5004a | ||
|
|
972d010954 | ||
|
|
b1f4207738 | ||
|
|
45dfc1305e | ||
|
|
5f90b32210 | ||
|
|
29a8e1b281 | ||
|
|
78b838f516 | ||
|
|
17d4fcb8db | ||
|
|
e03b3b84e0 | ||
|
|
dd2f20fba4 | ||
|
|
d62f398351 | ||
|
|
c17a836858 | ||
|
|
f359e32610 | ||
|
|
b28649e6af | ||
|
|
a0f2269da3 | ||
|
|
143c4dbd65 | ||
|
|
347c63d500 | ||
|
|
f0df487131 | ||
|
|
90449d22ee | ||
|
|
3a06ca484b | ||
|
|
8ba32172ca | ||
|
|
9652545440 | ||
|
|
55f7015834 | ||
|
|
afd5d5548f | ||
|
|
cc04810361 | ||
|
|
fb6ec1c350 | ||
|
|
d32d7401a3 | ||
|
|
c7f9d37c12 | ||
|
|
f3d2100b03 | ||
|
|
79d69c9492 | ||
|
|
e4a2d01488 | ||
| 5648b4dbd6 | |||
|
|
977a2beb4c | ||
|
|
8f9c43ad99 | ||
|
|
8bb89cbf76 | ||
|
|
294d3b0d4e | ||
| 87f002a68b |
9
.copier-answers.yml
Normal file
9
.copier-answers.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
# Do not edit this file!
|
||||
# It is needed to track the repo template version, and editing may break things.
|
||||
# This file will be overwritten by copier on template updates.
|
||||
|
||||
_commit: v1.0.0
|
||||
_src_path: https://github.com/bec-project/plugin_copier_template.git
|
||||
make_commit: false
|
||||
project_name: csaxs_bec
|
||||
widget_plugins_input: []
|
||||
@@ -6,3 +6,15 @@ include:
|
||||
target: "csaxs_bec"
|
||||
branch: $CHILD_PIPELINE_BRANCH
|
||||
|
||||
pages:
|
||||
stage: Deploy
|
||||
needs: []
|
||||
variables:
|
||||
TARGET_BRANCH: $CI_COMMIT_REF_NAME
|
||||
rules:
|
||||
- if: "$CI_COMMIT_TAG != null"
|
||||
variables:
|
||||
TARGET_BRANCH: $CI_COMMIT_TAG
|
||||
- if: '$CI_COMMIT_REF_NAME == "main" && $CI_PROJECT_PATH == "bec/csaxs_bec"'
|
||||
script:
|
||||
- curl -X POST -d "branches=$CI_COMMIT_REF_NAME" -d "token=$RTD_TOKEN" https://readthedocs.org/api/v2/webhook/sls-csaxs/270162/
|
||||
|
||||
29
.readthedocs.yaml
Normal file
29
.readthedocs.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
version: 2
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3.10"
|
||||
jobs:
|
||||
pre_install:
|
||||
- pip install .
|
||||
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
# If using Sphinx, optionally build your docs in additional formats such as PDF
|
||||
# formats:
|
||||
# - pdf
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
29
LICENSE
Normal file
29
LICENSE
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2025, Paul Scherrer Institute
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1
bin/.gitignore
vendored
Normal file
1
bin/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Add anything you don't want to check in to git, e.g. very large files
|
||||
@@ -13,7 +13,6 @@ logger = bec_logger.logger
|
||||
class PilatusConverter:
|
||||
def __init__(self, host: str, port: int) -> None:
|
||||
self._connector = RedisConnector(f"{host}:{port}")
|
||||
self._producer = self._connector.producer()
|
||||
|
||||
def start(self) -> None:
|
||||
"""start the consumer"""
|
||||
@@ -57,10 +56,9 @@ class PilatusConverter:
|
||||
"""
|
||||
Start the consumer.
|
||||
"""
|
||||
file_consumer = self._connector.consumer(
|
||||
self._connector.register(
|
||||
MessageEndpoints.file_event("pilatus_2"), cb=self.on_new_message, parent=self
|
||||
)
|
||||
file_consumer.start()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -280,14 +280,22 @@ class LamNIOpticsMixin:
|
||||
umv(dev.losaz, losaz_out)
|
||||
umv(dev.losay, losay_out)
|
||||
|
||||
def lfzp_info(self):
|
||||
def lfzp_info(self, mokev_val=-1):
|
||||
|
||||
if mokev_val == -1:
|
||||
try:
|
||||
mokev_val = dev.mokev.readback.get()
|
||||
except:
|
||||
print(
|
||||
"Device mokev does not exist. You can specify the energy in keV as an argument instead."
|
||||
)
|
||||
return
|
||||
loptz_val = dev.loptz.read()["loptz"]["value"]
|
||||
distance = -loptz_val + 85.6 + 52
|
||||
print(f"The sample is in a distance of {distance:.1f} mm from the FZP.")
|
||||
|
||||
diameters = [80e-6, 100e-6, 120e-6, 150e-6, 170e-6, 200e-6, 220e-6, 250e-6]
|
||||
|
||||
mokev_val = dev.mokev.read()["mokev"]["value"]
|
||||
console = Console()
|
||||
table = Table(
|
||||
title=f"At the current energy of {mokev_val:.4f} keV we have following options:",
|
||||
|
||||
0
csaxs_bec/bec_ipython_client/plugins/LamNI/load_additional_correction.py
Executable file → Normal file
0
csaxs_bec/bec_ipython_client/plugins/LamNI/load_additional_correction.py
Executable file → Normal file
@@ -0,0 +1,351 @@
|
||||
corr_elements = 175
|
||||
corr_angle[0] = 0.100000
|
||||
corr_angle[1] = 1.001000
|
||||
corr_angle[2] = 1.902000
|
||||
corr_angle[3] = 2.798000
|
||||
corr_angle[4] = 7.305000
|
||||
corr_angle[5] = 8.204000
|
||||
corr_angle[6] = 9.104000
|
||||
corr_angle[7] = 10.005000
|
||||
corr_angle[8] = 14.504000
|
||||
corr_angle[9] = 15.404000
|
||||
corr_angle[10] = 16.304000
|
||||
corr_angle[11] = 17.204000
|
||||
corr_angle[12] = 21.704000
|
||||
corr_angle[13] = 22.604000
|
||||
corr_angle[14] = 23.504000
|
||||
corr_angle[15] = 24.404000
|
||||
corr_angle[16] = 28.904000
|
||||
corr_angle[17] = 29.804000
|
||||
corr_angle[18] = 30.704000
|
||||
corr_angle[19] = 31.604000
|
||||
corr_angle[20] = 36.104000
|
||||
corr_angle[21] = 37.004000
|
||||
corr_angle[22] = 37.904000
|
||||
corr_angle[23] = 38.804000
|
||||
corr_angle[24] = 43.305000
|
||||
corr_angle[25] = 44.205000
|
||||
corr_angle[26] = 45.104000
|
||||
corr_angle[27] = 46.005000
|
||||
corr_angle[28] = 50.504000
|
||||
corr_angle[29] = 51.404000
|
||||
corr_angle[30] = 52.305000
|
||||
corr_angle[31] = 53.205000
|
||||
corr_angle[32] = 57.705000
|
||||
corr_angle[33] = 58.605000
|
||||
corr_angle[34] = 59.505000
|
||||
corr_angle[35] = 60.405000
|
||||
corr_angle[36] = 64.904000
|
||||
corr_angle[37] = 65.804000
|
||||
corr_angle[38] = 66.704000
|
||||
corr_angle[39] = 67.604000
|
||||
corr_angle[40] = 72.104000
|
||||
corr_angle[41] = 73.004000
|
||||
corr_angle[42] = 73.904000
|
||||
corr_angle[43] = 74.804000
|
||||
corr_angle[44] = 79.304000
|
||||
corr_angle[45] = 80.204000
|
||||
corr_angle[46] = 81.104000
|
||||
corr_angle[47] = 82.005000
|
||||
corr_angle[48] = 86.505000
|
||||
corr_angle[49] = 87.404000
|
||||
corr_angle[50] = 88.304000
|
||||
corr_angle[51] = 89.205000
|
||||
corr_angle[52] = 93.704000
|
||||
corr_angle[53] = 94.604000
|
||||
corr_angle[54] = 95.505000
|
||||
corr_angle[55] = 96.404000
|
||||
corr_angle[56] = 100.904000
|
||||
corr_angle[57] = 101.804000
|
||||
corr_angle[58] = 102.704000
|
||||
corr_angle[59] = 103.604000
|
||||
corr_angle[60] = 108.104000
|
||||
corr_angle[61] = 109.004000
|
||||
corr_angle[62] = 109.904000
|
||||
corr_angle[63] = 110.804000
|
||||
corr_angle[64] = 115.304000
|
||||
corr_angle[65] = 116.204000
|
||||
corr_angle[66] = 117.104000
|
||||
corr_angle[67] = 118.004000
|
||||
corr_angle[68] = 122.504000
|
||||
corr_angle[69] = 123.404000
|
||||
corr_angle[70] = 124.304000
|
||||
corr_angle[71] = 125.204000
|
||||
corr_angle[72] = 129.704000
|
||||
corr_angle[73] = 130.604000
|
||||
corr_angle[74] = 131.504000
|
||||
corr_angle[75] = 132.404000
|
||||
corr_angle[76] = 136.904000
|
||||
corr_angle[77] = 137.804000
|
||||
corr_angle[78] = 138.701000
|
||||
corr_angle[79] = 139.604000
|
||||
corr_angle[80] = 144.104000
|
||||
corr_angle[81] = 145.004000
|
||||
corr_angle[82] = 145.904000
|
||||
corr_angle[83] = 146.804000
|
||||
corr_angle[84] = 151.304000
|
||||
corr_angle[85] = 152.204000
|
||||
corr_angle[86] = 153.104000
|
||||
corr_angle[87] = 154.004000
|
||||
corr_angle[88] = 158.504000
|
||||
corr_angle[89] = 159.404000
|
||||
corr_angle[90] = 160.304000
|
||||
corr_angle[91] = 161.204000
|
||||
corr_angle[92] = 165.704000
|
||||
corr_angle[93] = 166.604000
|
||||
corr_angle[94] = 167.504000
|
||||
corr_angle[95] = 168.404000
|
||||
corr_angle[96] = 172.904000
|
||||
corr_angle[97] = 173.805000
|
||||
corr_angle[98] = 174.704000
|
||||
corr_angle[99] = 180.104000
|
||||
corr_angle[100] = 183.704000
|
||||
corr_angle[101] = 184.603000
|
||||
corr_angle[102] = 185.504000
|
||||
corr_angle[103] = 190.904000
|
||||
corr_angle[104] = 191.805000
|
||||
corr_angle[105] = 192.704000
|
||||
corr_angle[106] = 198.104000
|
||||
corr_angle[107] = 199.004000
|
||||
corr_angle[108] = 199.904000
|
||||
corr_angle[109] = 205.304000
|
||||
corr_angle[110] = 206.204000
|
||||
corr_angle[111] = 207.104000
|
||||
corr_angle[112] = 212.504000
|
||||
corr_angle[113] = 213.404000
|
||||
corr_angle[114] = 214.304000
|
||||
corr_angle[115] = 219.704000
|
||||
corr_angle[116] = 220.604000
|
||||
corr_angle[117] = 221.504000
|
||||
corr_angle[118] = 226.904000
|
||||
corr_angle[119] = 227.804000
|
||||
corr_angle[120] = 228.704000
|
||||
corr_angle[121] = 234.104000
|
||||
corr_angle[122] = 235.004000
|
||||
corr_angle[123] = 235.904000
|
||||
corr_angle[124] = 241.304000
|
||||
corr_angle[125] = 242.204000
|
||||
corr_angle[126] = 243.104000
|
||||
corr_angle[127] = 248.504000
|
||||
corr_angle[128] = 249.404000
|
||||
corr_angle[129] = 250.304000
|
||||
corr_angle[130] = 255.704000
|
||||
corr_angle[131] = 256.604000
|
||||
corr_angle[132] = 257.504000
|
||||
corr_angle[133] = 262.904000
|
||||
corr_angle[134] = 263.804000
|
||||
corr_angle[135] = 264.704000
|
||||
corr_angle[136] = 270.104000
|
||||
corr_angle[137] = 271.004000
|
||||
corr_angle[138] = 271.904000
|
||||
corr_angle[139] = 277.304000
|
||||
corr_angle[140] = 278.205000
|
||||
corr_angle[141] = 279.104000
|
||||
corr_angle[142] = 284.504000
|
||||
corr_angle[143] = 285.405000
|
||||
corr_angle[144] = 286.304000
|
||||
corr_angle[145] = 291.703000
|
||||
corr_angle[146] = 292.604000
|
||||
corr_angle[147] = 293.504000
|
||||
corr_angle[148] = 298.904000
|
||||
corr_angle[149] = 299.804000
|
||||
corr_angle[150] = 300.704000
|
||||
corr_angle[151] = 306.104000
|
||||
corr_angle[152] = 307.004000
|
||||
corr_angle[153] = 307.904000
|
||||
corr_angle[154] = 313.304000
|
||||
corr_angle[155] = 314.204000
|
||||
corr_angle[156] = 315.104000
|
||||
corr_angle[157] = 320.504000
|
||||
corr_angle[158] = 321.404000
|
||||
corr_angle[159] = 322.304000
|
||||
corr_angle[160] = 327.704000
|
||||
corr_angle[161] = 328.605000
|
||||
corr_angle[162] = 329.504000
|
||||
corr_angle[163] = 334.904000
|
||||
corr_angle[164] = 335.804000
|
||||
corr_angle[165] = 336.705000
|
||||
corr_angle[166] = 342.104000
|
||||
corr_angle[167] = 343.004000
|
||||
corr_angle[168] = 343.904000
|
||||
corr_angle[169] = 349.304000
|
||||
corr_angle[170] = 350.204000
|
||||
corr_angle[171] = 351.104000
|
||||
corr_angle[172] = 356.504000
|
||||
corr_angle[173] = 357.404000
|
||||
corr_angle[174] = 358.304000
|
||||
corr_pos[0] = 0.012330
|
||||
corr_pos[1] = 0.024870
|
||||
corr_pos[2] = 0.037262
|
||||
corr_pos[3] = 0.049438
|
||||
corr_pos[4] = 0.108462
|
||||
corr_pos[5] = 0.119791
|
||||
corr_pos[6] = 0.130986
|
||||
corr_pos[7] = 0.142044
|
||||
corr_pos[8] = 0.195045
|
||||
corr_pos[9] = 0.205834
|
||||
corr_pos[10] = 0.216589
|
||||
corr_pos[11] = 0.226402
|
||||
corr_pos[12] = 0.271931
|
||||
corr_pos[13] = 0.281684
|
||||
corr_pos[14] = 0.290769
|
||||
corr_pos[15] = 0.299392
|
||||
corr_pos[16] = 0.337986
|
||||
corr_pos[17] = 0.345178
|
||||
corr_pos[18] = 0.352253
|
||||
corr_pos[19] = 0.358528
|
||||
corr_pos[20] = 0.379520
|
||||
corr_pos[21] = 0.382947
|
||||
corr_pos[22] = 0.386110
|
||||
corr_pos[23] = 0.388887
|
||||
corr_pos[24] = 0.395645
|
||||
corr_pos[25] = 0.396154
|
||||
corr_pos[26] = 0.396679
|
||||
corr_pos[27] = 0.396367
|
||||
corr_pos[28] = 0.392400
|
||||
corr_pos[29] = 0.392530
|
||||
corr_pos[30] = 0.391826
|
||||
corr_pos[31] = 0.391325
|
||||
corr_pos[32] = 0.379188
|
||||
corr_pos[33] = 0.376449
|
||||
corr_pos[34] = 0.373195
|
||||
corr_pos[35] = 0.369588
|
||||
corr_pos[36] = 0.343021
|
||||
corr_pos[37] = 0.336754
|
||||
corr_pos[38] = 0.330310
|
||||
corr_pos[39] = 0.323447
|
||||
corr_pos[40] = 0.281171
|
||||
corr_pos[41] = 0.272735
|
||||
corr_pos[42] = 0.263888
|
||||
corr_pos[43] = 0.254469
|
||||
corr_pos[44] = 0.203024
|
||||
corr_pos[45] = 0.192980
|
||||
corr_pos[46] = 0.182359
|
||||
corr_pos[47] = 0.170780
|
||||
corr_pos[48] = 0.111580
|
||||
corr_pos[49] = 0.101222
|
||||
corr_pos[50] = 0.090051
|
||||
corr_pos[51] = 0.077918
|
||||
corr_pos[52] = 0.015225
|
||||
corr_pos[53] = 0.003876
|
||||
corr_pos[54] = -0.007756
|
||||
corr_pos[55] = -0.020383
|
||||
corr_pos[56] = -0.084910
|
||||
corr_pos[57] = -0.096848
|
||||
corr_pos[58] = -0.108732
|
||||
corr_pos[59] = -0.121432
|
||||
corr_pos[60] = -0.184349
|
||||
corr_pos[61] = -0.195904
|
||||
corr_pos[62] = -0.207113
|
||||
corr_pos[63] = -0.219319
|
||||
corr_pos[64] = -0.274799
|
||||
corr_pos[65] = -0.284942
|
||||
corr_pos[66] = -0.294809
|
||||
corr_pos[67] = -0.305437
|
||||
corr_pos[68] = -0.352114
|
||||
corr_pos[69] = -0.359689
|
||||
corr_pos[70] = -0.367451
|
||||
corr_pos[71] = -0.375629
|
||||
corr_pos[72] = -0.404347
|
||||
corr_pos[73] = -0.407683
|
||||
corr_pos[74] = -0.410857
|
||||
corr_pos[75] = -0.414904
|
||||
corr_pos[76] = -0.424625
|
||||
corr_pos[77] = -0.424357
|
||||
corr_pos[78] = -0.424411
|
||||
corr_pos[79] = -0.424615
|
||||
corr_pos[80] = -0.421392
|
||||
corr_pos[81] = -0.419977
|
||||
corr_pos[82] = -0.417860
|
||||
corr_pos[83] = -0.416400
|
||||
corr_pos[84] = -0.398108
|
||||
corr_pos[85] = -0.392613
|
||||
corr_pos[86] = -0.386455
|
||||
corr_pos[87] = -0.380338
|
||||
corr_pos[88] = -0.341288
|
||||
corr_pos[89] = -0.332298
|
||||
corr_pos[90] = -0.322767
|
||||
corr_pos[91] = -0.311630
|
||||
corr_pos[92] = -0.256798
|
||||
corr_pos[93] = -0.244808
|
||||
corr_pos[94] = -0.232932
|
||||
corr_pos[95] = -0.219785
|
||||
corr_pos[96] = -0.158685
|
||||
corr_pos[97] = -0.146198
|
||||
corr_pos[98] = -0.130743
|
||||
corr_pos[99] = -0.054066
|
||||
corr_pos[100] = -0.001498
|
||||
corr_pos[101] = 0.012010
|
||||
corr_pos[102] = 0.025195
|
||||
corr_pos[103] = 0.094982
|
||||
corr_pos[104] = 0.109235
|
||||
corr_pos[105] = 0.120813
|
||||
corr_pos[106] = 0.179893
|
||||
corr_pos[107] = 0.192147
|
||||
corr_pos[108] = 0.201902
|
||||
corr_pos[109] = 0.245092
|
||||
corr_pos[110] = 0.250501
|
||||
corr_pos[111] = 0.255536
|
||||
corr_pos[112] = 0.280598
|
||||
corr_pos[113] = 0.280673
|
||||
corr_pos[114] = 0.282529
|
||||
corr_pos[115] = 0.293286
|
||||
corr_pos[116] = 0.292713
|
||||
corr_pos[117] = 0.291123
|
||||
corr_pos[118] = 0.288721
|
||||
corr_pos[119] = 0.288260
|
||||
corr_pos[120] = 0.286480
|
||||
corr_pos[121] = 0.271630
|
||||
corr_pos[122] = 0.268004
|
||||
corr_pos[123] = 0.265418
|
||||
corr_pos[124] = 0.239187
|
||||
corr_pos[125] = 0.233224
|
||||
corr_pos[126] = 0.226652
|
||||
corr_pos[127] = 0.189034
|
||||
corr_pos[128] = 0.180302
|
||||
corr_pos[129] = 0.170931
|
||||
corr_pos[130] = 0.125760
|
||||
corr_pos[131] = 0.116433
|
||||
corr_pos[132] = 0.106845
|
||||
corr_pos[133] = 0.057551
|
||||
corr_pos[134] = 0.048531
|
||||
corr_pos[135] = 0.038276
|
||||
corr_pos[136] = -0.012292
|
||||
corr_pos[137] = -0.021223
|
||||
corr_pos[138] = -0.030046
|
||||
corr_pos[139] = -0.077647
|
||||
corr_pos[140] = -0.085863
|
||||
corr_pos[141] = -0.093816
|
||||
corr_pos[142] = -0.138532
|
||||
corr_pos[143] = -0.145584
|
||||
corr_pos[144] = -0.152699
|
||||
corr_pos[145] = -0.192594
|
||||
corr_pos[146] = -0.200980
|
||||
corr_pos[147] = -0.208816
|
||||
corr_pos[148] = -0.241983
|
||||
corr_pos[149] = -0.248319
|
||||
corr_pos[150] = -0.253789
|
||||
corr_pos[151] = -0.276869
|
||||
corr_pos[152] = -0.279240
|
||||
corr_pos[153] = -0.281538
|
||||
corr_pos[154] = -0.294317
|
||||
corr_pos[155] = -0.295586
|
||||
corr_pos[156] = -0.296029
|
||||
corr_pos[157] = -0.297443
|
||||
corr_pos[158] = -0.297185
|
||||
corr_pos[159] = -0.295946
|
||||
corr_pos[160] = -0.284463
|
||||
corr_pos[161] = -0.282598
|
||||
corr_pos[162] = -0.281260
|
||||
corr_pos[163] = -0.256509
|
||||
corr_pos[164] = -0.250326
|
||||
corr_pos[165] = -0.244372
|
||||
corr_pos[166] = -0.204043
|
||||
corr_pos[167] = -0.196147
|
||||
corr_pos[168] = -0.187928
|
||||
corr_pos[169] = -0.131831
|
||||
corr_pos[170] = -0.121351
|
||||
corr_pos[171] = -0.110548
|
||||
corr_pos[172] = -0.038951
|
||||
corr_pos[173] = -0.025887
|
||||
corr_pos[174] = -0.012501
|
||||
@@ -424,18 +424,18 @@ class FlomniSampleTransferMixin:
|
||||
def show_signal_strength_interferometer(self):
|
||||
dev.rtx.controller.show_signal_strength_interferometer()
|
||||
|
||||
def rt_feedback_disable(self):
|
||||
def feedback_disable(self):
|
||||
self.device_manager.devices.rtx.controller.feedback_disable()
|
||||
|
||||
def rt_feedback_enable_with_reset(self):
|
||||
def feedback_enable_with_reset(self):
|
||||
self.device_manager.devices.rtx.controller.feedback_enable_with_reset()
|
||||
self.rt_feedback_status()
|
||||
|
||||
def rt_feedback_enable_without_reset(self):
|
||||
def feedback_enable_without_reset(self):
|
||||
self.device_manager.devices.rtx.controller.feedback_enable_without_reset()
|
||||
self.rt_feedback_status()
|
||||
|
||||
def rt_feedback_status(self):
|
||||
def feedback_status(self):
|
||||
feedback_status = self.device_manager.devices.rtx.controller.feedback_is_running()
|
||||
if feedback_status == True:
|
||||
print("The rt feedback is \x1b[92mrunning\x1b[0m.")
|
||||
@@ -455,7 +455,7 @@ class FlomniSampleTransferMixin:
|
||||
|
||||
umv(dev.fsamroy, 0)
|
||||
|
||||
self.rt_feedback_disable()
|
||||
self.feedback_disable()
|
||||
|
||||
self.ensure_fheater_up()
|
||||
|
||||
@@ -1051,7 +1051,7 @@ class FlomniAlignmentMixin:
|
||||
value = line.split(" ")[2]
|
||||
name = line.split(" ")[0].split("[")[0]
|
||||
if name == "corr_pos":
|
||||
corr_pos.append(float(value) / 1000)
|
||||
corr_pos.append(float(value))
|
||||
elif name == "corr_angle":
|
||||
corr_angle.append(float(value))
|
||||
print(
|
||||
@@ -1142,7 +1142,7 @@ class Flomni(
|
||||
fsamx_in = self._get_user_param_safe(dev.fsamx, "in")
|
||||
if np.isclose(fsamx_in, dev.fsamx.readback.get(), 0.5):
|
||||
print("Stopping alignment. Returning to fsamx in position.")
|
||||
self.rt_feedback_disable()
|
||||
self.feedback_disable()
|
||||
umv(dev.fsamx, fsamx_in)
|
||||
raise exc
|
||||
|
||||
@@ -1521,7 +1521,7 @@ class Flomni(
|
||||
angles = np.flip(angles)
|
||||
for angle in angles:
|
||||
self.progress["subtomo"] = subtomo_number
|
||||
self.progress["subtomo_projection"] = angles.index(angle)
|
||||
self.progress["subtomo_projection"] = np.where(angles == angle)[0][0]
|
||||
self.progress["subtomo_total_projections"] = 180 / self.tomo_angle_stepsize
|
||||
self.progress["projection"] = (subtomo_number - 1) * self.progress[
|
||||
"subtomo_total_projections"
|
||||
@@ -1701,7 +1701,7 @@ class Flomni(
|
||||
def _print_progress(self):
|
||||
print("\x1b[95mProgress report:")
|
||||
print(f"Tomo type: ....................... {self.progress['tomo_type']}")
|
||||
print(f"Projection: ...................... {self.progress['projection']}")
|
||||
print(f"Projection: ...................... {self.progress['projection']:.0f}")
|
||||
print(f"Total projections expected ....... {self.progress['total_projections']}")
|
||||
print(f"Angle: ........................... {self.progress['angle']}")
|
||||
print(f"Current subtomo: ................. {self.progress['subtomo']}")
|
||||
|
||||
@@ -100,7 +100,7 @@ class XrayEyeAlign:
|
||||
|
||||
self.flomni.laser_tracker_on()
|
||||
|
||||
self.flomni.rt_feedback_enable_with_reset()
|
||||
self.flomni.feedback_enable_with_reset()
|
||||
|
||||
# disable movement buttons
|
||||
self.movement_buttons_enabled = False
|
||||
@@ -109,7 +109,7 @@ class XrayEyeAlign:
|
||||
epics_put("XOMNYI-XEYE-SAMPLENAME:0.DESC", sample_name)
|
||||
|
||||
# this makes sure we are in a defined state
|
||||
self.flomni.rt_feedback_disable()
|
||||
self.flomni.feedback_disable()
|
||||
|
||||
epics_put("XOMNYI-XEYE-PIXELSIZE:0", self.PIXEL_CALIBRATION)
|
||||
|
||||
@@ -143,13 +143,13 @@ class XrayEyeAlign:
|
||||
self.movement_buttons_enabled = False
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1) # disable submit button
|
||||
|
||||
self.flomni.rt_feedback_disable()
|
||||
self.flomni.feedback_disable()
|
||||
fsamx_in = self.flomni._get_user_param_safe("fsamx", "in")
|
||||
umv(dev.fsamx, fsamx_in)
|
||||
|
||||
self.flomni.foptics_out()
|
||||
|
||||
self.flomni.rt_feedback_disable()
|
||||
self.flomni.feedback_disable()
|
||||
umv(dev.fsamx, fsamx_in - 0.25)
|
||||
|
||||
self.update_frame()
|
||||
@@ -160,7 +160,7 @@ class XrayEyeAlign:
|
||||
|
||||
umv(dev.fsamx, fsamx_in)
|
||||
time.sleep(0.5)
|
||||
self.flomni.rt_feedback_enable_with_reset()
|
||||
self.flomni.feedback_enable_with_reset()
|
||||
|
||||
self.update_frame()
|
||||
self.send_message("Adjust sample height and submit center")
|
||||
@@ -205,11 +205,11 @@ class XrayEyeAlign:
|
||||
# allow movements, store movements to calculate center
|
||||
_xrayeyalignmvy = epics_get("XOMNYI-XEYE-MVY:0")
|
||||
if _xrayeyalignmvy != 0:
|
||||
self.flomni.rt_feedback_disable()
|
||||
self.flomni.feedback_disable()
|
||||
umvr(dev.fsamy, _xrayeyalignmvy / 1000)
|
||||
time.sleep(2)
|
||||
epics_put("XOMNYI-XEYE-MVY:0", 0)
|
||||
self.flomni.rt_feedback_enable_with_reset()
|
||||
self.flomni.feedback_enable_with_reset()
|
||||
self.update_frame()
|
||||
time.sleep(0.2)
|
||||
|
||||
|
||||
1
csaxs_bec/bec_ipython_client/plugins/omny/__init__.py
Normal file
1
csaxs_bec/bec_ipython_client/plugins/omny/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .omny import OMNY
|
||||
@@ -0,0 +1,715 @@
|
||||
corr_elements = 357
|
||||
corr_angle[0] = 0.097400
|
||||
corr_angle[1] = 0.603500
|
||||
corr_angle[2] = 1.134200
|
||||
corr_angle[3] = 1.625000
|
||||
corr_angle[4] = 2.162200
|
||||
corr_angle[5] = 2.700100
|
||||
corr_angle[6] = 3.191600
|
||||
corr_angle[7] = 3.714300
|
||||
corr_angle[8] = 4.223200
|
||||
corr_angle[9] = 4.730900
|
||||
corr_angle[10] = 5.253300
|
||||
corr_angle[11] = 5.743300
|
||||
corr_angle[12] = 6.279200
|
||||
corr_angle[13] = 6.782900
|
||||
corr_angle[14] = 7.301200
|
||||
corr_angle[15] = 7.808100
|
||||
corr_angle[16] = 8.325300
|
||||
corr_angle[17] = 8.859400
|
||||
corr_angle[18] = 9.359400
|
||||
corr_angle[19] = 9.887900
|
||||
corr_angle[20] = 10.395400
|
||||
corr_angle[21] = 10.930700
|
||||
corr_angle[22] = 11.415400
|
||||
corr_angle[23] = 11.928900
|
||||
corr_angle[24] = 12.456900
|
||||
corr_angle[25] = 12.955900
|
||||
corr_angle[26] = 13.479000
|
||||
corr_angle[27] = 13.982700
|
||||
corr_angle[28] = 14.500900
|
||||
corr_angle[29] = 15.016200
|
||||
corr_angle[30] = 15.528000
|
||||
corr_angle[31] = 16.053800
|
||||
corr_angle[32] = 16.562800
|
||||
corr_angle[33] = 17.076600
|
||||
corr_angle[34] = 17.592400
|
||||
corr_angle[35] = 18.094100
|
||||
corr_angle[36] = 18.623800
|
||||
corr_angle[37] = 19.118400
|
||||
corr_angle[38] = 19.655000
|
||||
corr_angle[39] = 20.143900
|
||||
corr_angle[40] = 20.672200
|
||||
corr_angle[41] = 21.171500
|
||||
corr_angle[42] = 21.696300
|
||||
corr_angle[43] = 22.215900
|
||||
corr_angle[44] = 22.728900
|
||||
corr_angle[45] = 23.233100
|
||||
corr_angle[46] = 23.760000
|
||||
corr_angle[47] = 24.267700
|
||||
corr_angle[48] = 24.792100
|
||||
corr_angle[49] = 25.287900
|
||||
corr_angle[50] = 25.824600
|
||||
corr_angle[51] = 26.321900
|
||||
corr_angle[52] = 26.842600
|
||||
corr_angle[53] = 27.337200
|
||||
corr_angle[54] = 27.873500
|
||||
corr_angle[55] = 28.373900
|
||||
corr_angle[56] = 28.895900
|
||||
corr_angle[57] = 29.404900
|
||||
corr_angle[58] = 29.926700
|
||||
corr_angle[59] = 30.439300
|
||||
corr_angle[60] = 30.963700
|
||||
corr_angle[61] = 31.460000
|
||||
corr_angle[62] = 31.989500
|
||||
corr_angle[63] = 32.489700
|
||||
corr_angle[64] = 33.026400
|
||||
corr_angle[65] = 33.516500
|
||||
corr_angle[66] = 34.044000
|
||||
corr_angle[67] = 34.547700
|
||||
corr_angle[68] = 35.070800
|
||||
corr_angle[69] = 35.578400
|
||||
corr_angle[70] = 36.103200
|
||||
corr_angle[71] = 36.603200
|
||||
corr_angle[72] = 37.128200
|
||||
corr_angle[73] = 37.645200
|
||||
corr_angle[74] = 38.164300
|
||||
corr_angle[75] = 38.662100
|
||||
corr_angle[76] = 39.191000
|
||||
corr_angle[77] = 39.693400
|
||||
corr_angle[78] = 40.222500
|
||||
corr_angle[79] = 40.719500
|
||||
corr_angle[80] = 41.247000
|
||||
corr_angle[81] = 41.755700
|
||||
corr_angle[82] = 42.271300
|
||||
corr_angle[83] = 42.767600
|
||||
corr_angle[84] = 43.302200
|
||||
corr_angle[85] = 43.818700
|
||||
corr_angle[86] = 44.330000
|
||||
corr_angle[87] = 44.835300
|
||||
corr_angle[88] = 45.359800
|
||||
corr_angle[89] = 45.867200
|
||||
corr_angle[90] = 46.396200
|
||||
corr_angle[91] = 46.895000
|
||||
corr_angle[92] = 47.411500
|
||||
corr_angle[93] = 47.915200
|
||||
corr_angle[94] = 48.436600
|
||||
corr_angle[95] = 48.946100
|
||||
corr_angle[96] = 49.472300
|
||||
corr_angle[97] = 49.979800
|
||||
corr_angle[98] = 50.503300
|
||||
corr_angle[99] = 51.008700
|
||||
corr_angle[100] = 51.535000
|
||||
corr_angle[101] = 52.036700
|
||||
corr_angle[102] = 52.563700
|
||||
corr_angle[103] = 53.063600
|
||||
corr_angle[104] = 53.591700
|
||||
corr_angle[105] = 54.091200
|
||||
corr_angle[106] = 54.618900
|
||||
corr_angle[107] = 55.116900
|
||||
corr_angle[108] = 55.636100
|
||||
corr_angle[109] = 56.143100
|
||||
corr_angle[110] = 56.672200
|
||||
corr_angle[111] = 57.172900
|
||||
corr_angle[112] = 57.704600
|
||||
corr_angle[113] = 58.204800
|
||||
corr_angle[114] = 58.728600
|
||||
corr_angle[115] = 59.239500
|
||||
corr_angle[116] = 59.768400
|
||||
corr_angle[117] = 60.268300
|
||||
corr_angle[118] = 60.788800
|
||||
corr_angle[119] = 61.289300
|
||||
corr_angle[120] = 61.813300
|
||||
corr_angle[121] = 62.310800
|
||||
corr_angle[122] = 62.836700
|
||||
corr_angle[123] = 63.353700
|
||||
corr_angle[124] = 63.866600
|
||||
corr_angle[125] = 64.377200
|
||||
corr_angle[126] = 64.906600
|
||||
corr_angle[127] = 65.414000
|
||||
corr_angle[128] = 65.937100
|
||||
corr_angle[129] = 66.429400
|
||||
corr_angle[130] = 66.970000
|
||||
corr_angle[131] = 67.459200
|
||||
corr_angle[132] = 67.996400
|
||||
corr_angle[133] = 68.499800
|
||||
corr_angle[134] = 69.014500
|
||||
corr_angle[135] = 69.509500
|
||||
corr_angle[136] = 70.044000
|
||||
corr_angle[137] = 70.543200
|
||||
corr_angle[138] = 71.079400
|
||||
corr_angle[139] = 71.579300
|
||||
corr_angle[140] = 72.103500
|
||||
corr_angle[141] = 72.607000
|
||||
corr_angle[142] = 73.137100
|
||||
corr_angle[143] = 73.633000
|
||||
corr_angle[144] = 74.164500
|
||||
corr_angle[145] = 74.660200
|
||||
corr_angle[146] = 75.180600
|
||||
corr_angle[147] = 75.674200
|
||||
corr_angle[148] = 76.215400
|
||||
corr_angle[149] = 76.718900
|
||||
corr_angle[150] = 77.242300
|
||||
corr_angle[151] = 77.752000
|
||||
corr_angle[152] = 78.279300
|
||||
corr_angle[153] = 78.780500
|
||||
corr_angle[154] = 79.314900
|
||||
corr_angle[155] = 79.424500
|
||||
corr_angle[156] = 79.807000
|
||||
corr_angle[157] = 80.336500
|
||||
corr_angle[158] = 80.338700
|
||||
corr_angle[159] = 80.835300
|
||||
corr_angle[160] = 81.367100
|
||||
corr_angle[161] = 81.376100
|
||||
corr_angle[162] = 81.859000
|
||||
corr_angle[163] = 82.382300
|
||||
corr_angle[164] = 82.384000
|
||||
corr_angle[165] = 82.881100
|
||||
corr_angle[166] = 83.415000
|
||||
corr_angle[167] = 83.421600
|
||||
corr_angle[168] = 83.917100
|
||||
corr_angle[169] = 84.439200
|
||||
corr_angle[170] = 84.439300
|
||||
corr_angle[171] = 84.947400
|
||||
corr_angle[172] = 85.472700
|
||||
corr_angle[173] = 85.987700
|
||||
corr_angle[174] = 86.512400
|
||||
corr_angle[175] = 87.009500
|
||||
corr_angle[176] = 87.536500
|
||||
corr_angle[177] = 88.035600
|
||||
corr_angle[178] = 88.560100
|
||||
corr_angle[179] = 89.057600
|
||||
corr_angle[180] = 89.583200
|
||||
corr_angle[181] = 90.090500
|
||||
corr_angle[182] = 90.614600
|
||||
corr_angle[183] = 91.119900
|
||||
corr_angle[184] = 91.638300
|
||||
corr_angle[185] = 92.153300
|
||||
corr_angle[186] = 92.681600
|
||||
corr_angle[187] = 93.181800
|
||||
corr_angle[188] = 93.710900
|
||||
corr_angle[189] = 94.206100
|
||||
corr_angle[190] = 94.732700
|
||||
corr_angle[191] = 95.226600
|
||||
corr_angle[192] = 95.766400
|
||||
corr_angle[193] = 96.259000
|
||||
corr_angle[194] = 96.783400
|
||||
corr_angle[195] = 97.283100
|
||||
corr_angle[196] = 97.811500
|
||||
corr_angle[197] = 98.323600
|
||||
corr_angle[198] = 98.839400
|
||||
corr_angle[199] = 99.350700
|
||||
corr_angle[200] = 99.880200
|
||||
corr_angle[201] = 100.378100
|
||||
corr_angle[202] = 100.913300
|
||||
corr_angle[203] = 101.405000
|
||||
corr_angle[204] = 101.935700
|
||||
corr_angle[205] = 102.426300
|
||||
corr_angle[206] = 102.957300
|
||||
corr_angle[207] = 103.456500
|
||||
corr_angle[208] = 103.985100
|
||||
corr_angle[209] = 104.490300
|
||||
corr_angle[210] = 105.015100
|
||||
corr_angle[211] = 105.518400
|
||||
corr_angle[212] = 106.047400
|
||||
corr_angle[213] = 106.551100
|
||||
corr_angle[214] = 107.077100
|
||||
corr_angle[215] = 107.575800
|
||||
corr_angle[216] = 108.115200
|
||||
corr_angle[217] = 108.598800
|
||||
corr_angle[218] = 109.129100
|
||||
corr_angle[219] = 109.626200
|
||||
corr_angle[220] = 110.158400
|
||||
corr_angle[221] = 110.661700
|
||||
corr_angle[222] = 111.188600
|
||||
corr_angle[223] = 111.695000
|
||||
corr_angle[224] = 112.216400
|
||||
corr_angle[225] = 112.720000
|
||||
corr_angle[226] = 113.246200
|
||||
corr_angle[227] = 113.757100
|
||||
corr_angle[228] = 114.281900
|
||||
corr_angle[229] = 114.780000
|
||||
corr_angle[230] = 115.306800
|
||||
corr_angle[231] = 115.799800
|
||||
corr_angle[232] = 116.328400
|
||||
corr_angle[233] = 116.829900
|
||||
corr_angle[234] = 117.355400
|
||||
corr_angle[235] = 117.858200
|
||||
corr_angle[236] = 118.380600
|
||||
corr_angle[237] = 118.893200
|
||||
corr_angle[238] = 119.418200
|
||||
corr_angle[239] = 119.921000
|
||||
corr_angle[240] = 120.446100
|
||||
corr_angle[241] = 120.953800
|
||||
corr_angle[242] = 121.480300
|
||||
corr_angle[243] = 121.977600
|
||||
corr_angle[244] = 122.507100
|
||||
corr_angle[245] = 122.996200
|
||||
corr_angle[246] = 123.529600
|
||||
corr_angle[247] = 124.032200
|
||||
corr_angle[248] = 124.554800
|
||||
corr_angle[249] = 125.057800
|
||||
corr_angle[250] = 125.580800
|
||||
corr_angle[251] = 126.090000
|
||||
corr_angle[252] = 126.611600
|
||||
corr_angle[253] = 127.127000
|
||||
corr_angle[254] = 127.650900
|
||||
corr_angle[255] = 128.153700
|
||||
corr_angle[256] = 128.677200
|
||||
corr_angle[257] = 129.170800
|
||||
corr_angle[258] = 129.703000
|
||||
corr_angle[259] = 130.194900
|
||||
corr_angle[260] = 130.733600
|
||||
corr_angle[261] = 131.228300
|
||||
corr_angle[262] = 131.756900
|
||||
corr_angle[263] = 132.263200
|
||||
corr_angle[264] = 132.784700
|
||||
corr_angle[265] = 133.296300
|
||||
corr_angle[266] = 133.818800
|
||||
corr_angle[267] = 134.318900
|
||||
corr_angle[268] = 134.846800
|
||||
corr_angle[269] = 135.344800
|
||||
corr_angle[270] = 135.876000
|
||||
corr_angle[271] = 136.372600
|
||||
corr_angle[272] = 136.902700
|
||||
corr_angle[273] = 137.397800
|
||||
corr_angle[274] = 137.926800
|
||||
corr_angle[275] = 138.428000
|
||||
corr_angle[276] = 138.953700
|
||||
corr_angle[277] = 139.461300
|
||||
corr_angle[278] = 139.987800
|
||||
corr_angle[279] = 140.492600
|
||||
corr_angle[280] = 141.017900
|
||||
corr_angle[281] = 141.524000
|
||||
corr_angle[282] = 142.061200
|
||||
corr_angle[283] = 142.545400
|
||||
corr_angle[284] = 143.069900
|
||||
corr_angle[285] = 143.568700
|
||||
corr_angle[286] = 144.102200
|
||||
corr_angle[287] = 144.596200
|
||||
corr_angle[288] = 145.126400
|
||||
corr_angle[289] = 145.626900
|
||||
corr_angle[290] = 146.158700
|
||||
corr_angle[291] = 146.662200
|
||||
corr_angle[292] = 147.184700
|
||||
corr_angle[293] = 147.692300
|
||||
corr_angle[294] = 148.225900
|
||||
corr_angle[295] = 148.716000
|
||||
corr_angle[296] = 149.243400
|
||||
corr_angle[297] = 149.739400
|
||||
corr_angle[298] = 150.272400
|
||||
corr_angle[299] = 150.762100
|
||||
corr_angle[300] = 151.301800
|
||||
corr_angle[301] = 151.796300
|
||||
corr_angle[302] = 152.333500
|
||||
corr_angle[303] = 152.833100
|
||||
corr_angle[304] = 153.363600
|
||||
corr_angle[305] = 153.862900
|
||||
corr_angle[306] = 154.396100
|
||||
corr_angle[307] = 154.895400
|
||||
corr_angle[308] = 155.417700
|
||||
corr_angle[309] = 155.916900
|
||||
corr_angle[310] = 156.451600
|
||||
corr_angle[311] = 156.942700
|
||||
corr_angle[312] = 157.467600
|
||||
corr_angle[313] = 157.970900
|
||||
corr_angle[314] = 158.501100
|
||||
corr_angle[315] = 158.999600
|
||||
corr_angle[316] = 159.526100
|
||||
corr_angle[317] = 160.028100
|
||||
corr_angle[318] = 160.555800
|
||||
corr_angle[319] = 161.067700
|
||||
corr_angle[320] = 161.597300
|
||||
corr_angle[321] = 162.091300
|
||||
corr_angle[322] = 162.616600
|
||||
corr_angle[323] = 163.107400
|
||||
corr_angle[324] = 163.639100
|
||||
corr_angle[325] = 164.139700
|
||||
corr_angle[326] = 164.672500
|
||||
corr_angle[327] = 165.176800
|
||||
corr_angle[328] = 165.698600
|
||||
corr_angle[329] = 166.205400
|
||||
corr_angle[330] = 166.727300
|
||||
corr_angle[331] = 167.238600
|
||||
corr_angle[332] = 167.771500
|
||||
corr_angle[333] = 168.265000
|
||||
corr_angle[334] = 168.794800
|
||||
corr_angle[335] = 169.293800
|
||||
corr_angle[336] = 169.813300
|
||||
corr_angle[337] = 170.320200
|
||||
corr_angle[338] = 170.845100
|
||||
corr_angle[339] = 171.344000
|
||||
corr_angle[340] = 171.866200
|
||||
corr_angle[341] = 172.375300
|
||||
corr_angle[342] = 172.899400
|
||||
corr_angle[343] = 173.404400
|
||||
corr_angle[344] = 173.928500
|
||||
corr_angle[345] = 174.430800
|
||||
corr_angle[346] = 174.827800
|
||||
corr_angle[347] = 175.460400
|
||||
corr_angle[348] = 175.993100
|
||||
corr_angle[349] = 176.492100
|
||||
corr_angle[350] = 177.014200
|
||||
corr_angle[351] = 177.512100
|
||||
corr_angle[352] = 178.044200
|
||||
corr_angle[353] = 178.643800
|
||||
corr_angle[354] = 179.067200
|
||||
corr_angle[355] = 179.571600
|
||||
corr_angle[356] = 180.093700
|
||||
corr_pos[0] = -0.814519
|
||||
corr_pos[1] = -0.810675
|
||||
corr_pos[2] = -0.806338
|
||||
corr_pos[3] = -0.802047
|
||||
corr_pos[4] = -0.797044
|
||||
corr_pos[5] = -0.791712
|
||||
corr_pos[6] = -0.786558
|
||||
corr_pos[7] = -0.780781
|
||||
corr_pos[8] = -0.774864
|
||||
corr_pos[9] = -0.768674
|
||||
corr_pos[10] = -0.762005
|
||||
corr_pos[11] = -0.755474
|
||||
corr_pos[12] = -0.748024
|
||||
corr_pos[13] = -0.740730
|
||||
corr_pos[14] = -0.732929
|
||||
corr_pos[15] = -0.725011
|
||||
corr_pos[16] = -0.716637
|
||||
corr_pos[17] = -0.707676
|
||||
corr_pos[18] = -0.698861
|
||||
corr_pos[19] = -0.686245
|
||||
corr_pos[20] = -0.676596
|
||||
corr_pos[21] = -0.663643
|
||||
corr_pos[22] = -0.655664
|
||||
corr_pos[23] = -0.642249
|
||||
corr_pos[24] = -0.633516
|
||||
corr_pos[25] = -0.621402
|
||||
corr_pos[26] = -0.612846
|
||||
corr_pos[27] = -0.599978
|
||||
corr_pos[28] = -0.592135
|
||||
corr_pos[29] = -0.577949
|
||||
corr_pos[30] = -0.570695
|
||||
corr_pos[31] = -0.555560
|
||||
corr_pos[32] = -0.549015
|
||||
corr_pos[33] = -0.532162
|
||||
corr_pos[34] = -0.524479
|
||||
corr_pos[35] = -0.507848
|
||||
corr_pos[36] = -0.500301
|
||||
corr_pos[37] = -0.484361
|
||||
corr_pos[38] = -0.477365
|
||||
corr_pos[39] = -0.461751
|
||||
corr_pos[40] = -0.455963
|
||||
corr_pos[41] = -0.439438
|
||||
corr_pos[42] = -0.436103
|
||||
corr_pos[43] = -0.420587
|
||||
corr_pos[44] = -0.417361
|
||||
corr_pos[45] = -0.402270
|
||||
corr_pos[46] = -0.400459
|
||||
corr_pos[47] = -0.384745
|
||||
corr_pos[48] = -0.385280
|
||||
corr_pos[49] = -0.371217
|
||||
corr_pos[50] = -0.373612
|
||||
corr_pos[51] = -0.361838
|
||||
corr_pos[52] = -0.365771
|
||||
corr_pos[53] = -0.354641
|
||||
corr_pos[54] = -0.360647
|
||||
corr_pos[55] = -0.351446
|
||||
corr_pos[56] = -0.359147
|
||||
corr_pos[57] = -0.348696
|
||||
corr_pos[58] = -0.359348
|
||||
corr_pos[59] = -0.349962
|
||||
corr_pos[60] = -0.360782
|
||||
corr_pos[61] = -0.355040
|
||||
corr_pos[62] = -0.367441
|
||||
corr_pos[63] = -0.360511
|
||||
corr_pos[64] = -0.372617
|
||||
corr_pos[65] = -0.366120
|
||||
corr_pos[66] = -0.377568
|
||||
corr_pos[67] = -0.370362
|
||||
corr_pos[68] = -0.380918
|
||||
corr_pos[69] = -0.372553
|
||||
corr_pos[70] = -0.381460
|
||||
corr_pos[71] = -0.371828
|
||||
corr_pos[72] = -0.379428
|
||||
corr_pos[73] = -0.368465
|
||||
corr_pos[74] = -0.374297
|
||||
corr_pos[75] = -0.360340
|
||||
corr_pos[76] = -0.365429
|
||||
corr_pos[77] = -0.349168
|
||||
corr_pos[78] = -0.351544
|
||||
corr_pos[79] = -0.332514
|
||||
corr_pos[80] = -0.333505
|
||||
corr_pos[81] = -0.313316
|
||||
corr_pos[82] = -0.313014
|
||||
corr_pos[83] = -0.291107
|
||||
corr_pos[84] = -0.287807
|
||||
corr_pos[85] = -0.264483
|
||||
corr_pos[86] = -0.260891
|
||||
corr_pos[87] = -0.236646
|
||||
corr_pos[88] = -0.231362
|
||||
corr_pos[89] = -0.205833
|
||||
corr_pos[90] = -0.200663
|
||||
corr_pos[91] = -0.174834
|
||||
corr_pos[92] = -0.171662
|
||||
corr_pos[93] = -0.146200
|
||||
corr_pos[94] = -0.142890
|
||||
corr_pos[95] = -0.118389
|
||||
corr_pos[96] = -0.112895
|
||||
corr_pos[97] = -0.088879
|
||||
corr_pos[98] = -0.084146
|
||||
corr_pos[99] = -0.061625
|
||||
corr_pos[100] = -0.054742
|
||||
corr_pos[101] = -0.032741
|
||||
corr_pos[102] = -0.026725
|
||||
corr_pos[103] = -0.004827
|
||||
corr_pos[104] = 0.002678
|
||||
corr_pos[105] = 0.024418
|
||||
corr_pos[106] = 0.031105
|
||||
corr_pos[107] = 0.052334
|
||||
corr_pos[108] = 0.060072
|
||||
corr_pos[109] = 0.081470
|
||||
corr_pos[110] = 0.088550
|
||||
corr_pos[111] = 0.109685
|
||||
corr_pos[112] = 0.116675
|
||||
corr_pos[113] = 0.136298
|
||||
corr_pos[114] = 0.142152
|
||||
corr_pos[115] = 0.161986
|
||||
corr_pos[116] = 0.166996
|
||||
corr_pos[117] = 0.186466
|
||||
corr_pos[118] = 0.190874
|
||||
corr_pos[119] = 0.208729
|
||||
corr_pos[120] = 0.212714
|
||||
corr_pos[121] = 0.229992
|
||||
corr_pos[122] = 0.232685
|
||||
corr_pos[123] = 0.248748
|
||||
corr_pos[124] = 0.249688
|
||||
corr_pos[125] = 0.264768
|
||||
corr_pos[126] = 0.264432
|
||||
corr_pos[127] = 0.278801
|
||||
corr_pos[128] = 0.278424
|
||||
corr_pos[129] = 0.289656
|
||||
corr_pos[130] = 0.289612
|
||||
corr_pos[131] = 0.299899
|
||||
corr_pos[132] = 0.299782
|
||||
corr_pos[133] = 0.307473
|
||||
corr_pos[134] = 0.309489
|
||||
corr_pos[135] = 0.315999
|
||||
corr_pos[136] = 0.317413
|
||||
corr_pos[137] = 0.325060
|
||||
corr_pos[138] = 0.325931
|
||||
corr_pos[139] = 0.332544
|
||||
corr_pos[140] = 0.332095
|
||||
corr_pos[141] = 0.338738
|
||||
corr_pos[142] = 0.337864
|
||||
corr_pos[143] = 0.343909
|
||||
corr_pos[144] = 0.342973
|
||||
corr_pos[145] = 0.348449
|
||||
corr_pos[146] = 0.346060
|
||||
corr_pos[147] = 0.351949
|
||||
corr_pos[148] = 0.349873
|
||||
corr_pos[149] = 0.354969
|
||||
corr_pos[150] = 0.352375
|
||||
corr_pos[151] = 0.358388
|
||||
corr_pos[152] = 0.354736
|
||||
corr_pos[153] = 0.359539
|
||||
corr_pos[154] = 0.354369
|
||||
corr_pos[155] = 0.358549
|
||||
corr_pos[156] = 0.353217
|
||||
corr_pos[157] = 0.355795
|
||||
corr_pos[158] = 0.351299
|
||||
corr_pos[159] = 0.352922
|
||||
corr_pos[160] = 0.346933
|
||||
corr_pos[161] = 0.350201
|
||||
corr_pos[162] = 0.343937
|
||||
corr_pos[163] = 0.349304
|
||||
corr_pos[164] = 0.344857
|
||||
corr_pos[165] = 0.347471
|
||||
corr_pos[166] = 0.335793
|
||||
corr_pos[167] = 0.341109
|
||||
corr_pos[168] = 0.330453
|
||||
corr_pos[169] = 0.326576
|
||||
corr_pos[170] = 0.320299
|
||||
corr_pos[171] = 0.315348
|
||||
corr_pos[172] = 0.300744
|
||||
corr_pos[173] = 0.294366
|
||||
corr_pos[174] = 0.280438
|
||||
corr_pos[175] = 0.273618
|
||||
corr_pos[176] = 0.259335
|
||||
corr_pos[177] = 0.251464
|
||||
corr_pos[178] = 0.237247
|
||||
corr_pos[179] = 0.229092
|
||||
corr_pos[180] = 0.214882
|
||||
corr_pos[181] = 0.207363
|
||||
corr_pos[182] = 0.193246
|
||||
corr_pos[183] = 0.185868
|
||||
corr_pos[184] = 0.173256
|
||||
corr_pos[185] = 0.165378
|
||||
corr_pos[186] = 0.153853
|
||||
corr_pos[187] = 0.147031
|
||||
corr_pos[188] = 0.135535
|
||||
corr_pos[189] = 0.129435
|
||||
corr_pos[190] = 0.119843
|
||||
corr_pos[191] = 0.115062
|
||||
corr_pos[192] = 0.107115
|
||||
corr_pos[193] = 0.105182
|
||||
corr_pos[194] = 0.099647
|
||||
corr_pos[195] = 0.098162
|
||||
corr_pos[196] = 0.094628
|
||||
corr_pos[197] = 0.095257
|
||||
corr_pos[198] = 0.084490
|
||||
corr_pos[199] = 0.085389
|
||||
corr_pos[200] = 0.074302
|
||||
corr_pos[201] = 0.075265
|
||||
corr_pos[202] = 0.063623
|
||||
corr_pos[203] = 0.064487
|
||||
corr_pos[204] = 0.052841
|
||||
corr_pos[205] = 0.053559
|
||||
corr_pos[206] = 0.042022
|
||||
corr_pos[207] = 0.043321
|
||||
corr_pos[208] = 0.032826
|
||||
corr_pos[209] = 0.032277
|
||||
corr_pos[210] = 0.022169
|
||||
corr_pos[211] = 0.020740
|
||||
corr_pos[212] = 0.010378
|
||||
corr_pos[213] = 0.008668
|
||||
corr_pos[214] = -0.001930
|
||||
corr_pos[215] = -0.003882
|
||||
corr_pos[216] = -0.014694
|
||||
corr_pos[217] = -0.016629
|
||||
corr_pos[218] = -0.026380
|
||||
corr_pos[219] = -0.028069
|
||||
corr_pos[220] = -0.037125
|
||||
corr_pos[221] = -0.039429
|
||||
corr_pos[222] = -0.047773
|
||||
corr_pos[223] = -0.049261
|
||||
corr_pos[224] = -0.056872
|
||||
corr_pos[225] = -0.058756
|
||||
corr_pos[226] = -0.065279
|
||||
corr_pos[227] = -0.066859
|
||||
corr_pos[228] = -0.073027
|
||||
corr_pos[229] = -0.074253
|
||||
corr_pos[230] = -0.079062
|
||||
corr_pos[231] = -0.079800
|
||||
corr_pos[232] = -0.084350
|
||||
corr_pos[233] = -0.084805
|
||||
corr_pos[234] = -0.088621
|
||||
corr_pos[235] = -0.088437
|
||||
corr_pos[236] = -0.092166
|
||||
corr_pos[237] = -0.090769
|
||||
corr_pos[238] = -0.093820
|
||||
corr_pos[239] = -0.091724
|
||||
corr_pos[240] = -0.094152
|
||||
corr_pos[241] = -0.090866
|
||||
corr_pos[242] = -0.092575
|
||||
corr_pos[243] = -0.089239
|
||||
corr_pos[244] = -0.089666
|
||||
corr_pos[245] = -0.086864
|
||||
corr_pos[246] = -0.087183
|
||||
corr_pos[247] = -0.083974
|
||||
corr_pos[248] = -0.083709
|
||||
corr_pos[249] = -0.079848
|
||||
corr_pos[250] = -0.078494
|
||||
corr_pos[251] = -0.072782
|
||||
corr_pos[252] = -0.069638
|
||||
corr_pos[253] = -0.063004
|
||||
corr_pos[254] = -0.058599
|
||||
corr_pos[255] = -0.051737
|
||||
corr_pos[256] = -0.046451
|
||||
corr_pos[257] = -0.040238
|
||||
corr_pos[258] = -0.034071
|
||||
corr_pos[259] = -0.028578
|
||||
corr_pos[260] = -0.021481
|
||||
corr_pos[261] = -0.016346
|
||||
corr_pos[262] = -0.009475
|
||||
corr_pos[263] = -0.004141
|
||||
corr_pos[264] = 0.002780
|
||||
corr_pos[265] = 0.008455
|
||||
corr_pos[266] = 0.015507
|
||||
corr_pos[267] = 0.021672
|
||||
corr_pos[268] = 0.029704
|
||||
corr_pos[269] = 0.036662
|
||||
corr_pos[270] = 0.044794
|
||||
corr_pos[271] = 0.052031
|
||||
corr_pos[272] = 0.061478
|
||||
corr_pos[273] = 0.069150
|
||||
corr_pos[274] = 0.078715
|
||||
corr_pos[275] = 0.087785
|
||||
corr_pos[276] = 0.098593
|
||||
corr_pos[277] = 0.107863
|
||||
corr_pos[278] = 0.118256
|
||||
corr_pos[279] = 0.127631
|
||||
corr_pos[280] = 0.139011
|
||||
corr_pos[281] = 0.150077
|
||||
corr_pos[282] = 0.162154
|
||||
corr_pos[283] = 0.173758
|
||||
corr_pos[284] = 0.186998
|
||||
corr_pos[285] = 0.200111
|
||||
corr_pos[286] = 0.214116
|
||||
corr_pos[287] = 0.227291
|
||||
corr_pos[288] = 0.240662
|
||||
corr_pos[289] = 0.252955
|
||||
corr_pos[290] = 0.265359
|
||||
corr_pos[291] = 0.275995
|
||||
corr_pos[292] = 0.287613
|
||||
corr_pos[293] = 0.295789
|
||||
corr_pos[294] = 0.306424
|
||||
corr_pos[295] = 0.313027
|
||||
corr_pos[296] = 0.322181
|
||||
corr_pos[297] = 0.329313
|
||||
corr_pos[298] = 0.338191
|
||||
corr_pos[299] = 0.345243
|
||||
corr_pos[300] = 0.353316
|
||||
corr_pos[301] = 0.360491
|
||||
corr_pos[302] = 0.367891
|
||||
corr_pos[303] = 0.375027
|
||||
corr_pos[304] = 0.380865
|
||||
corr_pos[305] = 0.388354
|
||||
corr_pos[306] = 0.395257
|
||||
corr_pos[307] = 0.401478
|
||||
corr_pos[308] = 0.408087
|
||||
corr_pos[309] = 0.414083
|
||||
corr_pos[310] = 0.420361
|
||||
corr_pos[311] = 0.424284
|
||||
corr_pos[312] = 0.429614
|
||||
corr_pos[313] = 0.433888
|
||||
corr_pos[314] = 0.438529
|
||||
corr_pos[315] = 0.442302
|
||||
corr_pos[316] = 0.445899
|
||||
corr_pos[317] = 0.449014
|
||||
corr_pos[318] = 0.451693
|
||||
corr_pos[319] = 0.453795
|
||||
corr_pos[320] = 0.455132
|
||||
corr_pos[321] = 0.455438
|
||||
corr_pos[322] = 0.455334
|
||||
corr_pos[323] = 0.454055
|
||||
corr_pos[324] = 0.451146
|
||||
corr_pos[325] = 0.447259
|
||||
corr_pos[326] = 0.442478
|
||||
corr_pos[327] = 0.437520
|
||||
corr_pos[328] = 0.432297
|
||||
corr_pos[329] = 0.426442
|
||||
corr_pos[330] = 0.418918
|
||||
corr_pos[331] = 0.411040
|
||||
corr_pos[332] = 0.402610
|
||||
corr_pos[333] = 0.394491
|
||||
corr_pos[334] = 0.383925
|
||||
corr_pos[335] = 0.374590
|
||||
corr_pos[336] = 0.363650
|
||||
corr_pos[337] = 0.353143
|
||||
corr_pos[338] = 0.339756
|
||||
corr_pos[339] = 0.328074
|
||||
corr_pos[340] = 0.315463
|
||||
corr_pos[341] = 0.302641
|
||||
corr_pos[342] = 0.288898
|
||||
corr_pos[343] = 0.275134
|
||||
corr_pos[344] = 0.260308
|
||||
corr_pos[345] = 0.245582
|
||||
corr_pos[346] = 0.233584
|
||||
corr_pos[347] = 0.213812
|
||||
corr_pos[348] = 0.196540
|
||||
corr_pos[349] = 0.179844
|
||||
corr_pos[350] = 0.161839
|
||||
corr_pos[351] = 0.144160
|
||||
corr_pos[352] = 0.124715
|
||||
corr_pos[353] = 0.102123
|
||||
corr_pos[354] = 0.085736
|
||||
corr_pos[355] = 0.065743
|
||||
corr_pos[356] = 0.044511
|
||||
File diff suppressed because it is too large
Load Diff
171
csaxs_bec/bec_ipython_client/plugins/omny/gui_tools.py
Normal file
171
csaxs_bec/bec_ipython_client/plugins/omny/gui_tools.py
Normal file
@@ -0,0 +1,171 @@
|
||||
import builtins
|
||||
|
||||
from bec_widgets.cli.client import BECDockArea
|
||||
|
||||
# from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get, epics_put, fshopen, fshclose
|
||||
|
||||
if builtins.__dict__.get("bec") is not None:
|
||||
bec = builtins.__dict__.get("bec")
|
||||
dev = builtins.__dict__.get("dev")
|
||||
umv = builtins.__dict__.get("umv")
|
||||
umvr = builtins.__dict__.get("umvr")
|
||||
|
||||
|
||||
class OMNYGuiToolsError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNYGuiTools:
|
||||
|
||||
def __init__(self, client):
|
||||
self.gui = getattr(client, "gui", None)
|
||||
self.gui_window = self.gui.windows['main'].widget
|
||||
self.fig200 = None
|
||||
self.fig201 = None
|
||||
self.fig202 = None
|
||||
self.fig203 = None
|
||||
self.progressbar = None
|
||||
self.text_box = None
|
||||
self.idle_text_box = None
|
||||
|
||||
def omnygui_show_gui(self):
|
||||
self.gui_window.show()
|
||||
|
||||
def omnygui_stop_gui(self):
|
||||
self.gui_window.hide()
|
||||
|
||||
def _omnycam_parking(self):
|
||||
self.omnygui_show_omnycam_parking()
|
||||
|
||||
def omnygui_show_omnycam_parking(self):
|
||||
self.omnygui_show_gui()
|
||||
if self.fig200 is None:
|
||||
self._omnycam_clear()
|
||||
self.fig200 = self.gui_window.add_dock(name="omnycam200").add_widget("BECImageWidget")
|
||||
if self._omnycam_check_device_exists(dev.cam200):
|
||||
fig = self.fig200.image("cam200")
|
||||
fig.set_rotation(deg_90=3)
|
||||
self.fig200.lock_aspect_ratio(True)
|
||||
else:
|
||||
print("Cannot open cam200. Device does not exist.")
|
||||
self.fig203 = self.gui_window.add_dock(name="omnycam203").add_widget("BECImageWidget")
|
||||
if self._omnycam_check_device_exists(dev.cam203):
|
||||
fig = self.fig203.image("cam203")
|
||||
fig.set_rotation(deg_90=3)
|
||||
self.fig203.lock_aspect_ratio(True)
|
||||
else:
|
||||
print("Cannot open cam203. Device does not exist.")
|
||||
try:
|
||||
self.gui_window.remove_dock(name="default_figure")
|
||||
except:
|
||||
pass
|
||||
|
||||
def omnygui_remove_all_docks(self):
|
||||
self.gui_window.clear_all()
|
||||
self.fig200 = None
|
||||
self.fig201 = None
|
||||
self.fig202 = None
|
||||
self.fig203 = None
|
||||
self.progressbar = None
|
||||
self.text_box = None
|
||||
self.idle_text_box = None
|
||||
|
||||
def omnygui_idle(self):
|
||||
self.omnygui_show_gui()
|
||||
if self.idle_text_box is None:
|
||||
self.omnygui_remove_all_docks()
|
||||
self.idle_text_box = self.gui_window.add_dock(name="idle_text").add_widget("TextBox")
|
||||
try:
|
||||
self.gui_window.remove_dock(name="default_figure")
|
||||
except:
|
||||
pass
|
||||
text = (
|
||||
"<pre>"
|
||||
+ " ,o888888o. ,8. ,8. b. 8 `8.`8888. ,8' \n"
|
||||
+ " . 8888 `88. ,888. ,888. 888o. 8 `8.`8888. ,8' \n"
|
||||
+ ",8 8888 `8b .`8888. .`8888. Y88888o. 8 `8.`8888. ,8' \n"
|
||||
+ "88 8888 `8b ,8.`8888. ,8.`8888. .`Y888888o. 8 `8.`8888.,8' \n"
|
||||
+ "88 8888 88 ,8'8.`8888,8^8.`8888. 8o. `Y888888o. 8 `8.`88888' \n"
|
||||
+ "88 8888 88 ,8' `8.`8888' `8.`8888. 8`Y8o. `Y88888o8 `8. 8888 \n"
|
||||
+ "88 8888 ,8P ,8' `8.`88' `8.`8888. 8 `Y8o. `Y8888 `8 8888 \n"
|
||||
+ "`8 8888 ,8P ,8' `8.`' `8.`8888. 8 `Y8o. `Y8 8 8888 \n"
|
||||
+ " ` 8888 ,88' ,8' `8 `8.`8888. 8 `Y8o.` 8 8888 \n"
|
||||
+ " `8888888P' ,8' ` `8.`8888. 8 `Yo 8 8888 \n"
|
||||
+ "</pre>"
|
||||
)
|
||||
self.idle_text_box.set_html_text(text)
|
||||
|
||||
def _omnycam_clear(self):
|
||||
self.omnygui_remove_all_docks()
|
||||
|
||||
def _omnycam_check_device_exists(self, device):
|
||||
try:
|
||||
device
|
||||
except:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def _omnycam_samplestage(self):
|
||||
self.omnygui_show_omnycam_samplestage()
|
||||
|
||||
def omnygui_show_omnycam_samplestage(self):
|
||||
self.omnygui_show_gui()
|
||||
if self.fig201 is None:
|
||||
self.omnygui_remove_all_docks()
|
||||
self.fig201 = self.gui_window.add_dock(name="omnycam201").add_widget("BECImageWidget")
|
||||
if self._omnycam_check_device_exists(dev.cam201):
|
||||
fig = self.fig201.image("cam201")
|
||||
fig.set_rotation(deg_90=3)
|
||||
self.fig201.lock_aspect_ratio(True)
|
||||
else:
|
||||
print("Cannot open cam201. Device does not exist.")
|
||||
self.fig202 = self.gui_window.add_dock(name="omnycam202").add_widget("BECImageWidget")
|
||||
if self._omnycam_check_device_exists(dev.cam202):
|
||||
fig = self.fig202.image("cam202")
|
||||
fig.set_rotation(deg_90=3)
|
||||
self.fig202.lock_aspect_ratio(True)
|
||||
else:
|
||||
print("Cannot open cam202. Device does not exist.")
|
||||
try:
|
||||
self.gui_window.remove_dock(name="default_figure")
|
||||
except:
|
||||
pass
|
||||
|
||||
def omnygui_show_progress(self):
|
||||
self.omnygui_show_gui()
|
||||
if self.progressbar is None:
|
||||
self.omnygui_remove_all_docks()
|
||||
# Add a new dock with a RingProgressBar widget
|
||||
self.progressbar = self.gui_window.add_dock(name="progress").add_widget("RingProgressBar")
|
||||
# Customize the size of the progress ring
|
||||
self.progressbar.set_line_widths(20)
|
||||
# Disable automatic updates and manually set the self.progressbar value
|
||||
self.progressbar.enable_auto_updates(False)
|
||||
# Set precision for the self.progressbar display
|
||||
self.progressbar.set_precision(1) # Display self.progressbar with one decimal places
|
||||
# Setting multiple rigns with different values
|
||||
self.progressbar.set_number_of_bars(3)
|
||||
self.progressbar.rings[2].set_update("scan")
|
||||
# Set the values of the rings to 50, 75, and 25 from outer to inner ring
|
||||
# self.progressbar.set_value([50, 75])
|
||||
# Add a new dock with a TextBox widget
|
||||
self.text_box = self.gui_window.add_dock(name="progress_text").add_widget("TextBox")
|
||||
try:
|
||||
self.gui_window.remove_dock(name="default_figure")
|
||||
except:
|
||||
pass
|
||||
self._omnygui_update_progress()
|
||||
|
||||
def _omnygui_update_progress(self):
|
||||
if self.progressbar is not None:
|
||||
progress = self.progress["projection"] / self.progress["total_projections"] * 100
|
||||
subotmo_progress = (
|
||||
self.progress["subtomo_projection"]
|
||||
/ self.progress["subtomo_total_projections"]
|
||||
* 100
|
||||
)
|
||||
self.progressbar.set_value([progress, subotmo_progress])
|
||||
|
||||
text = f"Progress report:\n Tomo type: ....................... {self.progress['tomo_type']}\n Projection: ...................... {self.progress['projection']:.0f}\n Total projections expected ....... {self.progress['total_projections']}\n Angle: ........................... {self.progress['angle']}\n Current subtomo: ................. {self.progress['subtomo']}\n Current projection within subtomo: {self.progress['subtomo_projection']}\n Total projections per subtomo: ... {self.progress['subtomo_total_projections']}"
|
||||
self.text_box.set_plain_text(text)
|
||||
1532
csaxs_bec/bec_ipython_client/plugins/omny/omny.py
Normal file
1532
csaxs_bec/bec_ipython_client/plugins/omny/omny.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,246 @@
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
from rich import box
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
from typeguard import typechecked
|
||||
from bec_lib import bec_logger
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class OMNYAlignmentError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNYAlignmentMixin:
|
||||
default_correction_file = "correction_omny_202204.txt"
|
||||
default_correction_file_x = "correction_omny_202204_x.txt"
|
||||
|
||||
def reset_correction(self, use_default_correction=True):
|
||||
"""
|
||||
Reset the correction to the default values.
|
||||
If use_default_correction is False, the correction will be set to empty values.
|
||||
Otherwise the default values will be loaded.
|
||||
|
||||
Args:
|
||||
use_default_correction (bool, optional): If set to true, a call reset the correction to the default values. Defaults to True.
|
||||
"""
|
||||
self.corr_pos_x = []
|
||||
self.corr_angle_x = []
|
||||
self.corr_pos_y = []
|
||||
self.corr_angle_y = []
|
||||
self.corr_pos_y_2 = []
|
||||
self.corr_angle_y_2 = []
|
||||
|
||||
if use_default_correction:
|
||||
try:
|
||||
self.read_additional_correction_x(self.default_correction_file_x)
|
||||
logger.info(f"Applying default x correction from {self.default_correction_file_x}")
|
||||
except FileNotFoundError:
|
||||
logger.warning(
|
||||
f"Could not find default correction file {self.default_correction_file_x}."
|
||||
)
|
||||
logger.warning("Not applying any correction.")
|
||||
try:
|
||||
self.read_additional_correction_y(self.default_correction_file)
|
||||
logger.info(f"Applying default y correction from {self.default_correction_file}")
|
||||
except FileNotFoundError:
|
||||
logger.warning(
|
||||
f"Could not find default correction file {self.default_correction_file}."
|
||||
)
|
||||
logger.warning("Not applying any correction.")
|
||||
|
||||
def reset_tomo_alignment_fit(self):
|
||||
self.client.delete_global_var("tomo_alignment_fit")
|
||||
|
||||
def read_alignment_offset(
|
||||
self,
|
||||
dir_path=os.path.expanduser("~/Data10/specES1/internal/"),
|
||||
setup="omny",
|
||||
use_vertical_default_values=True,
|
||||
):
|
||||
"""
|
||||
Read the alignment offset from the given directory and set the global parameter
|
||||
tomo_alignment_fit.
|
||||
|
||||
Args:
|
||||
dir_path (str, optional): The directory to read the alignment offset from. Defaults to os.path.expanduser("~/Data10/specES1/internal/").
|
||||
"""
|
||||
tomo_alignment_fit = np.zeros((2, 5))
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Ax.txt"), "r") as file:
|
||||
tomo_alignment_fit[0][0] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Bx.txt"), "r") as file:
|
||||
tomo_alignment_fit[0][1] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Cx.txt"), "r") as file:
|
||||
tomo_alignment_fit[0][2] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Ay.txt"), "r") as file:
|
||||
tomo_alignment_fit[1][0] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_By.txt"), "r") as file:
|
||||
tomo_alignment_fit[1][1] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Cy.txt"), "r") as file:
|
||||
tomo_alignment_fit[1][2] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Ay3.txt"), "r") as file:
|
||||
tomo_alignment_fit[1][3] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Cy3.txt"), "r") as file:
|
||||
tomo_alignment_fit[1][4] = file.readline()
|
||||
|
||||
print("New alignment parameters loaded:")
|
||||
print(
|
||||
f"X Amplitude {tomo_alignment_fit[0][0]}, "
|
||||
f"X Phase {tomo_alignment_fit[0][1]}, "
|
||||
f"X Offset {tomo_alignment_fit[0][2]}, "
|
||||
f"Y Amplitude {tomo_alignment_fit[1][0]}, "
|
||||
f"Y Phase {tomo_alignment_fit[1][1]}, "
|
||||
f"Y Offset {tomo_alignment_fit[1][2]}, "
|
||||
f"Y 3rd Order Amplitude {tomo_alignment_fit[1][3]}, "
|
||||
f"Y 3rd Order Phase {tomo_alignment_fit[1][4]} ."
|
||||
)
|
||||
|
||||
if use_vertical_default_values:
|
||||
print(
|
||||
f"Using default values for vertical alignment for setup {setup}. Optional: use_vertical_default_values=False"
|
||||
)
|
||||
if setup == "flomni":
|
||||
tomo_alignment_fit[1][0] = 0
|
||||
tomo_alignment_fit[1][1] = 0
|
||||
tomo_alignment_fit[1][2] = 0
|
||||
tomo_alignment_fit[1][3] = 0
|
||||
tomo_alignment_fit[1][4] = 0
|
||||
elif setup == "omny":
|
||||
tomo_alignment_fit[1][0] = 2.588628
|
||||
tomo_alignment_fit[1][1] = -2.385422
|
||||
tomo_alignment_fit[1][2] = 0
|
||||
tomo_alignment_fit[1][3] = 1.010583
|
||||
tomo_alignment_fit[1][4] = -1.359157
|
||||
|
||||
print("Follwing parameters will be used:")
|
||||
print(
|
||||
f"X Amplitude {tomo_alignment_fit[0][0]}, "
|
||||
f"X Phase {tomo_alignment_fit[0][1]}, "
|
||||
f"X Offset {tomo_alignment_fit[0][2]}, "
|
||||
f"Y Amplitude {tomo_alignment_fit[1][0]}, "
|
||||
f"Y Phase {tomo_alignment_fit[1][1]}, "
|
||||
f"Y Offset {tomo_alignment_fit[1][2]}, "
|
||||
f"Y 3rd Order Amplitude {tomo_alignment_fit[1][3]}, "
|
||||
f"Y 3rd Order Phase {tomo_alignment_fit[1][4]} ."
|
||||
)
|
||||
|
||||
self.client.set_global_var("tomo_alignment_fit", tomo_alignment_fit.tolist())
|
||||
# x amp, phase, offset, y amp, phase, offset, 3rd order amp, 3rd order phase
|
||||
# 0 0 0 1 0 2 1 0 1 1 1 2 1 3 1 4
|
||||
|
||||
def get_alignment_offset(self, angle: float):
|
||||
"""
|
||||
Compute the alignment offset for the given angle.
|
||||
|
||||
Args:
|
||||
angle (float): The angle to compute the alignment offset for.
|
||||
|
||||
Returns:
|
||||
tuple: The alignment offset in x, y and z direction.
|
||||
"""
|
||||
tomo_alignment_fit = self.client.get_global_var("tomo_alignment_fit")
|
||||
if tomo_alignment_fit is None:
|
||||
print("Not applying any alignment offsets. No tomo alignment fit data available.\n")
|
||||
return (0, 0, 0)
|
||||
|
||||
# x amp, phase, offset, y amp, phase, offset
|
||||
# 0 0 0 1 0 2 1 0 1 1 1 2
|
||||
correction_x = (
|
||||
tomo_alignment_fit[0][0] * np.sin(np.radians(angle) + tomo_alignment_fit[0][1])
|
||||
+ tomo_alignment_fit[0][2]
|
||||
)
|
||||
correction_y = (
|
||||
tomo_alignment_fit[1][0] * np.sin(np.radians(angle) + tomo_alignment_fit[1][1])
|
||||
+ tomo_alignment_fit[1][2]
|
||||
+ tomo_alignment_fit[1][3] * np.sin(3 * np.radians(angle) + tomo_alignment_fit[1][4])
|
||||
)
|
||||
correction_z = tomo_alignment_fit[0][0] * np.sin(
|
||||
np.radians(angle + 90) + tomo_alignment_fit[0][1]
|
||||
)
|
||||
|
||||
print(
|
||||
f"Alignment offset x {correction_x}, y {correction_y}, z {correction_z} for angle"
|
||||
f" {angle}\n"
|
||||
)
|
||||
return (correction_x, correction_y, correction_z)
|
||||
|
||||
def _read_correction_file(self, correction_file: str):
|
||||
with open(correction_file, "r") as f:
|
||||
num_elements = f.readline()
|
||||
int_num_elements = int(num_elements.split(" ")[2])
|
||||
corr_pos = []
|
||||
corr_angle = []
|
||||
for j in range(int_num_elements * 2):
|
||||
line = f.readline()
|
||||
value = line.split(" ")[2]
|
||||
name = line.split(" ")[0].split("[")[0]
|
||||
if name == "corr_pos":
|
||||
corr_pos.append(float(value))
|
||||
elif name == "corr_angle":
|
||||
corr_angle.append(float(value))
|
||||
print(
|
||||
f"Loading default mirror correction from file {correction_file} containing {int_num_elements} elements."
|
||||
)
|
||||
# print(corr_pos)
|
||||
return corr_pos, corr_angle
|
||||
|
||||
def read_additional_correction_x(self, correction_file: str):
|
||||
self.corr_pos_x, self.corr_angle_x = self._read_correction_file(correction_file)
|
||||
|
||||
def read_additional_correction_y(self, correction_file: str):
|
||||
self.corr_pos_y, self.corr_angle_y = self._read_correction_file(correction_file)
|
||||
|
||||
def read_additional_correction_y_2(self, correction_file: str):
|
||||
self.corr_pos_y_2, self.corr_angle_y_2 = self._read_correction_file(correction_file)
|
||||
|
||||
def compute_additional_correction_x(self, angle):
|
||||
return self._compute_additional_correction(angle, iteration="x1")
|
||||
|
||||
def compute_additional_correction_y(self, angle):
|
||||
return self._compute_additional_correction(angle, iteration="y1")
|
||||
|
||||
def compute_additional_correction_y_2(self, angle):
|
||||
return self._compute_additional_correction(angle, iteration="y2")
|
||||
|
||||
def _compute_additional_correction(self, angle, iteration="y1"):
|
||||
if iteration == "x1":
|
||||
corr_pos = self.corr_pos_x
|
||||
corr_angle = self.corr_angle_x
|
||||
elif iteration == "y1":
|
||||
corr_pos = self.corr_pos_y
|
||||
corr_angle = self.corr_angle_y
|
||||
elif iteration == "y2":
|
||||
corr_pos = self.corr_pos_y_2
|
||||
corr_angle = self.corr_angle_y_2
|
||||
if not corr_pos:
|
||||
print(f"Not applying any additional correction {iteration}. No data available.\n")
|
||||
return 0
|
||||
|
||||
# find index of closest angle
|
||||
for j, _ in enumerate(corr_pos):
|
||||
newangledelta = np.fabs(corr_angle[j] - angle)
|
||||
if j == 0:
|
||||
angledelta = newangledelta
|
||||
additional_correction_shift = corr_pos[j]
|
||||
continue
|
||||
|
||||
if newangledelta < angledelta:
|
||||
additional_correction_shift = corr_pos[j]
|
||||
angledelta = newangledelta
|
||||
|
||||
if additional_correction_shift == 0 and angle > corr_angle[-1]:
|
||||
additional_correction_shift = corr_pos[-1]
|
||||
print(f"Additional correction shift {iteration}: {additional_correction_shift}")
|
||||
return additional_correction_shift
|
||||
153
csaxs_bec/bec_ipython_client/plugins/omny/omny_general_tools.py
Normal file
153
csaxs_bec/bec_ipython_client/plugins/omny/omny_general_tools.py
Normal file
@@ -0,0 +1,153 @@
|
||||
import time
|
||||
import numpy as np
|
||||
import sys
|
||||
import termios
|
||||
import tty
|
||||
import fcntl
|
||||
import os
|
||||
import builtins
|
||||
|
||||
from rich import box
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
# from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get, epics_put, fshopen, fshclose
|
||||
|
||||
if builtins.__dict__.get("bec") is not None:
|
||||
bec = builtins.__dict__.get("bec")
|
||||
dev = builtins.__dict__.get("dev")
|
||||
umv = builtins.__dict__.get("umv")
|
||||
umvr = builtins.__dict__.get("umvr")
|
||||
|
||||
|
||||
class OMNYToolsError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNYTools:
|
||||
|
||||
HEADER = "\033[95m"
|
||||
OKBLUE = "\033[94m"
|
||||
OKCYAN = "\033[96m"
|
||||
OKGREEN = "\033[92m"
|
||||
WARNING = "\033[93m"
|
||||
FAIL = "\033[91m"
|
||||
ENDC = "\033[0m"
|
||||
BOLD = "\033[1m"
|
||||
UNDERLINE = "\033[4m"
|
||||
|
||||
def __init__(self, client) -> None:
|
||||
self.client = client
|
||||
|
||||
@staticmethod
|
||||
def _get_user_param_safe(device, var):
|
||||
param = dev[device].user_parameter
|
||||
if not param or param.get(var) is None:
|
||||
raise ValueError(f"Device {device} has no user parameter definition for {var}.")
|
||||
return param.get(var)
|
||||
|
||||
def printgreen(self, string: str):
|
||||
print(self.OKGREEN + string + self.ENDC)
|
||||
|
||||
def printgreenbold(self, string: str):
|
||||
print(self.BOLD + self.OKGREEN + string + self.ENDC)
|
||||
|
||||
def yesno(self, message: str, default="none", autoconfirm=0) -> bool:
|
||||
if autoconfirm and default == "y":
|
||||
self.printgreen(message + " Automatically confirming default: yes")
|
||||
return True
|
||||
elif autoconfirm and default == "n":
|
||||
self.printgreen(message + " Automatically confirming default: no")
|
||||
return False
|
||||
if default == "y":
|
||||
message_ending = " [Y]/n? "
|
||||
elif default == "n":
|
||||
message_ending = " y/[N]? "
|
||||
else:
|
||||
message_ending = " y/n? "
|
||||
while True:
|
||||
user_input = input(self.OKBLUE + message + message_ending + self.ENDC)
|
||||
if (
|
||||
user_input == "Y" or user_input == "y" or user_input == "yes" or user_input == "Yes"
|
||||
) or (default == "y" and user_input == ""):
|
||||
return True
|
||||
if (
|
||||
user_input == "N" or user_input == "n" or user_input == "no" or user_input == "No"
|
||||
) or (default == "n" and user_input == ""):
|
||||
return False
|
||||
else:
|
||||
print("Please expicitely confirm y or n.")
|
||||
|
||||
def tweak_cursor(
|
||||
self, dev1, step1: float, dev2="none", step2: float = "0", special_command="none"
|
||||
):
|
||||
if dev1 not in dev.enabled_devices:
|
||||
print(f"Device 1 {dev} is not in enabled devices.")
|
||||
return
|
||||
if dev2 not in dev.enabled_devices and dev2 != "none":
|
||||
print(f"Device 2 {dev} is not in enabled devices.")
|
||||
return
|
||||
# Save the current terminal settings
|
||||
fd = sys.stdin.fileno()
|
||||
old_term = termios.tcgetattr(fd)
|
||||
try:
|
||||
# Set the terminal to raw mode to capture single key presses
|
||||
tty.setraw(fd)
|
||||
# Set stdin to non-blocking mode
|
||||
old_flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, old_flags | os.O_NONBLOCK)
|
||||
print("Tweak Cursor." + self.BOLD + self.OKBLUE + "Press (q) to quit!\r" + self.ENDC)
|
||||
while True:
|
||||
try:
|
||||
# Read single character input
|
||||
key = sys.stdin.read(1)
|
||||
if key == "q":
|
||||
print("\n\rExiting tweak mode\r")
|
||||
break
|
||||
elif key == "\x1b": # Escape sequences for arrow keys
|
||||
next1, next2 = sys.stdin.read(2)
|
||||
if next1 == "[":
|
||||
if next2 == "A":
|
||||
# print("up")
|
||||
if dev2 != "none":
|
||||
umvr(dev2, step2)
|
||||
if special_command != "none":
|
||||
special_command()
|
||||
elif next2 == "B":
|
||||
# print(" down")
|
||||
if dev2 != "none":
|
||||
umvr(dev2, -step2)
|
||||
if special_command != "none":
|
||||
special_command()
|
||||
elif next2 == "C":
|
||||
# print("right")
|
||||
umvr(dev1, step1)
|
||||
if special_command != "none":
|
||||
special_command()
|
||||
elif next2 == "D":
|
||||
# print("left")
|
||||
umvr(dev1, -step1)
|
||||
if special_command != "none":
|
||||
special_command()
|
||||
|
||||
elif key == "+":
|
||||
step1 = step1 * 2
|
||||
if dev2 != "none":
|
||||
step2 = step2 * 2
|
||||
print(f"\rDouble step size. New step size: {step1}, {step2}\r")
|
||||
elif key == "-":
|
||||
step1 = step1 / 2
|
||||
if dev2 != "none":
|
||||
step2 = step2 / 2
|
||||
print(f"\rHalf step size. New step size: {step1}, {step2}\r")
|
||||
except IOError:
|
||||
# No input available, keep looping
|
||||
pass
|
||||
|
||||
# Sleep for a short period to avoid high CPU usage
|
||||
time.sleep(0.02)
|
||||
|
||||
finally:
|
||||
# Restore the terminal to its original state
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old_term)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, old_flags)
|
||||
384
csaxs_bec/bec_ipython_client/plugins/omny/omny_optics_mixin.py
Normal file
384
csaxs_bec/bec_ipython_client/plugins/omny/omny_optics_mixin.py
Normal file
@@ -0,0 +1,384 @@
|
||||
import time
|
||||
import numpy as np
|
||||
|
||||
from rich import box
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_put, fshclose
|
||||
|
||||
|
||||
class OMNYError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNYOpticsMixin:
|
||||
@staticmethod
|
||||
def _get_user_param_safe(device, var):
|
||||
param = dev[device].user_parameter
|
||||
if not param or param.get(var) is None:
|
||||
raise ValueError(f"Device {device} has no user parameter definition for {var}.")
|
||||
return param.get(var)
|
||||
|
||||
def ooptics_in(self):
|
||||
self.ofzp_in()
|
||||
# ocs_in
|
||||
self.oosa_in()
|
||||
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_enable()
|
||||
|
||||
self.align.update_frame()
|
||||
|
||||
user_input = input(
|
||||
"Is the direct beam gone on the xray eye? Do you see the cone of the FZP?"
|
||||
)
|
||||
if user_input == "y":
|
||||
printf("Next oeye_out...\n")
|
||||
else:
|
||||
raise OMNYError("Failed to properly move in the Xray optics")
|
||||
|
||||
def _oeyey_mv(self, position):
|
||||
# direction dependent speeds
|
||||
if dev.oeyez.get().readback < position:
|
||||
dev.oeyez.controller.socket_put_confirmed("axspeed[7]=15000")
|
||||
else:
|
||||
dev.oeyez.controller.socket_put_confirmed("axspeed[7]=10000")
|
||||
umv(dev.oeyey, position)
|
||||
dev.oeyez.controller.socket_put_confirmed("axspeed[7]=10000")
|
||||
|
||||
def oeye_out(self):
|
||||
fshclose()
|
||||
if self.OMNYTools.yesno("Did you move in the optics?"):
|
||||
umv(dev.oeyez, -2)
|
||||
self._oeyey_mv(-60.3)
|
||||
# free camera
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 2)
|
||||
else:
|
||||
raise OMNYError("The optics were not moved in. Please do so prior to eyey_out")
|
||||
self.OMNYTools.printgreen("Oeye is out.")
|
||||
|
||||
def oeye_cam_in(self):
|
||||
if dev.oeyez.get().readback < -80:
|
||||
umv(dev.oeyez, -50)
|
||||
|
||||
if np.fabs(dev.oeyey.get().readback + 4.8) > 0.1:
|
||||
self._oeyey_mv(-4.8)
|
||||
|
||||
if np.fabs(dev.oeyez.get().readback + 2) > 0.1 or np.fabs(dev.oeyex.get().readback) > 0.1:
|
||||
umv(dev.oeyez, -2, dev.oeyex, 0)
|
||||
# if still too close in z -- safety check
|
||||
if np.fabs(dev.oeyez.get().readback + 2) > 0.1:
|
||||
raise OMNYError("The oeye is too close in z for transfer. ERROR! Aborting.")
|
||||
self.OMNYTools.printgreen("Oeye is at cam position.")
|
||||
|
||||
def _oeye_xray_is_in(self) -> bool:
|
||||
omny_oeye_xray_inx = self._get_user_param_safe("oeyex", "xray_in")
|
||||
omny_oeye_xray_iny = self._get_user_param_safe("oeyey", "xray_in")
|
||||
omny_oeye_currentx = dev.oeyex.get().readback
|
||||
omny_oeye_currenty = dev.oeyey.get().readback
|
||||
|
||||
if (
|
||||
np.fabs(omny_oeye_currentx - omny_oeye_xray_inx) < 0.1
|
||||
and np.fabs(omny_oeye_currenty - omny_oeye_xray_iny) < 0.1
|
||||
):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def oeye_xray_in(self):
|
||||
if self._oeye_xray_is_in():
|
||||
pass
|
||||
else:
|
||||
# todo
|
||||
# self._otransfer_gripper_safe_xray_in_operation()
|
||||
# if(!_oshield_is_ST_closed())
|
||||
# {
|
||||
# printf("The shield of the sample stage is not closed. Aborting.\n")
|
||||
# exit
|
||||
# }
|
||||
omny_oeye_xray_inx = self._get_user_param_safe("oeyex", "xray_in")
|
||||
omny_oeye_xray_iny = self._get_user_param_safe("oeyey", "xray_in")
|
||||
omny_oeye_xray_inz = self._get_user_param_safe("oeyez", "xray_in")
|
||||
|
||||
self._oeyey_mv(omny_oeye_xray_iny)
|
||||
omny_oeye_currenty = dev.oeyey.get().readback
|
||||
if np.fabs(omny_oeye_currenty - omny_oeye_xray_iny) > 0.1:
|
||||
raise OMNYError("The oeye did not move up.\n")
|
||||
umv(dev.oeyex, omny_oeye_xray_inx, dev.oeyez, omny_oeye_xray_inz)
|
||||
self.OMNYTools.printgreen("Oeye is at X-ray position.")
|
||||
|
||||
# some notes for the vis microscope:
|
||||
# initial position for the vis light microscope
|
||||
# do not open the shield when the microscope is at the vis mic position
|
||||
# found eoeyx -45.13, z -84.9, y 0.64
|
||||
# for a samy position of 2.8 with delta off
|
||||
# the osa position should be in z around 7.4. in x it seems better
|
||||
# around -0.6, where potentially xrays dont pass anymore
|
||||
#
|
||||
|
||||
def _oosa_check_y(self):
|
||||
omny_oosa_currenty = dev.oosay.get().readback
|
||||
if np.fabs(omny_oosa_currenty - 0.9) > 0.05:
|
||||
umv(dev.oosay, 0.9)
|
||||
omny_oosa_currenty = dev.oosay.get().readback
|
||||
if np.fabs(omny_oosa_currenty - 0.9) > 0.05:
|
||||
raise OMNYError("oosay is not around 0.9. Aborting.")
|
||||
|
||||
def _oosa_to_move_corridor(self):
|
||||
self._oosa_check_y()
|
||||
dev.oosax.limits = [-3, 3.7] # risk collision with shield
|
||||
umv(dev.oosax, -2)
|
||||
dev.oosax.read(cached=False)
|
||||
omny_oosa_currentx = dev.oosax.get().readback
|
||||
if np.fabs(omny_oosa_currentx + 2) > 0.1:
|
||||
raise OMNYError("oosax did not reach target position. Not moving in z.\n")
|
||||
|
||||
def oosa_in(self):
|
||||
self._oosa_check_y()
|
||||
dev.oshield.read(cached=False)
|
||||
omny_oshield_current = dev.oshield.get().readback
|
||||
if omny_oshield_current < 15:
|
||||
self._oshield_ST_close()
|
||||
if self.near_field == False:
|
||||
x_in_pos = self._get_user_param_safe("oosax", "far_field_in")
|
||||
y_in_pos = self._get_user_param_safe("oosay", "far_field_in")
|
||||
z_in_pos = self._get_user_param_safe("oosaz", "far_field_in")
|
||||
print("OSA movement in far-field mode.")
|
||||
dev.oosaz.read(cached=False)
|
||||
omny_oosa_currentz = dev.oosaz.get().readback
|
||||
if omny_oosa_currentz < 6.4:
|
||||
self._oosa_to_move_corridor()
|
||||
dev.oosaz.limits = [6.4, 6.6]
|
||||
umv(dev.oosaz, z_in_pos)
|
||||
umv(dev.oosax, x_in_pos)
|
||||
umv(dev.oosay, y_in_pos)
|
||||
#### For the 30 nm FZP 220 um we use this part
|
||||
# umv oosaz 6.5
|
||||
# umv oosax 3.2453
|
||||
# umv oosay 0.386015
|
||||
|
||||
if self.near_field == True:
|
||||
x_in_pos = self._get_user_param_safe("oosax", "near_field_in")
|
||||
y_in_pos = self._get_user_param_safe("oosay", "near_field_in")
|
||||
z_in_pos = self._get_user_param_safe("oosaz", "near_field_in")
|
||||
print("OSA movement in near-field mode.")
|
||||
dev.oosaz.read(cached=False)
|
||||
omny_oosa_currentz = dev.oosaz.get().readback
|
||||
if omny_oosa_currentz > 0:
|
||||
self._oosa_to_move_corridor()
|
||||
dev.oosaz.limits = [-0.4, -0.6]
|
||||
umv(dev.oosaz, z_in_pos)
|
||||
umv(dev.oosax, x_in_pos)
|
||||
omny_osamy_current = dev.osamy.get().readback
|
||||
if omny_osamy_current < 3.25:
|
||||
umv(dev.oosay, y_in_pos)
|
||||
else:
|
||||
raise OMNYError("Failed to move oosa in. osamy position is too large.")
|
||||
|
||||
self.OMNYTools.printgreen("OSA is in.")
|
||||
|
||||
# todo
|
||||
# _omny_interferometer_align_tracking
|
||||
# rt_feedback_enable
|
||||
|
||||
def oosa_out(self):
|
||||
self._oosa_check_y()
|
||||
dev.oshield.read(cached=False)
|
||||
omny_oshield_current = dev.oshield.get().readback
|
||||
if omny_oshield_current < 15:
|
||||
self._oshield_ST_close()
|
||||
omny_oosaz_current = dev.oosaz.get().readback
|
||||
if self.near_field == False:
|
||||
print("OSA movement in far-field mode.")
|
||||
if omny_oosaz_current < 6.4:
|
||||
self._oosa_to_move_corridor()
|
||||
dev.oosaz.limits = [6.4, 6.6]
|
||||
umv(dev.oosaz, 6.5)
|
||||
umv(dev.oosax, -2)
|
||||
if self.near_field == True:
|
||||
print("OSA movement in near-field mode.")
|
||||
if omny_oosaz_current > 0:
|
||||
self._oosa_to_move_corridor()
|
||||
dev.oosaz.limits = [-0.4, -0.6]
|
||||
umv(dev.oosaz, -0.45)
|
||||
umv(dev.oosax, -2)
|
||||
# todo _omny_interferometer_align_tracking
|
||||
|
||||
self.OMNYTools.printgreen("OSA is out.")
|
||||
|
||||
def oosa_move_out_of_shield(self):
|
||||
# todo: _omnycam_samplestage
|
||||
self._oosa_check_y()
|
||||
self._oosa_to_move_corridor()
|
||||
omny_osamx_current = dev.osamx.get().readback
|
||||
if np.fabs(omny_osamx_current) > 0.2:
|
||||
umv(dev.osamx, 0)
|
||||
omny_oosaz_current = dev.oosaz.get().readback
|
||||
if omny_oosaz_current > 0.1:
|
||||
dev.oosaz.limits = [-0.1, 0.1]
|
||||
umv(dev.oosaz, 0)
|
||||
|
||||
self.OMNYTools.printgreen("OSA is out of shield.")
|
||||
|
||||
def ofzp_out(self):
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
y_out_pos = self._get_user_param_safe("ofzpy", "out")
|
||||
if np.fabs(dev.ofzpy.get().readback - y_out_pos) > 0.02:
|
||||
umv(dev.ofzpy, y_out_pos)
|
||||
self.OMNYTools.printgreen("FZP at out position")
|
||||
|
||||
def ofzp_in(self):
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
x_in_pos = self._get_user_param_safe("ofzpx", "in")
|
||||
y_in_pos = self._get_user_param_safe("ofzpy", "in")
|
||||
if np.fabs(dev.ofzpy.get().readback - y_in_pos) > 0.02:
|
||||
umv(dev.ofzpy, y_in_pos)
|
||||
|
||||
if np.fabs(dev.ofzpx.get().readback - x_in_pos) > 0.02:
|
||||
umv(dev.ofzpx, x_in_pos)
|
||||
self.OMNYTools.printgreen("FZP at in position")
|
||||
# 220 mu FZP at ofzpz 31.8025 for eiger probe (about 2.4 mm propagation after focus)
|
||||
# umv(dev.ofzpy, 0.7944)
|
||||
# if np.fabs(dev.ofzpx.get().readback+0.4317)>0.05:
|
||||
# umv(dev.ofzpx, -0.4317)
|
||||
# note the 220 fzp also works for near field 6.2 kev by just moving back osa and fzp
|
||||
# ofzpz 24.8 leads to a 9.5 mm propagation distance.
|
||||
# With the 220 mu FZP this gives 100 nm pixel recons
|
||||
# for the oosa macro set near_field=1
|
||||
# 170 mu FZP at 6.2 kev for large beam at ofzpz 31.8025 of about 58 mu diameter
|
||||
# 120 mu FZP at ofzpz 28.1991
|
||||
|
||||
# 250 mu FZP 60 nm at 5.65 keV
|
||||
# ofzpz 29.7 for propagation distance 2.2
|
||||
# umv ofzpx -0.4457
|
||||
# umv ofzpy 0.193630
|
||||
|
||||
# 150 um fzp, 60 nm, ofzpz 33.8 at 8.9 kev for propagation of 1.7 mm after focus
|
||||
# umv ofzpx -0.756678
|
||||
# umv ofzpy 0.193515
|
||||
|
||||
# 250 um 30 nm FZP upper right
|
||||
# small abberrations, seems to give good results in weak objects
|
||||
# ofzpx -0.609240
|
||||
# umv ofzpy 0.118265
|
||||
# 250 um 30 nm FZP lower right very aberated
|
||||
# ofzpx -0.881935
|
||||
# umv ofzpy 0.537050
|
||||
|
||||
# ofzpz 28.4027
|
||||
# 5.30 mm prop at 8.9 keV, 45 nm pixel in near field
|
||||
|
||||
# ofzpz 33.103
|
||||
# 0.6 mm prop at 8.9 kev far field 7 m flight tube at foptz
|
||||
|
||||
# ofzpz 49.4 is reachable just without interferometer swap
|
||||
# which at 6.2 keV and 250 um diam, 30 nm should gives a propagation of 0.8 after focus
|
||||
# and a beam size of 6 microns diamter
|
||||
###coordinates 30 nm FZP for comparing them
|
||||
# not sure if that is really correct
|
||||
# FZP 1 - FZP 2
|
||||
# FZP 5
|
||||
# FZP 4 - FZP 1
|
||||
|
||||
# FZP
|
||||
##upper right
|
||||
# umv ofzpx -0.6154 ofzpy 0.1183
|
||||
# umv ocsx -0.6070 ocsy 0.0540
|
||||
|
||||
# lower right
|
||||
# umv ofzpx -0.8341 ofzpy 0.5683
|
||||
# umv ocsx -0.3880 ocsy -0.3960
|
||||
|
||||
# lower left
|
||||
# umv ofzpx -0.3876 ofzpy 0.7902
|
||||
# umv ocsx -0.8380 ocsy -0.6180
|
||||
|
||||
# upper left
|
||||
# umv ofzpx -0.1678 ofzpy 0.3403
|
||||
# umv ocsx -1.0550 ocsy -0.1680
|
||||
|
||||
def ofzp_info(self, mokev_val=-1, ofzpz_val=-1):
|
||||
print(f"{ofzpz_val}")
|
||||
|
||||
if mokev_val == -1:
|
||||
try:
|
||||
mokev_val = dev.mokev.readback.get()
|
||||
except:
|
||||
print(
|
||||
"Device mokev does not exist. You can specify the energy in keV as an argument instead."
|
||||
)
|
||||
return
|
||||
if ofzpz_val == -1:
|
||||
ofzpz_val = dev.ofzpz.readback.get()
|
||||
distance = 66 + 2.4 + 31.8025 - ofzpz_val
|
||||
print(
|
||||
f"\nThe sample is in a distance of \033[1m{distance:.1f} mm\033[0m from the 60 nm FZP.\n"
|
||||
)
|
||||
print(f"At the current energy of {mokev_val:.4f} keV we have following options:\n")
|
||||
|
||||
diameters = [80e-6, 100e-6, 120e-6, 150e-6, 170e-6, 200e-6, 220e-6, 250e-6]
|
||||
|
||||
console = Console()
|
||||
table = Table(title="Outermost zone width \033[1m60 nm\033[0m", box=box.SQUARE)
|
||||
table.add_column("Diameter", justify="center")
|
||||
table.add_column("Focal distance", justify="center")
|
||||
table.add_column("Current beam size", justify="center")
|
||||
|
||||
wavelength = 1.2398e-9 / mokev_val
|
||||
|
||||
for diameter in diameters:
|
||||
outermost_zonewidth = 60e-9
|
||||
focal_distance = diameter * outermost_zonewidth / wavelength * 1000
|
||||
beam_size = -diameter / (focal_distance * 1000) * (focal_distance - distance) * 1e9
|
||||
table.add_row(
|
||||
f"{diameter*1e6:.2f} microns",
|
||||
f"{focal_distance:.2f} mm",
|
||||
f"{beam_size:.2f} microns",
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
# 30 nm with additional spacer
|
||||
distance = 53.84 + 0.6 + 33.1 - ofzpz_val
|
||||
print(
|
||||
f"\nThe sample is in a distance of \033[1m{distance:.1f} mm\033[0m from the 30 nm FZP.\n"
|
||||
)
|
||||
|
||||
diameters = [150e-6, 250e-6]
|
||||
|
||||
console = Console()
|
||||
table = Table(title="Outermost zone width \033[1m30 nm\033[0m", box=box.SQUARE)
|
||||
table.add_column("Diameter", justify="center")
|
||||
table.add_column("Focal distance", justify="center")
|
||||
table.add_column("Current beam size", justify="center")
|
||||
|
||||
wavelength = 1.2398e-9 / mokev_val
|
||||
|
||||
for diameter in diameters:
|
||||
outermost_zonewidth = 30e-9
|
||||
focal_distance = diameter * outermost_zonewidth / wavelength * 1000
|
||||
beam_size = -diameter / (focal_distance * 1000) * (focal_distance - distance) * 1e9
|
||||
table.add_row(
|
||||
f"{diameter*1e6:.2f} microns",
|
||||
f"{focal_distance:.2f} mm",
|
||||
f"{beam_size:.2f} microns",
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
print(
|
||||
"This function can be called with explicit energy and ofzpz position.\n Example: omny.ffzp_info(mokev_val=6.2, ofzpz_val=33.2)"
|
||||
)
|
||||
|
||||
# from flomni
|
||||
# oosaz_val = dev.oosaz.readback.get()
|
||||
|
||||
# print("\nOSA Information:")
|
||||
# print(f" Current fosaz {fosaz_val:.1f}")
|
||||
# print(
|
||||
# f" The OSA will collide with a normal OMNY pin at fosaz \033[1m{(33-fosaz_val):.1f}\033[0m"
|
||||
# )
|
||||
# print(f" Remaining space: \033[1m{-fosaz_val+(33-foptz_val):.1f}\033[0m")
|
||||
241
csaxs_bec/bec_ipython_client/plugins/omny/omny_rt.py
Normal file
241
csaxs_bec/bec_ipython_client/plugins/omny/omny_rt.py
Normal file
@@ -0,0 +1,241 @@
|
||||
import time
|
||||
import numpy as np
|
||||
import sys
|
||||
import termios
|
||||
import tty
|
||||
import fcntl
|
||||
import os
|
||||
|
||||
|
||||
from rich import box
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get, epics_put, fshopen, fshclose
|
||||
|
||||
|
||||
class OMNY_rt_clientError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNY_rt_client:
|
||||
def __init__(self):
|
||||
self.mirror_channel = -1
|
||||
self.mirror_amplitutde_increase = 0
|
||||
self.mirror_parameters = {}
|
||||
for j in range(1, 9):
|
||||
self.mirror_parameters[j] = dev.rtx.controller.get_mirror_parameters(j)
|
||||
|
||||
@staticmethod
|
||||
def _get_user_param_safe(device, var):
|
||||
param = dev[device].user_parameter
|
||||
if not param or param.get(var) is None:
|
||||
raise OMNY_rt_clientError(
|
||||
f"Device {device} has no user parameter definition for {var}."
|
||||
)
|
||||
return param.get(var)
|
||||
|
||||
def _omny_interferometer_openloop_steps(self, channel, steps, amplitude):
|
||||
dev.rtx.controller._omny_interferometer_openloop_steps(channel, steps, amplitude)
|
||||
|
||||
def interferometer_tweaking(self):
|
||||
self._tweak_interferometer()
|
||||
|
||||
def _tweak_interferometer(self):
|
||||
self.mirror_channel = -1
|
||||
|
||||
# Save the current terminal settings
|
||||
fd = sys.stdin.fileno()
|
||||
old_term = termios.tcgetattr(fd)
|
||||
|
||||
print("Ready to tweak the interferometer. Press q to quit.")
|
||||
print("The arrows adjust directions.")
|
||||
print("Numbers select the mirror aligner.")
|
||||
|
||||
try:
|
||||
# Set the terminal to raw mode to capture single key presses
|
||||
tty.setraw(fd)
|
||||
# Set stdin to non-blocking mode
|
||||
old_flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, old_flags | os.O_NONBLOCK)
|
||||
opt_mirrorname = "none"
|
||||
max = 0
|
||||
while True:
|
||||
try:
|
||||
# Read single character input
|
||||
key = sys.stdin.read(1)
|
||||
|
||||
if key == "q":
|
||||
self.mirror_amplitutde_increase = 0
|
||||
self.mirror_channel = -1
|
||||
print("\n\rExiting tweak mode\r")
|
||||
break
|
||||
elif key == "\x1b": # Escape sequences for arrow keys
|
||||
next1, next2 = sys.stdin.read(2)
|
||||
|
||||
if next1 == "[":
|
||||
printit = True
|
||||
if next2 == "A":
|
||||
# print("up")
|
||||
if self.mirror_channel != -1:
|
||||
self._omny_interferometer_openloop_steps(
|
||||
4,
|
||||
-self.mirror_parameters[self.mirror_channel][
|
||||
"opt_steps2_neg"
|
||||
],
|
||||
self.mirror_parameters[self.mirror_channel][
|
||||
"opt_amplitude2_neg"
|
||||
]
|
||||
+ self.mirror_amplitutde_increase,
|
||||
)
|
||||
elif next2 == "B":
|
||||
# print(" down")
|
||||
if self.mirror_channel != -1:
|
||||
self._omny_interferometer_openloop_steps(
|
||||
4,
|
||||
self.mirror_parameters[self.mirror_channel][
|
||||
"opt_steps2_pos"
|
||||
],
|
||||
self.mirror_parameters[self.mirror_channel][
|
||||
"opt_amplitude2_pos"
|
||||
]
|
||||
+ self.mirror_amplitutde_increase,
|
||||
)
|
||||
elif next2 == "C":
|
||||
# print("right")
|
||||
if self.mirror_channel != -1:
|
||||
self._omny_interferometer_openloop_steps(
|
||||
3,
|
||||
-self.mirror_parameters[self.mirror_channel][
|
||||
"opt_steps1_neg"
|
||||
],
|
||||
self.mirror_parameters[self.mirror_channel][
|
||||
"opt_amplitude1_neg"
|
||||
]
|
||||
+ self.mirror_amplitutde_increase,
|
||||
)
|
||||
elif next2 == "D":
|
||||
# print("left")
|
||||
if self.mirror_channel != -1:
|
||||
self._omny_interferometer_openloop_steps(
|
||||
3,
|
||||
self.mirror_parameters[self.mirror_channel][
|
||||
"opt_steps1_pos"
|
||||
],
|
||||
self.mirror_parameters[self.mirror_channel][
|
||||
"opt_amplitude1_pos"
|
||||
]
|
||||
+ self.mirror_amplitutde_increase,
|
||||
)
|
||||
elif key.isdigit() and 1 <= int(key) <= 8:
|
||||
self.mirror_channel = int(key)
|
||||
opt_mirrorname = self.mirror_parameters[self.mirror_channel][
|
||||
"opt_mirrorname"
|
||||
]
|
||||
autostop = self.mirror_parameters[self.mirror_channel]["opt_signal_stop"]
|
||||
averaging_time = self.mirror_parameters[self.mirror_channel][
|
||||
"opt_averaging_time"
|
||||
]
|
||||
print(
|
||||
f"\nSelected mirror channel {self.mirror_channel}: {opt_mirrorname}. Autostop {autostop}. Signal averaging time: {averaging_time}\r"
|
||||
)
|
||||
if int(key) == 6:
|
||||
dev.rtx.controller.laser_tracker_on()
|
||||
dev.rtx.controller._omny_interferometer_switch_channel(self.mirror_channel)
|
||||
max = 0
|
||||
printit = True
|
||||
elif key == "+":
|
||||
print("\nIncreasing voltage amplitudes by 100.\r")
|
||||
self.mirror_amplitutde_increase += 100
|
||||
elif key == "-":
|
||||
print("\nDecreasing voltage amplitudes by 100.\r")
|
||||
self.mirror_amplitutde_increase -= 100
|
||||
elif key == "a":
|
||||
if self.mirror_channel != -1:
|
||||
dev.rtx.controller._omny_interferometer_optimize(
|
||||
mirror_channel=self.mirror_channel, channel=3
|
||||
)
|
||||
dev.rtx.controller._omny_interferometer_optimize(
|
||||
mirror_channel=self.mirror_channel, channel=4
|
||||
)
|
||||
dev.rtx.controller._omny_interferometer_optimize(
|
||||
mirror_channel=self.mirror_channel, channel=3
|
||||
)
|
||||
dev.rtx.controller._omny_interferometer_optimize(
|
||||
mirror_channel=self.mirror_channel, channel=4
|
||||
)
|
||||
if self.mirror_channel != -1 and printit:
|
||||
printit = False
|
||||
signal = dev.rtx.controller._omny_interferometer_get_signalsample(
|
||||
self.mirror_parameters[self.mirror_channel]["opt_signalchannel"],
|
||||
self.mirror_parameters[self.mirror_channel]["opt_averaging_time"],
|
||||
)
|
||||
if signal > max:
|
||||
max = signal
|
||||
info_str = f"Channel {self.mirror_channel}, {opt_mirrorname}, Current signal: {signal:.0f}"
|
||||
filling = " " * (50 - len(info_str))
|
||||
# Calculate the number of filled and unfilled segments
|
||||
length = 30
|
||||
percentage = signal / max
|
||||
filled_length = int(length * percentage)
|
||||
unfilled_length = length - filled_length
|
||||
bar = "#" * filled_length + "-" * unfilled_length
|
||||
print(info_str + filling + "0 " + bar + f" {max:.0f} (q)uit\r", end="")
|
||||
|
||||
except IOError:
|
||||
# No input available, keep looping
|
||||
pass
|
||||
|
||||
# Sleep for a short period to avoid high CPU usage
|
||||
time.sleep(0.02)
|
||||
|
||||
finally:
|
||||
# Restore the terminal to its original state
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old_term)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, old_flags)
|
||||
dev.rtx.controller._omny_interferometer_switch_alloff()
|
||||
self.mirror_channel = -1
|
||||
self.mirror_amplitutde_increase = 0
|
||||
dev.rtx.controller.show_signal_strength_interferometer()
|
||||
|
||||
def show_signal_strength_interferometer(self):
|
||||
dev.rtx.controller.show_signal_strength_interferometer()
|
||||
|
||||
def omny_interferometer_align_incoupling_angle(self):
|
||||
dev.rtx.controller.omny_interferometer_align_incoupling_angle()
|
||||
|
||||
def interferometer_tweak_otrack(self):
|
||||
self.OMNYTools.tweak_cursor(
|
||||
dev.otrackz,
|
||||
0.1,
|
||||
dev.otracky,
|
||||
0.1,
|
||||
special_command=dev.rtx.controller.laser_tracker_print_intensity_for_otrack_tweaking,
|
||||
)
|
||||
|
||||
def feedback_enable_with_reset(self):
|
||||
dev.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def feedback_disable(self):
|
||||
dev.rtx.controller.feedback_disable()
|
||||
|
||||
def feedback_status(self):
|
||||
if dev.rtx.controller.feedback_is_running():
|
||||
print("Feedback is running.")
|
||||
else:
|
||||
print("Feedback is NOT running.")
|
||||
|
||||
def laser_tracker_on(self):
|
||||
dev.rtx.controller.laser_tracker_on()
|
||||
|
||||
def laser_tracker_off(self):
|
||||
dev.rtx.controller.laser_tracker_off()
|
||||
|
||||
def laser_tracker_show_all(self):
|
||||
dev.rtx.controller.laser_tracker_show_all()
|
||||
|
||||
def omny_interferometer_align_tracking(self):
|
||||
dev.rtx.controller.omny_interferometer_align_tracking()
|
||||
|
||||
def laser_tracker_check_and_wait_for_signalstrength(self):
|
||||
dev.rtx.controller.laser_tracker_check_and_wait_for_signalstrength()
|
||||
File diff suppressed because it is too large
Load Diff
235
csaxs_bec/bec_ipython_client/plugins/omny/x_ray_eye_align.py
Normal file
235
csaxs_bec/bec_ipython_client/plugins/omny/x_ray_eye_align.py
Normal file
@@ -0,0 +1,235 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import builtins
|
||||
import os
|
||||
import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bec_lib import bec_logger
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get, epics_put, fshopen
|
||||
|
||||
logger = bec_logger.logger
|
||||
# import builtins to avoid linter errors
|
||||
bec = builtins.__dict__.get("bec")
|
||||
dev = builtins.__dict__.get("dev")
|
||||
umv = builtins.__dict__.get("umv")
|
||||
umvr = builtins.__dict__.get("umvr")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bec_ipython_client.plugins.omny import OMNY
|
||||
|
||||
|
||||
class XrayEyeAlign:
|
||||
# pixel calibration, multiply to get mm
|
||||
PIXEL_CALIBRATION = 0.2 / 218 # .2 with binning
|
||||
|
||||
def __init__(self, client, omny: OMNY) -> None:
|
||||
self.client = client
|
||||
self.omny = omny
|
||||
self.device_manager = client.device_manager
|
||||
self.scans = client.scans
|
||||
self.alignment_values = {}
|
||||
self.omny.reset_correction()
|
||||
self.omny.reset_tomo_alignment_fit()
|
||||
|
||||
def _reset_init_values(self):
|
||||
self.shift_xy = [0, 0]
|
||||
self._xray_fov_xy = [0, 0]
|
||||
|
||||
def save_frame(self):
|
||||
epics_put("XOMNYI-XEYE-SAVFRAME:0", 1)
|
||||
|
||||
def update_frame(self):
|
||||
epics_put("XOMNYI-XEYE-ACQDONE:0", 0)
|
||||
# start live
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 1)
|
||||
# wait for start live
|
||||
while epics_get("XOMNYI-XEYE-ACQDONE:0") == 0:
|
||||
time.sleep(0.5)
|
||||
print("waiting for live view to start...")
|
||||
fshopen()
|
||||
|
||||
epics_put("XOMNYI-XEYE-ACQDONE:0", 0)
|
||||
|
||||
while epics_get("XOMNYI-XEYE-ACQDONE:0") == 0:
|
||||
print("waiting for new frame...")
|
||||
time.sleep(0.5)
|
||||
|
||||
time.sleep(0.5)
|
||||
# stop live view
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 0)
|
||||
time.sleep(1)
|
||||
# fshclose
|
||||
print("got new frame")
|
||||
|
||||
def tomo_rotate(self, val: float):
|
||||
# pylint: disable=undefined-variable
|
||||
umv(self.device_manager.devices.osamroy, val)
|
||||
|
||||
def get_tomo_angle(self):
|
||||
return self.device_manager.devices.osamroy.readback.get()
|
||||
|
||||
def update_fov(self, k: int):
|
||||
self._xray_fov_xy[0] = max(epics_get(f"XOMNYI-XEYE-XWIDTH_X:{k}"), self._xray_fov_xy[0])
|
||||
self._xray_fov_xy[1] = max(0, self._xray_fov_xy[0])
|
||||
|
||||
@property
|
||||
def movement_buttons_enabled(self):
|
||||
return [epics_get("XOMNYI-XEYE-ENAMVX:0"), epics_get("XOMNYI-XEYE-ENAMVY:0")]
|
||||
|
||||
@movement_buttons_enabled.setter
|
||||
def movement_buttons_enabled(self, enabled: bool):
|
||||
enabled = int(enabled)
|
||||
epics_put("XOMNYI-XEYE-ENAMVX:0", enabled)
|
||||
epics_put("XOMNYI-XEYE-ENAMVY:0", enabled)
|
||||
|
||||
def send_message(self, msg: str):
|
||||
epics_put("XOMNYI-XEYE-MESSAGE:0.DESC", msg)
|
||||
|
||||
def align(self):
|
||||
# reset shift xy and fov params
|
||||
self._reset_init_values()
|
||||
|
||||
self.tomo_rotate(0)
|
||||
epics_put("XOMNYI-XEYE-ANGLE:0", 0)
|
||||
|
||||
self.omny.oeye_xray_in()
|
||||
|
||||
self.omny.feedback_enable_with_reset()
|
||||
|
||||
# disable movement buttons
|
||||
self.movement_buttons_enabled = False
|
||||
|
||||
sample_name = dev.omny_samples.get_sample_name_in_samplestage()
|
||||
epics_put("XOMNYI-XEYE-SAMPLENAME:0.DESC", sample_name)
|
||||
|
||||
# this makes sure we are in a defined state
|
||||
self.omny.feedback_disable()
|
||||
|
||||
epics_put("XOMNYI-XEYE-PIXELSIZE:0", self.PIXEL_CALIBRATION)
|
||||
|
||||
osamx_in = self.omny.OMNYTools._get_user_param_safe("osamx", "in")
|
||||
umv(dev.osamx, osamx_in - 0.35)
|
||||
|
||||
self.omny.ofzp_in()
|
||||
self.update_frame()
|
||||
|
||||
# enable submit buttons
|
||||
self.movement_buttons_enabled = False
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
|
||||
epics_put("XOMNYI-XEYE-STEP:0", 0)
|
||||
self.send_message("Submit center value of FZP.")
|
||||
|
||||
k = 0
|
||||
while True:
|
||||
if epics_get("XOMNYI-XEYE-SUBMIT:0") == 1:
|
||||
val_x = epics_get(f"XOMNYI-XEYE-XVAL_X:{k}") / 2 * self.PIXEL_CALIBRATION # in mm
|
||||
self.alignment_values[k] = val_x
|
||||
print(f"Clicked position {k}: x {self.alignment_values[k]}")
|
||||
rtx_position = dev.rtx.readback.get() / 1000
|
||||
print(f"Current rtx position {rtx_position}")
|
||||
self.alignment_values[k] -= rtx_position
|
||||
print(f"Corrected position {k}: x {self.alignment_values[k]}")
|
||||
|
||||
if k == 0: # received center value of FZP
|
||||
self.send_message("please wait ...")
|
||||
self.movement_buttons_enabled = False
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1) # disable submit button
|
||||
|
||||
self.omny.feedback_disable()
|
||||
osamx_in = self.omny.OMNYTools._get_user_param_safe("osamx", "in")
|
||||
umv(dev.osamx, osamx_in)
|
||||
|
||||
self.omny.ofzp_out()
|
||||
|
||||
self.update_frame()
|
||||
epics_put("XOMNYI-XEYE-RECBG:0", 1)
|
||||
while epics_get("XOMNYI-XEYE-RECBG:0") == 1:
|
||||
time.sleep(0.5)
|
||||
print("waiting for background frame...")
|
||||
|
||||
umv(dev.osamx, osamx_in)
|
||||
time.sleep(0.5)
|
||||
self.omny.feedback_enable_with_reset()
|
||||
|
||||
self.update_frame()
|
||||
self.send_message("Adjust sample height and submit center")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
|
||||
self.movement_buttons_enabled = True
|
||||
|
||||
elif 1 <= k < 5: # received sample center value at samroy 0 ... 315
|
||||
self.send_message("please wait ...")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1)
|
||||
self.movement_buttons_enabled = False
|
||||
|
||||
umv(dev.rtx, 0)
|
||||
self.tomo_rotate(k * 45)
|
||||
epics_put("XOMNYI-XEYE-ANGLE:0", self.get_tomo_angle())
|
||||
self.update_frame()
|
||||
self.send_message("Submit sample center")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
|
||||
epics_put("XOMNYI-XEYE-ENAMVX:0", 1)
|
||||
self.update_fov(k)
|
||||
|
||||
elif k == 5: # received sample center value at samroy 270 and done
|
||||
self.send_message("done...")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1) # disable submit button
|
||||
self.movement_buttons_enabled = False
|
||||
self.update_fov(k)
|
||||
break
|
||||
|
||||
k += 1
|
||||
epics_put("XOMNYI-XEYE-STEP:0", k)
|
||||
|
||||
_xrayeyalignmvx = epics_get("XOMNYI-XEYE-MVX:0")
|
||||
if _xrayeyalignmvx != 0:
|
||||
umvr(dev.rtx, _xrayeyalignmvx)
|
||||
print(f"Current rtx position {dev.rtx.readback.get() / 1000}")
|
||||
epics_put("XOMNYI-XEYE-MVX:0", 0)
|
||||
if k > 0:
|
||||
epics_put(f"XOMNYI-XEYE-STAGEPOSX:{k}", dev.rtx.readback.get() / 1000)
|
||||
time.sleep(3)
|
||||
self.update_frame()
|
||||
|
||||
if k < 2:
|
||||
# allow movements, store movements to calculate center
|
||||
_xrayeyalignmvy = epics_get("XOMNYI-XEYE-MVY:0")
|
||||
if _xrayeyalignmvy != 0:
|
||||
self.omny.feedback_disable()
|
||||
umvr(dev.osamy, _xrayeyalignmvy / 1000)
|
||||
time.sleep(2)
|
||||
epics_put("XOMNYI-XEYE-MVY:0", 0)
|
||||
self.omny.feedback_enable_with_reset()
|
||||
self.update_frame()
|
||||
time.sleep(0.2)
|
||||
|
||||
self.write_output()
|
||||
fovx = self._xray_fov_xy[0] * self.PIXEL_CALIBRATION * 1000 / 2
|
||||
fovy = self._xray_fov_xy[1] * self.PIXEL_CALIBRATION * 1000 / 2
|
||||
|
||||
self.tomo_rotate(0)
|
||||
|
||||
umv(dev.rtx, 0)
|
||||
|
||||
# free camera
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 2)
|
||||
|
||||
print(
|
||||
f"The largest field of view from the xrayeyealign was \nfovx = {fovx:.0f} microns, fovy"
|
||||
f" = {fovy:.0f} microns"
|
||||
)
|
||||
print("Use the matlab routine to FIT the current alignment...")
|
||||
|
||||
print("Then LOAD ALIGNMENT PARAMETERS by running omny.read_alignment_offset()\n")
|
||||
|
||||
def write_output(self):
|
||||
file = os.path.expanduser("~/Data10/specES1/internal/xrayeye_alignmentvalues")
|
||||
if not os.path.exists(file):
|
||||
os.makedirs(os.path.dirname(file), exist_ok=True)
|
||||
with open(file, "w") as alignment_values_file:
|
||||
alignment_values_file.write("angle\thorizontal\n")
|
||||
for k in range(1, 6):
|
||||
fovx_offset = self.alignment_values[0] - self.alignment_values[k]
|
||||
print(f"Writing to file new alignment: number {k}, value x {fovx_offset}")
|
||||
alignment_values_file.write(f"{(k-1)*45}\t{fovx_offset*1000}\n")
|
||||
@@ -62,7 +62,6 @@ bec._beamline_mixin._bl_info_register(OperatorInfo)
|
||||
bec._ip.prompts.username = _session_name
|
||||
bec._ip.prompts.status = 1
|
||||
|
||||
|
||||
# REGISTER BEAMLINE CHECKS
|
||||
from bec_lib.bl_conditions import (
|
||||
FastOrbitFeedbackCondition,
|
||||
|
||||
@@ -12,3 +12,10 @@ def extend_command_line_args(parser):
|
||||
parser.add_argument("--session", help="Session name", type=str, default="cSAXS")
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
# def get_config() -> ServiceConfig:
|
||||
# """
|
||||
# Create and return the service configuration.
|
||||
# """
|
||||
# return ServiceConfig(redis={"host": "localhost", "port": 6379})
|
||||
|
||||
63
csaxs_bec/bec_widgets/auto_updates/auto_updates.py
Normal file
63
csaxs_bec/bec_widgets/auto_updates/auto_updates.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bec_widgets.widgets.containers.auto_update.auto_updates import AutoUpdates
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from bec_lib.messages import ScanStatusMessage
|
||||
|
||||
|
||||
class cSAXSUpdate(AutoUpdates):
|
||||
|
||||
#######################################################################
|
||||
################# GUI Callbacks #######################################
|
||||
#######################################################################
|
||||
|
||||
def on_start(self) -> None:
|
||||
"""
|
||||
Procedure to run when the auto updates are enabled.
|
||||
"""
|
||||
self.start_default_dock()
|
||||
|
||||
def on_stop(self) -> None:
|
||||
"""
|
||||
Procedure to run when the auto updates are disabled.
|
||||
"""
|
||||
|
||||
def on_scan_open(self, msg: ScanStatusMessage) -> None:
|
||||
"""
|
||||
Procedure to run when a scan starts.
|
||||
|
||||
Args:
|
||||
msg (ScanStatusMessage): The scan status message.
|
||||
"""
|
||||
if msg.scan_name == "line_scan" and msg.scan_report_devices:
|
||||
return self.simple_line_scan(msg)
|
||||
if msg.scan_name == "grid_scan" and msg.scan_report_devices:
|
||||
return self.simple_grid_scan(msg)
|
||||
if msg.scan_report_devices:
|
||||
return self.best_effort(msg)
|
||||
return None
|
||||
|
||||
def on_scan_closed(self, msg: ScanStatusMessage) -> None:
|
||||
"""
|
||||
Procedure to run when a scan ends.
|
||||
|
||||
Args:
|
||||
msg (ScanStatusMessage): The scan status message.
|
||||
"""
|
||||
|
||||
def on_scan_abort(self, msg: ScanStatusMessage) -> None:
|
||||
"""
|
||||
Procedure to run when a scan is aborted.
|
||||
|
||||
Args:
|
||||
msg (ScanStatusMessage): The scan status message.
|
||||
"""
|
||||
|
||||
|
||||
class cSAXSUpdateAlignment(AutoUpdates): ...
|
||||
|
||||
|
||||
class cSAXSUpdateScan(AutoUpdates): ...
|
||||
75
csaxs_bec/bec_widgets/widgets/client.py
Normal file
75
csaxs_bec/bec_widgets/widgets/client.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# This file was automatically generated by generate_cli.py
|
||||
# type: ignore
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from bec_lib.logger import bec_logger
|
||||
|
||||
from bec_widgets.cli.rpc.rpc_base import RPCBase, rpc_call
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
# pylint: skip-file
|
||||
|
||||
|
||||
_Widgets = {
|
||||
"OmnyAlignment": "OmnyAlignment",
|
||||
}
|
||||
|
||||
|
||||
class OmnyAlignment(RPCBase):
|
||||
@property
|
||||
@rpc_call
|
||||
def enable_live_view(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
@enable_live_view.setter
|
||||
@rpc_call
|
||||
def enable_live_view(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
@property
|
||||
@rpc_call
|
||||
def user_message(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
@user_message.setter
|
||||
@rpc_call
|
||||
def user_message(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
@property
|
||||
@rpc_call
|
||||
def sample_name(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
@sample_name.setter
|
||||
@rpc_call
|
||||
def sample_name(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
@property
|
||||
@rpc_call
|
||||
def enable_move_buttons(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
@enable_move_buttons.setter
|
||||
@rpc_call
|
||||
def enable_move_buttons(self):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
139
csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py
Normal file
139
csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py
Normal file
@@ -0,0 +1,139 @@
|
||||
|
||||
|
||||
from typing import TypedDict
|
||||
from bec_widgets.utils.error_popups import SafeSlot
|
||||
import os
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
from bec_widgets.utils.ui_loader import UILoader
|
||||
from qtpy.QtWidgets import QWidget, QPushButton, QLineEdit, QLabel, QVBoxLayout
|
||||
from bec_qthemes import material_icon
|
||||
from bec_lib.logger import bec_logger
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
# class OmnyAlignmentUIComponents(TypedDict):
|
||||
# moveRightButton: QPushButton
|
||||
# moveLeftButton: QPushButton
|
||||
# moveUpButton: QPushButton
|
||||
# moveDownButton: QPushButton
|
||||
# image: Image
|
||||
|
||||
|
||||
class OmnyAlignment(BECWidget, QWidget):
|
||||
USER_ACCESS = ["enable_live_view", "enable_live_view.setter", "user_message", "user_message.setter","sample_name", "sample_name.setter", "enable_move_buttons", "enable_move_buttons.setter"]
|
||||
PLUGIN = True
|
||||
ui_file = "./omny_alignment.ui"
|
||||
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
super().__init__(parent=parent, **kwargs)
|
||||
|
||||
self._load_ui()
|
||||
|
||||
def _load_ui(self):
|
||||
current_path = os.path.dirname(__file__)
|
||||
self.ui = UILoader(self).loader(os.path.join(current_path, self.ui_file))
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.ui)
|
||||
self.setLayout(layout)
|
||||
|
||||
icon_options = {"size": (16, 16), "convert_to_pixmap": False}
|
||||
self.ui.moveRightButton.setText("")
|
||||
self.ui.moveRightButton.setIcon(
|
||||
material_icon(icon_name="keyboard_arrow_right", **icon_options)
|
||||
)
|
||||
|
||||
self.ui.moveLeftButton.setText("")
|
||||
self.ui.moveLeftButton.setIcon(
|
||||
material_icon(icon_name="keyboard_arrow_left", **icon_options)
|
||||
)
|
||||
|
||||
self.ui.moveUpButton.setText("")
|
||||
self.ui.moveUpButton.setIcon(
|
||||
material_icon(icon_name="keyboard_arrow_up", **icon_options)
|
||||
)
|
||||
|
||||
self.ui.moveDownButton.setText("")
|
||||
self.ui.moveDownButton.setIcon(
|
||||
material_icon(icon_name="keyboard_arrow_down", **icon_options)
|
||||
)
|
||||
|
||||
self.ui.confirmButton.setText("OK")
|
||||
|
||||
|
||||
self.ui.liveViewSwitch.enabled.connect(self.on_live_view_enabled)
|
||||
|
||||
|
||||
@property
|
||||
def enable_live_view(self):
|
||||
return self.ui.liveViewSwitch.checked
|
||||
|
||||
@enable_live_view.setter
|
||||
def enable_live_view(self, enable:bool):
|
||||
self.ui.liveViewSwitch.checked = enable
|
||||
|
||||
|
||||
@property
|
||||
def user_message(self):
|
||||
return self.ui.messageLineEdit.text()
|
||||
|
||||
@user_message.setter
|
||||
def user_message(self, message:str):
|
||||
self.ui.messageLineEdit.setText(message)
|
||||
|
||||
@property
|
||||
def sample_name(self):
|
||||
return self.ui.sampleLineEdit.text()
|
||||
|
||||
@sample_name.setter
|
||||
def sample_name(self, message:str):
|
||||
self.ui.sampleLineEdit.setText(message)
|
||||
|
||||
|
||||
@SafeSlot(bool)
|
||||
def on_live_view_enabled(self, enabled:bool):
|
||||
from bec_widgets.widgets.plots.image.image import Image
|
||||
logger.info(f"Live view is enabled: {enabled}")
|
||||
image: Image = self.ui.image
|
||||
if enabled:
|
||||
image.image("cam200")
|
||||
return
|
||||
|
||||
image.disconnect_monitor("cam200")
|
||||
|
||||
|
||||
|
||||
@property
|
||||
def enable_move_buttons(self):
|
||||
move_up:QPushButton = self.ui.moveUpButton
|
||||
move_down:QPushButton = self.ui.moveDownButton
|
||||
move_left:QPushButton = self.ui.moveLeftButton
|
||||
move_right:QPushButton = self.ui.moveRightButton
|
||||
return move_up.isEnabled() and move_down.isEnabled() and move_left.isEnabled() and move_right.isEnabled()
|
||||
|
||||
@enable_move_buttons.setter
|
||||
def enable_move_buttons(self, enabled:bool):
|
||||
move_up:QPushButton = self.ui.moveUpButton
|
||||
move_down:QPushButton = self.ui.moveDownButton
|
||||
move_left:QPushButton = self.ui.moveLeftButton
|
||||
move_right:QPushButton = self.ui.moveRightButton
|
||||
|
||||
move_up.setEnabled(enabled)
|
||||
move_down.setEnabled(enabled)
|
||||
move_left.setEnabled(enabled)
|
||||
move_right.setEnabled(enabled)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from qtpy.QtWidgets import QApplication
|
||||
import sys
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
widget = OmnyAlignment()
|
||||
|
||||
widget.show()
|
||||
sys.exit(app.exec_())
|
||||
@@ -0,0 +1 @@
|
||||
{'files': ['omny_alignment.py']}
|
||||
125
csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.ui
Normal file
125
csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.ui
Normal file
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>988</width>
|
||||
<height>821</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="moveRightButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="moveLeftButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="moveUpButton">
|
||||
<property name="text">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="moveDownButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="confirmButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="sampleLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="messageLineEdit"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Sample</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="Image" name="image">
|
||||
<property name="enable_toolbar" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="inner_axes" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="monitor" stdset="0">
|
||||
<string>cam200</string>
|
||||
</property>
|
||||
<property name="rotation" stdset="0">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="ToggleSwitch" name="liveViewSwitch"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Live View</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Image</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>image</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ToggleSwitch</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>toggle_switch</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
||||
|
||||
from bec_widgets.utils.bec_designer import designer_material_icon
|
||||
from csaxs_bec.bec_widgets.widgets.omny_alignment.omny_alignment import OmnyAlignment
|
||||
|
||||
DOM_XML = """
|
||||
<ui language='c++'>
|
||||
<widget class='OmnyAlignment' name='omny_alignment'>
|
||||
</widget>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
|
||||
class OmnyAlignmentPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._form_editor = None
|
||||
|
||||
def createWidget(self, parent):
|
||||
t = OmnyAlignment(parent)
|
||||
return t
|
||||
|
||||
def domXml(self):
|
||||
return DOM_XML
|
||||
|
||||
def group(self):
|
||||
return ""
|
||||
|
||||
def icon(self):
|
||||
return designer_material_icon(OmnyAlignment.ICON_NAME)
|
||||
|
||||
def includeFile(self):
|
||||
return "omny_alignment"
|
||||
|
||||
def initialize(self, form_editor):
|
||||
self._form_editor = form_editor
|
||||
|
||||
def isContainer(self):
|
||||
return False
|
||||
|
||||
def isInitialized(self):
|
||||
return self._form_editor is not None
|
||||
|
||||
def name(self):
|
||||
return "OmnyAlignment"
|
||||
|
||||
def toolTip(self):
|
||||
return "OmnyAlignment"
|
||||
|
||||
def whatsThis(self):
|
||||
return self.toolTip()
|
||||
@@ -0,0 +1,15 @@
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
||||
return
|
||||
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
||||
|
||||
from csaxs_bec.bec_widgets.widgets.omny_alignment.omny_alignment_plugin import OmnyAlignmentPlugin
|
||||
|
||||
QPyDesignerCustomWidgetCollection.addCustomWidget(OmnyAlignmentPlugin())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
||||
@@ -1,11 +0,0 @@
|
||||
import os
|
||||
|
||||
|
||||
def setup_epics_ca():
|
||||
os.environ["EPICS_CA_AUTO_ADDR_LIST"] = "NO"
|
||||
os.environ["EPICS_CA_ADDR_LIST"] = "129.129.122.255 sls-x12sa-cagw.psi.ch:5836"
|
||||
os.environ["PYTHONIOENCODING"] = "latin1"
|
||||
|
||||
|
||||
def run():
|
||||
setup_epics_ca()
|
||||
0
csaxs_bec/deployments/__init__.py
Normal file
0
csaxs_bec/deployments/__init__.py
Normal file
0
csaxs_bec/deployments/device_server/__init__.py
Normal file
0
csaxs_bec/deployments/device_server/__init__.py
Normal file
11
csaxs_bec/deployments/device_server/startup.py
Normal file
11
csaxs_bec/deployments/device_server/startup.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import os
|
||||
|
||||
|
||||
def setup_epics_ca():
|
||||
# os.environ["EPICS_CA_AUTO_ADDR_LIST"] = "NO"
|
||||
# os.environ["EPICS_CA_ADDR_LIST"] = "129.129.122.255 sls-x12sa-cagw.psi.ch:5836"
|
||||
os.environ["PYTHONIOENCODING"] = "latin1"
|
||||
|
||||
|
||||
def run():
|
||||
setup_epics_ca()
|
||||
0
csaxs_bec/device_configs/bec_device_config_sastt.yaml
Executable file → Normal file
0
csaxs_bec/device_configs/bec_device_config_sastt.yaml
Executable file → Normal file
50
csaxs_bec/device_configs/epics_devices_config.yaml
Normal file
50
csaxs_bec/device_configs/epics_devices_config.yaml
Normal file
@@ -0,0 +1,50 @@
|
||||
ddg_detectors:
|
||||
description: DelayGenerator for detector triggering
|
||||
deviceClass: csaxs_bec.devices.epics.delay_generator_csaxs.DelayGeneratorcSAXS
|
||||
deviceConfig:
|
||||
prefix: 'X12SA-CPCL-DDG3:'
|
||||
ddg_config:
|
||||
delay_burst: 40.e-3
|
||||
delta_width: 0
|
||||
additional_triggers: 0
|
||||
polarity:
|
||||
- 1 # T0 -> DDG MCS
|
||||
- 0 # eiger
|
||||
- 1 # falcon
|
||||
- 1
|
||||
- 1
|
||||
amplitude: 4.5
|
||||
offset: 0
|
||||
thres_trig_level: 2.5
|
||||
set_high_on_exposure: False
|
||||
set_high_on_stage: False
|
||||
deviceTags:
|
||||
- cSAXS
|
||||
- ddg_detectors
|
||||
onFailure: buffer
|
||||
enabled: true
|
||||
readoutPriority: async
|
||||
softwareTrigger: True
|
||||
bpm4i:
|
||||
readoutPriority: monitored
|
||||
deviceClass: ophyd_devices.SimMonitor
|
||||
deviceConfig:
|
||||
deviceTags:
|
||||
- beamline
|
||||
enabled: true
|
||||
readOnly: false
|
||||
samx:
|
||||
readoutPriority: baseline
|
||||
deviceClass: ophyd_devices.SimPositioner
|
||||
deviceConfig:
|
||||
delay: 1
|
||||
limits:
|
||||
- -50
|
||||
- 50
|
||||
tolerance: 0.01
|
||||
update_frequency: 400
|
||||
deviceTags:
|
||||
- user motors
|
||||
enabled: true
|
||||
readOnly: false
|
||||
|
||||
602
csaxs_bec/device_configs/omny_config.yaml
Normal file → Executable file
602
csaxs_bec/device_configs/omny_config.yaml
Normal file → Executable file
@@ -1,3 +1,107 @@
|
||||
# ############################################################
|
||||
# #################### IDS Camera ######################
|
||||
# ############################################################
|
||||
cam200:
|
||||
description: Camera200
|
||||
deviceClass: csaxs_bec.devices.ids_cameras.ids_camera.IDSCamera
|
||||
deviceConfig:
|
||||
camera_ID: 200
|
||||
bits_per_pixel: 24
|
||||
channels: 3
|
||||
m_n_colormode: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: async
|
||||
|
||||
cam201:
|
||||
description: Camera201
|
||||
deviceClass: csaxs_bec.devices.ids_cameras.ids_camera.IDSCamera
|
||||
deviceConfig:
|
||||
camera_ID: 201
|
||||
bits_per_pixel: 24
|
||||
channels: 3
|
||||
m_n_colormode: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: async
|
||||
|
||||
cam202:
|
||||
description: Camera202
|
||||
deviceClass: csaxs_bec.devices.ids_cameras.ids_camera.IDSCamera
|
||||
deviceConfig:
|
||||
camera_ID: 202
|
||||
bits_per_pixel: 24
|
||||
channels: 3
|
||||
m_n_colormode: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: async
|
||||
|
||||
cam203:
|
||||
description: Camera203
|
||||
deviceClass: csaxs_bec.devices.ids_cameras.ids_camera.IDSCamera
|
||||
deviceConfig:
|
||||
camera_ID: 203
|
||||
bits_per_pixel: 24
|
||||
channels: 3
|
||||
m_n_colormode: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: async
|
||||
|
||||
############################################################
|
||||
#################### OMNY RT motors ########################
|
||||
############################################################
|
||||
|
||||
rtx:
|
||||
description: OMNY rt
|
||||
deviceClass: csaxs_bec.devices.omny.rt.rt_omny_ophyd.RtOMNYMotor
|
||||
deviceConfig:
|
||||
axis_Id: A
|
||||
host: mpc3217.psi.ch
|
||||
port: 3333
|
||||
sign: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: on_request
|
||||
userParameter:
|
||||
low_signal: 8500
|
||||
min_signal: 8000
|
||||
rty:
|
||||
description: OMNY rt
|
||||
deviceClass: csaxs_bec.devices.omny.rt.rt_omny_ophyd.RtOMNYMotor
|
||||
deviceConfig:
|
||||
axis_Id: B
|
||||
host: mpc3217.psi.ch
|
||||
port: 3333
|
||||
sign: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: on_request
|
||||
userParameter:
|
||||
tomo_additional_offsety: 0
|
||||
rtz:
|
||||
description: OMNY rt
|
||||
deviceClass: csaxs_bec.devices.omny.rt.rt_omny_ophyd.RtOMNYMotor
|
||||
deviceConfig:
|
||||
axis_Id: C
|
||||
host: mpc3217.psi.ch
|
||||
port: 3333
|
||||
sign: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: on_request
|
||||
|
||||
# ############################################################
|
||||
# ##################### OMNY samples #########################
|
||||
# ############################################################
|
||||
omny_samples:
|
||||
description: OMNYSampleStorage
|
||||
deviceClass: csaxs_bec.devices.omny.omny_sample_storage.OMNYSampleStorage
|
||||
@@ -6,3 +110,501 @@ omny_samples:
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
# ############################################################
|
||||
# ##################### OMNY vacuum ##########################
|
||||
# ############################################################
|
||||
# omny_vcs:
|
||||
# description: OMNYVCS
|
||||
# deviceClass: csaxs_bec.devices.omny.omny_vcs.OMNYVCS
|
||||
# deviceConfig: {}
|
||||
# enabled: true
|
||||
# onFailure: buffer
|
||||
# readOnly: false
|
||||
# readoutPriority: baseline
|
||||
# ############################################################
|
||||
# ##################### OMNY dewar ###########################
|
||||
# ############################################################
|
||||
omny_dewar:
|
||||
description: OMNY Dewar Information
|
||||
deviceClass: csaxs_bec.devices.omny.omny_dewar.OMNYDewar
|
||||
deviceConfig: {}
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
|
||||
# ############################################################
|
||||
# ##################### OMNY temperatures ####################
|
||||
# ############################################################
|
||||
omny_temperatures:
|
||||
description: OMNY Temperatures and pressures
|
||||
deviceClass: csaxs_bec.devices.omny.omny_temperatures.OMNYTemperatures
|
||||
deviceConfig: {}
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
|
||||
############################################################
|
||||
##################### OMNY Galil motors ####################
|
||||
############################################################
|
||||
ofzpx:
|
||||
description: FZP X
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: A
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8081
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: -0.4317
|
||||
ofzpy:
|
||||
description: FZP Y
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: B
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8081
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0.7944
|
||||
out: 0.6377
|
||||
ofzpz:
|
||||
description: FZP Z
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: C
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8081
|
||||
sign: -1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
otransx:
|
||||
description: Transfer X
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: D
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8081
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
otransy:
|
||||
description: Transfer Y
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: E
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8081
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
up_position: -1.2
|
||||
gripper_sensorvoltagetarget: -2.30
|
||||
otransz:
|
||||
description: Transfer Z
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: F
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8081
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
osamx:
|
||||
description: Sample X
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: A
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: -0.1
|
||||
osamz:
|
||||
description: Sample Z
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: B
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: false
|
||||
onFailure: buffer
|
||||
readOnly: true
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
oosay:
|
||||
description: OSA Y
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: C
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
near_field_in: 0.531
|
||||
far_field_in: 0.4122
|
||||
oosax:
|
||||
description: OSA X
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: D
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: -1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
near_field_in: 3.2044
|
||||
far_field_in: 3.022
|
||||
oosaz:
|
||||
description: OSA Z
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: E
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: -1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
near_field_in: -0.4452
|
||||
far_field_in: 6.5
|
||||
oparkz:
|
||||
description: OSA Y
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: F
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
oshuttleopen:
|
||||
description: Shuttle opener
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: G
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: true
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
oshuttlealign:
|
||||
description: Shuttle aligner
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: H
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8082
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: true
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
osamy:
|
||||
description: Sample Y
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: A
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8083
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
otracky:
|
||||
description: Laser Tracker Y
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: B
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8083
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
start_pos: -4.3431
|
||||
osamroy:
|
||||
description: Sample rotation
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: C
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8083
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
in: 0
|
||||
otrackz:
|
||||
description: Laser Tracker Z
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: E
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8083
|
||||
sign: -1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
start_pos: -0.6948
|
||||
oeyex:
|
||||
description: Xray eye X
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: F
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8083
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
xray_in: -45.7394
|
||||
oeyez:
|
||||
description: Xray eye Z
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: G
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8083
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
xray_in: -2
|
||||
oeyey:
|
||||
description: Xray eye Y
|
||||
deviceClass: csaxs_bec.devices.omny.galil.ogalil_ophyd.OMNYGalilMotor
|
||||
deviceConfig:
|
||||
axis_Id: H
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- 0
|
||||
- 0
|
||||
port: 8083
|
||||
sign: 1
|
||||
deviceTags:
|
||||
- omny
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
xray_in: 0.0229
|
||||
|
||||
############################################################
|
||||
#################### flOMNI Smaract motors #################
|
||||
############################################################
|
||||
|
||||
ocsx:
|
||||
description: Central Stop X
|
||||
deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
|
||||
deviceConfig:
|
||||
axis_Id: B
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- -2
|
||||
- 2
|
||||
port: 3334
|
||||
sign: -1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
nothing: 0
|
||||
ocsy:
|
||||
description: Central Stop Y
|
||||
deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
|
||||
deviceConfig:
|
||||
axis_Id: A
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- -2
|
||||
- 2
|
||||
port: 3334
|
||||
sign: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
nothing: 0
|
||||
oshield:
|
||||
description: Thermal Shield Sample Stage
|
||||
deviceClass: csaxs_bec.devices.smaract.smaract_ophyd.SmaractMotor
|
||||
deviceConfig:
|
||||
axis_Id: C
|
||||
host: mpc3217.psi.ch
|
||||
limits:
|
||||
- -14.5
|
||||
- 15.8
|
||||
port: 3334
|
||||
sign: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
userParameter:
|
||||
nothing: 0
|
||||
|
||||
@@ -18,16 +18,22 @@
|
||||
| GirderMotorX1 | Girder X translation pseudo motor | [csaxs_bec.devices.epics.specMotors](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/specMotors.py) |
|
||||
| GirderMotorY1 | Girder Y translation pseudo motor | [csaxs_bec.devices.epics.specMotors](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/specMotors.py) |
|
||||
| GirderMotorYAW | Girder YAW pseudo motor | [csaxs_bec.devices.epics.specMotors](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/specMotors.py) |
|
||||
| IDSCamera | | [csaxs_bec.devices.ids_cameras.ids_camera](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/ids_cameras/ids_camera.py) |
|
||||
| InsertionDevice | Python wrapper for the CSAXS insertion device control<br><br> This wrapper provides a positioner interface for the ID control.<br> is completely custom XBPM with templates directly in the<br> VME repo. Thus it needs a custom ophyd template as well...<br><br> WARN: The x and y are not updated by the IOC<br> | [csaxs_bec.devices.epics.InsertionDevice](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/InsertionDevice.py) |
|
||||
| LamniGalilMotor | | [csaxs_bec.devices.omny.galil.lgalil_ophyd](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/galil/lgalil_ophyd.py) |
|
||||
| MCScSAXS | MCS card for cSAXS for implementation at cSAXS beamline | [csaxs_bec.devices.epics.mcs_csaxs](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/mcs_csaxs.py) |
|
||||
| NPointAxis | <br> NPointAxis class, which inherits from Device and PositionerBase. This class<br> represents an axis of an nPoint piezo stage and provides the necessary<br> functionality to move the axis and read its current position.<br> | [csaxs_bec.devices.npoint.npoint](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/npoint/npoint.py) |
|
||||
| OMNYDewar | | [csaxs_bec.devices.omny.omny_dewar](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/omny_dewar.py) |
|
||||
| OMNYGalilMotor | | [csaxs_bec.devices.omny.galil.ogalil_ophyd](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/galil/ogalil_ophyd.py) |
|
||||
| OMNYSampleStorage | | [csaxs_bec.devices.omny.omny_sample_storage](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/omny_sample_storage.py) |
|
||||
| OMNYTemperatures | | [csaxs_bec.devices.omny.omny_temperatures](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/omny_temperatures.py) |
|
||||
| OMNYVCS | | [csaxs_bec.devices.omny.omny_vcs](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/omny_vcs.py) |
|
||||
| PilatuscSAXS | Pilatus_2 300k detector for CSAXS<br><br> Parent class: PSIDetectorBase<br><br> class attributes:<br> custom_prepare_cls (Eiger9MSetup) : Custom detector setup class for cSAXS,<br> inherits from CustomDetectorMixin<br> cam (SLSDetectorCam) : Detector camera<br> MIN_READOUT (float) : Minimum readout time for the detector<br><br> | [csaxs_bec.devices.epics.pilatus_csaxs](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/pilatus_csaxs.py) |
|
||||
| PmDetectorRotation | Detector rotation pseudo motor<br><br> Small wrapper to convert detector pusher position to rotation angle.<br> | [csaxs_bec.devices.epics.specMotors](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/specMotors.py) |
|
||||
| PmMonoBender | Monochromator bender<br><br> Small wrapper to combine the four monochromator bender motors.<br> | [csaxs_bec.devices.epics.specMotors](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/specMotors.py) |
|
||||
| RtFlomniMotor | | [csaxs_bec.devices.omny.rt.rt_flomni_ophyd](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py) |
|
||||
| RtLamniMotor | | [csaxs_bec.devices.omny.rt.rt_lamni_ophyd](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py) |
|
||||
| RtOMNYMotor | | [csaxs_bec.devices.omny.rt.rt_omny_ophyd](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py) |
|
||||
| SGalilMotor | "SGalil Motors at cSAXS have a<br> DC motor (y axis - vertical) - implemented as C<br> and a step motor (x-axis horizontal) - implemented as E<br> that require different communication for control<br> | [csaxs_bec.devices.omny.galil.sgalil_ophyd](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/omny/galil/sgalil_ophyd.py) |
|
||||
| SIS38XX | SIS38XX card for access to EPICs PVs at cSAXS beamline | [csaxs_bec.devices.epics.mcs_csaxs](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/mcs_csaxs.py) |
|
||||
| SLSDetectorCam | SLS Detector Camera - Pilatus<br><br> Base class to map EPICS PVs to ophyd signals.<br> | [csaxs_bec.devices.epics.pilatus_csaxs](https://gitlab.psi.ch/bec/csaxs_bec/-/blob/main/csaxs_bec/devices/epics/pilatus_csaxs.py) |
|
||||
|
||||
@@ -1,29 +1,24 @@
|
||||
from bec_lib import bec_logger
|
||||
from ophyd import Component
|
||||
from ophyd_devices.interfaces.base_classes.psi_delay_generator_base import (
|
||||
DDGCustomMixin,
|
||||
PSIDelayGeneratorBase,
|
||||
TriggerSource,
|
||||
)
|
||||
from ophyd import Component, DeviceStatus, Kind
|
||||
from ophyd_devices.devices.delay_generator_645 import DelayGenerator, TriggerSource
|
||||
from ophyd_devices.interfaces.base_classes.bec_device_base import BECDeviceBase, CustomPrepare
|
||||
from ophyd_devices.sim.sim_signals import SetableSignal
|
||||
from ophyd_devices.utils import bec_utils
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class DelayGeneratorError(Exception):
|
||||
class DelayGeneratorcSAXSError(Exception):
|
||||
"""Exception raised for errors."""
|
||||
|
||||
|
||||
class DDGSetup(DDGCustomMixin):
|
||||
class DDGSetup(CustomPrepare["DelayGeneratorcSAXS"]):
|
||||
"""
|
||||
Mixin class for DelayGenerator logic at cSAXS.
|
||||
|
||||
At cSAXS, multiple DDGs were operated at the same time. There different behaviour is
|
||||
implemented in the ddg_config signals that are passed via the device config.
|
||||
Custom Prepare class with hooks for beamline specific logic for the DG645 at CSAXS
|
||||
"""
|
||||
|
||||
def initialize_default_parameter(self) -> None:
|
||||
"""Method to initialize default parameters."""
|
||||
def on_wait_for_connection(self) -> None:
|
||||
"""Init default parameter after the all signals are connected"""
|
||||
for ii, channel in enumerate(self.parent.all_channels):
|
||||
self.parent.set_channels("polarity", self.parent.polarity.get()[ii], [channel])
|
||||
|
||||
@@ -40,129 +35,68 @@ class DDGSetup(DDGCustomMixin):
|
||||
# Set threshold level for ext. pulses
|
||||
self.parent.level.put(self.parent.thres_trig_level.get())
|
||||
|
||||
def prepare_ddg(self) -> None:
|
||||
"""
|
||||
Method to prepare scan logic of cSAXS
|
||||
|
||||
Two scantypes are supported: "step" and "fly":
|
||||
- step: Scan is performed by stepping the motor and acquiring data at each step
|
||||
- fly: Scan is performed by moving the motor with a constant velocity and acquiring data
|
||||
|
||||
Custom logic for different DDG behaviour during scans.
|
||||
|
||||
- set_high_on_exposure : If True, then TTL signal is high during
|
||||
the full exposure time of the scan (all frames).
|
||||
E.g. Keep shutter open for the full scan.
|
||||
- fixed_ttl_width : fixed_ttl_width is a list of 5 values, one for each channel.
|
||||
If the value is 0, then the width of the TTL pulse is determined,
|
||||
no matter which parameters are passed from the scaninfo for exposure time
|
||||
- set_trigger_source : Specifies the default trigger source for the DDG. For cSAXS, relevant ones
|
||||
were: SINGLE_SHOT, EXT_RISING_EDGE
|
||||
"""
|
||||
self.parent.set_trigger(getattr(TriggerSource, self.parent.set_trigger_source.get()))
|
||||
# scantype "step"
|
||||
def on_stage(self) -> None:
|
||||
"Hook execute before the scan starts"
|
||||
if self.parent.scaninfo.scan_type == "step":
|
||||
# High on exposure means that the signal
|
||||
if self.parent.set_high_on_exposure.get():
|
||||
# caluculate parameters
|
||||
num_burst_cycle = 1 + self.parent.additional_triggers.get()
|
||||
exp_time = self.parent.scaninfo.exp_time
|
||||
delay = 0
|
||||
self.parent.burst_disable()
|
||||
self.parent.set_trigger(TriggerSource.SINGLE_SHOT)
|
||||
self.parent.set_channels(signal="width", value=exp_time)
|
||||
self.parent.set_channels(signal="delay", value=delay)
|
||||
return
|
||||
scan_name = self.parent.scaninfo.scan_msg.content["info"].get("scan_name", "")
|
||||
if scan_name == "jjf_test":
|
||||
# TODO implement the logic for JJF triggering
|
||||
exp_time = 480e-6 # self.parent.scaninfo.exp_time
|
||||
readout = 20e-6 # self.parent.scaninfo.readout_time
|
||||
total_exposure = exp_time + readout
|
||||
num_burst_cycle = self.parent.scaninfo.scan_msg.content["info"]["kwargs"]["num_points"]
|
||||
num_burst_cycle = int(num_burst_cycle * self.parent.scaninfo.exp_time / total_exposure)
|
||||
delay = 0
|
||||
delay_burst = self.parent.delay_burst.get()
|
||||
|
||||
exp_time = (
|
||||
self.parent.delta_width.get()
|
||||
+ self.parent.scaninfo.frames_per_trigger
|
||||
* (self.parent.scaninfo.exp_time + self.parent.scaninfo.readout_time)
|
||||
)
|
||||
total_exposure = exp_time
|
||||
delay_burst = self.parent.delay_burst.get()
|
||||
self.parent.set_trigger(trigger_source=TriggerSource.SINGLE_SHOT)
|
||||
|
||||
# Set individual channel widths, if fixed_ttl_width and trigger_width are combined, this can be a common call too
|
||||
if not self.parent.trigger_width.get():
|
||||
self.parent.set_channels("width", exp_time)
|
||||
else:
|
||||
self.parent.set_channels("width", self.parent.trigger_width.get())
|
||||
for value, channel in zip(
|
||||
self.parent.fixed_ttl_width.get(), self.parent.all_channels
|
||||
):
|
||||
logger.debug(f"Trying to set DDG {channel} to {value}")
|
||||
if value != 0:
|
||||
self.parent.set_channels("width", value, channels=[channel])
|
||||
else:
|
||||
# caluculate parameters
|
||||
exp_time = self.parent.delta_width.get() + self.parent.scaninfo.exp_time
|
||||
total_exposure = exp_time + self.parent.scaninfo.readout_time
|
||||
delay_burst = self.parent.delay_burst.get()
|
||||
num_burst_cycle = (
|
||||
self.parent.scaninfo.frames_per_trigger + self.parent.additional_triggers.get()
|
||||
)
|
||||
self.parent.set_channels(signal="width", value=exp_time)
|
||||
self.parent.set_channels(signal="delay", value=delay)
|
||||
self.parent.burst_enable(
|
||||
count=num_burst_cycle, delay=delay_burst, period=total_exposure, config="first"
|
||||
)
|
||||
logger.info(
|
||||
f"{self.parent.name}: On stage with n_burst: {num_burst_cycle} and total_exp {total_exposure}"
|
||||
)
|
||||
|
||||
# Set individual channel widths, if fixed_ttl_width and trigger_width are combined, this can be a common call too
|
||||
if not self.parent.trigger_width.get():
|
||||
self.parent.set_channels("width", exp_time)
|
||||
else:
|
||||
self.parent.set_channels("width", self.parent.trigger_width.get())
|
||||
# scantype "fly"
|
||||
elif self.parent.scaninfo.scan_type == "fly":
|
||||
if self.parent.set_high_on_exposure.get():
|
||||
# caluculate parameters
|
||||
exp_time = (
|
||||
self.parent.delta_width.get()
|
||||
+ self.parent.scaninfo.exp_time * self.parent.scaninfo.num_points
|
||||
+ self.parent.scaninfo.readout_time * (self.parent.scaninfo.num_points - 1)
|
||||
)
|
||||
total_exposure = exp_time
|
||||
delay_burst = self.parent.delay_burst.get()
|
||||
num_burst_cycle = 1 + self.parent.additional_triggers.get()
|
||||
|
||||
# Set individual channel widths, if fixed_ttl_width and trigger_width are combined, this can be a common call too
|
||||
if not self.parent.trigger_width.get():
|
||||
self.parent.set_channels("width", exp_time)
|
||||
else:
|
||||
self.parent.set_channels("width", self.parent.trigger_width.get())
|
||||
for value, channel in zip(
|
||||
self.parent.fixed_ttl_width.get(), self.parent.all_channels
|
||||
):
|
||||
logger.debug(f"Trying to set DDG {channel} to {value}")
|
||||
if value != 0:
|
||||
self.parent.set_channels("width", value, channels=[channel])
|
||||
else:
|
||||
# caluculate parameters
|
||||
exp_time = self.parent.delta_width.get() + self.parent.scaninfo.exp_time
|
||||
total_exposure = exp_time + self.parent.scaninfo.readout_time
|
||||
delay_burst = self.parent.delay_burst.get()
|
||||
num_burst_cycle = (
|
||||
self.parent.scaninfo.num_points + self.parent.additional_triggers.get()
|
||||
)
|
||||
|
||||
# Set individual channel widths, if fixed_ttl_width and trigger_width are combined, this can be a common call too
|
||||
if not self.parent.trigger_width.get():
|
||||
self.parent.set_channels("width", exp_time)
|
||||
else:
|
||||
self.parent.set_channels("width", self.parent.trigger_width.get())
|
||||
|
||||
else:
|
||||
raise Exception(f"Unknown scan type {self.parent.scaninfo.scan_type}")
|
||||
# Set common DDG parameters
|
||||
self.parent.burst_enable(num_burst_cycle, delay_burst, total_exposure, config="first")
|
||||
self.parent.set_channels("delay", 0.0)
|
||||
|
||||
def on_trigger(self) -> None:
|
||||
def on_trigger(self) -> DeviceStatus:
|
||||
"""Method to be executed upon trigger"""
|
||||
if self.parent.source.read()[self.parent.source.name]["value"] == TriggerSource.SINGLE_SHOT:
|
||||
if self.parent.scaninfo.scan_type == "step":
|
||||
self.parent.trigger_shot.put(1)
|
||||
return
|
||||
scan_name = self.parent.scaninfo.scan_msg.content["info"].get("scan_name", "")
|
||||
if scan_name == "jjf_test":
|
||||
exp_time = 480e-6 # self.parent.scaninfo.exp_time
|
||||
readout = 20e-6 # self.parent.scaninfo.readout_time
|
||||
total_exposure = exp_time + readout
|
||||
num_burst_cycle = self.parent.scaninfo.scan_msg.content["info"]["kwargs"]["num_points"]
|
||||
num_burst_cycle = int(num_burst_cycle * self.parent.scaninfo.exp_time / total_exposure)
|
||||
|
||||
def check_scan_id(self) -> None:
|
||||
"""
|
||||
Method to check if scan_id has changed.
|
||||
# Start trigger cycle
|
||||
self.parent.trigger_burst_readout.put(1)
|
||||
|
||||
If yes, then it changes parent.stopped to True, which will stop further actions.
|
||||
"""
|
||||
old_scan_id = self.parent.scaninfo.scan_id
|
||||
self.parent.scaninfo.load_scan_metadata()
|
||||
if self.parent.scaninfo.scan_id != old_scan_id:
|
||||
self.parent.stopped = True
|
||||
# Create status object that will wait for the end of the burst cycle
|
||||
status = self.wait_with_status(
|
||||
signal_conditions=[(self.parent.burst_cycle_finished, 1)],
|
||||
timeout=num_burst_cycle * total_exposure + 1, # add 1s to be sure
|
||||
check_stopped=True,
|
||||
exception_on_timeout=DelayGeneratorcSAXSError(
|
||||
f"{self.parent.name} run into timeout in complete call."
|
||||
),
|
||||
)
|
||||
logger.info(f"Return status {self.parent.name}")
|
||||
return status
|
||||
|
||||
def finished(self) -> None:
|
||||
"""Method checks if DDG finished acquisition"""
|
||||
def on_complete(self) -> DeviceStatus:
|
||||
pass
|
||||
|
||||
def on_pre_scan(self) -> None:
|
||||
"""
|
||||
@@ -174,7 +108,7 @@ class DDGSetup(DDGCustomMixin):
|
||||
self.parent.trigger_shot.put(1)
|
||||
|
||||
|
||||
class DelayGeneratorcSAXS(PSIDelayGeneratorBase):
|
||||
class DelayGeneratorcSAXS(BECDeviceBase, DelayGenerator):
|
||||
"""
|
||||
DG645 delay generator at cSAXS (multiple can be in use depending on the setup)
|
||||
|
||||
@@ -203,6 +137,9 @@ class DelayGeneratorcSAXS(PSIDelayGeneratorBase):
|
||||
|
||||
custom_prepare_cls = DDGSetup
|
||||
|
||||
# Custom signals passed on during the init procedure via BEC
|
||||
# TODO review whether those should remain here like that
|
||||
|
||||
delay_burst = Component(
|
||||
bec_utils.ConfigSignal, name="delay_burst", kind="config", config_storage_name="ddg_config"
|
||||
)
|
||||
@@ -280,16 +217,12 @@ class DelayGeneratorcSAXS(PSIDelayGeneratorBase):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
prefix="",
|
||||
*,
|
||||
name,
|
||||
kind=None,
|
||||
read_attrs=None,
|
||||
configuration_attrs=None,
|
||||
name: str,
|
||||
prefix: str = "",
|
||||
kind: Kind = None,
|
||||
ddg_config: dict = None,
|
||||
parent=None,
|
||||
device_manager=None,
|
||||
sim_mode=False,
|
||||
ddg_config=None,
|
||||
**kwargs,
|
||||
):
|
||||
"""
|
||||
@@ -305,6 +238,7 @@ class DelayGeneratorcSAXS(PSIDelayGeneratorBase):
|
||||
ddg_config (dict, optional): Dictionary of ddg_config signals. Defaults to None.
|
||||
|
||||
"""
|
||||
|
||||
# Default values for ddg_config signals
|
||||
self.ddg_config = {
|
||||
# Setup default values
|
||||
@@ -330,16 +264,11 @@ class DelayGeneratorcSAXS(PSIDelayGeneratorBase):
|
||||
prefix=prefix,
|
||||
name=name,
|
||||
kind=kind,
|
||||
read_attrs=read_attrs,
|
||||
configuration_attrs=configuration_attrs,
|
||||
parent=parent,
|
||||
device_manager=device_manager,
|
||||
sim_mode=sim_mode,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Start delay generator in simulation mode.
|
||||
# Note: To run, access to Epics must be available.
|
||||
dgen = DelayGeneratorcSAXS("delaygen:DG1:", name="dgen", sim_mode=True)
|
||||
# if __name__ == "__main__":
|
||||
# dgen = DelayGeneratorcSAXS("X12SA-CPCL-DDG3:", name="ddg3")
|
||||
|
||||
0
csaxs_bec/devices/ids_cameras/__init__.py
Normal file
0
csaxs_bec/devices/ids_cameras/__init__.py
Normal file
312
csaxs_bec/devices/ids_cameras/ids_camera.py
Normal file
312
csaxs_bec/devices/ids_cameras/ids_camera.py
Normal file
@@ -0,0 +1,312 @@
|
||||
import threading
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import DeviceStatus, Kind, StatusBase
|
||||
from ophyd_devices import PSIDeviceBase
|
||||
from ophyd_devices.utils.bec_signals import PreviewSignal
|
||||
|
||||
try:
|
||||
from pyueye import ueye
|
||||
except ImportError:
|
||||
# The pyueye library is not installed or doesn't provide the necessary c libs
|
||||
ueye = None
|
||||
|
||||
|
||||
class IDSCamera(PSIDeviceBase):
|
||||
USER_ACCESS = ["start_live_mode", "stop_live_mode"]
|
||||
|
||||
image_data = Cpt(PreviewSignal, value=np.empty((100, 100)), kind=Kind.omitted)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
prefix="",
|
||||
*,
|
||||
name: str,
|
||||
camera_ID: int,
|
||||
bits_per_pixel: int,
|
||||
channels: int,
|
||||
m_n_colormode: int,
|
||||
kind=None,
|
||||
device_manager=None,
|
||||
**kwargs,
|
||||
):
|
||||
|
||||
super().__init__(
|
||||
prefix=prefix, name=name, kind=kind, device_manager=device_manager, **kwargs
|
||||
)
|
||||
self.camera_ID = camera_ID
|
||||
self.bits_per_pixel = bits_per_pixel
|
||||
self.bytes_per_pixel = None
|
||||
self.channels = channels
|
||||
self._m_n_colormode_input = m_n_colormode
|
||||
self.m_n_colormode = None
|
||||
self.ueye = ueye
|
||||
self.h_cam = None
|
||||
self.s_info = None
|
||||
self.data_thread = None
|
||||
self.c_info = None
|
||||
self.pc_image_memory = None
|
||||
self.mem_id = None
|
||||
self.rect_aoi = None
|
||||
self.pitch = None
|
||||
self.n_bits_per_pixel = None
|
||||
self.width = None
|
||||
self.height = None
|
||||
self.thread_event = threading.Event()
|
||||
self.data_thread = None
|
||||
|
||||
def start_backend(self):
|
||||
if self.ueye is None:
|
||||
raise ImportError("The pyueye library is not installed.")
|
||||
self.h_cam = self.ueye.HIDS(
|
||||
self.camera_ID
|
||||
) # 0: first available camera; 1-254: The camera with the specified camera ID
|
||||
self.s_info = self.ueye.SENSORINFO()
|
||||
self.c_info = self.ueye.CAMINFO()
|
||||
self.pc_image_memory = self.ueye.c_mem_p()
|
||||
self.mem_id = self.ueye.int()
|
||||
self.rect_aoi = self.ueye.IS_RECT()
|
||||
self.pitch = self.ueye.INT()
|
||||
self.n_bits_per_pixel = self.ueye.INT(
|
||||
self.bits_per_pixel
|
||||
) # 24: bits per pixel for color mode; take 8 bits per pixel for monochrome
|
||||
self.m_n_colormode = self.ueye.INT(
|
||||
self._m_n_colormode_input
|
||||
) # Y8/RGB16/RGB24/REG32 (1 for our color cameras)
|
||||
self.bytes_per_pixel = int(self.n_bits_per_pixel / 8)
|
||||
|
||||
# Starts the driver and establishes the connection to the camera
|
||||
ret = self.ueye.is_InitCamera(self.h_cam, None)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_InitCamera ERROR")
|
||||
|
||||
# Reads out the data hard-coded in the non-volatile camera memory and writes it to the data structure that c_info points to
|
||||
ret = self.ueye.is_GetCameraInfo(self.h_cam, self.c_info)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_GetCameraInfo ERROR")
|
||||
|
||||
# You can query additional information about the sensor type used in the camera
|
||||
ret = self.ueye.is_GetSensorInfo(self.h_cam, self.s_info)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_GetSensorInfo ERROR")
|
||||
|
||||
ret = self.ueye.is_ResetToDefault(self.h_cam)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_ResetToDefault ERROR")
|
||||
|
||||
# Set display mode to DIB
|
||||
ret = self.ueye.is_SetDisplayMode(self.h_cam, self.ueye.IS_SET_DM_DIB)
|
||||
|
||||
# Set the right color mode
|
||||
if (
|
||||
int.from_bytes(self.s_info.nColorMode.value, byteorder="big")
|
||||
== self.ueye.IS_COLORMODE_BAYER
|
||||
):
|
||||
# setup the color depth to the current windows setting
|
||||
self.ueye.is_GetColorDepth(self.h_cam, self.n_bits_per_pixel, self.m_n_colormode)
|
||||
bytes_per_pixel = int(self.n_bits_per_pixel / 8)
|
||||
print("IS_COLORMODE_BAYER: ")
|
||||
print("\tm_n_colormode: \t\t", self.m_n_colormode)
|
||||
print("\tn_bits_per_pixel: \t\t", self.n_bits_per_pixel)
|
||||
print("\tbytes_per_pixel: \t\t", bytes_per_pixel)
|
||||
print()
|
||||
|
||||
elif (
|
||||
int.from_bytes(self.s_info.nColorMode.value, byteorder="big")
|
||||
== self.ueye.IS_COLORMODE_CBYCRY
|
||||
):
|
||||
# for color camera models use RGB32 mode
|
||||
m_n_colormode = self.ueye.IS_CM_BGRA8_PACKED
|
||||
n_bits_per_pixel = self.ueye.INT(32)
|
||||
bytes_per_pixel = int(self.n_bits_per_pixel / 8)
|
||||
print("IS_COLORMODE_CBYCRY: ")
|
||||
print("\tm_n_colormode: \t\t", m_n_colormode)
|
||||
print("\tn_bits_per_pixel: \t\t", n_bits_per_pixel)
|
||||
print("\tbytes_per_pixel: \t\t", bytes_per_pixel)
|
||||
print()
|
||||
|
||||
elif (
|
||||
int.from_bytes(self.s_info.nColorMode.value, byteorder="big")
|
||||
== self.ueye.IS_COLORMODE_MONOCHROME
|
||||
):
|
||||
# for color camera models use RGB32 mode
|
||||
m_n_colormode = self.ueye.IS_CM_MONO8
|
||||
n_bits_per_pixel = self.ueye.INT(8)
|
||||
bytes_per_pixel = int(n_bits_per_pixel / 8)
|
||||
print("IS_COLORMODE_MONOCHROME: ")
|
||||
print("\tm_n_colormode: \t\t", m_n_colormode)
|
||||
print("\tn_bits_per_pixel: \t\t", n_bits_per_pixel)
|
||||
print("\tbytes_per_pixel: \t\t", bytes_per_pixel)
|
||||
print()
|
||||
|
||||
else:
|
||||
# for monochrome camera models use Y8 mode
|
||||
m_n_colormode = self.ueye.IS_CM_MONO8
|
||||
n_bits_per_pixel = self.ueye.INT(8)
|
||||
bytes_per_pixel = int(n_bits_per_pixel / 8)
|
||||
print("else")
|
||||
|
||||
# Can be used to set the size and position of an "area of interest"(AOI) within an image
|
||||
ret = self.ueye.is_AOI(
|
||||
self.h_cam,
|
||||
self.ueye.IS_AOI_IMAGE_GET_AOI,
|
||||
self.rect_aoi,
|
||||
self.ueye.sizeof(self.rect_aoi),
|
||||
)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_AOI ERROR")
|
||||
|
||||
self.width = self.rect_aoi.s32Width
|
||||
self.height = self.rect_aoi.s32Height
|
||||
|
||||
# Prints out some information about the camera and the sensor
|
||||
print("Camera model:\t\t", self.s_info.strSensorName.decode("utf-8"))
|
||||
print("Camera serial no.:\t", self.c_info.SerNo.decode("utf-8"))
|
||||
print("Maximum image width:\t", self.width)
|
||||
print("Maximum image height:\t", self.height)
|
||||
print()
|
||||
|
||||
# ---------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# Allocates an image memory for an image having its dimensions defined by width and height and its color depth defined by n_bits_per_pixel
|
||||
ret = self.ueye.is_AllocImageMem(
|
||||
self.h_cam,
|
||||
self.width,
|
||||
self.height,
|
||||
self.n_bits_per_pixel,
|
||||
self.pc_image_memory,
|
||||
self.mem_id,
|
||||
)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_AllocImageMem ERROR")
|
||||
else:
|
||||
# Makes the specified image memory the active memory
|
||||
ret = self.ueye.is_SetImageMem(self.h_cam, self.pc_image_memory, self.mem_id)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_SetImageMem ERROR")
|
||||
else:
|
||||
# Set the desired color mode
|
||||
ret = self.ueye.is_SetColorMode(self.h_cam, self.m_n_colormode)
|
||||
|
||||
# Activates the camera's live video mode (free run mode)
|
||||
ret = self.ueye.is_CaptureVideo(self.h_cam, self.ueye.IS_DONT_WAIT)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_CaptureVideo ERROR")
|
||||
|
||||
# Enables the queue mode for existing image memory sequences
|
||||
ret = self.ueye.is_InquireImageMem(
|
||||
self.h_cam,
|
||||
self.pc_image_memory,
|
||||
self.mem_id,
|
||||
self.width,
|
||||
self.height,
|
||||
self.n_bits_per_pixel,
|
||||
self.pitch,
|
||||
)
|
||||
if ret != self.ueye.IS_SUCCESS:
|
||||
print("is_InquireImageMem ERROR")
|
||||
else:
|
||||
print("Press q to leave the programm")
|
||||
# startmeasureframerate = True
|
||||
# Gain = False
|
||||
|
||||
# Start live mode of camera immediately
|
||||
self.start_live_mode()
|
||||
|
||||
def _start_data_thread(self):
|
||||
self.data_thread = threading.Thread(target=self._receive_data_from_camera, daemon=True)
|
||||
self.data_thread.start()
|
||||
|
||||
def _receive_data_from_camera(self):
|
||||
while not self.thread_event.is_set():
|
||||
if self.ueye is None:
|
||||
print("pyueye library not available.")
|
||||
return
|
||||
# In order to display the image in an OpenCV window we need to...
|
||||
# ...extract the data of our image memory
|
||||
array = self.ueye.get_data(
|
||||
self.pc_image_memory,
|
||||
self.width,
|
||||
self.height,
|
||||
self.n_bits_per_pixel,
|
||||
self.pitch,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
# bytes_per_pixel = int(n_bits_per_pixel / 8)
|
||||
|
||||
# ...reshape it in an numpy array...
|
||||
frame = np.reshape(array, (self.height.value, self.width.value, self.bytes_per_pixel))
|
||||
self.image_data.put(frame)
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
def wait_for_connection(self, all_signals=False, timeout=10):
|
||||
if ueye is None:
|
||||
raise ImportError(
|
||||
"The pyueye library is not installed or doesn't provide the necessary c libs"
|
||||
)
|
||||
super().wait_for_connection(all_signals, timeout)
|
||||
|
||||
def start_live_mode(self):
|
||||
if self.data_thread is not None:
|
||||
self.stop_live_mode()
|
||||
self._start_data_thread()
|
||||
|
||||
def stop_live_mode(self):
|
||||
"""Stopping the camera live mode."""
|
||||
self.thread_event.set()
|
||||
if self.data_thread is not None:
|
||||
self.data_thread.join()
|
||||
self.thread_event.clear()
|
||||
self.data_thread = None
|
||||
|
||||
########################################
|
||||
# Beamline Specific Implementations #
|
||||
########################################
|
||||
|
||||
def on_init(self) -> None:
|
||||
"""
|
||||
Called when the device is initialized.
|
||||
|
||||
No signals are connected at this point. If you like to
|
||||
set default values on signals, please use on_connected instead.
|
||||
"""
|
||||
|
||||
def on_connected(self) -> None:
|
||||
"""
|
||||
Called after the device is connected and its signals are connected.
|
||||
Default values for signals should be set here.
|
||||
"""
|
||||
self.start_backend()
|
||||
|
||||
def on_stage(self) -> DeviceStatus | StatusBase | None:
|
||||
"""
|
||||
Called while staging the device.
|
||||
|
||||
Information about the upcoming scan can be accessed from the scan_info (self.scan_info.msg) object.
|
||||
"""
|
||||
|
||||
def on_unstage(self) -> DeviceStatus | StatusBase | None:
|
||||
"""Called while unstaging the device."""
|
||||
|
||||
def on_pre_scan(self) -> DeviceStatus | StatusBase | None:
|
||||
"""Called right before the scan starts on all devices automatically."""
|
||||
|
||||
def on_trigger(self) -> DeviceStatus | StatusBase | None:
|
||||
"""Called when the device is triggered."""
|
||||
|
||||
def on_complete(self) -> DeviceStatus | StatusBase | None:
|
||||
"""Called to inquire if a device has completed a scans."""
|
||||
|
||||
def on_kickoff(self) -> DeviceStatus | StatusBase | None:
|
||||
"""Called to kickoff a device for a fly scan. Has to be called explicitly."""
|
||||
|
||||
def on_stop(self) -> None:
|
||||
"""Called when the device is stopped."""
|
||||
|
||||
def on_destroy(self) -> None:
|
||||
"""Called when the device is destroyed. Cleanup resources here."""
|
||||
self.stop_live_mode()
|
||||
153
csaxs_bec/devices/jungfraujoch/jungfrau_joch_client.py
Normal file
153
csaxs_bec/devices/jungfraujoch/jungfrau_joch_client.py
Normal file
@@ -0,0 +1,153 @@
|
||||
import enum
|
||||
import math
|
||||
|
||||
import jfjoch_client
|
||||
from bec_lib.logger import bec_logger
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class JungfrauJochClientError(Exception):
|
||||
"""Base class for exceptions in this module."""
|
||||
|
||||
|
||||
class DetectorState(enum.StrEnum):
|
||||
"""Detector states for Jungfrau Joch detector
|
||||
['Inactive', 'Idle', 'Busy', 'Measuring', 'Pedestal', 'Error']
|
||||
"""
|
||||
|
||||
INACTIVE = "Inactive"
|
||||
IDLE = "Idle"
|
||||
BUSY = "Busy"
|
||||
MEASURING = "Measuring"
|
||||
PEDESTAL = "Pedestal"
|
||||
ERROR = "Error"
|
||||
|
||||
|
||||
class ResponseWaitDone(enum.IntEnum):
|
||||
"""Response state for Jungfrau Joch detector wait till done"""
|
||||
|
||||
DETECTOR_IDLE = 200
|
||||
TIMEOUT_PARAM_OUT_OF_RANGE = 400
|
||||
JUNGFRAU_ERROR = 500
|
||||
DETECTOR_INACTIVE = 502
|
||||
TIMEOUT_REACHED = 504
|
||||
|
||||
|
||||
class JungfrauJochClient:
|
||||
"""Thin wrapper around the Jungfrau Joch API client"""
|
||||
|
||||
def __init__(self, host: str = "http://sls-jfjoch-001:8080") -> None:
|
||||
self._initialised = False
|
||||
configuration = jfjoch_client.Configuration(host=host)
|
||||
api_client = jfjoch_client.ApiClient(configuration)
|
||||
self.api = jfjoch_client.DefaultApi(api_client)
|
||||
|
||||
@property
|
||||
def initialised(self) -> bool:
|
||||
"""Check if jfj is connected and ready to receive commands"""
|
||||
return self._initialised
|
||||
|
||||
@initialised.setter
|
||||
def initialised(self, value: bool) -> None:
|
||||
"""Set the connected status"""
|
||||
self._initialised = value
|
||||
|
||||
def get_jungfrau_joch_status(self) -> DetectorState:
|
||||
"""Get the status of JungfrauJoch"""
|
||||
return self.api.status_get().state
|
||||
|
||||
def connect_and_initialise(self, timeout: int = 5) -> None:
|
||||
"""Check if JungfrauJoch is connected and ready to receive commands"""
|
||||
status = self.api.status_get().state
|
||||
if status != DetectorState.IDLE:
|
||||
self.api.initialize_post()
|
||||
self.wait_till_done(timeout)
|
||||
self.initialised = True
|
||||
|
||||
def set_detector_settings(self, settings: dict | jfjoch_client.DatasetSettings) -> None:
|
||||
"""Set the detector settings. JungfrauJoch must be in IDLE, Error or Inactive state.
|
||||
Note, the full settings have to be provided, otherwise the settings will be overwritten with default values.
|
||||
|
||||
Args:
|
||||
settings (dict): dictionary of settings
|
||||
"""
|
||||
state = self.api.status_get().state
|
||||
if state not in [DetectorState.IDLE, DetectorState.ERROR, DetectorState.INACTIVE]:
|
||||
raise JungfrauJochClientError(
|
||||
f"Detector must be in IDLE, ERROR or INACTIVE state to set settings. Current state: {state}"
|
||||
)
|
||||
|
||||
if isinstance(settings, dict):
|
||||
settings = jfjoch_client.DatasetSettings(**settings)
|
||||
self.api.config_detector_put(settings)
|
||||
|
||||
def set_mesaurement_settings(self, settings: dict | jfjoch_client.DatasetSettings) -> None:
|
||||
"""Set the measurement settings. JungfrauJoch must be in IDLE state.
|
||||
The method call is blocking and JungfrauJoch will be ready to measure after the call resolves.
|
||||
|
||||
Please check the DataSettings class for the available settings.
|
||||
The minimum required settings are:
|
||||
beam_x_pxl: StrictFloat | StrictInt,
|
||||
beam_y_pxl: StrictFloat | StrictInt,
|
||||
detector_distance_mm: float | int,
|
||||
incident_energy_keV: float | int,
|
||||
|
||||
Args:
|
||||
settings (dict): dictionary of settings
|
||||
"""
|
||||
state = self.api.status_get().state
|
||||
if state != DetectorState.IDLE:
|
||||
raise JungfrauJochClientError(
|
||||
f"Detector must be in IDLE state to set settings. Current state: {state}"
|
||||
)
|
||||
|
||||
if isinstance(settings, dict):
|
||||
settings = jfjoch_client.DatasetSettings(**settings)
|
||||
try:
|
||||
res = self.api.start_post_with_http_info(dataset_settings=settings)
|
||||
if res.status_code != 200:
|
||||
logger.error(
|
||||
f"Error while setting measurement settings {settings}, response: {res}"
|
||||
)
|
||||
raise JungfrauJochClientError(
|
||||
f"Error while setting measurement settings {settings}, response: {res}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Error while setting measurement settings {settings}. Exception raised {e}"
|
||||
)
|
||||
raise JungfrauJochClientError(
|
||||
f"Error while setting measurement settings {settings}. Exception raised {e}"
|
||||
) from e
|
||||
|
||||
def wait_till_done(self, timeout: int = 5) -> None:
|
||||
"""Wait until JungfrauJoch is done.
|
||||
|
||||
Args:
|
||||
timeout (int): timeout in seconds
|
||||
"""
|
||||
success = False
|
||||
try:
|
||||
response = self.api.wait_till_done_post_with_http_info(math.ceil(timeout / 2))
|
||||
if response.status_code != ResponseWaitDone.DETECTOR_IDLE:
|
||||
logger.info(
|
||||
f"Waitin for JungfrauJoch to be done, status: {ResponseWaitDone(response.status_code)}; response msg {response}"
|
||||
)
|
||||
response = self.api.wait_till_done_post_with_http_info(math.floor(timeout / 2))
|
||||
if response.status_code == ResponseWaitDone.DETECTOR_IDLE:
|
||||
success = True
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error(f"Error while waiting for JungfrauJoch to initialise: {e}")
|
||||
raise JungfrauJochClientError(
|
||||
f"Error while waiting for JungfrauJoch to initialise: {e}"
|
||||
) from e
|
||||
else:
|
||||
if success is False:
|
||||
logger.error(
|
||||
f"Failed to initialise JungfrauJoch with status: {response.status_code}; response msg {response}"
|
||||
)
|
||||
raise JungfrauJochClientError(
|
||||
f"Failed to initialise JungfrauJoch with status: {response.status_code}; response msg {response}"
|
||||
)
|
||||
0
csaxs_bec/devices/omny/__init__.py
Normal file
0
csaxs_bec/devices/omny/__init__.py
Normal file
@@ -141,7 +141,7 @@ class FlomniGalilAxesReferenced(GalilAxesReferenced):
|
||||
|
||||
|
||||
class FlomniGalilMotor(Device, PositionerBase):
|
||||
USER_ACCESS = ["controller"]
|
||||
USER_ACCESS = ["controller", "drive_axis_to_limit"]
|
||||
readback = Cpt(FlomniGalilReadbackSignal, signal_name="readback", kind="hinted")
|
||||
user_setpoint = Cpt(FlomniGalilSetpointSignal, signal_name="setpoint")
|
||||
motor_resolution = Cpt(FlomniGalilMotorResolution, signal_name="resolution", kind="config")
|
||||
@@ -337,6 +337,18 @@ class FlomniGalilMotor(Device, PositionerBase):
|
||||
def unstage(self) -> list[object]:
|
||||
return super().unstage()
|
||||
|
||||
def drive_axis_to_limit(self, direction: str) -> None:
|
||||
"""
|
||||
Drive an axis to the limit in a specified direction.
|
||||
|
||||
Args:
|
||||
direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'.
|
||||
"""
|
||||
self.controller.drive_axis_to_limit(self.axis_Id_numeric, direction)
|
||||
#now force position read to cache
|
||||
val = self.readback.read()
|
||||
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
|
||||
|
||||
def stop(self, *, success=False):
|
||||
self.controller.stop_all_axes()
|
||||
return super().stop(success=success)
|
||||
|
||||
@@ -17,8 +17,8 @@ from csaxs_bec.devices.omny.galil.galil_ophyd import (
|
||||
GalilError,
|
||||
GalilMotorIsMoving,
|
||||
GalilMotorResolution,
|
||||
GalilReadbackSignal,
|
||||
GalilSetpointSignal,
|
||||
GalilSignalRO,
|
||||
retry_once,
|
||||
)
|
||||
|
||||
@@ -44,7 +44,7 @@ class FuprGalilController(GalilController):
|
||||
raise NotImplementedError("This function is not implemented for the FuprGalilController.")
|
||||
|
||||
|
||||
class FuprGalilReadbackSignal(GalilReadbackSignal):
|
||||
class FuprGalilReadbackSignal(GalilSignalRO):
|
||||
@retry_once
|
||||
@threadlocked
|
||||
def _socket_get(self) -> float:
|
||||
|
||||
@@ -59,6 +59,13 @@ class GalilController(Controller):
|
||||
"all_axes_referenced",
|
||||
]
|
||||
|
||||
OKBLUE = '\033[94m'
|
||||
OKCYAN = '\033[96m'
|
||||
OKGREEN = '\033[92m'
|
||||
WARNING = '\033[93m'
|
||||
FAIL = '\033[91m'
|
||||
ENDC = '\033[0m'
|
||||
|
||||
@threadlocked
|
||||
def socket_put(self, val: str) -> None:
|
||||
self.sock.put(f"{val}\r".encode())
|
||||
@@ -98,21 +105,64 @@ class GalilController(Controller):
|
||||
return True
|
||||
|
||||
def stop_all_axes(self) -> str:
|
||||
return self.socket_put_and_receive("XQ#STOP,1")
|
||||
if not self.is_thread_active(1):
|
||||
return self.socket_put_and_receive("XQ#STOP,1")
|
||||
else:
|
||||
return ":"
|
||||
|
||||
def get_digital_input(self, channel):
|
||||
return bool(float(self.socket_put_and_receive(f"MG @IN[{channel}]").strip()))
|
||||
|
||||
def axis_is_referenced(self, axis_Id_numeric) -> bool:
|
||||
return bool(float(self.socket_put_and_receive(f"MG axisref[{axis_Id_numeric}]").strip()))
|
||||
|
||||
def folerr_status(self, axis_Id_numeric) -> bool:
|
||||
return bool(float(self.socket_put_and_receive(f"MG folaxerr[{axis_Id_numeric}]").strip()))
|
||||
|
||||
def motor_temperature(self, axis_Id_numeric) -> float:
|
||||
#this is only valid for omny. consider moving to ogalil
|
||||
voltage = float(self.socket_put_and_receive(f"MG @AN[{axis_Id_numeric+1}]").strip())
|
||||
voltage2 = float(self.socket_put_and_receive(f"MG @AN[{axis_Id_numeric+1}]").strip())
|
||||
if voltage2 < voltage:
|
||||
voltage = voltage2
|
||||
# convert from [-10,10]V to [0,300]degC
|
||||
temperature_degC = round((voltage+10.0) / 20.0 * 300.0, 1)
|
||||
|
||||
#the motors of the parking station have a different offset
|
||||
#the range is reduced, so if at the limit, we show an extreme value
|
||||
if self.sock.port == 8082:
|
||||
#controller 2
|
||||
if axis_Id_numeric == 6:
|
||||
temperature_degC = round((voltage+10.0-11.4) / 20.0 * 300.0, 1)
|
||||
if voltage > 9.9:
|
||||
temperature_degC = 300
|
||||
if axis_Id_numeric == 7:
|
||||
temperature_degC = round((voltage+.0-12) / 20.0 * 300.0, 1)
|
||||
if voltage > 9.9:
|
||||
temperature_degC = 300
|
||||
return temperature_degC
|
||||
|
||||
def all_axes_referenced(self) -> bool:
|
||||
"""
|
||||
Check if all axes are referenced.
|
||||
"""
|
||||
return bool(float(self.socket_put_and_receive("MG allaxref").strip()))
|
||||
|
||||
def _omny_get_microstep_position(self,axis_Id):
|
||||
return float(self.socket_put_and_receive(f"MG _TD{axis_Id}").strip())
|
||||
|
||||
|
||||
def _omny_get_reference_limit(self,axis_Id):
|
||||
get_axis_no = float(self.socket_put_and_receive(f"MG frmmv").strip())
|
||||
if(get_axis_no>0):
|
||||
reference_is_before = float(self.socket_put_and_receive(f"MG _FL{axis_Id}").strip())
|
||||
elif(get_axis_no<0):
|
||||
reference_is_before = float(self.socket_put_and_receive(f"MG _BL{axis_Id}").strip())
|
||||
else:
|
||||
reference_is_before = 0
|
||||
return reference_is_before
|
||||
|
||||
def drive_axis_to_limit(self, axis_Id_numeric: int, direction: str) -> None:
|
||||
def drive_axis_to_limit(self, axis_Id_numeric: int, direction: str, verbose=0) -> None:
|
||||
"""
|
||||
Drive an axis to the limit in a specified direction.
|
||||
|
||||
@@ -133,10 +183,13 @@ class GalilController(Controller):
|
||||
time.sleep(0.1)
|
||||
self.socket_put_confirmed("XQ#FES")
|
||||
time.sleep(0.1)
|
||||
axis_Id = self.axis_Id_numeric_to_alpha(axis_Id_numeric)
|
||||
while self.is_axis_moving(None, axis_Id_numeric):
|
||||
time.sleep(0.01)
|
||||
if verbose:
|
||||
self.get_device_manager().connector.send_client_info(f"Current microstep position {self._omny_get_microstep_position(axis_Id):.0f}", scope="drive axis to limit", show_asap=True)
|
||||
time.sleep(0.5)
|
||||
|
||||
axis_Id = self.axis_Id_numeric_to_alpha(axis_Id_numeric)
|
||||
# check if we actually hit the limit
|
||||
if direction == "forward":
|
||||
limit = self.get_motor_limit_switch(axis_Id)[1]
|
||||
@@ -145,8 +198,16 @@ class GalilController(Controller):
|
||||
|
||||
if not limit:
|
||||
raise GalilError(f"Failed to drive axis {axis_Id}/{axis_Id_numeric} to limit.")
|
||||
else:
|
||||
print("Limit reached.")
|
||||
|
||||
def find_reference(self, axis_Id_numeric: int) -> None:
|
||||
def get_device_manager(self):
|
||||
for axis in self._axis:
|
||||
if hasattr(axis, "device_manager") and axis.device_manager:
|
||||
return axis.device_manager
|
||||
raise BECConfigError("Could not access the device_manager")
|
||||
|
||||
def find_reference(self, axis_Id_numeric: int, verbose=0, raise_error = 1) -> None:
|
||||
"""
|
||||
Find the reference of an axis.
|
||||
|
||||
@@ -159,14 +220,23 @@ class GalilController(Controller):
|
||||
time.sleep(0.1)
|
||||
self.socket_put_confirmed("XQ#FRM")
|
||||
time.sleep(0.1)
|
||||
axis_Id = self.axis_Id_numeric_to_alpha(axis_Id_numeric)
|
||||
while self.is_axis_moving(None, axis_Id_numeric):
|
||||
time.sleep(0.1)
|
||||
if verbose:
|
||||
self.get_device_manager().connector.send_client_info(f"Current microstep position {self._omny_get_microstep_position(axis_Id):.0f} reference is before {self._omny_get_reference_limit(axis_Id)}", scope="find axis reference", show_asap=True)
|
||||
time.sleep(0.5)
|
||||
|
||||
if not self.axis_is_referenced(axis_Id_numeric):
|
||||
raise GalilError(f"Failed to find reference of axis {axis_Id_numeric}.")
|
||||
|
||||
logger.info(f"Successfully found reference of axis {axis_Id_numeric}.")
|
||||
if raise_error:
|
||||
raise GalilError(f"Failed to find reference of axis {axis_Id_numeric}.")
|
||||
else:
|
||||
print(f"Failed to find reference of axis {axis_Id_numeric}.")
|
||||
else:
|
||||
logger.info(f"Successfully found reference of axis {axis_Id_numeric}.")
|
||||
print(f"Successfully found reference of axis {axis_Id_numeric}.")
|
||||
|
||||
|
||||
def show_running_threads(self) -> None:
|
||||
t = PrettyTable()
|
||||
t.title = f"Threads on {self.sock.host}:{self.sock.port}"
|
||||
@@ -181,7 +251,7 @@ class GalilController(Controller):
|
||||
|
||||
def is_motor_on(self, axis_Id) -> bool:
|
||||
return not bool(float(self.socket_put_and_receive(f"MG _MO{axis_Id}").strip()))
|
||||
|
||||
|
||||
def get_motor_limit_switch(self, axis_Id) -> list:
|
||||
"""
|
||||
Get the status of the motor limit switches.
|
||||
@@ -199,29 +269,60 @@ class GalilController(Controller):
|
||||
def describe(self) -> None:
|
||||
t = PrettyTable()
|
||||
t.title = f"{self.__class__.__name__} on {self.sock.host}:{self.sock.port}"
|
||||
t.field_names = [
|
||||
field_names = [
|
||||
"Axis",
|
||||
"Name",
|
||||
"Connected",
|
||||
"Referenced",
|
||||
"Motor On",
|
||||
"Limits",
|
||||
"Position",
|
||||
]
|
||||
# in case of OMNY
|
||||
if self.sock.host == "mpc3217.psi.ch":
|
||||
field_names.append("Temperature")
|
||||
field_names.append("FolErr")
|
||||
t.field_names = field_names
|
||||
for ax in range(self._axes_per_controller):
|
||||
axis = self._axis[ax]
|
||||
if axis is not None:
|
||||
t.add_row(
|
||||
[
|
||||
f"{axis.axis_Id_numeric}/{axis.axis_Id}",
|
||||
axis.name,
|
||||
axis.connected,
|
||||
self.axis_is_referenced(axis.axis_Id_numeric),
|
||||
self.is_motor_on(axis.axis_Id),
|
||||
self.get_motor_limit_switch(axis.axis_Id),
|
||||
axis.readback.read().get(axis.name).get("value"),
|
||||
]
|
||||
)
|
||||
if self.sock.host == "mpc3217.psi.ch":
|
||||
#case of omny. possibly consider moving to ogalil
|
||||
motor_on = self.is_motor_on(axis.axis_Id)
|
||||
if motor_on == True:
|
||||
motor_on = self.WARNING + "ON" + self.ENDC
|
||||
else:
|
||||
motor_on = "OFF"
|
||||
|
||||
folerr_status = self.folerr_status(axis.axis_Id_numeric)
|
||||
if folerr_status == True:
|
||||
folerr_status = self.WARNING + "True" + self.ENDC
|
||||
else:
|
||||
folerr_status = "False"
|
||||
position = axis.readback.read().get(axis.name).get("value")
|
||||
position = f'{position:.3f}'
|
||||
t.add_row(
|
||||
[
|
||||
f"{axis.axis_Id_numeric}/{axis.axis_Id}",
|
||||
axis.name,
|
||||
self.axis_is_referenced(axis.axis_Id_numeric),
|
||||
motor_on,
|
||||
self.get_motor_limit_switch(axis.axis_Id),
|
||||
position,
|
||||
self.motor_temperature(axis.axis_Id_numeric),
|
||||
self.folerr_status(axis.axis_Id_numeric),
|
||||
]
|
||||
)
|
||||
else:
|
||||
t.add_row(
|
||||
[
|
||||
f"{axis.axis_Id_numeric}/{axis.axis_Id}",
|
||||
axis.name,
|
||||
self.axis_is_referenced(axis.axis_Id_numeric),
|
||||
self.is_motor_on(axis.axis_Id),
|
||||
self.get_motor_limit_switch(axis.axis_Id),
|
||||
axis.readback.read().get(axis.name).get("value"),
|
||||
]
|
||||
)
|
||||
else:
|
||||
t.add_row([None for t in t.field_names])
|
||||
print(t)
|
||||
@@ -229,6 +330,8 @@ class GalilController(Controller):
|
||||
self.show_running_threads()
|
||||
self.show_status_other()
|
||||
|
||||
|
||||
|
||||
def show_status_other(self) -> None:
|
||||
"""
|
||||
Show additional device-specific status information.
|
||||
@@ -254,7 +357,6 @@ class GalilSignalBase(SocketSignal):
|
||||
self.signal_name = signal_name
|
||||
super().__init__(**kwargs)
|
||||
self.controller = self.parent.controller
|
||||
self.sock = self.parent.controller.sock
|
||||
|
||||
|
||||
class GalilSignalRO(GalilSignalBase):
|
||||
@@ -275,7 +377,6 @@ class GalilReadbackSignal(GalilSignalRO):
|
||||
Returns:
|
||||
float: Readback value after adjusting for sign and motor resolution.
|
||||
"""
|
||||
|
||||
current_pos = float(self.controller.socket_put_and_receive(f"TD{self.parent.axis_Id}"))
|
||||
current_pos *= self.parent.sign
|
||||
step_mm = self.parent.motor_resolution.get()
|
||||
@@ -284,13 +385,6 @@ class GalilReadbackSignal(GalilSignalRO):
|
||||
def read(self):
|
||||
self._metadata["timestamp"] = time.time()
|
||||
val = super().read()
|
||||
if self.parent.axis_Id_numeric == 2:
|
||||
try:
|
||||
rt = self.parent.device_manager.devices[self.parent.rt]
|
||||
if rt.enabled:
|
||||
rt.obj.controller.set_rotation_angle(val[self.parent.name]["value"])
|
||||
except KeyError:
|
||||
logger.warning("Failed to set RT value during readback.")
|
||||
return val
|
||||
|
||||
|
||||
@@ -326,7 +420,8 @@ class GalilSetpointSignal(GalilSignalBase):
|
||||
while self.controller.is_thread_active(0):
|
||||
time.sleep(0.1)
|
||||
|
||||
if self.parent.axis_Id_numeric == 2:
|
||||
#in the case of lamni, consider moving to lgalil
|
||||
if self.parent.axis_Id_numeric == 2 and self.controller.sock.host == "mpc2680.psi.ch":
|
||||
try:
|
||||
rt = self.parent.device_manager.devices[self.parent.rt]
|
||||
if rt.enabled:
|
||||
|
||||
@@ -7,6 +7,7 @@ from ophyd import Component as Cpt
|
||||
from ophyd import Device, PositionerBase, Signal
|
||||
from ophyd.status import wait as status_wait
|
||||
from ophyd.utils import LimitError
|
||||
from ophyd_devices.utils.controller import threadlocked
|
||||
from ophyd_devices.utils.socket import SocketIO, raise_if_disconnected
|
||||
|
||||
from csaxs_bec.devices.omny.galil.galil_ophyd import (
|
||||
@@ -15,8 +16,9 @@ from csaxs_bec.devices.omny.galil.galil_ophyd import (
|
||||
GalilController,
|
||||
GalilMotorIsMoving,
|
||||
GalilMotorResolution,
|
||||
GalilReadbackSignal,
|
||||
GalilSetpointSignal,
|
||||
GalilSignalRO,
|
||||
retry_once,
|
||||
)
|
||||
|
||||
logger = bec_logger.logger
|
||||
@@ -71,10 +73,35 @@ class LamniGalilController(GalilController):
|
||||
air_off = bool(self.socket_put_and_receive("MG@OUT[13]"))
|
||||
return rt_not_blocked_by_galil and air_off
|
||||
|
||||
class LamniGalilReadbackSignal(GalilSignalRO):
|
||||
@retry_once
|
||||
@threadlocked
|
||||
def _socket_get(self) -> float:
|
||||
"""Get command for the readback signal
|
||||
|
||||
Returns:
|
||||
float: Readback value after adjusting for sign and motor resolution.
|
||||
"""
|
||||
current_pos = float(self.controller.socket_put_and_receive(f"TD{self.parent.axis_Id}"))
|
||||
current_pos *= self.parent.sign
|
||||
step_mm = self.parent.motor_resolution.get()
|
||||
return current_pos / step_mm
|
||||
|
||||
def read(self):
|
||||
self._metadata["timestamp"] = time.time()
|
||||
val = super().read()
|
||||
if self.parent.axis_Id_numeric == 2:
|
||||
try:
|
||||
rt = self.parent.device_manager.devices[self.parent.rtx]
|
||||
if rt.enabled:
|
||||
rt.obj.controller.set_rotation_angle(val[self.parent.name]["value"])
|
||||
except KeyError:
|
||||
logger.warning("Failed to set RT value during readback.")
|
||||
return val
|
||||
|
||||
class LamniGalilMotor(Device, PositionerBase):
|
||||
USER_ACCESS = ["controller"]
|
||||
readback = Cpt(GalilReadbackSignal, signal_name="readback", kind="hinted")
|
||||
USER_ACCESS = ["controller", "drive_axis_to_limit", "find_reference"]
|
||||
readback = Cpt(LamniGalilReadbackSignal, signal_name="readback", kind="hinted")
|
||||
user_setpoint = Cpt(GalilSetpointSignal, signal_name="setpoint")
|
||||
motor_resolution = Cpt(GalilMotorResolution, signal_name="resolution", kind="config")
|
||||
motor_is_moving = Cpt(GalilMotorIsMoving, signal_name="motor_is_moving", kind="normal")
|
||||
@@ -260,6 +287,27 @@ class LamniGalilMotor(Device, PositionerBase):
|
||||
"""The engineering units (EGU) for positions"""
|
||||
return "mm"
|
||||
|
||||
def find_reference(self):
|
||||
"""
|
||||
Find the reference of the axis.
|
||||
"""
|
||||
self.controller.find_reference(self.axis_Id_numeric)
|
||||
#now force position read to cache
|
||||
val = self.readback.read()
|
||||
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
|
||||
|
||||
def drive_axis_to_limit(self, direction: str) -> None:
|
||||
"""
|
||||
Drive an axis to the limit in a specified direction.
|
||||
|
||||
Args:
|
||||
direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'.
|
||||
"""
|
||||
self.controller.drive_axis_to_limit(self.axis_Id_numeric, direction)
|
||||
#now force position read to cache
|
||||
val = self.readback.read()
|
||||
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
|
||||
|
||||
def stop(self, *, success=False):
|
||||
self.controller.stop_all_axes()
|
||||
return super().stop(success=success)
|
||||
|
||||
515
csaxs_bec/devices/omny/galil/ogalil_ophyd.py
Normal file
515
csaxs_bec/devices/omny/galil/ogalil_ophyd.py
Normal file
@@ -0,0 +1,515 @@
|
||||
import functools
|
||||
import threading
|
||||
import time
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import numpy as np
|
||||
from bec_lib.logger import bec_logger
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import Device, PositionerBase, Signal
|
||||
from ophyd.status import wait as status_wait
|
||||
from ophyd.utils import LimitError
|
||||
from ophyd_devices.utils.controller import threadlocked
|
||||
from ophyd_devices.utils.socket import SocketIO, raise_if_disconnected
|
||||
|
||||
from csaxs_bec.devices.omny.galil.galil_ophyd import (
|
||||
BECConfigError,
|
||||
GalilAxesReferenced,
|
||||
GalilCommunicationError,
|
||||
GalilController,
|
||||
GalilError,
|
||||
GalilMotorIsMoving,
|
||||
GalilSetpointSignal,
|
||||
GalilSignalRO,
|
||||
)
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
def retry_once(fcn):
|
||||
"""Decorator to rerun a function in case a Galil communication error was raised. This may happen if the buffer was not empty."""
|
||||
|
||||
@functools.wraps(fcn)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
try:
|
||||
val = fcn(self, *args, **kwargs)
|
||||
except (GalilCommunicationError, GalilError):
|
||||
val = fcn(self, *args, **kwargs)
|
||||
return val
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class GalilMotorResolution(GalilSignalRO):
|
||||
@retry_once
|
||||
@threadlocked
|
||||
def _socket_get(self):
|
||||
if self.controller.sock.port == 8083 and self.parent.axis_Id_numeric == 2:
|
||||
# rotation stage
|
||||
return 89565.8666667
|
||||
else:
|
||||
return 51200
|
||||
|
||||
|
||||
class OMNYGalilReadbackSignal(GalilSignalRO):
|
||||
|
||||
previous_rotation_angle = 0
|
||||
ignore_glitch = True
|
||||
|
||||
@retry_once
|
||||
@threadlocked
|
||||
def _socket_get(self) -> float:
|
||||
"""Get command for the readback signal
|
||||
|
||||
Returns:
|
||||
float: Readback value after adjusting for sign and motor resolution.
|
||||
"""
|
||||
|
||||
current_pos = float(self.controller.socket_put_and_receive(f"TP{self.parent.axis_Id}"))
|
||||
current_pos *= self.parent.sign
|
||||
step_mm = self.parent.motor_resolution.get()
|
||||
#here we introduce an offset of 25 to the rotation axis
|
||||
#when setting a position this is taken into account in the controller
|
||||
#that way we just do tomography from 0 to 180 degrees
|
||||
if self.parent.axis_Id_numeric == 2 and self.controller.sock.port == 8083:
|
||||
return (current_pos / step_mm)+25
|
||||
else:
|
||||
return current_pos / step_mm
|
||||
|
||||
def read(self):
|
||||
self._metadata["timestamp"] = time.time()
|
||||
val = super().read()
|
||||
|
||||
#if reading rotation stage angle
|
||||
if self.parent.axis_Id_numeric == 2 and self.controller.sock.port == 8083:
|
||||
current_readback_value = val[self.parent.name]["value"]
|
||||
#print (f"previous rotation angle {self.previous_rotation_angle}, current readback {current_readback_value}.")
|
||||
|
||||
if np.fabs((self.previous_rotation_angle-current_readback_value)>10):
|
||||
message = f"Glitch detected in rotation stage. Previous rotation angle {self.previous_rotation_angle}, current readback {current_readback_value}."
|
||||
print(message)
|
||||
self.parent.device_manager.connector.send_client_info(message, scope="glitch detector", show_asap=True)
|
||||
|
||||
val = super().read()
|
||||
current_readback_value = val[self.parent.name]["value"]
|
||||
|
||||
if np.fabs((self.previous_rotation_angle-current_readback_value)>10):
|
||||
message = f"Glitch detected in rotation stage second read. Previous rotation angle {self.previous_rotation_angle}, current readback {current_readback_value}. Disabling the controller."
|
||||
print(message)
|
||||
self.parent.device_manager.connector.send_client_info(message, scope="glitch detector", show_asap=True)
|
||||
|
||||
self.parent.device_manager.devices["osamroy"].obj.controller.socket_put_confirmed("allaxref=0")
|
||||
self.parent.device_manager.devices["osamroy"].obj.enabled = False
|
||||
|
||||
return val
|
||||
|
||||
self.previous_rotation_angle = current_readback_value
|
||||
try:
|
||||
rt = self.parent.device_manager.devices["rtx"]
|
||||
if rt.enabled:
|
||||
rt.obj.controller.set_rotation_angle(val[self.parent.name]["value"]-25+54)
|
||||
except KeyError:
|
||||
logger.warning("Failed to set RT value during ogalil readback.")
|
||||
return val
|
||||
|
||||
|
||||
|
||||
class OMNYGalilController(GalilController):
|
||||
USER_ACCESS = [
|
||||
"describe",
|
||||
"show_running_threads",
|
||||
"galil_show_all",
|
||||
"socket_put_and_receive",
|
||||
"socket_put_confirmed",
|
||||
"get_motor_limit_switch",
|
||||
"is_motor_on",
|
||||
"all_axes_referenced",
|
||||
"_ogalil_switchsocket",
|
||||
"_ogalil_switchsocket_switch_all_on",
|
||||
"_ogalil_switchsocket_status",
|
||||
"_ogalil_switchsocket_are_all_on",
|
||||
"_ogalil_folerr_not_ignore",
|
||||
]
|
||||
|
||||
OKBLUE = '\033[94m'
|
||||
OKCYAN = '\033[96m'
|
||||
OKGREEN = '\033[92m'
|
||||
WARNING = '\033[93m'
|
||||
FAIL = '\033[91m'
|
||||
ENDC = '\033[0m'
|
||||
|
||||
def on(self) -> None:
|
||||
"""Open a new socket connection to the controller"""
|
||||
self._ogalil_switchsocket_switch_all_on()
|
||||
time.sleep(0.3)
|
||||
super().on()
|
||||
|
||||
def _ogalil_switchsocket(self, number: int, switch: bool):
|
||||
# number is socket number ranging from 1 to 4
|
||||
# switch is either 0 or 1
|
||||
if number not in range(1, 5):
|
||||
raise Exception("Socket number ranges from 1 to 4")
|
||||
else:
|
||||
contents = urllib.request.urlopen(
|
||||
f"http://mpc3217:8091/netio.cgi?pass=24A42C3929C5&output{number}={switch}"
|
||||
).read()
|
||||
# print(contents)
|
||||
if b"OK" in contents:
|
||||
print(f"Controller number switchsocket {number} is now {switch}")
|
||||
return 1
|
||||
else:
|
||||
print(f"Failed to switch controller number {number}")
|
||||
return 0
|
||||
|
||||
def _ogalil_switchsocket_are_all_on(self):
|
||||
if self._ogalil_switchsocket_status() == [1, 1, 1, 1]:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def _ogalil_tempdisabledebug(self):
|
||||
# sock_put(_ogalil_debugging_host_and_port_str[ogalil_no][],"WH\r\n") < 1) {
|
||||
# ret_str = sock_get(_ogalil_debugging_host_and_port_str[ogalil_no][],_ogalil_prompt_str)
|
||||
# printf("%s _ogalil_redirect_debug_output(%d): expected \"IHx\" received \"%s\"\n",\
|
||||
# cmd_str = sprintf("CF %s\r\n",substr(ret_str,3,1))
|
||||
# if (sock_put(_ogalil_debugging_host_and_port_str[ogalil_no][],cmd_str) < 1) {
|
||||
# cmd_str = sprintf("CW 2\r\n")
|
||||
# if (sock_put(_ogalil_debugging_host_and_port_str[ogalil_no][],cmd_str) < 1) {
|
||||
print("not yet implemented")
|
||||
return 0
|
||||
|
||||
def _ogalil_folerr_reset_and_ignore(self, axis_id_numeric: int) -> None:
|
||||
self.socket_put_confirmed(f"folaxerr[{axis_id_numeric}]=0")
|
||||
self.socket_put_confirmed("folerr=0")
|
||||
self.socket_put_confirmed("IgNoFol=1")
|
||||
self.socket_put_confirmed("XQ#STOP,1")
|
||||
|
||||
|
||||
def _ogalil_set_axis_to_pos_wo_reference_search(self, axis_id_numeric, axis_id, pos_mm, motor_resolution, motor_sign):
|
||||
|
||||
self.socket_put_confirmed("IgNoFol=1")
|
||||
|
||||
# pos_mm = pos_encoder / motor_resolution
|
||||
pos_encoder = pos_mm * motor_resolution * motor_sign
|
||||
#print(motor_resolution)
|
||||
|
||||
self.socket_put_confirmed(f"DE{axis_id}={pos_encoder:.0f}")
|
||||
self.socket_put_confirmed(f"DP{axis_id}=_TP{axis_id}*ratio[{axis_id_numeric:.0f}]")
|
||||
|
||||
self.socket_put_confirmed(f"folaxerr[{axis_id_numeric}]=0")
|
||||
self.socket_put_confirmed(f"axisref[{axis_id_numeric}]=1")
|
||||
self.socket_put_confirmed("folerr=0")
|
||||
|
||||
self._ogalil_folerr_not_ignore()
|
||||
|
||||
|
||||
def _ogalil_folerr_not_ignore(self):
|
||||
self.socket_put_confirmed("IgNoFol=0")
|
||||
|
||||
def _ogalil_switchsocket_switch_all_on(self):
|
||||
if not self._ogalil_switchsocket_are_all_on():
|
||||
for j in range(1, 5):
|
||||
self._ogalil_switchsocket(j, 1)
|
||||
time.sleep(0.4)
|
||||
|
||||
def _ogalil_switchsocket_status(self):
|
||||
contents = urllib.request.urlopen("http://mpc3217:8091/netio.xml").read()
|
||||
root = ET.fromstring(contents)
|
||||
returnvalue = []
|
||||
for j in range(0, 4):
|
||||
status = int(root[1][j][2].text)
|
||||
returnvalue.append(int(root[1][j][2].text))
|
||||
if status:
|
||||
print(f"Controller {j+1} is ON")
|
||||
else:
|
||||
print(f"Controller {j+1} is OFF")
|
||||
return returnvalue
|
||||
|
||||
def show_status_other(self):
|
||||
swver = float(self.socket_put_and_receive("MGswver"))
|
||||
allaxref = float(self.socket_put_and_receive("MGallaxref"))
|
||||
tempab = float(self.socket_put_and_receive("MGtempab"))
|
||||
timeab = float(self.socket_put_and_receive("MGtimeab"))
|
||||
IgNoFol = float(self.socket_put_and_receive("MGIgNoFol"))
|
||||
print(
|
||||
f"OMNY galil firmware {swver:2.0f}, TempAbort: {tempab:1.0f}, Allaxref: {allaxref:1.0f}, TimeAbort: {timeab:1.0f}, Ignore Folerr: {IgNoFol:1.0f}\n"
|
||||
)
|
||||
if self.sock.port == 8083:
|
||||
self._ogalil_switchsocket_status()
|
||||
|
||||
|
||||
class OMNYGalilMotor(Device, PositionerBase):
|
||||
USER_ACCESS = ["controller", "find_reference", "omny_osamx_to_scan_center", "drive_axis_to_limit", "_ogalil_folerr_reset_and_ignore", "_ogalil_set_axis_to_pos_wo_reference_search", "get_motor_limit_switch", "axis_is_referenced", "get_motor_temperature", "folerr_status"]
|
||||
readback = Cpt(OMNYGalilReadbackSignal, signal_name="readback", kind="hinted")
|
||||
user_setpoint = Cpt(GalilSetpointSignal, signal_name="setpoint")
|
||||
motor_resolution = Cpt(GalilMotorResolution, signal_name="resolution", kind="config")
|
||||
motor_is_moving = Cpt(GalilMotorIsMoving, signal_name="motor_is_moving", kind="normal")
|
||||
all_axes_referenced = Cpt(GalilAxesReferenced, signal_name="all_axes_referenced", kind="config")
|
||||
high_limit_travel = Cpt(Signal, value=0, kind="omitted")
|
||||
low_limit_travel = Cpt(Signal, value=0, kind="omitted")
|
||||
|
||||
SUB_READBACK = "readback"
|
||||
SUB_CONNECTION_CHANGE = "connection_change"
|
||||
_default_sub = SUB_READBACK
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
axis_Id,
|
||||
prefix="",
|
||||
*,
|
||||
name,
|
||||
kind=None,
|
||||
read_attrs=None,
|
||||
configuration_attrs=None,
|
||||
parent=None,
|
||||
host="mpc3217.psi.ch",
|
||||
port=8081,
|
||||
limits=None,
|
||||
sign=1,
|
||||
socket_cls=SocketIO,
|
||||
device_manager=None,
|
||||
**kwargs,
|
||||
):
|
||||
self.controller = OMNYGalilController(
|
||||
socket_cls=socket_cls, socket_host=host, socket_port=port
|
||||
)
|
||||
self.axis_Id = axis_Id
|
||||
self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric)
|
||||
self.sign = sign
|
||||
self.tolerance = kwargs.pop("tolerance", 0.5)
|
||||
self.device_mapping = kwargs.pop("device_mapping", {})
|
||||
self.device_manager = device_manager
|
||||
|
||||
if len(self.device_mapping) > 0 and self.device_manager is None:
|
||||
raise BECConfigError(
|
||||
"device_mapping has been specified but the device_manager cannot be accessed."
|
||||
)
|
||||
self.rt = self.device_mapping.get("rt")
|
||||
|
||||
super().__init__(
|
||||
prefix,
|
||||
name=name,
|
||||
kind=kind,
|
||||
read_attrs=read_attrs,
|
||||
configuration_attrs=configuration_attrs,
|
||||
parent=parent,
|
||||
**kwargs,
|
||||
)
|
||||
self.readback.name = self.name
|
||||
self.controller.subscribe(
|
||||
self._update_connection_state, event_type=self.SUB_CONNECTION_CHANGE
|
||||
)
|
||||
self._update_connection_state()
|
||||
# self.readback.subscribe(self._forward_readback, event_type=self.readback.SUB_VALUE)
|
||||
|
||||
if limits is not None:
|
||||
assert len(limits) == 2
|
||||
self.low_limit_travel.put(limits[0])
|
||||
self.high_limit_travel.put(limits[1])
|
||||
|
||||
@property
|
||||
def limits(self):
|
||||
return (self.low_limit_travel.get(), self.high_limit_travel.get())
|
||||
|
||||
@property
|
||||
def low_limit(self):
|
||||
return self.limits[0]
|
||||
|
||||
@property
|
||||
def high_limit(self):
|
||||
return self.limits[1]
|
||||
|
||||
def check_value(self, pos):
|
||||
"""Check that the position is within the soft limits"""
|
||||
low_limit, high_limit = self.limits
|
||||
|
||||
if low_limit < high_limit and not (low_limit <= pos <= high_limit):
|
||||
raise LimitError(f"position={pos} not within limits {self.limits}")
|
||||
|
||||
def _update_connection_state(self, **kwargs):
|
||||
for walk in self.walk_signals():
|
||||
walk.item._metadata["connected"] = self.controller.connected
|
||||
|
||||
def _forward_readback(self, **kwargs):
|
||||
kwargs.pop("sub_type")
|
||||
self._run_subs(sub_type="readback", **kwargs)
|
||||
|
||||
@raise_if_disconnected
|
||||
def move(self, position, wait=True, **kwargs):
|
||||
"""Move to a specified position, optionally waiting for motion to
|
||||
complete.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
position
|
||||
Position to move to
|
||||
moved_cb : callable
|
||||
Call this callback when movement has finished. This callback must
|
||||
accept one keyword argument: 'obj' which will be set to this
|
||||
positioner instance.
|
||||
timeout : float, optional
|
||||
Maximum time to wait for the motion. If None, the default timeout
|
||||
for this positioner is used.
|
||||
|
||||
Returns
|
||||
-------
|
||||
status : MoveStatus
|
||||
|
||||
Raises
|
||||
------
|
||||
TimeoutError
|
||||
When motion takes longer than `timeout`
|
||||
ValueError
|
||||
On invalid positions
|
||||
RuntimeError
|
||||
If motion fails other than timing out
|
||||
"""
|
||||
self._started_moving = False
|
||||
timeout = kwargs.pop("timeout", 100)
|
||||
status = super().move(position, timeout=timeout, **kwargs)
|
||||
self.user_setpoint.put(position, wait=False)
|
||||
|
||||
def move_and_finish():
|
||||
while self.motor_is_moving.get():
|
||||
logger.info("motor is moving")
|
||||
val = self.readback.read()
|
||||
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
|
||||
time.sleep(0.1)
|
||||
val = self.readback.read()
|
||||
success = np.isclose(val[self.name]["value"], position, atol=self.tolerance)
|
||||
|
||||
if not success:
|
||||
print(" stop")
|
||||
self._done_moving(success=success)
|
||||
logger.info("Move finished")
|
||||
|
||||
threading.Thread(target=move_and_finish, daemon=True).start()
|
||||
try:
|
||||
if wait:
|
||||
status_wait(status)
|
||||
except KeyboardInterrupt:
|
||||
self.stop()
|
||||
raise
|
||||
|
||||
return status
|
||||
|
||||
@property
|
||||
def axis_Id(self):
|
||||
return self._axis_Id_alpha
|
||||
|
||||
@axis_Id.setter
|
||||
def axis_Id(self, val):
|
||||
if isinstance(val, str):
|
||||
if len(val) != 1:
|
||||
raise ValueError("Only single-character axis_Ids are supported.")
|
||||
self._axis_Id_alpha = val
|
||||
self._axis_Id_numeric = self.controller.axis_Id_to_numeric(val)
|
||||
else:
|
||||
raise TypeError(f"Expected value of type str but received {type(val)}")
|
||||
|
||||
@property
|
||||
def axis_Id_numeric(self):
|
||||
return self._axis_Id_numeric
|
||||
|
||||
@axis_Id_numeric.setter
|
||||
def axis_Id_numeric(self, val):
|
||||
if isinstance(val, int):
|
||||
if val > 26:
|
||||
raise ValueError("Numeric value exceeds supported range.")
|
||||
self._axis_Id_alpha = self.controller.axis_Id_numeric_to_alpha(val)
|
||||
self._axis_Id_numeric = val
|
||||
else:
|
||||
raise TypeError(f"Expected value of type int but received {type(val)}")
|
||||
|
||||
@property
|
||||
def egu(self):
|
||||
"""The engineering units (EGU) for positions"""
|
||||
return "mm"
|
||||
|
||||
def _ogalil_folerr_reset_and_ignore(self):
|
||||
# pylint: disable=protected-access
|
||||
self.controller._ogalil_folerr_reset_and_ignore(self.axis_Id_numeric)
|
||||
|
||||
def _ogalil_set_axis_to_pos_wo_reference_search(self, pos_mm):
|
||||
motor_resolution = self.motor_resolution.get()
|
||||
self.controller._ogalil_set_axis_to_pos_wo_reference_search(self.axis_Id_numeric, self.axis_Id, pos_mm, motor_resolution, self.sign)
|
||||
#now force position read to cache
|
||||
val = self.readback.read()
|
||||
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
|
||||
|
||||
def find_reference(self, raise_error=1):
|
||||
"""
|
||||
Find the reference of the axis.
|
||||
"""
|
||||
verbose=1
|
||||
self.controller.find_reference(self.axis_Id_numeric, verbose, raise_error)
|
||||
#now force position read to cache
|
||||
val = self.readback.read()
|
||||
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
|
||||
|
||||
def drive_axis_to_limit(self, direction: str) -> None:
|
||||
"""
|
||||
Drive an axis to the limit in a specified direction.
|
||||
|
||||
Args:
|
||||
direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'.
|
||||
"""
|
||||
self.controller.drive_axis_to_limit(self.axis_Id_numeric, direction, verbose=1)
|
||||
#now force position read to cache
|
||||
val = self.readback.read()
|
||||
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
|
||||
|
||||
def get_motor_limit_switch(self) -> list:
|
||||
"""
|
||||
Get status of the motor limit switches
|
||||
"""
|
||||
return self.controller.get_motor_limit_switch(self.axis_Id)
|
||||
|
||||
def get_motor_temperature(self) -> float:
|
||||
"""
|
||||
Get motor temperature
|
||||
"""
|
||||
return self.controller.motor_temperature(self.axis_Id_numeric)
|
||||
|
||||
def axis_is_referenced(self) -> bool:
|
||||
"""
|
||||
check if an axis is referenced
|
||||
"""
|
||||
return self.controller.axis_is_referenced(self.axis_Id_numeric)
|
||||
|
||||
def _get_user_param_safe(self, device, var):
|
||||
param = self.device_manager.devices[device].user_parameter
|
||||
if not param or param.get(var) is None:
|
||||
raise ValueError(f"Device {device} has no user parameter definition for {var}.")
|
||||
return param.get(var)
|
||||
|
||||
def omny_osamx_to_scan_center(self, cenx):
|
||||
if self.controller.sock.port == 8082 and self.axis_Id_numeric == 0:
|
||||
# get last setpoint
|
||||
osamx = self.device_manager.devices["osamx"]
|
||||
osamx_current_setpoint = osamx.obj.readback.get()
|
||||
omny_samx_in = self._get_user_param_safe("osamx","in")
|
||||
if np.fabs(osamx_current_setpoint-(omny_samx_in+cenx/1000)) > 0.025:
|
||||
message=f"Moving osamx to scan center. new osamx target {omny_samx_in+cenx/1000:.3f}."
|
||||
logger.info(message)
|
||||
|
||||
osamx.read_only = False
|
||||
#osamx.controller.("osamx", "controller.socket_put_confirmed('axspeed[0]=1000')")
|
||||
osamx.set(omny_samx_in+cenx/1000)
|
||||
time.sleep(0.1)
|
||||
while(osamx.motor_is_moving.get()):
|
||||
time.sleep(0.05)
|
||||
osamx.read_only = True
|
||||
time.sleep(2)
|
||||
rt = self.device_manager.devices["rtx"]
|
||||
if rt.enabled:
|
||||
rt.obj.controller.laser_tracker_on()
|
||||
rt.obj.controller.laser_tracker_check_and_wait_for_signalstrength()
|
||||
|
||||
def folerr_status(self) -> bool:
|
||||
return self.controller.folerr_status(self.axis_Id_numeric)
|
||||
|
||||
def stop(self, *, success=False):
|
||||
self.controller.stop_all_axes()
|
||||
return super().stop(success=success)
|
||||
111
csaxs_bec/devices/omny/omny_dewar.py
Normal file
111
csaxs_bec/devices/omny/omny_dewar.py
Normal file
@@ -0,0 +1,111 @@
|
||||
import time
|
||||
import datetime
|
||||
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import Device
|
||||
from ophyd import DynamicDeviceComponent as Dcpt
|
||||
from ophyd import EpicsSignal
|
||||
from prettytable import FRAME, PrettyTable
|
||||
import numpy as np
|
||||
|
||||
class OMNYDewarError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNYDewar(Device):
|
||||
USER_ACCESS = [
|
||||
"show_all",
|
||||
"is_flow_low",
|
||||
"help",
|
||||
]
|
||||
SUB_VALUE = "value"
|
||||
_default_sub = SUB_VALUE
|
||||
|
||||
|
||||
|
||||
dewar_press_0 = Cpt(
|
||||
EpicsSignal, name="dewar_press_0", read_pv="XOMNY-TEMP-DEWAR-PRESS0:GET"
|
||||
)
|
||||
|
||||
dewar_refilling = Cpt(
|
||||
EpicsSignal, name="dewar_refilling", read_pv="XOMNY-TEMP-DEWAR-Refilling:GET"
|
||||
)
|
||||
|
||||
dewar_press_1 = Cpt(
|
||||
EpicsSignal, name="dewar_press_1", read_pv="XOMNY-TEMP-DEWAR-PRESS1:GET"
|
||||
)
|
||||
|
||||
dewar_press_2 = Cpt(
|
||||
EpicsSignal, name="dewar_press_2", read_pv="XOMNY-TEMP-DEWAR-PRESS2:GET"
|
||||
)
|
||||
|
||||
dewar_flow_0 = Cpt(
|
||||
EpicsSignal, name="dewar_flow_0", read_pv="XOMNY-TEMP-DEWAR-FLOW0:GET"
|
||||
)
|
||||
|
||||
dewar_valvepos = Cpt(
|
||||
EpicsSignal, name="dewar_valvepos", read_pv="XOMNY-TEMP-DEWAR-ValvePos:GET"
|
||||
)
|
||||
|
||||
dewar_supply_voltage = Cpt(
|
||||
EpicsSignal, name="dewar_supply_voltage", read_pv="XOMNY-TEMP-DEWAR-SupplyVoltage:GET"
|
||||
)
|
||||
|
||||
dewar_uptime_h = Cpt(
|
||||
EpicsSignal, name="dewar_uptime_h", read_pv="XOMNY-TEMP-DEWAR-UpH:GET"
|
||||
)
|
||||
dewar_uptime_m = Cpt(
|
||||
EpicsSignal, name="dewar_uptime_m", read_pv="XOMNY-TEMP-DEWAR-UpM:GET"
|
||||
)
|
||||
dewar_uptime_s = Cpt(
|
||||
EpicsSignal, name="dewar_uptime_s", read_pv="XOMNY-TEMP-DEWAR-UpS:GET"
|
||||
)
|
||||
|
||||
dewar_valve_movements_h = Cpt(
|
||||
EpicsSignal, name="dewar_valve_movements_h", read_pv="XOMNY-TEMP-DEWAR-MovH:GET"
|
||||
)
|
||||
dewar_valve_movements_m = Cpt(
|
||||
EpicsSignal, name="dewar_valve_movements_m", read_pv="XOMNY-TEMP-DEWAR-MovM:GET"
|
||||
)
|
||||
dewar_valve_movements_s = Cpt(
|
||||
EpicsSignal, name="dewar_valve_movements_s", read_pv="XOMNY-TEMP-DEWAR-MovS:GET"
|
||||
)
|
||||
|
||||
def __init__(self, prefix="", *, name, **kwargs):
|
||||
super().__init__(prefix, name=name, **kwargs)
|
||||
self.dewar_flow_0.subscribe(self._emit_value)
|
||||
|
||||
def _emit_value(self, **kwargs):
|
||||
timestamp = kwargs.pop("timestamp", time.time())
|
||||
self.wait_for_connection()
|
||||
self._run_subs(sub_type=self.SUB_VALUE, timestamp=timestamp, obj=self)
|
||||
|
||||
|
||||
def is_flow_low(self):
|
||||
if(float(self.dewar_flow_0.get())<3.8):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def show_all(self):
|
||||
red = "\x1b[91m"
|
||||
white = "\x1b[0m"
|
||||
|
||||
|
||||
print("OMNY Dewar Status")
|
||||
print(f" DewarPressure: {float(self.dewar_press_0.get()):.0f} mbar")
|
||||
print(f" Dewar Refilling: {float(self.dewar_refilling.get()):.0f}")
|
||||
print(f" LN2flow In Pressure: {float(self.dewar_press_1.get()):.0f} mbar")
|
||||
print(f" LN2flow Out Pressure: {float(self.dewar_press_2.get()):.0f} mbar")
|
||||
print(f" LN2flow In Flow Rate: {float(self.dewar_flow_0.get()):.1f} l/s")
|
||||
if self.is_flow_low():
|
||||
print(red + "This flow rate is LOW. Increase the LN2flow In Pressure" + white)
|
||||
print(f" Valve Opening (0-1): {float(self.dewar_valvepos.get()):.2f}")
|
||||
print(f" Valve Supply Voltage: {float(self.dewar_supply_voltage.get()):.2f} V")
|
||||
print(f" Uptime of System: {float(self.dewar_uptime_h.get()):2.0f}:{float(self.dewar_uptime_m.get()):2.0f}:{float(self.dewar_uptime_s.get()):2.0f}")
|
||||
print(f" Active Valve Movements: {float(self.dewar_valve_movements_h.get()):2.0f}:{float(self.dewar_valve_movements_m.get()):2.0f}:{float(self.dewar_valve_movements_s.get()):2.0f}")
|
||||
|
||||
|
||||
def help(self):
|
||||
print("Help for OMNY Dewar:")
|
||||
print("This device shows an overview of the dewar status. Use show_all()")
|
||||
@@ -22,6 +22,7 @@ class OMNYSampleStorage(Device):
|
||||
"set_sample_in_samplestage",
|
||||
"unset_sample_in_samplestage",
|
||||
"get_sample_name_in_samplestage",
|
||||
"get_sample_name_in_gripper",
|
||||
"get_sample_name",
|
||||
"is_sample_in_samplestage",
|
||||
"set_shuttle_slot",
|
||||
@@ -30,6 +31,7 @@ class OMNYSampleStorage(Device):
|
||||
"is_shuttle_slot_used",
|
||||
"search_shuttle_in_slot",
|
||||
"show_all",
|
||||
"help",
|
||||
]
|
||||
SUB_VALUE = "value"
|
||||
_default_sub = SUB_VALUE
|
||||
@@ -137,20 +139,28 @@ class OMNYSampleStorage(Device):
|
||||
elif container == "C":
|
||||
getattr(self.sample_shuttle_C_placed, f"sample{slot_nr}").set(1)
|
||||
getattr(self.sample_shuttle_C_names, f"sample{slot_nr}").set(name)
|
||||
elif container == "O":
|
||||
getattr(self.sample_placed, f"sample{slot_nr}").set(1)
|
||||
getattr(self.sample_names, f"sample{slot_nr}").set(name)
|
||||
|
||||
def unset_sample_slot(self, shuttle: str, slot_nr: int) -> bool:
|
||||
|
||||
def unset_sample_slot(self, container: str, slot_nr: int) -> bool:
|
||||
if slot_nr > 20:
|
||||
raise OMNYSampleStorageError(f"Invalid slot number {slot_nr}.")
|
||||
|
||||
if shuttle == "A":
|
||||
if container == "A":
|
||||
getattr(self.sample_shuttle_A_placed, f"sample{slot_nr}").set(0)
|
||||
getattr(self.sample_shuttle_A_names, f"sample{slot_nr}").set("-")
|
||||
if shuttle == "B":
|
||||
elif container == "B":
|
||||
getattr(self.sample_shuttle_B_placed, f"sample{slot_nr}").set(0)
|
||||
getattr(self.sample_shuttle_B_names, f"sample{slot_nr}").set("-")
|
||||
if shuttle == "C":
|
||||
elif container == "C":
|
||||
getattr(self.sample_shuttle_C_placed, f"sample{slot_nr}").set(0)
|
||||
getattr(self.sample_shuttle_C_names, f"sample{slot_nr}").set("-")
|
||||
elif container == "O":
|
||||
getattr(self.sample_placed, f"sample{slot_nr}").set(0)
|
||||
getattr(self.sample_names, f"sample{slot_nr}").set("-")
|
||||
|
||||
|
||||
def set_shuttle_slot(self, container: str, slot_nr: int) -> bool:
|
||||
if slot_nr > 6:
|
||||
@@ -275,8 +285,24 @@ class OMNYSampleStorage(Device):
|
||||
row = []
|
||||
row.extend([f"Position {i:3d}"])
|
||||
if self.is_sample_slot_used("O", i):
|
||||
row.extend(self.get_sample_name("O", i))
|
||||
name = self.get_sample_name("O", i)
|
||||
row.extend([name])
|
||||
else:
|
||||
row.extend(["free"])
|
||||
t.add_row(row)
|
||||
print(t)
|
||||
|
||||
print("Use dev.omny_samples.help() for assistance.")
|
||||
|
||||
def help(self):
|
||||
print("Help for OMNY sample storage:")
|
||||
print(" To get an overview use dev.omny_samples.show_all()")
|
||||
print(" Modify a slot:")
|
||||
print(" dev.omny_samples.unset_sample_slot('system',position)")
|
||||
print(" dev.omny_samples.set_sample_slot('system',position,'name')")
|
||||
print(" system can be A, B, C, O")
|
||||
print(" dev.omny_samples.set_sample_in_gripper('name') / unset_sample_in_gripper()")
|
||||
print(" dev.omny_samples.set_sample_in_samplestage('name'), unset_sample_in_samplestage()")
|
||||
print(" dev.omny_samples.set_shuttle_slot(container, slot_nr) / unset_shuttle_slot(slot_nr)")
|
||||
print(" dev.omny_samples.set_shuttle_slot('A',2)")
|
||||
print(" omny.otransfer_help()")
|
||||
|
||||
260
csaxs_bec/devices/omny/omny_temperatures.py
Normal file
260
csaxs_bec/devices/omny/omny_temperatures.py
Normal file
@@ -0,0 +1,260 @@
|
||||
import time
|
||||
import datetime
|
||||
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import Device
|
||||
from ophyd import DynamicDeviceComponent as Dcpt
|
||||
from ophyd import EpicsSignal
|
||||
from prettytable import FRAME, PrettyTable
|
||||
import numpy as np
|
||||
|
||||
class OMNYTemperaturesError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNYTemperatures(Device):
|
||||
USER_ACCESS = [
|
||||
"temperature_controller_used_get_name_and_values",
|
||||
"set_setpoint",
|
||||
"show_all",
|
||||
"help",
|
||||
"_set_TEMP_default_setpoints",
|
||||
"temperature_controller_TEMP_running",
|
||||
"temperature_controller_CRYO_running",
|
||||
]
|
||||
SUB_VALUE = "value"
|
||||
_default_sub = SUB_VALUE
|
||||
|
||||
temperature = {
|
||||
f"temperature{i}": (EpicsSignal, f"XOMNY-TEMP{i}:GET", {}) for i in range(1, 49)
|
||||
}
|
||||
temperature = Dcpt(temperature)
|
||||
|
||||
temperature_setpoint = {
|
||||
f"temperature_setpoint{i}": (EpicsSignal, f"XOMNY-TEMP{i}:SET", {}) for i in range(1, 49)
|
||||
}
|
||||
temperature_setpoint = Dcpt(temperature_setpoint)
|
||||
|
||||
temperature_unit = {
|
||||
f"temperature_unit{i}": (EpicsSignal, f"XOMNY-TEMP{i}:GET.EGU", {}) for i in range(1, 49)
|
||||
}
|
||||
temperature_unit = Dcpt(temperature_unit)
|
||||
|
||||
temperature_alarmstate = {
|
||||
f"temperature_alarmstate{i}": (EpicsSignal, f"XOMNY-TEMP{i}:ALARM", {}) for i in range(1, 49)
|
||||
}
|
||||
temperature_alarmstate = Dcpt(temperature_alarmstate)
|
||||
|
||||
temperature_names = {
|
||||
f"temperature_name{i}": (EpicsSignal, f"XOMNY-TEMP{i}:GET.DESC", {"string": True})
|
||||
for i in range(1, 49)
|
||||
}
|
||||
temperature_names = Dcpt(temperature_names)
|
||||
|
||||
temperature_update_time = Cpt(
|
||||
EpicsSignal, name="temperature_update_time", read_pv="XOMNY-TEMP:UPDATED.VAL"
|
||||
)
|
||||
|
||||
cryo_temperature = {
|
||||
f"cryo_temperature{i}": (EpicsSignal, f"XOMNY-TEMP-CRYO-{chr(i+ord('A')-1)}:GET.VAL", {}) for i in range(1,5)
|
||||
}
|
||||
cryo_temperature = Dcpt(cryo_temperature)
|
||||
|
||||
cryo_temperature_setpoint = {
|
||||
f"cryo_temperature_setpoint{i}": (EpicsSignal, f"XOMNY-TEMP-CRYO-{chr(i+ord('A')-1)}:SET.VAL", {}) for i in range(1,5)
|
||||
}
|
||||
cryo_temperature_setpoint = Dcpt(cryo_temperature_setpoint)
|
||||
|
||||
cryo_temperature_name = {
|
||||
f"cryo_temperature_name{i}": (EpicsSignal, f"XOMNY-TEMP-CRYO-{chr(i+ord('A')-1)}:GET.DESC", {}) for i in range(1,5)
|
||||
}
|
||||
cryo_temperature_name = Dcpt(cryo_temperature_name)
|
||||
|
||||
cryo_temperature_update_time = Cpt(
|
||||
EpicsSignal, name="cryo_temperature_update_time", read_pv="XOMNY-TEMP-CRYO:UPDATED.VAL"
|
||||
)
|
||||
|
||||
cryo_temperature_closed_loop = Cpt(
|
||||
EpicsSignal, name="cryo_temperature_closed_loop", read_pv="XOMNY-TEMP-CRYO:CLOSEDLOOP.VAL"
|
||||
)
|
||||
|
||||
def __init__(self, prefix="", *, name, **kwargs):
|
||||
super().__init__(prefix, name=name, **kwargs)
|
||||
self.temperature.temperature1.subscribe(self._emit_value)
|
||||
|
||||
def _emit_value(self, **kwargs):
|
||||
timestamp = kwargs.pop("timestamp", time.time())
|
||||
self.wait_for_connection()
|
||||
self._run_subs(sub_type=self.SUB_VALUE, timestamp=timestamp, obj=self)
|
||||
|
||||
def set_setpoint(self, type: str, controller_nr: int, temperature: float):
|
||||
if type == "TEMP":
|
||||
getattr(self.temperature_setpoint, f"temperature_setpoint{controller_nr}").set(temperature)
|
||||
elif type == "CRYO":
|
||||
getattr(self.cryo_temperature_setpoint, f"cryo_temperature_setpoint{controller_nr}").set(temperature)
|
||||
else:
|
||||
raise OMNYTemperaturesError("invalid type")
|
||||
|
||||
|
||||
def _set_TEMP_default_setpoints(self):
|
||||
self.set_setpoint("TEMP",8,-199.9)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",9,23)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",10,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",16,-199.9)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",17,23)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",18,26)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",19,26)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",20,26)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",21,23)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",22,-199.9)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",23,-199.9)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",24,-199.9)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",25,25)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",27,25)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",28,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",29,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",30,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",31,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",35,25)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",36,25)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",37,25)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",38,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",39,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",41,30)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",42,25)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",44,25)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",45,-199.9)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",46,73.2)
|
||||
time.sleep(0.1)
|
||||
self.set_setpoint("TEMP",47,73.2)
|
||||
time.sleep(0.1)
|
||||
|
||||
def temperature_controller_TEMP_running(self):
|
||||
time_diff = np.fabs(float(self.temperature_update_time.get()) - time.time())
|
||||
if time_diff > 600:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def temperature_controller_CRYO_running(self):
|
||||
time_diff = np.fabs(float(self.cryo_temperature_update_time.get()) - time.time())
|
||||
if time_diff > 600:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def temperature_controller_used_get_name_and_values(self, type: str, controller_nr: int) -> bool:
|
||||
if type == "TEMP":
|
||||
controller_name = str(getattr(self.temperature_names, f"temperature_name{controller_nr}").get())
|
||||
if controller_name == '-' or controller_name == 'NOT INITIALIZED':
|
||||
return (False, "none", 0, 0, "none", False, False)
|
||||
else:
|
||||
temperature = float(getattr(self.temperature, f"temperature{controller_nr}").get())
|
||||
setpoint = float(getattr(self.temperature_setpoint, f"temperature_setpoint{controller_nr}").get())
|
||||
unit = str(getattr(self.temperature_unit, f"temperature_unit{controller_nr}").get())
|
||||
alarmstate = bool(getattr(self.temperature_alarmstate, f"temperature_alarmstate{controller_nr}").get())
|
||||
controller_running = self.temperature_controller_TEMP_running()
|
||||
return (True, controller_name, temperature, setpoint, unit, alarmstate,controller_running)
|
||||
elif type == "CRYO":
|
||||
controller_name = str(getattr(self.cryo_temperature_name, f"cryo_temperature_name{controller_nr}").get())
|
||||
temperature = float(getattr(self.cryo_temperature, f"cryo_temperature{controller_nr}").get())
|
||||
setpoint = float(getattr(self.cryo_temperature_setpoint, f"cryo_temperature_setpoint{controller_nr}").get())
|
||||
unit = 'K'
|
||||
alarmstate = False
|
||||
controller_running = self.temperature_controller_CRYO_running()
|
||||
return (True, controller_name, temperature, setpoint, unit, alarmstate,controller_running)
|
||||
else:
|
||||
raise OMNYTemperaturesError("invalid type")
|
||||
|
||||
|
||||
|
||||
def show_all(self):
|
||||
red = "\x1b[91m"
|
||||
white = "\x1b[0m"
|
||||
t = PrettyTable()
|
||||
t.clear()
|
||||
t.title = "OMNY Temperature Controllers"
|
||||
t.field_names = ["Channel","Name","Temperature","Setpoint","Unit","AlarmState"]
|
||||
for i in range (1,49):
|
||||
controller_status = self.temperature_controller_used_get_name_and_values("TEMP", i)
|
||||
if controller_status[0]:
|
||||
row = []
|
||||
row.extend([f"{i}"])
|
||||
row.extend([controller_status[1]])
|
||||
row.extend([f"{controller_status[2]:.2f}"])
|
||||
if (controller_status[3] < -199 and controller_status[4] == "degC") or (np.fabs(controller_status[3]-73.25) < 0.1 and controller_status[4] == "K"):
|
||||
row.extend([" "])
|
||||
else:
|
||||
row.extend([f"{controller_status[3]:.2f}"])
|
||||
row.extend([f"{controller_status[4]}"])
|
||||
if controller_status[5]:
|
||||
row.extend(["Alarm"])
|
||||
else:
|
||||
row.extend([" "])
|
||||
t.add_row(row)
|
||||
t.header = True
|
||||
t.vrules = FRAME
|
||||
print(t)
|
||||
if not self.temperature_controller_TEMP_running():
|
||||
print (red + "Warning: the temperature controller communication is not running" + white)
|
||||
print (f"The last update was {datetime.datetime.fromtimestamp(float(self.temperature_update_time.get())).strftime('%c')}\n")
|
||||
|
||||
|
||||
t.clear()
|
||||
t.title = "OMNY Cryo Temperature Controller"
|
||||
t.field_names = ["Channel","Name","Temperature","Setpoint","Unit"]
|
||||
for i in range (1,5):
|
||||
controller_status = self.temperature_controller_used_get_name_and_values("CRYO", i)
|
||||
if controller_status[0]:
|
||||
row = []
|
||||
row.extend([f"{i}"])
|
||||
row.extend([controller_status[1]])
|
||||
row.extend([f"{controller_status[2]:.2f}"])
|
||||
row.extend([f"{controller_status[3]:.2f}"])
|
||||
row.extend([f"{controller_status[4]}"])
|
||||
t.add_row(row)
|
||||
t.header = True
|
||||
t.vrules = FRAME
|
||||
print(t)
|
||||
|
||||
if bool(self.cryo_temperature_closed_loop.get()):
|
||||
print ("Cryo controller is running in closed loop.")
|
||||
else:
|
||||
print ("Cryo controller is running in " + red + "open" + white + " loop.")
|
||||
|
||||
if not self.temperature_controller_CRYO_running():
|
||||
print (red + "Warning: the temperature controller communication is not running" + white)
|
||||
|
||||
print (f"The last update was {datetime.datetime.fromtimestamp(float(self.cryo_temperature_update_time.get())).strftime('%c')}\n")
|
||||
|
||||
print("Use dev.omny_temperatures.help() for assistance.")
|
||||
|
||||
def help(self):
|
||||
print("Help for OMNY temperatures:")
|
||||
161
csaxs_bec/devices/omny/omny_vcs.py
Normal file
161
csaxs_bec/devices/omny/omny_vcs.py
Normal file
@@ -0,0 +1,161 @@
|
||||
import time
|
||||
import datetime
|
||||
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import Device
|
||||
from ophyd import DynamicDeviceComponent as Dcpt
|
||||
from ophyd import EpicsSignal
|
||||
from prettytable import FRAME, PrettyTable
|
||||
import numpy as np
|
||||
|
||||
class OMNYVCSError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OMNYVCS(Device):
|
||||
USER_ACCESS = [
|
||||
"show_all",
|
||||
"valves_in_measurement_position",
|
||||
"help",
|
||||
]
|
||||
SUB_VALUE = "value"
|
||||
_default_sub = SUB_VALUE
|
||||
|
||||
|
||||
|
||||
XOMNY_ES1_EXPMP1_VOLTAGE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_EXPMP1_VOLTAGE", read_pv="XOMNY-ES1-EXPMP1:VOLTAGE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_EXPMP1_PRESSURE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_EXPMP1_PRESSURE", read_pv="XOMNY-ES1-EXPMP1:PRESSURE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_PU2MT1_VOLTAGE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_PU2MT1_VOLTAGE", read_pv="XOMNY-ES1-PU2MT1:VOLTAGE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_PU2MT1_PRESSURE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_PU2MT1_PRESSURE", read_pv="XOMNY-ES1-PU2MT1:PRESSURE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_PU1MF1_VOLTAGE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_PU1MF1_VOLTAGE", read_pv="XOMNY-ES1-PU1MF1:VOLTAGE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_PU1MF1_PRESSURE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_PU1MF1_PRESSURE", read_pv="XOMNY-ES1-PU1MF1:PRESSURE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_LL1MF1_VOLTAGE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_LL1MF1_VOLTAGE", read_pv="XOMNY-ES1-LL1MF1:VOLTAGE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_LL1MF1_PRESSURE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_LL1MF1_PRESSURE", read_pv="XOMNY-ES1-LL1MF1:PRESSURE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_VV1MT1_VOLTAGE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_VV1MT1_VOLTAGE", read_pv="XOMNY-ES1-VV1MT1:VOLTAGE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_VV1MT1_PRESSURE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_VV1MT1_PRESSURE", read_pv="XOMNY-ES1-VV1MT1:PRESSURE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_EXPVG1_POSITION = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_EXPVG1_POSITION", read_pv="XOMNY-ES1-EXPVG1:POSITION"
|
||||
)
|
||||
|
||||
XOMNY_ES1_WI2VG1_POSITION = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_WI2VG1_POSITION", read_pv="XOMNY-ES1-WI2VG1:POSITION"
|
||||
)
|
||||
|
||||
XOMNY_ES1_EXPVG2_POSITION = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_EXPVG2_POSITION", read_pv="XOMNY-ES1-EXPVG2:POSITION"
|
||||
)
|
||||
|
||||
XOMNY_ES1_LL1VG1_CLOSE = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_LL1VG1_CLOSE", read_pv="XOMNY-ES1-LL1VG1:CLOSE"
|
||||
)
|
||||
|
||||
XOMNY_ES1_LL1DK_VG_CLOSED = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_LL1DK_VG_CLOSED", read_pv="XOMNY-ES1-LL1DK:VG_CLOSED"
|
||||
)
|
||||
|
||||
XOMNY_ES1_LL1SH_VG_CLOSED = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_LL1SH_VG_CLOSED", read_pv="XOMNY-ES1-LL1SH:VG_CLOSED"
|
||||
)
|
||||
|
||||
XOMNY_ES1_LL1SH_MAN_POS_OK = Cpt(
|
||||
EpicsSignal, name="XOMNY_ES1_LL1SH_MAN_POS_OK", read_pv="XOMNY-ES1-LL1SH:MAN_POS_OK"
|
||||
)
|
||||
|
||||
|
||||
def __init__(self, prefix="", *, name, **kwargs):
|
||||
super().__init__(prefix, name=name, **kwargs)
|
||||
self.XOMNY_ES1_LL1SH_MAN_POS_OK.subscribe(self._emit_value)
|
||||
|
||||
def _emit_value(self, **kwargs):
|
||||
timestamp = kwargs.pop("timestamp", time.time())
|
||||
self.wait_for_connection()
|
||||
self._run_subs(sub_type=self.SUB_VALUE, timestamp=timestamp, obj=self)
|
||||
|
||||
|
||||
def show_all(self):
|
||||
red = "\x1b[91m"
|
||||
white = "\x1b[0m"
|
||||
|
||||
print("OMNY Vaccum Status")
|
||||
if float(self.XOMNY_ES1_EXPMP1_VOLTAGE.get()) < 0.5:
|
||||
print(red + " Main chamber: Sensor failure" + white)
|
||||
else:
|
||||
print(f" Main chamber: {float(self.XOMNY_ES1_EXPMP1_PRESSURE.get()):.2e} mbar")
|
||||
|
||||
if float(self.XOMNY_ES1_PU2MT1_VOLTAGE.get()) < 0.5:
|
||||
print(red + " Flight tube: Sensor failure" + white)
|
||||
else:
|
||||
print(f" Flight tube: {float(self.XOMNY_ES1_PU2MT1_PRESSURE.get()):.2e} mbar")
|
||||
|
||||
if float(self.XOMNY_ES1_PU1MF1_VOLTAGE.get()) < 0.5:
|
||||
print(red+" Beamline: Sensor failure"+white)
|
||||
else:
|
||||
print(f" Beamline: {float(self.XOMNY_ES1_PU1MF1_PRESSURE.get()):.2e} mbar")
|
||||
|
||||
if float(self.XOMNY_ES1_LL1MF1_VOLTAGE.get()) < 0.5:
|
||||
print(red+" LoadLock: Sensor failure"+white)
|
||||
else:
|
||||
print(f" LoadLock: {float(self.XOMNY_ES1_LL1MF1_PRESSURE.get()):.2e} mbar")
|
||||
|
||||
if float(self.XOMNY_ES1_VV1MT1_VOLTAGE.get()) < 0.5:
|
||||
print(red+" Pre-pump: Sensor failure"+white)
|
||||
else:
|
||||
print(f" Pre-pump: {float(self.XOMNY_ES1_VV1MT1_PRESSURE.get()):.2e} mbar")
|
||||
|
||||
print("\nValve status")
|
||||
print(f" Upstream gate valve: {str(self.XOMNY_ES1_EXPVG1_POSITION.get())}")
|
||||
#printf (" Upstream window valve: %s\n", _ovcs_upstream_window_valve)
|
||||
print(f" Downstream window bypass: {str(self.XOMNY_ES1_WI2VG1_POSITION.get())}")
|
||||
print(f" Downstream gate valve: {str(self.XOMNY_ES1_EXPVG2_POSITION.get())}")
|
||||
if self.valves_in_measurement_position():
|
||||
print("The OMNY valves are in the correct configuration to perform a measurement")
|
||||
else:
|
||||
print(red+"The valves of the OMNY vacuum system are not in the state for measurements."+white)
|
||||
|
||||
|
||||
print("\nLoad Lock Status")
|
||||
print(f" Chamber: {str(self.XOMNY_ES1_LL1VG1_CLOSE.get())}")
|
||||
print(f" Dock: {str(self.XOMNY_ES1_LL1DK_VG_CLOSED.get())}")
|
||||
print(f" Shuttle: {str(self.XOMNY_ES1_LL1SH_VG_CLOSED.get())}")
|
||||
print(f" Manipulator status: {str(self.XOMNY_ES1_LL1SH_MAN_POS_OK.get())}")
|
||||
|
||||
def valves_in_measurement_position(self):
|
||||
if str(self.XOMNY_ES1_EXPVG1_POSITION.get()) == "OPEN" and str(self.XOMNY_ES1_WI2VG1_POSITION.get()) == "CLOSED" and str(self.XOMNY_ES1_EXPVG2_POSITION.get()) == "OPEN":
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def help(self):
|
||||
print("Help for OMNY Vacuum System:")
|
||||
print("This device shows an overview of the OMNY vacuum status. Use show_all()")
|
||||
@@ -47,6 +47,7 @@ class RtFlomniController(Controller):
|
||||
"read_ssi_interferometer",
|
||||
"laser_tracker_check_signalstrength",
|
||||
"laser_tracker_check_enabled",
|
||||
"is_axis_moving",
|
||||
]
|
||||
|
||||
def __init__(
|
||||
@@ -538,8 +539,8 @@ class RtFlomniController(Controller):
|
||||
|
||||
logger.info(
|
||||
"Flomni statistics: Average of all standard deviations: x"
|
||||
f" {self.average_stdeviations_x_st_fzp/number_of_samples_to_read}, y"
|
||||
f" {self.average_stdeviations_y_st_fzp/number_of_samples_to_read}."
|
||||
f" {self.average_stdeviations_x_st_fzp/read_counter*1000:.1f}, y"
|
||||
f" {self.average_stdeviations_y_st_fzp/read_counter*1000:.1f}"
|
||||
)
|
||||
|
||||
def publish_device_data(self, signals, point_id):
|
||||
|
||||
1233
csaxs_bec/devices/omny/rt/rt_omny_ophyd.py
Normal file
1233
csaxs_bec/devices/omny/rt/rt_omny_ophyd.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -80,6 +80,8 @@ class SmaractController(Controller):
|
||||
"describe",
|
||||
"axis_is_referenced",
|
||||
"all_axes_referenced",
|
||||
"set_closed_loop_move_speed",
|
||||
"is_axis_moving",
|
||||
]
|
||||
|
||||
def __init__(
|
||||
|
||||
@@ -110,9 +110,8 @@ class LamNIMixin:
|
||||
logger.info(
|
||||
f"Compensating {[val/1000 for val in lamni_to_stage_coordinates(x_drift,y_drift)]}"
|
||||
)
|
||||
yield from self.stubs.set_and_wait(
|
||||
device=["lsamx", "lsamy"], positions=[move_x, move_y]
|
||||
)
|
||||
yield from self.stubs.set(device="lsamx", value=move_x)
|
||||
yield from self.stubs.set(device="lsamy", value=move_y)
|
||||
|
||||
time.sleep(0.01)
|
||||
rtx_current = yield from self.stubs.send_rpc_and_wait("rtx", "readback.get")
|
||||
@@ -148,9 +147,9 @@ class LamNIMixin:
|
||||
+ lamni_to_stage_coordinates(x_drift, y_drift)[1] / 1000
|
||||
+ lamni_to_stage_coordinates(x_drift2, y_drift2)[1] / 1000
|
||||
)
|
||||
yield from self.stubs.set_and_wait(
|
||||
device=["lsamx", "lsamy"], positions=[move_x, move_y]
|
||||
)
|
||||
yield from self.stubs.set(device="lsamx", value=move_x)
|
||||
yield from self.stubs.set(device="lsamy", value=move_y)
|
||||
|
||||
time.sleep(0.01)
|
||||
rtx_current = yield from self.stubs.send_rpc_and_wait("rtx", "readback.get")
|
||||
rty_current = yield from self.stubs.send_rpc_and_wait("rty", "readback.get")
|
||||
@@ -444,7 +443,7 @@ class LamNIFermatScan(ScanBase, LamNIMixin):
|
||||
}
|
||||
}
|
||||
)
|
||||
yield from self.stubs.set_and_wait(device=["lsamrot"], positions=[angle])
|
||||
yield from self.stubs.set(device="lsamrot", value=angle)
|
||||
|
||||
def scan_core(self):
|
||||
if self.scan_type == "step":
|
||||
@@ -457,7 +456,7 @@ class LamNIFermatScan(ScanBase, LamNIMixin):
|
||||
# scan ID before sending the message to the device server
|
||||
yield from self.stubs.kickoff(device="rtx")
|
||||
while True:
|
||||
yield from self.stubs.read_and_wait(group="primary", wait_group="readout_primary")
|
||||
yield from self.stubs.read(group="monitored")
|
||||
msg = self.device_manager.connector.get(MessageEndpoints.device_status("rt_scan"))
|
||||
if msg:
|
||||
status = msg
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
from .flomni_fermat_scan import FlomniFermatScan
|
||||
from .jungfrau_joch_scan import JungfrauJochTestScan
|
||||
from .LamNIFermatScan import LamNIFermatScan, LamNIMoveToScanCenter
|
||||
from .omny_fermat_scan import OMNYFermatScan
|
||||
from .owis_grid import OwisGrid
|
||||
from .sgalil_grid import SgalilGrid
|
||||
|
||||
@@ -35,7 +35,7 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
scan_name = "flomni_fermat_scan"
|
||||
scan_report_hint = "table"
|
||||
scan_type = "fly"
|
||||
required_kwargs = ["fov_size", "exp_time", "step", "angle"]
|
||||
required_kwargs = ["fovx", "fovy", "exp_time", "step", "angle"]
|
||||
arg_input = {}
|
||||
arg_bundle_size = {"bundle": len(arg_input), "min": None, "max": None}
|
||||
|
||||
@@ -59,8 +59,8 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
Args:
|
||||
fovx(float) [um]: Fov in the piezo plane (i.e. piezo range). Max 200 um
|
||||
fovy(float) [um]: Fov in the piezo plane (i.e. piezo range). Max 100 um
|
||||
cenx(float) [mm]: center position in x.
|
||||
ceny(float) [mm]: center position in y.
|
||||
cenx(float) [um]: center position in x.
|
||||
ceny(float) [um]: center position in y.
|
||||
exp_time(float) [s]: exposure time
|
||||
step(float) [um]: stepsize
|
||||
zshift(float) [um]: shift in z
|
||||
@@ -95,6 +95,7 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
if self.zshift < -100:
|
||||
logger.warning("The zshift is smaller than -100 um. It will be limited to -100 um.")
|
||||
self.zshift = -100
|
||||
self.flomni_rotation_status = None
|
||||
|
||||
def initialize(self):
|
||||
self.scan_motors = []
|
||||
@@ -115,13 +116,12 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
shorten the movement time. In order to keep the last state, even if the
|
||||
server is restarted, the state is stored in a global variable in redis.
|
||||
"""
|
||||
producer = self.device_manager.producer
|
||||
msg = producer.get(MessageEndpoints.global_vars("reverse_flomni_trajectory"))
|
||||
msg = self.connector.get(MessageEndpoints.global_vars("reverse_flomni_trajectory"))
|
||||
if msg:
|
||||
val = msg.content.get("value", False)
|
||||
else:
|
||||
val = False
|
||||
producer.set(
|
||||
self.connector.set(
|
||||
MessageEndpoints.global_vars("reverse_flomni_trajectory"),
|
||||
messages.VariableMessage(value=(not val)),
|
||||
)
|
||||
@@ -150,17 +150,17 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
yield from self.stubs.send_rpc_and_wait("rty", "set", self.positions[0][1])
|
||||
|
||||
def _prepare_setup_part2(self):
|
||||
yield from self.stubs.wait(wait_type="move", device="fsamroy", wait_group="flomni_rotation")
|
||||
yield from self.stubs.set(
|
||||
device="rtx", value=self.positions[0][0], wait_group="prepare_setup_part2"
|
||||
)
|
||||
yield from self.stubs.set(
|
||||
device="rtz", value=self.positions[0][2], wait_group="prepare_setup_part2"
|
||||
)
|
||||
if self.flomni_rotation_status:
|
||||
self.flomni_rotation_status.wait()
|
||||
|
||||
rtx_status = yield from self.stubs.set(device="rtx", value=self.positions[0][0], wait=False)
|
||||
rtz_status = yield from self.stubs.set(device="rtz", value=self.positions[0][2], wait=False)
|
||||
|
||||
yield from self.stubs.send_rpc_and_wait("rtx", "controller.laser_tracker_on")
|
||||
yield from self.stubs.wait(
|
||||
wait_type="move", device=["rtx", "rtz"], wait_group="prepare_setup_part2"
|
||||
)
|
||||
|
||||
rtx_status.wait()
|
||||
rtz_status.wait()
|
||||
|
||||
yield from self._transfer_positions_to_flomni()
|
||||
yield from self.stubs.send_rpc_and_wait(
|
||||
"rtx", "controller.move_samx_to_scan_region", self.fovx, self.cenx
|
||||
@@ -200,7 +200,9 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
}
|
||||
}
|
||||
)
|
||||
yield from self.stubs.set(device="fsamroy", value=angle, wait_group="flomni_rotation")
|
||||
self.flomni_rotation_status = yield from self.stubs.set(
|
||||
device="fsamroy", value=angle, wait=False
|
||||
)
|
||||
|
||||
def _transfer_positions_to_flomni(self):
|
||||
yield from self.stubs.send_rpc_and_wait(
|
||||
@@ -276,8 +278,8 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
# scan ID before sending the message to the device server
|
||||
yield from self.stubs.kickoff(device="rtx")
|
||||
while True:
|
||||
yield from self.stubs.read_and_wait(group="primary", wait_group="readout_primary")
|
||||
status = self.device_manager.producer.get(MessageEndpoints.device_status("rt_scan"))
|
||||
yield from self.stubs.read(group="monitored")
|
||||
status = self.connector.get(MessageEndpoints.device_status("rt_scan"))
|
||||
if status:
|
||||
status_id = status.content.get("status", 1)
|
||||
request_id = status.metadata.get("RID")
|
||||
@@ -297,19 +299,7 @@ class FlomniFermatScan(SyncFlyScanBase):
|
||||
"""return to the start position"""
|
||||
# in flomni, we need to move to the start position of the next scan
|
||||
if isinstance(self.positions, np.ndarray) and len(self.positions[-1]) == 3:
|
||||
yield from self.stubs.set(
|
||||
device="rtx", value=self.positions[-1][0], wait_group="scan_motor"
|
||||
)
|
||||
yield from self.stubs.set(
|
||||
device="rty", value=self.positions[-1][1], wait_group="scan_motor"
|
||||
)
|
||||
yield from self.stubs.set(
|
||||
device="rtz", value=self.positions[-1][2], wait_group="scan_motor"
|
||||
)
|
||||
|
||||
yield from self.stubs.wait(
|
||||
wait_type="move", device=["rtx", "rty", "rtz"], wait_group="scan_motor"
|
||||
)
|
||||
yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=self.positions[-1])
|
||||
return
|
||||
|
||||
logger.warning("No positions found to return to start")
|
||||
|
||||
58
csaxs_bec/scans/jungfrau_joch_scan.py
Normal file
58
csaxs_bec/scans/jungfrau_joch_scan.py
Normal file
@@ -0,0 +1,58 @@
|
||||
""" Module with JungfrauJochTestScan class. """
|
||||
|
||||
from bec_lib import bec_logger
|
||||
from bec_server.scan_server.scans import AsyncFlyScanBase, ScanAbortion
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class JungfrauJochTestScan(AsyncFlyScanBase):
|
||||
"""Owis-based grid scan."""
|
||||
|
||||
scan_name = "jjf_test"
|
||||
# scan_report_hint = "device_progress"
|
||||
required_kwargs = ["points", "exp_time", "readout_time"]
|
||||
arg_input = {}
|
||||
arg_bundle_size = {"bundle": len(arg_input), "min": None, "max": None}
|
||||
gui_config = {
|
||||
"Acquisition Parameters": ["num_points", "cycles"],
|
||||
"Exposure Parameters": ["exp_time", "readout_time"],
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self, num_points: int, exp_time: float, readout_time: float, cycles: int = 1, **kwargs
|
||||
):
|
||||
"""
|
||||
JungfrauJoch Test scan.
|
||||
|
||||
Args:
|
||||
device (DeviceBase) : The device to be triggered, currently only for delaygenerator csaxs
|
||||
num_points (int) : Number of points per burst
|
||||
exp_time (float) : exposure time.
|
||||
readout_time (float): readout time of detector
|
||||
cycles (int) : number of cycles, default is 1
|
||||
|
||||
Example:
|
||||
scans.jjf_test(points = 100, exp_time= 1e-3, readout_time=1e-3, cycles = 2)
|
||||
"""
|
||||
if readout_time <= 0:
|
||||
raise ScanAbortion(f"Readout time must be larger than 0, provided value {readout_time}")
|
||||
super().__init__(exp_time=exp_time, readout_time=readout_time, **kwargs)
|
||||
self.device = "ddg"
|
||||
self.num_points = num_points
|
||||
self.cycles = cycles
|
||||
self.primary_readout_cycle = 0.2
|
||||
|
||||
def scan_core(self):
|
||||
logger.info(f"Starting with Scan Core")
|
||||
total_exposure = self.num_points * (self.exp_time + self.readout_time)
|
||||
for i in range(self.cycles):
|
||||
logger.info(f"Beginning cycle {i} of {self.cycles}")
|
||||
|
||||
status = yield from self.stubs.trigger(min_wait=total_exposure, wait=False)
|
||||
yield from self.stubs.read(group="monitored", point_id=self.point_id, wait=True)
|
||||
self.point_id += 1
|
||||
status.wait()
|
||||
logger.info(f"Finished cycle {i} of {self.cycles}")
|
||||
logger.info(f"Finished scan")
|
||||
self.num_pos = self.point_id
|
||||
0
csaxs_bec/scans/metadata_schema/__init__.py
Normal file
0
csaxs_bec/scans/metadata_schema/__init__.py
Normal file
12
csaxs_bec/scans/metadata_schema/metadata_schema_registry.py
Normal file
12
csaxs_bec/scans/metadata_schema/metadata_schema_registry.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# from .metadata_schema_template import ExampleSchema
|
||||
|
||||
METADATA_SCHEMA_REGISTRY = {
|
||||
# Add models which should be used to validate scan metadata here.
|
||||
# Make a model according to the template, and import it as above
|
||||
# Then associate it with a scan like so:
|
||||
# "example_scan": ExampleSchema
|
||||
}
|
||||
|
||||
# Define a default schema type which should be used as the fallback for everything:
|
||||
|
||||
DEFAULT_SCHEMA = None
|
||||
34
csaxs_bec/scans/metadata_schema/metadata_schema_template.py
Normal file
34
csaxs_bec/scans/metadata_schema/metadata_schema_template.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# # By inheriting from BasicScanMetadata you can define a schema by which metadata
|
||||
# # supplied to a scan must be validated.
|
||||
# # This schema is a Pydantic model: https://docs.pydantic.dev/latest/concepts/models/
|
||||
# # but by default it will still allow you to add any arbitrary information to it.
|
||||
# # That is to say, when you run a scan with which such a model has been associated in the
|
||||
# # metadata_schema_registry, you can supply any python dictionary with strings as keys
|
||||
# # and built-in python types (strings, integers, floats) as values, and these will be
|
||||
# # added to the experiment metadata, but it *must* contain the keys and values of the
|
||||
# # types defined in the schema class.
|
||||
# #
|
||||
# #
|
||||
# # For example, say that you would like to enforce recording information about sample
|
||||
# # pretreatment, you could define the following:
|
||||
# #
|
||||
#
|
||||
# from bec_lib.metadata_schema import BasicScanMetadata
|
||||
#
|
||||
#
|
||||
# class ExampleSchema(BasicScanMetadata):
|
||||
# treatment_description: str
|
||||
# treatment_temperature_k: int
|
||||
#
|
||||
#
|
||||
# # If this was used according to the example in metadata_schema_registry.py,
|
||||
# # then when calling the scan, the user would need to write something like:
|
||||
# >>> scans.example_scan(
|
||||
# >>> motor,
|
||||
# >>> 1,
|
||||
# >>> 2,
|
||||
# >>> 3,
|
||||
# >>> metadata={"treatment_description": "oven overnight", "treatment_temperature_k": 575},
|
||||
# >>> )
|
||||
#
|
||||
# # And the additional metadata would be saved in the HDF5 file created for the scan.
|
||||
304
csaxs_bec/scans/omny_fermat_scan.py
Normal file
304
csaxs_bec/scans/omny_fermat_scan.py
Normal file
@@ -0,0 +1,304 @@
|
||||
"""
|
||||
SCAN PLUGINS
|
||||
|
||||
All new scans should be derived from ScanBase. ScanBase provides various methods that can be customized and overriden
|
||||
but they are executed in a specific order:
|
||||
|
||||
- self.initialize # initialize the class if needed
|
||||
- self.read_scan_motors # used to retrieve the start position (and the relative position shift if needed)
|
||||
- self.prepare_positions # prepare the positions for the scan. The preparation is split into multiple sub fuctions:
|
||||
- self._calculate_positions # calculate the positions
|
||||
- self._set_positions_offset # apply the previously retrieved scan position shift (if needed)
|
||||
- self._check_limits # tests to ensure the limits won't be reached
|
||||
- self.open_scan # send an open_scan message including the scan name, the number of points and the scan motor names
|
||||
- self.stage # stage all devices for the upcoming acquisiton
|
||||
- self.run_baseline_readings # read all devices to get a baseline for the upcoming scan
|
||||
- self.scan_core # run a loop over all position
|
||||
- self._at_each_point(ind, pos) # called at each position with the current index and the target positions as arguments
|
||||
- self.finalize # clean up the scan, e.g. move back to the start position; wait everything to finish
|
||||
- self.unstage # unstage all devices that have been staged before
|
||||
- self.cleanup # send a close scan message and perform additional cleanups if needed
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from bec_lib import bec_logger, messages
|
||||
from bec_lib.endpoints import MessageEndpoints
|
||||
from bec_server.scan_server.errors import ScanAbortion
|
||||
from bec_server.scan_server.scans import SyncFlyScanBase
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class OMNYFermatScan(SyncFlyScanBase):
|
||||
scan_name = "omny_fermat_scan"
|
||||
scan_report_hint = "table"
|
||||
scan_type = "fly"
|
||||
required_kwargs = ["fovx", "fovy", "exp_time", "step", "angle"]
|
||||
arg_input = {}
|
||||
arg_bundle_size = {"bundle": len(arg_input), "min": None, "max": None}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
fovx: float,
|
||||
fovy: float,
|
||||
cenx: float,
|
||||
ceny: float,
|
||||
exp_time: float,
|
||||
step: float,
|
||||
zshift: float,
|
||||
angle: float = None,
|
||||
corridor_size: float = 3,
|
||||
parameter: dict = None,
|
||||
**kwargs,
|
||||
):
|
||||
"""
|
||||
An OMNY scan following Fermat's spiral.
|
||||
|
||||
Args:
|
||||
fovx(float) [um]: Fov in the piezo plane (i.e. piezo range). Max 200 um
|
||||
fovy(float) [um]: Fov in the piezo plane (i.e. piezo range). Max 100 um
|
||||
cenx(float) [um]: center position in x.
|
||||
ceny(float) [um]: center position in y.
|
||||
exp_time(float) [s]: exposure time
|
||||
step(float) [um]: stepsize
|
||||
zshift(float) [um]: shift in z
|
||||
angle(float) [deg]: rotation angle (will rotate first)
|
||||
corridor_size(float) [um]: corridor size for the corridor optimization. Default 3 um
|
||||
|
||||
Returns:
|
||||
|
||||
Examples:
|
||||
>>> scans.omny_fermat_scan(fovx=20, fovy=25, cenx=10, ceny=0, zshift=0, angle=0, step=2, exp_time=0.01)
|
||||
"""
|
||||
|
||||
super().__init__(parameter=parameter, **kwargs)
|
||||
self.axis = []
|
||||
self.fovx = fovx
|
||||
self.fovy = fovy
|
||||
self.cenx = cenx
|
||||
self.ceny = ceny
|
||||
self.exp_time = exp_time
|
||||
self.step = step
|
||||
self.zshift = zshift
|
||||
self.angle = angle
|
||||
self.optim_trajectory = "corridor"
|
||||
self.optim_trajectory_corridor = corridor_size
|
||||
if self.fovy > 100:
|
||||
raise ScanAbortion("The FOV in y must be smaller than 100 um.")
|
||||
if self.fovx > 200:
|
||||
raise ScanAbortion("The FOV in x must be smaller than 200 um.")
|
||||
if self.zshift > 100:
|
||||
logger.warning("The zshift is larger than 100 um. It will be limited to 100 um.")
|
||||
self.zshift = 100
|
||||
if self.zshift < -100:
|
||||
logger.warning("The zshift is smaller than -100 um. It will be limited to -100 um.")
|
||||
self.zshift = -100
|
||||
self.omny_rotation_status = None
|
||||
|
||||
def initialize(self):
|
||||
self.scan_motors = []
|
||||
self.update_readout_priority()
|
||||
|
||||
def _optimize_trajectory(self):
|
||||
self.positions = self.optimize_corridor(
|
||||
self.positions, corridor_size=self.optim_trajectory_corridor
|
||||
)
|
||||
|
||||
@property
|
||||
def monitor_sync(self):
|
||||
return "rt_omny"
|
||||
|
||||
def reverse_trajectory(self):
|
||||
"""
|
||||
Reverse the trajectory. Every other scan should be reversed to
|
||||
shorten the movement time. In order to keep the last state, even if the
|
||||
server is restarted, the state is stored in a global variable in redis.
|
||||
"""
|
||||
msg = self.connector.get(MessageEndpoints.global_vars("reverse_omny_trajectory"))
|
||||
if msg:
|
||||
val = msg.content.get("value", False)
|
||||
else:
|
||||
val = False
|
||||
self.connector.set(
|
||||
MessageEndpoints.global_vars("reverse_omny_trajectory"),
|
||||
messages.VariableMessage(value=(not val)),
|
||||
)
|
||||
return val
|
||||
|
||||
def prepare_positions(self):
|
||||
self._calculate_positions()
|
||||
self._optimize_trajectory()
|
||||
flip_axes = self.reverse_trajectory()
|
||||
if flip_axes:
|
||||
self.positions = np.flipud(self.positions)
|
||||
|
||||
self.num_pos = len(self.positions)
|
||||
self._check_min_positions()
|
||||
|
||||
def _check_min_positions(self):
|
||||
if self.num_pos < 20:
|
||||
raise ScanAbortion(
|
||||
f"The number of positions must exceed 20. Currently: {self.num_pos}."
|
||||
)
|
||||
|
||||
def _prepare_setup(self):
|
||||
yield from self.stubs.send_rpc_and_wait("rtx", "controller.clear_trajectory_generator")
|
||||
yield from self.omny_rotation(self.angle)
|
||||
|
||||
yield from self.stubs.send_rpc_and_wait("rty", "set", self.positions[0][1])
|
||||
|
||||
def _prepare_setup_part2(self):
|
||||
if self.omny_rotation_status:
|
||||
self.omny_rotation_status.wait()
|
||||
|
||||
rtx_status = yield from self.stubs.set(device="rtx", value=self.positions[0][0], wait=False)
|
||||
rtz_status = yield from self.stubs.set(device="rtz", value=self.positions[0][2], wait=False)
|
||||
|
||||
yield from self.stubs.send_rpc_and_wait(
|
||||
"rtx", "controller.laser_tracker_check_and_wait_for_signalstrength"
|
||||
)
|
||||
|
||||
rtx_status.wait()
|
||||
rtz_status.wait()
|
||||
|
||||
yield from self._transfer_positions_to_omny()
|
||||
yield from self.stubs.send_rpc_and_wait("osamx", "omny_osamx_to_scan_center", self.cenx)
|
||||
|
||||
def omny_rotation(self, angle):
|
||||
# get last setpoint (cannot be based on pos get because they will deviate slightly)
|
||||
osamroy_current_setpoint = yield from self.stubs.send_rpc_and_wait(
|
||||
"osamroy", "user_setpoint.get"
|
||||
)
|
||||
if angle == osamroy_current_setpoint:
|
||||
logger.info("No rotation required")
|
||||
else:
|
||||
logger.info("Rotating to requested angle")
|
||||
yield from self.stubs.scan_report_instruction(
|
||||
{
|
||||
"readback": {
|
||||
"RID": self.metadata["RID"],
|
||||
"devices": ["osamroy"],
|
||||
"start": [osamroy_current_setpoint],
|
||||
"end": [angle],
|
||||
}
|
||||
}
|
||||
)
|
||||
self.omny_rotation_status = yield from self.stubs.set(
|
||||
device="osamroy", value=angle, wait=False
|
||||
)
|
||||
|
||||
def _transfer_positions_to_omny(self):
|
||||
yield from self.stubs.send_rpc_and_wait(
|
||||
"rtx", "controller.add_pos_to_scan", self.positions.tolist()
|
||||
)
|
||||
|
||||
def _calculate_positions(self):
|
||||
self.positions = self.get_omny_fermat_spiral_pos(
|
||||
-np.abs(self.fovx / 2),
|
||||
np.abs(self.fovx / 2),
|
||||
-np.abs(self.fovy / 2),
|
||||
np.abs(self.fovy / 2),
|
||||
step=self.step,
|
||||
spiral_type=0,
|
||||
center=False,
|
||||
)
|
||||
|
||||
def get_omny_fermat_spiral_pos(
|
||||
self, m1_start, m1_stop, m2_start, m2_stop, step=1, spiral_type=0, center=False
|
||||
):
|
||||
"""
|
||||
Calculate positions for a Fermat spiral scan.
|
||||
|
||||
Args:
|
||||
m1_start(float): start position in m1
|
||||
m1_stop(float): stop position in m1
|
||||
m2_start(float): start position in m2
|
||||
m2_stop(float): stop position in m2
|
||||
step(float): stepsize
|
||||
spiral_type(int): 0 for traditional Fermat spiral
|
||||
center(bool): whether to include the center position
|
||||
|
||||
Returns:
|
||||
positions(array): positions
|
||||
"""
|
||||
positions = []
|
||||
phi = 2 * np.pi * ((1 + np.sqrt(5)) / 2.0) + spiral_type * np.pi
|
||||
|
||||
start = int(not center)
|
||||
|
||||
length_axis1 = np.abs(m1_stop - m1_start)
|
||||
length_axis2 = np.abs(m2_stop - m2_start)
|
||||
n_max = int(length_axis1 * length_axis2 * 3.2 / step / step)
|
||||
|
||||
z_pos = self.zshift
|
||||
|
||||
for ii in range(start, n_max):
|
||||
radius = step * 0.57 * np.sqrt(ii)
|
||||
# FOV is restructed below at check pos in range
|
||||
if abs(radius * np.sin(ii * phi)) > length_axis1 / 2:
|
||||
continue
|
||||
if abs(radius * np.cos(ii * phi)) > length_axis2 / 2:
|
||||
continue
|
||||
x = radius * np.sin(ii * phi)
|
||||
y = radius * np.cos(ii * phi)
|
||||
positions.append([x + self.cenx, y + self.ceny, z_pos])
|
||||
left_lower_corner = [
|
||||
min(m1_start, m1_stop) + self.cenx,
|
||||
min(m2_start, m2_stop) + self.ceny,
|
||||
z_pos,
|
||||
]
|
||||
right_upper_corner = [
|
||||
max(m1_start, m1_stop) + self.cenx,
|
||||
max(m2_start, m2_stop) + self.ceny,
|
||||
z_pos,
|
||||
]
|
||||
positions.append(left_lower_corner)
|
||||
positions.append(right_upper_corner)
|
||||
return np.array(positions)
|
||||
|
||||
def scan_core(self):
|
||||
# use a device message to receive the scan number and
|
||||
# scan ID before sending the message to the device server
|
||||
yield from self.stubs.kickoff(device="rtx")
|
||||
while True:
|
||||
yield from self.stubs.read(group="monitored")
|
||||
status = self.connector.get(MessageEndpoints.device_status("rt_scan"))
|
||||
if status:
|
||||
status_id = status.content.get("status", 1)
|
||||
request_id = status.metadata.get("RID")
|
||||
if status_id == 0 and self.metadata.get("RID") == request_id:
|
||||
break
|
||||
if status_id == 2 and self.metadata.get("RID") == request_id:
|
||||
raise ScanAbortion(
|
||||
"An error occured during the omny readout:"
|
||||
f" {status.metadata.get('error')}"
|
||||
)
|
||||
|
||||
time.sleep(1)
|
||||
logger.debug("reading monitors")
|
||||
# yield from self.device_rpc("rtx", "controller.kickoff")
|
||||
|
||||
def return_to_start(self):
|
||||
"""return to the start position"""
|
||||
# in omny, we need to move to the start position of the next scan
|
||||
if isinstance(self.positions, np.ndarray) and len(self.positions[-1]) == 3:
|
||||
yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=self.positions[-1])
|
||||
return
|
||||
|
||||
logger.warning("No positions found to return to start")
|
||||
|
||||
def run(self):
|
||||
self.initialize()
|
||||
yield from self.read_scan_motors()
|
||||
self.prepare_positions()
|
||||
yield from self._prepare_setup()
|
||||
yield from self.open_scan()
|
||||
yield from self.stage()
|
||||
yield from self.run_baseline_reading()
|
||||
yield from self._prepare_setup_part2()
|
||||
yield from self.scan_core()
|
||||
yield from self.finalize()
|
||||
yield from self.unstage()
|
||||
yield from self.cleanup()
|
||||
@@ -262,10 +262,8 @@ class OwisGrid(AsyncFlyScanBase):
|
||||
yield from self.stubs.send_rpc_and_wait("samy", "acceleration.put", self.acc_time)
|
||||
|
||||
# Start motion and send triggers
|
||||
yield from self.stubs.set(
|
||||
device="samy",
|
||||
value=(self.end_y + (self.sign * self.premove_distance)),
|
||||
wait_group="flyer",
|
||||
flyer_status = yield from self.stubs.set(
|
||||
device="samy", value=(self.end_y + (self.sign * self.premove_distance)), wait=False
|
||||
)
|
||||
# Trigger fast shutter, open them right away
|
||||
yield from self.stubs.send_rpc_and_wait("ddg_fsh", "trigger")
|
||||
@@ -275,32 +273,28 @@ class OwisGrid(AsyncFlyScanBase):
|
||||
# Trigger detectors
|
||||
yield from self.stubs.send_rpc_and_wait("ddg_detectors", "trigger")
|
||||
|
||||
# Readout primary devices, this waits and could lead to additional overheads
|
||||
# if devices are slow to response. For optimizing performance, primary devices
|
||||
# Readout monitored devices, this waits and could lead to additional overheads
|
||||
# if devices are slow to response. For optimizing performance, monitored devices
|
||||
# could be read out only once at beginning and end
|
||||
yield from self.stubs.read_and_wait(
|
||||
group="primary", wait_group="readout_primary", point_id=self.point_id
|
||||
)
|
||||
yield from self.stubs.read(group="monitored", point_id=self.point_id)
|
||||
self.point_id += 1
|
||||
|
||||
# Wait for motion to finish
|
||||
yield from self.stubs.wait(device="samy", wait_group="flyer", wait_type="move")
|
||||
flyer_status.wait()
|
||||
|
||||
# Move second axis by a step
|
||||
yield from self.stubs.set(
|
||||
device="samx", value=(self.start_x - ii * self.stepping_x), wait_group="motion"
|
||||
status_x = yield from self.stubs.set(
|
||||
device="samx", value=(self.start_x - ii * self.stepping_x), wait=False
|
||||
)
|
||||
# Set acceleration and velocity to max
|
||||
yield from self.stubs.send_rpc_and_wait("samy", "velocity.put", self.high_velocity)
|
||||
yield from self.stubs.send_rpc_and_wait("samy", "acceleration.put", self.high_acc_time)
|
||||
|
||||
# Move back to start
|
||||
status_prepos = yield from self.stubs.send_rpc_and_wait(
|
||||
"samy", "move", (self.start_y - self.premove_distance)
|
||||
)
|
||||
yield from self.stubs.set(device="samy", value=(self.start_y - self.premove_distance))
|
||||
|
||||
# Wait for motion to finish
|
||||
status_prepos.wait()
|
||||
status_x.wait()
|
||||
|
||||
# Set speed and acceleration to initial values
|
||||
def finalize(self):
|
||||
|
||||
@@ -126,7 +126,7 @@ class SgalilGrid(AsyncFlyScanBase):
|
||||
"""
|
||||
|
||||
# set up the delay generators
|
||||
status_ddg_detectors_burst = yield from self.stubs.send_rpc_and_wait(
|
||||
yield from self.stubs.send_rpc_and_wait(
|
||||
"ddg_detectors",
|
||||
"burst_enable",
|
||||
count=self.interval_y,
|
||||
@@ -134,7 +134,7 @@ class SgalilGrid(AsyncFlyScanBase):
|
||||
period=(self.exp_time + self.readout_time),
|
||||
config="first",
|
||||
)
|
||||
status_ddg_mcs_burst = yield from self.stubs.send_rpc_and_wait(
|
||||
yield from self.stubs.send_rpc_and_wait(
|
||||
"ddg_mcs",
|
||||
"burst_enable",
|
||||
count=self.interval_y,
|
||||
@@ -143,9 +143,9 @@ class SgalilGrid(AsyncFlyScanBase):
|
||||
config="first",
|
||||
)
|
||||
# Disable burst mod on DDF for fsh and EN of MCS card
|
||||
status_ddg_fsh_burst = yield from self.stubs.send_rpc_and_wait("ddg_fsh", "burst_disable")
|
||||
yield from self.stubs.send_rpc_and_wait("ddg_fsh", "burst_disable")
|
||||
# Set width of FSH opening to 0
|
||||
status_ddg_fsh_ttlwidth = yield from self.stubs.send_rpc_and_wait(
|
||||
yield from self.stubs.send_rpc_and_wait(
|
||||
"ddg_fsh", "set_channels", "width", 0, channels=["channelCD"]
|
||||
)
|
||||
|
||||
@@ -166,19 +166,17 @@ class SgalilGrid(AsyncFlyScanBase):
|
||||
# status_ddg_mcs_ttlwidth = yield from self.stubs.send_rpc_and_wait(
|
||||
# "ddg_mcs", "set_channels", "width", 3e-3
|
||||
# )
|
||||
status_ddg_mcs_ttldelay = yield from self.stubs.send_rpc_and_wait(
|
||||
"ddg_mcs", "set_channels", "delay", 0
|
||||
)
|
||||
yield from self.stubs.send_rpc_and_wait("ddg_mcs", "set_channels", "delay", 0)
|
||||
|
||||
# wait for the delay generators to finish setting up
|
||||
status_ddg_detectors_source.wait()
|
||||
status_ddg_mcs_source.wait()
|
||||
trigger_ddg_fsh = yield from self.stubs.send_rpc_and_wait("ddg_fsh", "trigger")
|
||||
yield from self.stubs.send_rpc_and_wait("ddg_fsh", "trigger")
|
||||
# trigger_ddg_fsh.wait()
|
||||
# status_mcs_points_per_line.wait()
|
||||
# status_mcs_lines.wait()
|
||||
|
||||
yield from self.stubs.kickoff(
|
||||
kickoff_status = yield from self.stubs.kickoff(
|
||||
device="samx",
|
||||
parameter={
|
||||
"start_y": self.start_y,
|
||||
@@ -190,19 +188,14 @@ class SgalilGrid(AsyncFlyScanBase):
|
||||
"exp_time": self.exp_time,
|
||||
"readout_time": self.readout_time,
|
||||
},
|
||||
wait=False,
|
||||
)
|
||||
target_diid = self.DIID - 1
|
||||
while True:
|
||||
# readout the primary device and wait for the fly scan to finish
|
||||
yield from self.stubs.read_and_wait(
|
||||
group="primary", wait_group="readout_primary", point_id=self.point_id
|
||||
)
|
||||
|
||||
while not kickoff_status.done:
|
||||
# readout the monitored device and wait for the fly scan to finish
|
||||
yield from self.stubs.read(group="monitored", point_id=self.point_id)
|
||||
self.point_id += 1
|
||||
status = self.stubs.get_req_status(
|
||||
device="samx", RID=self.metadata["RID"], DIID=target_diid
|
||||
)
|
||||
if status:
|
||||
break
|
||||
|
||||
time.sleep(self.sleep_time)
|
||||
if self.scan_progress() > int(self.timeout_scan_abortion / self.sleep_time):
|
||||
logger.info("would have raised a scan abortion here")
|
||||
|
||||
0
csaxs_bec/services/__init__.py
Normal file
0
csaxs_bec/services/__init__.py
Normal file
20
docs/Makefile
Normal file
20
docs/Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
170
docs/_static/custom.css
vendored
Normal file
170
docs/_static/custom.css
vendored
Normal file
File diff suppressed because one or more lines are too long
34
docs/_templates/custom-class-template.rst
vendored
Normal file
34
docs/_templates/custom-class-template.rst
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{{ fullname | escape | underline}}
|
||||
|
||||
.. currentmodule:: {{ module }}
|
||||
|
||||
.. autoclass:: {{ objname }}
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members:
|
||||
:special-members: __call__, __add__, __mul__
|
||||
|
||||
{% block methods %}
|
||||
{% if methods %}
|
||||
.. rubric:: {{ _('Methods') }}
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
{% for item in methods %}
|
||||
{%- if not item.startswith('_') %}
|
||||
~{{ name }}.{{ item }}
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block attributes %}
|
||||
{% if attributes %}
|
||||
.. rubric:: {{ _('Attributes') }}
|
||||
|
||||
.. autosummary::
|
||||
{% for item in attributes %}
|
||||
~{{ name }}.{{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
66
docs/_templates/custom-module-template.rst
vendored
Normal file
66
docs/_templates/custom-module-template.rst
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
{{ fullname | escape | underline}}
|
||||
|
||||
.. automodule:: {{ fullname }}
|
||||
|
||||
{% block attributes %}
|
||||
{% if attributes %}
|
||||
.. rubric:: Module attributes
|
||||
|
||||
.. autosummary::
|
||||
:toctree:
|
||||
{% for item in attributes %}
|
||||
{{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block functions %}
|
||||
{% if functions %}
|
||||
.. rubric:: {{ _('Functions') }}
|
||||
|
||||
.. autosummary::
|
||||
:toctree:
|
||||
:nosignatures:
|
||||
{% for item in functions %}
|
||||
{{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block classes %}
|
||||
{% if classes %}
|
||||
.. rubric:: {{ _('Classes') }}
|
||||
|
||||
.. autosummary::
|
||||
:toctree:
|
||||
:template: custom-class-template.rst
|
||||
:nosignatures:
|
||||
{% for item in classes %}
|
||||
{{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block exceptions %}
|
||||
{% if exceptions %}
|
||||
.. rubric:: {{ _('Exceptions') }}
|
||||
|
||||
.. autosummary::
|
||||
:toctree:
|
||||
{% for item in exceptions %}
|
||||
{{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block modules %}
|
||||
{% if modules %}
|
||||
.. autosummary::
|
||||
:toctree:
|
||||
:template: custom-module-template.rst
|
||||
:recursive:
|
||||
{% for item in modules %}
|
||||
{{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
12
docs/api_reference/api_reference.md
Normal file
12
docs/api_reference/api_reference.md
Normal file
@@ -0,0 +1,12 @@
|
||||
(api_reference)=
|
||||
# API Reference
|
||||
|
||||
```{eval-rst}
|
||||
.. autosummary::
|
||||
:toctree: _autosummary
|
||||
:template: custom-module-template.rst
|
||||
:recursive:
|
||||
|
||||
csaxs_bec
|
||||
|
||||
```
|
||||
1
docs/assets/biotech.svg
Normal file
1
docs/assets/biotech.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="40px" viewBox="0 -960 960 960" width="40px" fill="#5f6368"><path d="M200-120v-66.67h205.33v-96h-10q-81.66 0-138.5-56.83Q200-396.33 200-478q0-61 34.5-111t91.5-71q5.33-38 35.17-61.67Q391-745.33 430-743.33l-21.33-60 40-14.38-14-36.96L504-880l13.33 37.33 39.34-14 112 296.67-41.34 14.67 14 37.33-68 24.67L560-520.67l-41.33 15.34L494-572.67q-15 16-35.17 23.34-20.16 7.33-42.39 6Q392-544.67 371-558.5q-21-13.83-34.33-34.83-32.34 16.66-51.17 47.64T266.67-478q0 53.61 37.52 91.14 37.53 37.53 91.14 37.53h338v66.66H512v96h248V-120H200Zm352.67-454L600-591.33l-76-200L476-774l76.67 200Zm-128.79-22.67q19.79 0 33.29-13.38t13.5-33.17q0-19.78-13.39-33.28Q443.9-690 424.12-690q-19.79 0-33.29 13.38-13.5 13.39-13.5 33.17t13.39 33.28q13.38 13.5 33.16 13.5ZM552.67-574ZM424-644.67Zm1.33 0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 828 B |
76
docs/assets/index_contribute.svg
Normal file
76
docs/assets/index_contribute.svg
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="89.624855mm"
|
||||
height="89.96759mm"
|
||||
viewBox="0 0 89.62486 89.96759"
|
||||
version="1.1"
|
||||
id="svg1040"
|
||||
inkscape:version="0.92.4 (f8dce91, 2019-08-02)"
|
||||
sodipodi:docname="index_contribute.svg">
|
||||
<defs
|
||||
id="defs1034" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="683.11893"
|
||||
inkscape:cy="-59.078181"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="930"
|
||||
inkscape:window-height="472"
|
||||
inkscape:window-x="2349"
|
||||
inkscape:window-y="267"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata1037">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(234.72009,17.466935)">
|
||||
<g
|
||||
id="g875"
|
||||
transform="matrix(0.99300176,0,0,0.99300176,-133.24106,-172.58804)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path869"
|
||||
d="m -97.139881,161.26069 47.247024,40.25446 -47.247024,40.25446"
|
||||
style="fill:none;stroke:#5a5a5a;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path871"
|
||||
d="m -49.514879,241.81547 h 32.505951"
|
||||
style="fill:none;stroke:#5a5a5a;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
67
docs/assets/index_user_guide.svg
Normal file
67
docs/assets/index_user_guide.svg
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="123.72241mm"
|
||||
height="89.96759mm"
|
||||
viewBox="0 0 123.72242 89.96759"
|
||||
version="1.1"
|
||||
id="svg1040"
|
||||
inkscape:version="0.92.4 (f8dce91, 2019-08-02)"
|
||||
sodipodi:docname="index_userguide.svg">
|
||||
<defs
|
||||
id="defs1034" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="332.26618"
|
||||
inkscape:cy="83.744004"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="930"
|
||||
inkscape:window-height="472"
|
||||
inkscape:window-x="2349"
|
||||
inkscape:window-y="267"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata1037">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(141.8903,-20.32143)">
|
||||
<path
|
||||
style="fill:#5a5a5a;fill-opacity:1;stroke-width:0.20483544"
|
||||
d="m -139.53374,110.1657 c -0.80428,-0.24884 -1.71513,-1.11296 -2.07107,-1.96486 -0.23905,-0.57214 -0.28453,-6.28104 -0.28453,-35.720988 0,-38.274546 -0.079,-35.840728 1.19849,-36.91568 0.58869,-0.495345 4.63766,-2.187548 8.47998,-3.544073 l 1.58749,-0.560453 v -3.309822 c 0,-3.025538 0.0396,-3.388179 0.46086,-4.222122 0.68808,-1.362003 1.38671,-1.714455 4.60319,-2.322195 4.12797,-0.779966 5.13304,-0.912766 8.81544,-1.16476 11.80964,-0.808168 22.80911,2.509277 30.965439,9.3392 1.750401,1.465747 3.840861,3.5635 5.0903,5.108065 l 0.659122,0.814805 0.659109,-0.814805 c 1.249431,-1.544565 3.33988,-3.642318 5.09029,-5.108065 8.156331,-6.829923 19.155791,-10.147368 30.965441,-9.3392 3.682389,0.251994 4.68748,0.384794 8.81544,1.16476 3.21647,0.60774 3.91511,0.960192 4.60318,2.322195 0.4213,0.833943 0.46087,1.196584 0.46087,4.222122 v 3.309822 l 1.58748,0.560453 c 4.10165,1.448077 7.98852,3.072753 8.5259,3.563743 1.22643,1.120567 1.15258,-1.245868 1.15258,36.927177 0,34.567591 -0.005,35.083151 -0.40663,35.903991 -0.22365,0.45804 -0.73729,1.05665 -1.14143,1.33024 -1.22281,0.82783 -2.17721,0.70485 -5.86813,-0.7561 -9.19595,-3.63998 -18.956011,-6.38443 -26.791332,-7.53353 -3.02827,-0.44412 -9.26189,-0.61543 -11.77821,-0.3237 -5.19357,0.60212 -8.736108,2.05527 -11.700039,4.79936 -0.684501,0.63371 -1.466141,1.23646 -1.736979,1.33942 -0.63859,0.2428 -4.236521,0.2428 -4.875112,0 -0.27083,-0.10296 -1.05247,-0.70571 -1.73696,-1.33942 -2.96395,-2.74409 -6.50648,-4.19724 -11.700058,-4.79936 -2.516312,-0.29173 -8.749941,-0.12042 -11.778201,0.3237 -7.78194,1.14127 -17.39965,3.83907 -26.73341,7.49883 -3.38325,1.32658 -4.15525,1.50926 -5.11851,1.21125 z m 4.2107,-5.34052 c 5.86759,-2.29858 14.40398,-4.922695 20.2018,-6.210065 6.31584,-1.402418 8.5236,-1.646248 14.91592,-1.647338 4.68699,-7.94e-4 6.013661,0.0632 7.257809,0.3497 0.837332,0.19286 1.561052,0.312028 1.60828,0.264819 0.147111,-0.147119 -1.803289,-1.307431 -4.154879,-2.471801 -8.12511,-4.023029 -18.27311,-4.986568 -29.0861,-2.761718 -1.09536,0.22538 -2.32708,0.40827 -2.73715,0.406418 -1.12787,-0.005 -2.3054,-0.76382 -2.84516,-1.8332 l -0.46086,-0.913098 V 62.99179 35.97471 l -0.56331,0.138329 c -0.30981,0.07608 -1.89985,0.665075 -3.5334,1.308881 -2.27551,0.896801 -2.96414,1.252878 -2.94452,1.522563 0.014,0.193604 0.0372,15.284513 0.0512,33.535345 0.014,18.250839 0.0538,33.183322 0.0884,33.183322 0.0346,0 1.02543,-0.3771 2.20198,-0.83801 z m 113.006991,-32.697216 -0.0518,-33.535203 -3.17495,-1.272156 c -1.74623,-0.699685 -3.33627,-1.278755 -3.53341,-1.286819 -0.33966,-0.01389 -0.35847,1.401778 -0.35847,26.980216 v 26.994863 l -0.46087,0.913112 c -0.53976,1.06939 -1.71729,1.828088 -2.84515,1.833189 -0.41008,0.0021 -1.6418,-0.181031 -2.73716,-0.406421 -11.888201,-2.446089 -22.84337,-1.046438 -31.491022,4.02332 -1.68175,0.985941 -2.216748,1.467501 -1.36534,1.228942 1.575181,-0.441362 4.990592,-0.73864 8.524862,-0.742011 5.954408,-0.005 11.43046,0.791951 19.10874,2.78333 3.9516,1.024874 12.1555,3.687454 15.6699,5.085704 1.23926,0.49306 2.36869,0.90517 2.50985,0.9158 0.20489,0.0155 0.2462,-6.745894 0.20483,-33.515866 z m -59.76135,-2.233777 V 40.065438 l -0.95972,-1.357442 c -1.380522,-1.952627 -5.376262,-5.847994 -7.64336,-7.45136 -3.778692,-2.672401 -9.063392,-4.943324 -13.672511,-5.875304 -3.19731,-0.646503 -5.23069,-0.833103 -9.05886,-0.831312 -4.37716,0.0021 -7.70223,0.349169 -11.83461,1.235469 l -1.07538,0.230645 v 31.242342 c 0,26.565778 0.0426,31.226011 0.28429,31.133261 0.15637,-0.06 1.42379,-0.297169 2.81648,-0.527026 12.37657,-2.042634 23.21658,-0.346861 32.521639,5.087596 2.10018,1.226558 5.20202,3.618878 6.880942,5.30692 0.788609,0.792909 1.502978,1.446609 1.587468,1.452679 0.0845,0.006 0.153622,-13.411893 0.153622,-29.817719 z m 5.80221,28.3766 c 6.21476,-6.141601 15.08488,-10.061509 25.025529,-11.05933 4.262419,-0.427849 11.579921,-0.0054 16.017661,0.924912 0.75932,0.15916 1.45259,0.244888 1.54058,0.190498 0.088,-0.05434 0.16003,-14.060382 0.16003,-31.124436 V 26.176883 l -0.52136,-0.198219 c -0.66893,-0.254325 -4.77649,-0.95482 -7.159981,-1.221048 -2.41372,-0.269605 -8.559851,-0.266589 -10.759229,0.0052 -6.458111,0.798299 -12.584091,3.083792 -17.405651,6.49374 -2.267091,1.603366 -6.262831,5.498733 -7.64336,7.45136 l -0.959721,1.357438 v 29.828747 c 0,16.405812 0.0532,29.828746 0.11802,29.828746 0.065,0 0.77928,-0.65347 1.587482,-1.452149 z"
|
||||
id="path845"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csscccscsssscsssssscscsccsccsccscsscccccccscccccccccsccscscscccscccsccssccsscccscccccsccccsccscsccsscc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
1
docs/assets/receipt_long.svg
Normal file
1
docs/assets/receipt_long.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="40px" viewBox="0 -960 960 960" width="40px" fill="#5f6368"><path d="M228-80q-45.83 0-77.92-32.08Q118-144.17 118-190v-123.33h124.67V-880l59.86 60 59.87-60 59.87 60 59.86-60L542-820l60-60 60 60 60-60 60 60 60-60v690q0 45.83-32.08 77.92Q777.83-80 732-80H228Zm504-66.67q19 0 31.17-12.16Q775.33-171 775.33-190v-583.33h-466v460h379.34V-190q0 19 12.16 31.17Q713-146.67 732-146.67Zm-374-468v-66.66h240v66.66H358Zm0 129.34V-552h240v66.67H358Zm328.67-129.34q-13.67 0-23.5-9.83-9.84-9.83-9.84-23.5t9.84-23.5q9.83-9.83 23.5-9.83 13.66 0 23.5 9.83Q720-661.67 720-648t-9.83 23.5q-9.84 9.83-23.5 9.83Zm0 126q-13.67 0-23.5-9.83-9.84-9.83-9.84-23.5t9.84-23.5q9.83-9.83 23.5-9.83 13.66 0 23.5 9.83Q720-535.67 720-522t-9.83 23.5q-9.84 9.83-23.5 9.83Zm-459.34 342H622v-100H184.67V-190q0 19 12.26 31.17 12.27 12.16 30.4 12.16Zm-42.66 0v-100 100Z"/></svg>
|
||||
|
After Width: | Height: | Size: 881 B |
67
docs/conf.py
Normal file
67
docs/conf.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
|
||||
project = "SLS cSAXS"
|
||||
copyright = "2024, Paul Scherrer Institute"
|
||||
author = "Paul Scherrer Institute"
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
|
||||
extensions = [
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.autosummary",
|
||||
# "sphinx.ext.coverage",
|
||||
"sphinx.ext.viewcode",
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinx_toolbox.collapse",
|
||||
"sphinx_copybutton",
|
||||
"myst_parser",
|
||||
"sphinx_design",
|
||||
"sphinx_inline_tabs",
|
||||
]
|
||||
|
||||
myst_enable_extensions = [
|
||||
"amsmath",
|
||||
"attrs_inline",
|
||||
"colon_fence",
|
||||
"deflist",
|
||||
"dollarmath",
|
||||
"fieldlist",
|
||||
"html_admonition",
|
||||
"html_image",
|
||||
"replacements",
|
||||
"smartquotes",
|
||||
"strikethrough",
|
||||
"substitution",
|
||||
"tasklist",
|
||||
]
|
||||
|
||||
autosummary_generate = True # Turn on sphinx.ext.autosummary
|
||||
add_module_names = False # Remove namespaces from class/method signatures
|
||||
autodoc_inherit_docstrings = True # If no docstring, inherit from base class
|
||||
set_type_checking_flag = True # Enable 'expensive' imports for sphinx_autodoc_typehints
|
||||
autoclass_content = "both" # Include both class docstring and __init__
|
||||
autodoc_mock_imports = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
|
||||
language = "Python"
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = "pydata_sphinx_theme"
|
||||
html_static_path = ["_static"]
|
||||
html_css_files = ["custom.css"]
|
||||
# html_logo = "./assets/csaxs_icon.png"
|
||||
html_title = "SLS cSAXS"
|
||||
3
docs/developer/developer.md
Normal file
3
docs/developer/developer.md
Normal file
@@ -0,0 +1,3 @@
|
||||
(developer)=
|
||||
# Developer
|
||||
|
||||
50
docs/index.md
Normal file
50
docs/index.md
Normal file
@@ -0,0 +1,50 @@
|
||||
:html_theme.sidebar_secondary.remove:
|
||||
|
||||
# cSAXS documentation
|
||||
|
||||
Welcome to the cSAXS documentation. This documentation is divided into two main sections: the user guide and the developer guide. The user guide is intended for users of the cSAXS beamline, while the developer guide is intended for developers of the cSAXS beamline.
|
||||
|
||||
<br><br>
|
||||
|
||||
````{grid} 2
|
||||
:gutter: 5
|
||||
|
||||
```{grid-item-card}
|
||||
:link: introduction
|
||||
:link-type: ref
|
||||
:img-top: /assets/index_user_guide.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## User guide
|
||||
|
||||
Information for users of the cSAXS beamline.
|
||||
```
|
||||
|
||||
```{grid-item-card}
|
||||
:link: developer
|
||||
:link-type: ref
|
||||
:img-top: /assets/index_contribute.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## Developer guide
|
||||
|
||||
Information for developers of the cSAXS beamline.
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
numbered: true
|
||||
maxdepth: 2
|
||||
hidden: true
|
||||
---
|
||||
|
||||
introduction/introduction
|
||||
user/user
|
||||
developer/developer
|
||||
api_reference/api_reference
|
||||
```
|
||||
16
docs/introduction/introduction.md
Normal file
16
docs/introduction/introduction.md
Normal file
@@ -0,0 +1,16 @@
|
||||
(introduction)=
|
||||
# The cSAXS Beamline
|
||||
|
||||
## Overview
|
||||
|
||||
cSAXS is a beamline dedicated to small-angle X-ray scattering (SAXS) and coherent diffractive imaging, particularly ptychography, located at the Swiss Light Source at the Paul Scherrer Institut in Villigen, Switzerland. See the beamline's endstations website for information on experimental setups, geometries, and sample preparation details. We strongly encourage all prospective users to discuss their experimental plans with the beamline staff before submitting proposals.
|
||||
|
||||
Access to cSAXS is granted through the biannual SLS call for proposals. Access to PSI data analysis center is described in Photon Science Data Analysis.
|
||||
|
||||
## Experiment types
|
||||
|
||||
Experiments performed at cSAXS include, inter alia,
|
||||
|
||||
* Ptychographic nanotomography, see for example Dierolf et al., Nature 467, 436 (2010) or Holler et al., Nature Electronics 2, 464 (2019). Dedicated instrumentation, available to users, is described in Holler et al., Sci. Rep. 4, 3857 (2014), Holler et al., Rev. Sci. Instrum. 88, 113701 (2017), Holler et al., Rev. Sci. Instrum. 89, 043706 (2018), and Holler et al., J. Synchrotron Rad. 27, 730 (2020).
|
||||
* Optics characterization, see for example: Vila-Comamala et al. Opt Express 19, 21333 (2011)
|
||||
* Small-angle X-ray scattering (SAXS), e.g., Smeulders et al., Nature 478, 412 (2011), can be performed with spatial resolution as microscopy technique in 2D (Bunk et al. New J. Phys. 11, 123016 (2009)) and 3D (Liebi et al. Nature 527, 349 (2015)). SAXS is also available with time resolution in the millisecond range (Westenhoff et al., Nature Methods 7, 775 (2010)).
|
||||
470
docs/log.txt
Normal file
470
docs/log.txt
Normal file
@@ -0,0 +1,470 @@
|
||||
docstring of bec_widgets.utils.bec_table.BECTable.Shadow.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.utils.bec_table.BECTable.Shadow.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.utils.bec_table.BECTable.Shape.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.utils.bec_table.BECTable.Shape.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.examples.general_app.general_app.BECGeneralApp, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.examples.general_app.general_app.BECGeneralApp, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.examples.jupyter_console.jupyter_console_window.JupyterConsoleWindow, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.examples.jupyter_console.jupyter_console_window.JupyterConsoleWindow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.axes:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.axes, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.change_layout:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.change_layout, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.change_theme:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.change_theme, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.clear_all:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.clear_all, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.export:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.export, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.image:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.image, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.motor_map:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.motor_map, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.plot:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.plot, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.remove:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.remove, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.widget_list:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.widget_list, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECFigure.widgets:1: WARNING: duplicate object description of bec_widgets.cli.client.BECFigure.widgets, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECFigure, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.get_data:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.get_data, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_auto_downsample:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_auto_downsample, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_autorange:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_autorange, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_autorange_mode:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_autorange_mode, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_color_map:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_color_map, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_fft:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_fft, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_log:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_log, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_monitor:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_monitor, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_opacity:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_opacity, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_rotation:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_rotation, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_transpose:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_transpose, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageItem.set_vrange:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageItem.set_vrange, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.add_custom_image:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.add_custom_image, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.add_image_by_config:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.add_image_by_config, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.export:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.export, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.image:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.image, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.images:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.images, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.lock_aspect_ratio:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.lock_aspect_ratio, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.remove:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.remove, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_autorange:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_autorange, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_autorange_mode:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_autorange_mode, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_color_map:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_color_map, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_fft:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_fft, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_grid:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_grid, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_image_properties:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_image_properties, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_log:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_log, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_monitor:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_monitor, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_processing:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_processing, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_rotation:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_rotation, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_title:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_title, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_transpose:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_transpose, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_vrange:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_vrange, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_x_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_x_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_x_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_x_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_x_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_x_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_y_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_y_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_y_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_y_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageShow.set_y_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageShow.set_y_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageShow, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.image:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.image, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.lock_aspect_ratio:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.lock_aspect_ratio, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_fft:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_fft, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_grid:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_grid, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_log:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_log, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_rotation:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_rotation, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_title:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_title, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_transpose:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_transpose, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_vrange:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_vrange, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_x_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_x_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_x_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_x_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_x_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_x_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_y_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_y_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_y_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_y_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECImageWidget.set_y_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECImageWidget.set_y_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.change_motors:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.change_motors, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.export:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.export, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.get_data:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.get_data, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.remove:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.remove, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.reset_history:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.reset_history, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.set_background_value:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.set_background_value, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.set_max_points:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.set_max_points, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.set_num_dim_points:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.set_num_dim_points, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.set_precision:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.set_precision, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMap.set_scatter_size:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMap.set_scatter_size, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMap, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.change_motors:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.change_motors, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.export:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.export, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.get_data:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.get_data, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.reset_history:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.reset_history, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.set_background_value:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.set_background_value, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.set_max_points:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.set_max_points, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.set_num_dim_points:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.set_num_dim_points, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.set_precision:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.set_precision, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECMotorMapWidget.set_scatter_size:1: WARNING: duplicate object description of bec_widgets.cli.client.BECMotorMapWidget.set_scatter_size, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.export:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.export, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.lock_aspect_ratio:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.lock_aspect_ratio, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.remove:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.remove, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_grid:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_grid, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_legend_label_size:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_legend_label_size, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_title:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_title, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_x_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_x_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_x_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_x_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_x_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_x_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_y_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_y_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_y_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_y_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECPlotBase.set_y_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECPlotBase.set_y_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECPlotBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECQueue:1: WARNING: duplicate object description of bec_widgets.cli.client.BECQueue, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECQueue, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECQueue.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECQueue, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECStatusBox:1: WARNING: duplicate object description of bec_widgets.cli.client.BECStatusBox, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECStatusBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECStatusBox.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECStatusBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.add_dap:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.add_dap, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.clear_all:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.clear_all, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.curves:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.curves, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.export:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.export, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.get_all_data:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.get_all_data, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.get_curve:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.get_curve, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.get_dap_params:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.get_dap_params, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.lock_aspect_ratio:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.lock_aspect_ratio, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.plot:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.plot, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.remove:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.remove, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.remove_curve:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.remove_curve, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.scan_history:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.scan_history, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_colormap:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_colormap, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_grid:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_grid, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_legend_label_size:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_legend_label_size, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_title:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_title, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_x:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_x, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_x_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_x_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_x_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_x_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_x_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_x_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_y_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_y_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_y_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_y_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveform.set_y_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveform.set_y_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveform, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.add_dap:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.add_dap, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.curves:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.curves, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.export:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.export, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.export_to_matplotlib:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.export_to_matplotlib, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.get_all_data:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.get_all_data, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.get_dap_params:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.get_dap_params, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.lock_aspect_ratio:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.lock_aspect_ratio, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.plot:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.plot, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.remove_curve:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.remove_curve, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.scan_history:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.scan_history, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_auto_range:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_auto_range, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_grid:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_grid, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_legend_label_size:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_legend_label_size, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_title:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_title, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_x:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_x, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_x_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_x_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_x_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_x_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_x_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_x_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_y_label:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_y_label, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_y_lim:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_y_lim, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECWaveformWidget.set_y_scale:1: WARNING: duplicate object description of bec_widgets.cli.client.BECWaveformWidget.set_y_scale, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.DeviceBox:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceBox, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceBox.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.DeviceComboBox:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceComboBox, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceComboBox.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.DeviceInputBase:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceInputBase, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceInputBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceInputBase.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceInputBase, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.DeviceLineEdit:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceLineEdit, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceLineEdit, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.DeviceLineEdit.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.DeviceLineEdit, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.reset_connection:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.reset_connection, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.set_background:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.set_background, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.set_color:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.set_color, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.set_line_width:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.set_line_width, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.set_min_max_values:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.set_min_max_values, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.set_start_angle:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.set_start_angle, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.set_update:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.set_update, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Ring.set_value:1: WARNING: duplicate object description of bec_widgets.cli.client.Ring.set_value, other instance in api_reference/_autosummary/bec_widgets.cli.client.Ring, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.add_ring:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.add_ring, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.enable_auto_updates:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.enable_auto_updates, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.remove_ring:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.remove_ring, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.reset_diameter:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.reset_diameter, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.rings:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.rings, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_colors_directly:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_colors_directly, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_colors_from_map:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_colors_from_map, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_diameter:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_diameter, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_gap:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_gap, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_line_widths:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_line_widths, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_min_max_values:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_min_max_values, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_number_of_bars:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_number_of_bars, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_precision:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_precision, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.set_value:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.set_value, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.RingProgressBar.update_config:1: WARNING: duplicate object description of bec_widgets.cli.client.RingProgressBar.update_config, other instance in api_reference/_autosummary/bec_widgets.cli.client.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.ScanControl:1: WARNING: duplicate object description of bec_widgets.cli.client.ScanControl, other instance in api_reference/_autosummary/bec_widgets.cli.client.ScanControl, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.ScanControl.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.ScanControl, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.StopButton:1: WARNING: duplicate object description of bec_widgets.cli.client.StopButton, other instance in api_reference/_autosummary/bec_widgets.cli.client.StopButton, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.StopButton.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.StopButton, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.TextBox:1: WARNING: duplicate object description of bec_widgets.cli.client.TextBox, other instance in api_reference/_autosummary/bec_widgets.cli.client.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.TextBox.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.TextBox.set_color:1: WARNING: duplicate object description of bec_widgets.cli.client.TextBox.set_color, other instance in api_reference/_autosummary/bec_widgets.cli.client.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.TextBox.set_font_size:1: WARNING: duplicate object description of bec_widgets.cli.client.TextBox.set_font_size, other instance in api_reference/_autosummary/bec_widgets.cli.client.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.TextBox.set_text:1: WARNING: duplicate object description of bec_widgets.cli.client.TextBox.set_text, other instance in api_reference/_autosummary/bec_widgets.cli.client.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.VSCodeEditor:1: WARNING: duplicate object description of bec_widgets.cli.client.VSCodeEditor, other instance in api_reference/_autosummary/bec_widgets.cli.client.VSCodeEditor, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.VSCodeEditor.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.VSCodeEditor, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.WebsiteWidget:1: WARNING: duplicate object description of bec_widgets.cli.client.WebsiteWidget, other instance in api_reference/_autosummary/bec_widgets.cli.client.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.WebsiteWidget.back:1: WARNING: duplicate object description of bec_widgets.cli.client.WebsiteWidget.back, other instance in api_reference/_autosummary/bec_widgets.cli.client.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.WebsiteWidget.forward:1: WARNING: duplicate object description of bec_widgets.cli.client.WebsiteWidget.forward, other instance in api_reference/_autosummary/bec_widgets.cli.client.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.WebsiteWidget.get_url:1: WARNING: duplicate object description of bec_widgets.cli.client.WebsiteWidget.get_url, other instance in api_reference/_autosummary/bec_widgets.cli.client.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.WebsiteWidget.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.WebsiteWidget.reload:1: WARNING: duplicate object description of bec_widgets.cli.client.WebsiteWidget.reload, other instance in api_reference/_autosummary/bec_widgets.cli.client.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.WebsiteWidget.set_url:1: WARNING: duplicate object description of bec_widgets.cli.client.WebsiteWidget.set_url, other instance in api_reference/_autosummary/bec_widgets.cli.client.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.__add__:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.__add__, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.__mul__:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.__mul__, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.capitalize:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.capitalize, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.casefold:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.casefold, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.center:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.center, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.count:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.count, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.encode:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.encode, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.endswith:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.endswith, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.expandtabs:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.expandtabs, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.find:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.find, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.format:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.format, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.format_map:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.format_map, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.index:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.index, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isalnum:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isalnum, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isalpha:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isalpha, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isascii:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isascii, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isdecimal:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isdecimal, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isdigit:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isdigit, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isidentifier:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isidentifier, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.islower:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.islower, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isnumeric:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isnumeric, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isprintable:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isprintable, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isspace:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isspace, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.istitle:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.istitle, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.isupper:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.isupper, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.join:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.join, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.ljust:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.ljust, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.lower:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.lower, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.lstrip:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.lstrip, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.maketrans:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.maketrans, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.partition:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.partition, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.removeprefix:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.removeprefix, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.removesuffix:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.removesuffix, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.replace:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.replace, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.rfind:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.rfind, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.rindex:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.rindex, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.rjust:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.rjust, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.rpartition:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.rpartition, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.rsplit:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.rsplit, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.rstrip:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.rstrip, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.split:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.split, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.splitlines:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.splitlines, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.startswith:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.startswith, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.strip:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.strip, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.swapcase:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.swapcase, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.title:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.title, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.translate:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.translate, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.upper:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.upper, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.Widgets.zfill:1: WARNING: duplicate object description of bec_widgets.cli.client.Widgets.zfill, other instance in api_reference/_autosummary/bec_widgets.cli.client.Widgets, use :no-index: for one of them
|
||||
docstring of bec_widgets.examples.plugin_example_pyside.tictactoetaskmenu.TicTacToeDialog.DialogCode.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.examples.plugin_example_pyside.tictactoetaskmenu.TicTacToeDialog.DialogCode.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.examples.plugin_example_pyside.tictactoetaskmenu.TicTacToeDialog, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.examples.plugin_example_pyside.tictactoetaskmenu.TicTacToeDialog, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.qt_utils.error_popups.ExampleWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.qt_utils.error_popups.ExampleWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QDialog.DialogCode:1: WARNING: duplicate object description of PySide6.QtWidgets.QDialog.DialogCode, other instance in api_reference/_autosummary/bec_widgets.examples.plugin_example_pyside.tictactoetaskmenu.TicTacToeDialog, use :no-index: for one of them
|
||||
docstring of bec_widgets.qt_utils.settings_dialog.SettingsDialog.DialogCode.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.qt_utils.settings_dialog.SettingsDialog.DialogCode.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.qt_utils.settings_dialog.SettingWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.qt_utils.settings_dialog.SettingWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.qt_utils.settings_dialog.SettingsDialog, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.qt_utils.settings_dialog.SettingsDialog, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.examples.plugin_example_pyside.tictactoe.TicTacToe, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.examples.plugin_example_pyside.tictactoe.TicTacToe, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.stop_button.stop_button.StopButton, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.stop_button.stop_button.StopButton, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QFrame.Shadow:1: WARNING: duplicate object description of PySide6.QtWidgets.QFrame.Shadow, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
docstring of bec_widgets.widgets.text_box.text_box.TextBox.Shadow.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.widgets.text_box.text_box.TextBox.Shadow.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QFrame.Shape:1: WARNING: duplicate object description of PySide6.QtWidgets.QFrame.Shape, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
docstring of bec_widgets.widgets.text_box.text_box.TextBox.Shape.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.widgets.text_box.text_box.TextBox.Shape.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractScrollArea.SizeAdjustPolicy:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractScrollArea.SizeAdjustPolicy, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QFrame.StyleMask:1: WARNING: duplicate object description of PySide6.QtWidgets.QFrame.StyleMask, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.text_box.text_box.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.text_box.text_box.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.toggle.toggle.ToggleSwitch, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.toggle.toggle.ToggleSwitch, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.CurveSettings, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.CurveSettings, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.RemoveButton, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.RemoveButton, use :no-index: for one of them
|
||||
docstring of bec_widgets.widgets.waveform.waveform_popups.dap_summary_dialog.dap_summary_dialog.FitSummaryWidget.DialogCode.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.widgets.waveform.waveform_popups.dap_summary_dialog.dap_summary_dialog.FitSummaryWidget.DialogCode.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.StyleComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.StyleComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.dap_summary_dialog.dap_summary_dialog.FitSummaryWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.dap_summary_dialog.dap_summary_dialog.FitSummaryWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_widget.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_widget.BECWaveformWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/developer/developer.md:6: WARNING: toctree contains reference to nonexisting document 'developer/api_reference/api_reference'
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/index.md:60: WARNING: 'toctree': Invalid option value for 'numbered': true: invalid literal for int() with base 10: 'true' [myst.directive_option]
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client:1: WARNING: duplicate object description of bec_widgets.cli.client, other instance in api_reference/_autosummary/bec_widgets.cli.client, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.dap_params:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.dap_params, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.get_data:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.get_data, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.remove:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.remove, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_color:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_color, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_color_map_z:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_color_map_z, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_data:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_data, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_pen_style:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_pen_style, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_pen_width:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_pen_width, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_symbol:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_symbol, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_symbol_color:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_symbol_color, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECCurve.set_symbol_size:1: WARNING: duplicate object description of bec_widgets.cli.client.BECCurve.set_symbol_size, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECCurve, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.add_widget:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.add_widget, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.attach:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.attach, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.detach:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.detach, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.get_widgets_positions:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.get_widgets_positions, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.hide_title_bar:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.hide_title_bar, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.list_eligible_widgets:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.list_eligible_widgets, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.move_widget:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.move_widget, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.remove:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.remove, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.remove_widget:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.remove_widget, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.set_title:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.set_title, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.show_title_bar:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.show_title_bar, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDock.widget_list:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDock.widget_list, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDock, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.add_dock:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.add_dock, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.attach_all:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.attach_all, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.clear_all:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.clear_all, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.BECGuiClientMixin.close:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.close, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.detach_dock:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.detach_dock, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.RPCBase.gui_is_alive:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.gui_is_alive, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.panels:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.panels, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.remove_dock:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.remove_dock, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.restore_state:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.restore_state, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.save_state:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.save_state, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.selected_device:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.selected_device, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client_utils.BECGuiClientMixin.show:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.show, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/client.py:docstring of bec_widgets.cli.client.BECDockArea.temp_areas:1: WARNING: duplicate object description of bec_widgets.cli.client.BECDockArea.temp_areas, other instance in api_reference/_autosummary/bec_widgets.cli.client.BECDockArea, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.qt_utils.toolbar.ModularToolBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.qt_utils.toolbar.ModularToolBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.image.image_widget.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.image.image_widget.BECImageWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.jupyter_console.jupyter_console.BECJupyterConsole, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.jupyter_console.jupyter_console.BECJupyterConsole, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.motor_map.motor_map_dialog.motor_map_settings.MotorMapSettings, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.motor_map.motor_map_dialog.motor_map_settings.MotorMapSettings, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.motor_map.motor_map_widget.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.motor_map.motor_map_widget.BECMotorMapWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.examples.plugin_example_pyside.tictactoe.TicTacToe, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.examples.plugin_example_pyside.tictactoe.TicTacToe, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.ring_progress_bar.ring_progress_bar.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.ring_progress_bar.ring_progress_bar.RingProgressBar, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_control.ScanControl, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_control.ScanControl, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanCheckBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanCheckBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanDoubleSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanDoubleSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanGroupBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanGroupBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractSpinBox.ButtonSymbols:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractSpinBox.ButtonSymbols, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanDoubleSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractSpinBox.CorrectionMode:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractSpinBox.CorrectionMode, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanDoubleSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanLineEdit, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanLineEdit, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractSpinBox.StepEnabledFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractSpinBox.StepEnabledFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanDoubleSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractSpinBox.StepType:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractSpinBox.StepType, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanDoubleSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.scan_control.scan_group_box.ScanSpinBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.vscode.vscode.VSCodeEditor, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.vscode.vscode.VSCodeEditor, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.website.website.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.website.website.WebsiteWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QComboBox.InsertPolicy:1: WARNING: duplicate object description of PySide6.QtWidgets.QComboBox.InsertPolicy, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.StyleComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.device_box.device_box.DeviceBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.device_box.device_box.DeviceBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QComboBox.SizeAdjustPolicy:1: WARNING: duplicate object description of PySide6.QtWidgets.QComboBox.SizeAdjustPolicy, other instance in api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog.StyleComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.device_combobox.device_combobox.DeviceComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.device_combobox.device_combobox.DeviceComboBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.device_line_edit.device_line_edit.DeviceLineEdit, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.device_line_edit.device_line_edit.DeviceLineEdit, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.position_indicator.position_indicator.PositionIndicator, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.position_indicator.position_indicator.PositionIndicator, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.bec_status_box.bec_status_box.BECStatusBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.bec_status_box.bec_status_box.BECStatusBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.bec_status_box.status_item.StatusItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.bec_status_box.status_item.StatusItem, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.CursorAction:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.CursorAction, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.DragDropMode:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.DragDropMode, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.DropIndicatorPosition:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.DropIndicatorPosition, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.EditTrigger:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.EditTrigger, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtGui.QPaintDevice.PaintDeviceMetric:1: WARNING: duplicate object description of PySide6.QtGui.QPaintDevice.PaintDeviceMetric, other instance in api_reference/_autosummary/bec_widgets.widgets.spinner.spinner.SpinnerWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QWidget.RenderFlag:1: WARNING: duplicate object description of PySide6.QtWidgets.QWidget.RenderFlag, other instance in api_reference/_autosummary/bec_widgets.widgets.spinner.spinner.SpinnerWidget, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.ScrollHint:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.ScrollHint, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.ScrollMode:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.ScrollMode, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.SelectionBehavior:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.SelectionBehavior, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.SelectionMode:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.SelectionMode, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QFrame.Shadow:1: WARNING: duplicate object description of PySide6.QtWidgets.QFrame.Shadow, other instance in api_reference/_autosummary/bec_widgets.widgets.text_box.text_box.TextBox, use :no-index: for one of them
|
||||
docstring of bec_widgets.widgets.bec_queue.bec_queue.BECQueue.Shadow.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.widgets.bec_queue.bec_queue.BECQueue.Shadow.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QFrame.Shape:1: WARNING: duplicate object description of PySide6.QtWidgets.QFrame.Shape, other instance in api_reference/_autosummary/bec_widgets.widgets.text_box.text_box.TextBox, use :no-index: for one of them
|
||||
docstring of bec_widgets.widgets.bec_queue.bec_queue.BECQueue.Shape.from_bytes:9: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
docstring of bec_widgets.widgets.bec_queue.bec_queue.BECQueue.Shape.to_bytes:7: WARNING: Inline interpreted text or phrase reference start-string without end-string.
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractScrollArea.SizeAdjustPolicy:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractScrollArea.SizeAdjustPolicy, other instance in api_reference/_autosummary/bec_widgets.widgets.text_box.text_box.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QAbstractItemView.State:1: WARNING: duplicate object description of PySide6.QtWidgets.QAbstractItemView.State, other instance in api_reference/_autosummary/bec_widgets.utils.bec_table.BECTable, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/docstring of PySide6.QtWidgets.QFrame.StyleMask:1: WARNING: duplicate object description of PySide6.QtWidgets.QFrame.StyleMask, other instance in api_reference/_autosummary/bec_widgets.widgets.text_box.text_box.TextBox, use :no-index: for one of them
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/customisation.md: WARNING: document isn't included in any toctree
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/introduction.md: WARNING: document isn't included in any toctree
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/widgets/scan_control.md: WARNING: document isn't included in any toctree
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/auto_updates.py:docstring of bec_widgets.cli.auto_updates.AutoUpdates:1: WARNING: more than one target found for cross-reference 'BECDockArea': bec_widgets.cli.client.BECDockArea, bec_widgets.widgets.dock.dock_area.BECDockArea
|
||||
/Users/wakonig_k/.pyenv/versions/bec_widgets_docs/lib/python3.10/site-packages/bec_widgets/cli/auto_updates.py:docstring of bec_widgets.cli.auto_updates.AutoUpdates.get_default_figure:1: WARNING: more than one target found for cross-reference 'BECFigure': bec_widgets.cli.client.BECFigure, bec_widgets.widgets.figure.figure.BECFigure
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.qt_utils.toolbar.DeviceSelectionAction.rst:2: WARNING: more than one target found for cross-reference 'DeviceComboBox': bec_widgets.cli.client.DeviceComboBox, bec_widgets.widgets.device_combobox.device_combobox.DeviceComboBox
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.dock.dock_area.BECDockArea.rst:2: WARNING: more than one target found for cross-reference 'BECDock': bec_widgets.cli.client.BECDock, bec_widgets.widgets.dock.dock.BECDock
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.dock.dock_area.BECDockArea.rst:2: WARNING: more than one target found for cross-reference 'BECDock': bec_widgets.cli.client.BECDock, bec_widgets.widgets.dock.dock.BECDock
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.dock.dock_area.BECDockArea.rst:2: WARNING: more than one target found for cross-reference 'BECDock': bec_widgets.cli.client.BECDock, bec_widgets.widgets.dock.dock.BECDock
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.figure.BECFigure.rst:2: WARNING: more than one target found for cross-reference 'BECPlotBase': bec_widgets.cli.client.BECPlotBase, bec_widgets.widgets.figure.plots.plot_base.BECPlotBase
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.figure.BECFigure.rst:2: WARNING: more than one target found for cross-reference 'BECImageShow': bec_widgets.cli.client.BECImageShow, bec_widgets.widgets.figure.plots.image.image.BECImageShow
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.figure.BECFigure.rst:2: WARNING: more than one target found for cross-reference 'BECMotorMap': bec_widgets.cli.client.BECMotorMap, bec_widgets.widgets.figure.plots.motor_map.motor_map.BECMotorMap
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.figure.BECFigure.rst:2: WARNING: more than one target found for cross-reference 'BECWaveform': bec_widgets.cli.client.BECWaveform, bec_widgets.widgets.figure.plots.waveform.waveform.BECWaveform
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.figure.WidgetHandler.rst:2: WARNING: more than one target found for cross-reference 'BECPlotBase': bec_widgets.cli.client.BECPlotBase, bec_widgets.widgets.figure.plots.plot_base.BECPlotBase
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.image.image.BECImageShow.rst:2: WARNING: more than one target found for cross-reference 'BECImageItem': bec_widgets.cli.client.BECImageItem, bec_widgets.widgets.figure.plots.image.image_item.BECImageItem
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.image.image.BECImageShow.rst:2: WARNING: more than one target found for cross-reference 'BECImageItem': bec_widgets.cli.client.BECImageItem, bec_widgets.widgets.figure.plots.image.image_item.BECImageItem
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.image.image.BECImageShow.rst:2: WARNING: more than one target found for cross-reference 'BECImageItem': bec_widgets.cli.client.BECImageItem, bec_widgets.widgets.figure.plots.image.image_item.BECImageItem
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.image.image.BECImageShow.rst:2: WARNING: more than one target found for cross-reference 'BECImageItem': bec_widgets.cli.client.BECImageItem, bec_widgets.widgets.figure.plots.image.image_item.BECImageItem
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.waveform.waveform.BECWaveform.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.waveform.waveform.BECWaveform.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.waveform.waveform.BECWaveform.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.waveform.waveform.BECWaveform.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.waveform.waveform.BECWaveform.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.figure.plots.waveform.waveform.BECWaveform.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.ring_progress_bar.ring_progress_bar.RingProgressBar.rst:2: WARNING: more than one target found for cross-reference 'Ring': bec_widgets.cli.client.Ring, bec_widgets.widgets.ring_progress_bar.ring.Ring
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_widget.BECWaveformWidget.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_widget.BECWaveformWidget.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/api_reference/_autosummary/bec_widgets.widgets.waveform.waveform_widget.BECWaveformWidget.rst:2: WARNING: more than one target found for cross-reference 'BECCurve': bec_widgets.cli.client.BECCurve, bec_widgets.widgets.figure.plots.waveform.waveform_curve.BECCurve
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:18: WARNING: 'myst' cross-reference target not found: 'user.widgets.waveform_1d' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:25: WARNING: local id not found in doc 'api_reference/_autosummary/bec_widgets.cli.client.BECFigure': 'bec_widgets.cli.client.BECFigure.plot' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:30: WARNING: local id not found in doc 'api_reference/_autosummary/bec_widgets.cli.client.BECWaveform': 'bec_widgets.cli.client.BECWaveform.set_title' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:30: WARNING: local id not found in doc 'api_reference/_autosummary/bec_widgets.cli.client.BECWaveform': 'bec_widgets.cli.client.BECWaveform.set_x_label' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:30: WARNING: local id not found in doc 'api_reference/_autosummary/bec_widgets.cli.client.BECWaveform': 'bec_widgets.cli.client.BECWaveform.set_x_lim' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:30: WARNING: 'myst' cross-reference target not found: 'user.widgets.waveform_1d' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:46: WARNING: 'myst' cross-reference target not found: '/api_reference/_autosummary/bec_widgets.cli.client.BECWaveForm' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:54: WARNING: 'myst' cross-reference target not found: 'user.widgets.image' [myst.xref_missing]
|
||||
/Users/wakonig_k/software/work/bec-widgets/docs/user/getting_started/quick_start.md:58: WARNING: Lexing literal_block 'gui.add_dock? # shows the dockstring of the add_dock method\n' as "python" resulted in an error at token: '?'. Retrying in relaxed mode.
|
||||
35
docs/make.bat
Normal file
35
docs/make.bat
Normal file
@@ -0,0 +1,35 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
10
docs/requirements.txt
Normal file
10
docs/requirements.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
sphinx
|
||||
sphinx_copybutton
|
||||
recommonmark
|
||||
sphinx-toolbox
|
||||
pydata-sphinx-theme
|
||||
sphinx-copybutton
|
||||
sphinx-inline-tabs
|
||||
myst-parser
|
||||
sphinx-design
|
||||
tomli
|
||||
5
docs/user/before_you_arrive/before_you_arrive.md
Normal file
5
docs/user/before_you_arrive/before_you_arrive.md
Normal file
@@ -0,0 +1,5 @@
|
||||
(user.before_you_arrive)=
|
||||
# Before you arrive
|
||||
|
||||
|
||||
## Before you arrive
|
||||
292
docs/user/ptychography/flomni.md
Normal file
292
docs/user/ptychography/flomni.md
Normal file
@@ -0,0 +1,292 @@
|
||||
(user.ptychography.flomni)=
|
||||
# flOMNI
|
||||
|
||||
flOMNI is an instrument for tomographic measurements via X-ray ptychography. The sample environment is at atmospheric pressure and room temperature (or higher).
|
||||
An early version of the setup is described [here](https://www.dora.lib4ri.ch/psi/islandora/object/psi:12560). Nano positioning is based on closed loop control to a position signal obtained from dedicated [laser interferometry](https://www.dora.lib4ri.ch/psi/islandora/object/psi:7524). For fast scanning a combined motion of the sample (slow axis) and beam defining fresnel zone plate (fast axis) is used. The method is described [here](https://www.dora.lib4ri.ch/psi/islandora/object/psi:21021). The setup is equipped with a [heater](https://www.dora.lib4ri.ch/psi/islandora/object/psi:45302), that can be used to apply hot gas streams to the sample.
|
||||
Samples are to be mounted on [OMNY pins](https://www.dora.lib4ri.ch/psi/islandora/object/psi:4528).
|
||||
|
||||
## How to flOMNI
|
||||
|
||||
… a step-by-step guide for users
|
||||
|
||||
(user.ptychography.flomni.transfer)=
|
||||
### Sample storage and transfer
|
||||
|
||||
Print the current usage of the sample storage
|
||||
`flomni.ftransfer_show_all()`
|
||||
|
||||
flOMNI has to know about the loaded positions and sample names. To modify use
|
||||
`flomni.ftransfer_modify_storage(<position>, 0 (=free) / 1 (=used))`
|
||||
positions `<1> .. <20>` are available slots in the tray.
|
||||
Special position: `0 = sample stage`, `100 = gripper`.
|
||||
You will be asked to enter a sample name.
|
||||
|
||||
To load a new sample in the sample stage, in principle only one command is needed
|
||||
`flomni.ftransfer_sample_change(<position new sample>)`
|
||||
You will be asked where the previous sample should go with a suggestion for an empty position in the tray.
|
||||
Other commands:
|
||||
`ftransfer_tray_in /_out (not yet implemented).`
|
||||
|
||||
__If something goes wrong__, there are additional commands to perform a manual operation of the gripper.
|
||||
|
||||
| command | explanation |
|
||||
| --- | --- |
|
||||
| `flomni.ftransfer_get_sample(<position>)` | Pick sample from <position> |
|
||||
| `flomni.ftransfer_put_sample(<position>)` | Mount sample at <position> |
|
||||
| `flomni.ftransfer_flomni_stage_in()` | stage to measurement position |
|
||||
| `flomni.ftransfer_flomni_stage_out()` | stage to the sample change position |
|
||||
|
||||
Manual operation of the gripper (do not leave it too long in open state)
|
||||
`flomni.ftransfer_gripper_open()`
|
||||
`flomni.ftransfer_gripper_close()`
|
||||
|
||||
Manually move the gripper to a transfer position
|
||||
`flomni.ftransfer_gripper_move(<position>)`
|
||||
|
||||
### Alignment of samples
|
||||
|
||||
#### Coarse alignment
|
||||
|
||||
After the sample transfer the sample stage moved to the measurement position with your new sample. The Xray eye will automatically move in and the shutter will open. You may already see the sample in the omny xeye interface running on the windows computer.
|
||||
If you see your sample already at the approximately correct height, you can skip steps 1 to 3. Otherwise adjust the height:
|
||||
|
||||
1. `flomni.rt_feedback_disable()` disable the closed loop operation to allow movement of coarse stages
|
||||
1. `umvr(dev.fsamy, 0.01)`, attention: unit <mm>, move the sample stage relative up (positive) or down (negative) until the sample is approximately vertically centered in xray eye screen
|
||||
1. `flomni.xrayeye_update_frame()` will update the current image on the xray eye screen
|
||||
1. `flomni.xrayeye_alignment_start()` start the coarse alignment of the sample by measuring (clicking in the X-ray eye software) the sample position at 0, 45, 90, 135, 180 degrees. Then use the matlab routine `SPEC_ptycho_align.m` to fit this data.
|
||||
1. `flomni.read_alignment_offset()` read the generated alignment data.
|
||||
|
||||
#### Fine alignment
|
||||
|
||||
After the xrayeyealign, a fine alignment needs to be performed using ptychography.
|
||||
_To bypass the fine alignment: `feye_out`_
|
||||
|
||||
|
||||
1. `flomni.tomo_parameters()` Adjust the ptychographic scan parameters for performing an alignment scan. Typically FOVX = FOVX(Xrayeye)+20 mu, shell step = beamsize/2.5, number of projections and tomo mode are ignored in the alignment scans.
|
||||
1. `flomni.tomo_alignment_scan()` perform the alignment scan. When the first scan is running, switch to a matlab session and run `SPEC_ptycho_align` again. Click left and right. The third click can define the height of the scan, but is not needed and ignored by default. The widest horizontal field of view will be printed at the end of the matlab session.
|
||||
1. `flomni.read_alignment_offset()` Load alignment parameters calculated in matlab.
|
||||
|
||||
### Tomographic Measurement
|
||||
|
||||
Now that the sample is aligned, the tomographic measurement can be performed.
|
||||
1. `flomni.tomo_parameters()` adjust the scan parameters for the tomographic scan. This includes the parameters for ptychographic scans of projections plus the strategy for angular sampling. The vertical shift adjusts the field of view, up (positive) or down (negative). After adjusting the numbers, type again `flomni.tomo_parameters()` and verify that they are correct.
|
||||
1. `flomni.tomo_scan_projection(angle)` perform a ptychographic scan at the rotation angle <angle>. Launch the tomographic measurement by `flomni.tomo_scan()`.
|
||||
1. Before changing sample, verify that all subtomograms were completely acquired using the `tomo_recons matlab` script.
|
||||
|
||||
#### If something went wrong…
|
||||
|
||||
A __single projection__ is to be repeated use
|
||||
`flomni.tomo_scan_projection(<angle>)`. The target angle of scans can be found in the second column of the file in
|
||||
`~/Data10/specES1/dat-files/omni_scannumbers.txt`
|
||||
|
||||
To continue an __interrupted tomography scan__:
|
||||
|
||||
Depending on the tomo mode following parameters can be given to the `flomni.tomo_scan()` command:
|
||||
| tomo type | parameters and their defaults |
|
||||
| --- | --- |
|
||||
| 8 sub-tomograms | subtomo_start=1, start_angle=None |
|
||||
| Golden ratio tomography (sorted in bunches) | projection_number=None |
|
||||
| Equally spaced with golden starting angle | projection_number=None |
|
||||
|
||||
## How to setup flOMNI (software)
|
||||
|
||||
This part of the manual is intended for beamline staff and expert users
|
||||
|
||||
The nano-positioning is controlled by a feedback loop running on a real-time linux based computer. With all related hardware connected, this loop has to be started manually.
|
||||
|
||||
1. Login to the computer by `ssh control@mpc2680`. The password is "engine".
|
||||
1. `cd OMNY/flOMNI/`
|
||||
1. `./startflOMNI`
|
||||
|
||||
Once the loop has started, it is possible to start bec with the flOMNI configuration file.
|
||||
|
||||
Loading the flOMNI configuration (this command will load the OMNY configuration only - isolated from the beamline)
|
||||
`bec.config.update_session_with_file("/bec/csaxs_bec/csaxs_bec/device_configs/flomni_config.yaml")`
|
||||
|
||||
Loading the flOMNI scripts
|
||||
`from csaxs_bec.bec_ipython_client.plugins.flomni import Flomni`
|
||||
`flomni = Flomni(bec)`
|
||||
|
||||
If the realtime system is restarted, bec will lose communication. To restart:
|
||||
`flomni.rt_off()` … then wait a few seconds
|
||||
`flomni.rt_on()`
|
||||
|
||||
### Initialization of the stages
|
||||
|
||||
The stages of flOMNI are referenced in respect to their endswitches. The stages have to be initialized at the beginning of a run or when the Galil motor controllers have been reset or restarted. To see the status of the stages following commands are available:
|
||||
|
||||
Show the status of all galil controllers (all stepper motors and the UPR rotation stage)
|
||||
`dev.fsamx.controller.galil_show_all()`
|
||||
|
||||
The same holds true for the Smaract stages which control the OSA position. Their status can be checked by
|
||||
`dev.fosax.controller.show_all()`
|
||||
|
||||
In case referencing of the flOMNI stages is required, run
|
||||
`flomni.flomni_init_stages()`
|
||||
This script will first verify that the stages are not in an initialized state, and then reference all stages in a safe way. The user will be warned in case of a potentially risky situation. This mainly involves a collision risk upstream with the exposure box exit window. It might be worth to check clearance prior to calling the init skript.
|
||||
|
||||
### X-ray optics alignment
|
||||
|
||||
The positions of the optics stages are stored as stage parameters and are thus linked to the configuration file.
|
||||
Example: The OSAx “in” position can be reviewed by `dev.fosax.user_parameter`
|
||||
Update the value by (example "fosax", "in") by `dev.fosax.update_user_parameter({"in":value})`
|
||||
|
||||
`flomni.ffzp_info()` shows info about the available FZPs at the current energy of the beamline. Optional parameter is the photon _energy_ in keV.
|
||||
Example: `flomni.ffzp_info(6.2)`
|
||||
|
||||
The [laser feedback](user.ptychography.flomni.laser_feedback) will be disabled and fine alignment lost if foptx/y are moved!
|
||||
|
||||
Following functions exist to move the optics in and out, with self-explaining naming.
|
||||
- `flomni.ffzp_in()`
|
||||
- `flomni.foptics_in()`
|
||||
- `flomni.foptics_out()`
|
||||
- `flomni.fosa_in()`
|
||||
- `flomni.fosa_out()`
|
||||
|
||||
### Interferometer
|
||||
|
||||
The position feedback in flOMNI is controlled in closed loop to an interferometric position measurement. To show the signal of the interferometers:
|
||||
`flomni.show_signal_strength_interferometer()`
|
||||
Typical values with proper alignment, sample stage at the measurement position and laser tracker running are
|
||||
_TODO_
|
||||
|
||||
#### Laser tracker commands
|
||||
|
||||
The horizontal interferometer is built according to the [tracking interferometer](https://www.dora.lib4ri.ch/psi/islandora/object/psi:7524). The tracker can be controlled by following commands. During commissioning of the setup it is worthy to check the status, but during general operation these commands should not be required.
|
||||
|
||||
- `flomni.laser_tracker_show_all()`
|
||||
- `flomni.laser_tracker_on()`
|
||||
- `flomni.laser_tracker_off()`
|
||||
|
||||
(user.ptychography.flomni.laser_feedback)=
|
||||
#### Interferometer feedback commands
|
||||
|
||||
The closed loop control of the Piezo stages can be controlled by
|
||||
- `flomni.rt_feedback_enable_with_reset()`.
|
||||
_There is also an enable without reset, which is used during tomography scans, when using coarse stages to increase the scan range. It should not be required to use manually._
|
||||
- `flomni.rt_feedback_disable()`
|
||||
- `flomni.rt_feedback_status()`
|
||||
|
||||
### Scanning in 2D and sample alignment
|
||||
|
||||
#### flOMNI Fermat scan
|
||||
|
||||
The basic scan function can be called by `scans.flomni_fermat_scan()` and offers a detailed doc string for further details (`scans.flomni_fermat_scan?`). A prerequisite for scanning is a running feedback system. The scan has following parameters.
|
||||
|
||||
| Parameters | |
|
||||
| --- | --- |
|
||||
| fovx (float) | Fov in the piezo plane (i.e. piezo range). Max 200 um |
|
||||
| fovy (float) | Fov in the piezo plane (i.e. piezo range). Max 100 um |
|
||||
| cenx (float) | center position in x |
|
||||
| ceny (float) | center position in y |
|
||||
| exp_time (float) | exposure time |
|
||||
| step (float) | stepsize |
|
||||
| zshift (float) | shift in z |
|
||||
| angle (float) | rotation angle (will rotate first) |
|
||||
| corridor_size (float) | corridor size for the corridor optimization. Default 3 um |
|
||||
|
||||
Example:
|
||||
`scans.flomni_fermat_scan(fovx=20, fovy=25, cenx=0.02, ceny=0, zshift=0, angle=0, step=0.5, exp_time=0.01)`
|
||||
|
||||
#### Overview of the alignment steps
|
||||
|
||||
There are several corrections applied to maintain the sample in the FOV:
|
||||
1. Mirror calibration
|
||||
1. X-ray eye alignment
|
||||
1. Ptychography fine alignment (improvement of the X-ray eye alignment step)
|
||||
1. Vertical shifts from tomography reconstruction (for very small vertical FOV)
|
||||
|
||||
#### XrayEye and sample alignment
|
||||
|
||||
The XrayEye can be moved in and out by
|
||||
`flomni.feye_in()`
|
||||
`flomni.feye_out()`
|
||||
|
||||
The _in_ and _out_ positions are stored as user parameters in the stage definition. Get the values by
|
||||
`dev.feyex.user_parameter`
|
||||
`dev.feyey.user_parameter`
|
||||
|
||||
Update the values by, example for feyex and in position,
|
||||
`dev.feyex.update_user_parameter({"in":value})`
|
||||
|
||||
To refresh the frame of the xray eye windows software
|
||||
`flomni.xrayeye_update_frame()`
|
||||
|
||||
To start the xray eye alignment (and clear any previous alignment)
|
||||
`flomni.xrayeye_alignment_start()`
|
||||
|
||||
To load the fit parameters from directory _dir_path_ computed by _SPEC_ptycho_align.m_ in Matlab run
|
||||
`flomni.read_alignment_offset(dir_path='')`
|
||||
The loading routine uses default values for the vertical alignment. This behavior can be changed (e.g. for getting new default values) by the parameter `use_vertical_default_values=False`.
|
||||
|
||||
At each projection, the angular dependent is computed by
|
||||
`flomni.get_alignment_offset(angle)`, with _angle_ in degrees.
|
||||
|
||||
The alignment can be cleared by
|
||||
`flomni.reset_tomo_alignment_fit()`
|
||||
|
||||
#### Fine alignment
|
||||
|
||||
The alginment obtained by the X-ray eye can be refinde by recording ptychography projections at 45 deg. intervals. For this, adjust the tomo parameters by
|
||||
`flomni.tomo_parameters()`
|
||||
|
||||
Next, run the alignment scan by
|
||||
`flomni.tomo_alignment_scan()`
|
||||
|
||||
Reconstruct the scan and use SPEC_ptycho_align.m to obtain improved fit parameters. The new parameters can be loaded by
|
||||
`flomni.read_alignment_offset()`
|
||||
|
||||
For a __very__ tight vertical field of view, a fine vertical alignment based on outputs generated from early tomography reconstructions can be used. A corresponding file can be generated by the tomography reconstruction script and can be loaded by the following two methods:
|
||||
`flomni.read_additional_correction_y()`
|
||||
`flomni.read_additional_correction_y2()`
|
||||
One __important__ note: The first method is by default loading a mirror correction file automatically. If the tomogram is using that data, do not overwrite it, use the secondary correction instead.
|
||||
|
||||
The scan offsets are computed at each projection by
|
||||
`flomni.compute_additional_correction_y(angle)`
|
||||
`flomni.compute_additional_correction_y2(angle)`
|
||||
|
||||
The additional correct can be __reset__ by
|
||||
`flomni.reset_correction()`
|
||||
It will automatically load the default mirror correction file as primary correction! To reset and not load any correction, which might be useful to obtain a new default correction file, run
|
||||
`flomni.reset_correction(use_default_correction=False)`
|
||||
|
||||
#### Scanning of projections
|
||||
|
||||
At any stage of the alignment process it is possible to scan a projection.
|
||||
|
||||
Define the scan parameters by `flomni.tomo_parameters()`
|
||||
|
||||
Run a scan at _angle_ (in degrees) by `flomni.tomo_scan_projection(angle)`
|
||||
|
||||
### Tomography
|
||||
|
||||
The tomo parameters have to be set by
|
||||
`flomni.tomo_parameters()`
|
||||
|
||||
Once satisfied with the alignment, the tomography scan can be started by
|
||||
`flomni.tomo_scan()`
|
||||
|
||||
Three modes for angular sampling are implemented and they have different optional parameters for the tomo_scan method:
|
||||
| tomography mode | parameters and defaults |
|
||||
| --- | --- |
|
||||
| 8 sub-tomograms | subtomo_start=1, start_angle=None |
|
||||
| Golden ratio tomography (sorted in bunches) | projection_number=None |
|
||||
| Equally spaced with golden starting angle | projection_number=None |
|
||||
|
||||
The parameters can be used to __restart an interrupted acquisition__.
|
||||
In case of eight equally spaced sub-tomograms, an individual sub tomogram can be scanned by flomni.sub_tomo_scan(subtomo_number, start_angle). If the start angle is not specified, it will be computed depending on the subtomo_number, which is ranging from 1 to 8.
|
||||
|
||||
### Sample storage and transfer
|
||||
|
||||
[See short version](user.ptychography.flomni.transfer)
|
||||
|
||||
### Heater
|
||||
|
||||
The [heater](https://www.dora.lib4ri.ch/psi/islandora/object/psi:45302) can be moved up and down by
|
||||
flomni.move_fheater_down()
|
||||
flomni.move_fheater_up()
|
||||
|
||||
The functions are safe in the sense that no collisions should occur. E.g. the OSA will be moved back before a movement of the heater.
|
||||
|
||||
__The heater still needs commissioning in BEC!!!__
|
||||
|
||||
173
docs/user/ptychography/lamni.md
Normal file
173
docs/user/ptychography/lamni.md
Normal file
@@ -0,0 +1,173 @@
|
||||
(user.ptychography.lamni)=
|
||||
# LamNI
|
||||
|
||||
LamNI is an instrument for 3D ptychography via ptychographic X-ray computed lamninography (PyXL). The instrument is described in detail [here](https://www.dora.lib4ri.ch/psi/islandora/object/psi:33067).
|
||||
|
||||
## How to LamNI
|
||||
|
||||
… a step-by-step guide for _beamline staff and expert users_.
|
||||
|
||||
### Sample change and alignment
|
||||
|
||||
The access to the sample region is blocked by the flight tube during measurement. To get the flight tube out of the way use
|
||||
`lamni.leye_in()`.
|
||||
Mount the new sample. The X-ray eye is already in, but the X-ray optics needs to be moved out of the beam path by
|
||||
`lamni.loptics_out()`. Potentially a larger area needs to be illuminated to properly see the sample, which can be done by
|
||||
`open slits`.
|
||||
|
||||
#### Coarse axis alignment
|
||||
|
||||
The effective position of the axis of rotation shifts with sample thickness or mounting position of the sample along the axis of rotation. The position of the axis of rotation is controlled by user parameters __center__ of the __lsamx__ and __lsamy__ stages. To observe the axis of rotation obtain the position of the Fresnel zone plate on the X-ray eye, possibly in the _ueye gui_ by:
|
||||
1. `lamni.lfzp_in()`, move the FZP in
|
||||
1. `dev.rtx.controller.feedback_disable()`, disable feedback to allow lsam movements
|
||||
1. `fshopen()`, open the shutter
|
||||
1. `umv(dev.lsamrot,90)` to rotate the sample. One might observe the center of rotation at 0 and 180 degress.
|
||||
1. `umvr(dev.lsamx,0.01)` to move lsamx and lsamy such that the center of rotation is at the center of the X-ray beam
|
||||
1. `dev.lsamx` and `dev.lsamy` will print current position and the center value. Update the center value by
|
||||
`dev.lsamx.update_user_parameter({'center':8.69})`
|
||||
`dev.lsamy.update_user_parameter({'center':8.69})`
|
||||
1. close the shutter: `fshclose()`
|
||||
|
||||
#### X-ray eye alignment
|
||||
|
||||
The GUI on the windows computer is used to obtain a coarse sample alignment. Start the alignment process (and clear any previous alignment) by
|
||||
`lamni.align.align()`. With LamNI it can be very difficult to follow a region of interest as the sample rotates. Therefore the X-ray shutter will be open during the entire process. Therefore the windows software has to be set on __FORCE__ to continuously update frames and not freeze frames after rotation.
|
||||
- run `SPEC_ptycho_align.m` (in matlab, use __force_ptychography = 0__)
|
||||
- `lamni.align.read_xray_eye_correction()` to read the alignment parameters. The correction is based on sinusoidal fits in x and y direction. The values are computed by
|
||||
`lamni_compute_additional_correction_xeye_mu(angle)`
|
||||
- If slits were opened during alignment, close the slits `slits 1 to around 0.3`
|
||||
- `lamni.leye_out()` remove the X-ray eye and move the flight tube in
|
||||
- _possibly check slit0wh, idgap_
|
||||
|
||||
To only see one frame on the Windows GUI run `lamni.align.update_frame()`
|
||||
|
||||
#### Fine alignment
|
||||
|
||||
The sample fine alignment can be obtained using ptychography. For this a short laminogram has to be recorded.
|
||||
- `lamni.tomo_parameters()` adjust the parameters for a coarse scan: A large step size and large FOV. Especially select __FOV offset = 0__ and __number of projections = 96__ (only one sub-laminogram will be recorded).
|
||||
- `lamni.sub_tomo_scan(1,0)` record one sub-laminogram
|
||||
- use the corresponding scan numbers in `SPEC_ptycho_align.m`
|
||||
- Record a last projection for all scans to reconstruct `lamni.tomo_scan_projection(0)` and wait for the reconstructions to be complete
|
||||
- Run `SPEC_ptycho_align.m` (in Matlab, __force ptycho=1__, and __correct scan numbers__)
|
||||
- Click the sample position in the Matlab GUI and then load the generated file by, for example
|
||||
`lamni.align.read_additional_correction('/sls/X12SA/data/e20632/Data10/cxs_software/ptycho/correction_lamni_um_S05389_lamni_fit.txt')`
|
||||
- With this alignment a second iteration could be performed. To read the second correction file use `lamni.align.read_additional_correction_2()`
|
||||
|
||||
#### Shifting the FOV
|
||||
|
||||
- `lamni.align.tomo_fovx/y_offset=value` [mm] will shift the field of view. Perform this adjustment from projections collected at __lsamrot 0 degrees__.
|
||||
|
||||
### Laminography scan
|
||||
|
||||
Start the laminography scan by
|
||||
1. `lamni.tomo_parameters()` adjust the parameters to the desired settings.
|
||||
1. for test scans run
|
||||
`lamni.tomo_scan_projection(angle)`
|
||||
`lamni.tomo_reconstruct()`
|
||||
1. `lamni.tomo_scan()` to start the lamninography scan
|
||||
|
||||
### Tips and Tricks
|
||||
|
||||
#### Reset corrections
|
||||
|
||||
- `lamni.align.reset_correction()`
|
||||
- `lamni.align.reset_correction_2()`
|
||||
- `lamni.align.reset_xray_eye_correction()`
|
||||
|
||||
#### Adjusting beam size with feedback running
|
||||
|
||||
If the beam size needs to be changed with feedback running, e.g. to switch from near-field to far-field ptychography, following steps can be taken:
|
||||
1. `dev.loptz.enable_set=True` to enable loptz movements with feedback running
|
||||
1. `umvr(dev.lopz,_value_)` move loptz to the desired position.
|
||||
1. `lamni._manual_shift_x/y = _value_` correct the stage run out from motion along the optical axis (units of um). The exact value can be checked by comparing feature positions in projections before/after adjusting loptz.
|
||||
1. Potentially correct the alignment of the OSA
|
||||
|
||||
#### BEC tips
|
||||
|
||||
Print all global variables `bec.global_vars()`
|
||||
|
||||
`dev.lsamx/y.wm` or `dev.lsamx/y` prints a motor position
|
||||
|
||||
## How to setup LamNI (software)
|
||||
|
||||
This part of the manual describes the software structure in more detail.
|
||||
|
||||
### start the realtime feedback loop and BEC with OMNY
|
||||
|
||||
The nano-positioning is controlled by a feedback loop running on a real-time linux based computer. With all related hardware connected, this loop has to be started manually.
|
||||
|
||||
1. Login to the computer by `ssh control@mpc2680`. The password is "engine".
|
||||
1. `cd OMNY/lamni/`
|
||||
1. `./startLAMNI`
|
||||
|
||||
Once the loop has started, it is possible to start bec with the LamNI configuration file.
|
||||
|
||||
Loading the LamNI configuration (this command will load the LamNI configuration only - isolated from the beamline)
|
||||
`bec.config.update_session_with_file("/bec/csaxs_bec/csaxs_bec/device_configs/lamni_config.yaml")`
|
||||
|
||||
Loading the LamNI scripts
|
||||
`from csaxs_bec.bec_ipython_client.plugins.LamNI import LamNI`
|
||||
`lamni = LamNI(bec)`
|
||||
|
||||
If the realtime system is restarted, BEC will lose communication. To restart:
|
||||
`lamni.rt_off()` … then wait a 10 seconds
|
||||
`lamni.rt_on()`
|
||||
|
||||
### Initialization of the stages
|
||||
|
||||
The stages of LamNI are referenced in respect to their endswitches or reference marks. The stages have to be initialized at the beginning of a run or when the Galil motor controller has been reset or restarted. To see the status of the stages following commands are available:
|
||||
|
||||
Show the status of all galil controllers (all stepper motors and the UPR rotation stage)
|
||||
`dev.lsamx.controller.galil_show_all()`
|
||||
|
||||
The same holds true for the Smaract stages which control the OSA position. Their status can be checked by
|
||||
`dev.losax.controller.show_all()`
|
||||
|
||||
In case referencing of the LamNI stages is required, run
|
||||
`lamni.init.lamni_init_stages()`
|
||||
This script will first verify that the stages are not in an initialized state, and then reference all stages in a safe way. The user will be warned in case of a potentially risky situation. This mainly involves a collision risk upstream with the exposure box exit window. It might be worth to check clearance prior to calling the init skript.
|
||||
|
||||
### Interferometer
|
||||
|
||||
The position feedback in LamNI is controlled in closed loop to an interferometric position measurement. To show the signal of the interferometers:
|
||||
`lamni.show_signal_strength_interferometer()`
|
||||
Typical values with proper alignment are
|
||||
_TODO_
|
||||
|
||||
#### Interferometer feedback commands
|
||||
|
||||
- `dev.rtx.feedback_enable_with_reset()`
|
||||
- `dev.rtx.feedback_disable()`
|
||||
- `dev.rtx.feedback_enable_without_reset()` *is only used internally by lamni methods
|
||||
- if reset of angle interferometer is required
|
||||
`dev.rtx.feedback_disable_and_even_reset_lamni_angle_interferometer()`
|
||||
- `dev.rtx.feedback_enable_with_reset()`
|
||||
|
||||
_ToDo Feedback status might be helpful. Plus make accessible via lamni.methods…_
|
||||
|
||||
### Scanning in 2D and sample alignment
|
||||
|
||||
The underlying scan function can be called as
|
||||
`scans.lamni_fermat_scan()`
|
||||
|
||||
Use `scans.lamni_fermat_scan?`for detailed information. A prerequisite for scanning is a running feedback system.
|
||||
|
||||
### X-ray optics alignment
|
||||
|
||||
The positions of the optics stages are stored as stage parameters and are thus linked to the configuration file.
|
||||
Example: The OSAx “in” position can be reviewed by `dev.losax.user_parameter`
|
||||
Update the value by (example "losax", "in") by `dev.losax.update_user_parameter({"in":value})`
|
||||
|
||||
`lamni.lfzp_info()` shows info about the available FZPs at the current energy of the beamline. Optional parameter is the photon _energy_ in keV.
|
||||
Example: `lamni.lfzp_info(6.2)`
|
||||
|
||||
The laser feedback will be disabled and fine alignment lost if foptx/y are moved!
|
||||
|
||||
Following functions exist to move the optics in and out, the naming is self-explaining.
|
||||
- `lamni.lfzp_in()`
|
||||
- `lamni.loptics_in()`
|
||||
- `lamni.loptics_out()`
|
||||
- `lamni.losa_in()`
|
||||
- `lamni.losa_out()`
|
||||
- `lamni.lfzp_in()`
|
||||
|
||||
434
docs/user/ptychography/omny.md
Normal file
434
docs/user/ptychography/omny.md
Normal file
@@ -0,0 +1,434 @@
|
||||
(user.ptychography.omny)=
|
||||
# OMNY
|
||||
|
||||
OMNY is a microscope setup for 3D mesurements via ptychographic X-ray computed tomography. The sample enviroment is in ultra-high vacuum and at a sample temperature of 90 K. The instrument is equipped with a load-lock system and allows loading and unloading of samples under cryogenic conditions. The setup is described in detail [here](https://www.dora.lib4ri.ch/psi/islandora/object/psi:4776). Samples have to be mounted on [OMNY pins](https://www.dora.lib4ri.ch/psi/islandora/object/psi:4528).
|
||||
|
||||
## HowTo OMNY
|
||||
|
||||
… a step-by-step guide for _beamline staff and expert users_.
|
||||
|
||||
### Change to a new sample
|
||||
|
||||
The sample storage, shuttles and parking positions are described in detail (here)[user.ptychography.omny.samples].
|
||||
|
||||
1. `omny.otransfer_get_sample(0)` remove current sample from sample stage. Watch gripper action and be ready to ctrl+c in case something is wrong.
|
||||
_If in doubt check that the correct sample shutte is in the active position by calling `omny.otransfer_storage()`. The slot can be selected by `omny.otransfer_park_slot(slot)`._
|
||||
1. `omny.otransfer_put_sample(position)` put the sample to the selected shuttle
|
||||
1. `omny.otransfer_get_sample(position) ` get the new sample from a shuttle
|
||||
1. `omny.otransfer_put_sample(0)`, mount the sample in the sample stage
|
||||
|
||||
### Alignment of samples
|
||||
|
||||
#### Coarse alignment
|
||||
|
||||
After mounting a new sample, the Xray eye will automatically be at the correct position to collect X-ray data. It can also be manually moved to the correct position by `omny.oeye_xray_in()`.
|
||||
|
||||
1. `omny.xrayeye_update_frame()` obtain a new frame that will be displayed on the Windows computer, OMNY software. If you see your sample already at the approximately correct height, you can skip step 2. Otherwise adjust the height:
|
||||
1. `umvr(dev.osamy, 0.01)`, attention: unit <mm>, move the sample stage relative up (positive) or down (negative) until the sample is approximately vertically centered in xray eye screen. After a move get a new frame by `omny.xrayeye_update_frame()`.
|
||||
1. `omny.xrayeye_alignment_start()` start the coarse alignment of the sample by measuring (clicking in the X-ray eye software) the sample position at 0, 45, 90, 135, 180 degrees. Then use the matlab routine `SPEC_ptycho_align.m` to fit this data.
|
||||
1. `omny.read_alignment_offset()` read the generated alignment data.
|
||||
|
||||
#### Fine alignment
|
||||
|
||||
After the xrayeyealign, a fine alignment needs to be performed using ptychography.
|
||||
_To bypass the fine alignment skip steps_.
|
||||
|
||||
1. `omny.tomo_parameters()` adjust the ptychographic scan parameters for performing an alignment scan. Typically FOVX = FOVX(Xrayeye)+20 mu, shell step = beamsize/2.5, number of projections and tomo mode are ignored in the alignment scans.
|
||||
1. `omny.optics_in()` move the Fresnel zone plate and order sorting aperture into position for ptychographic measurements.
|
||||
1. `omny.oeye_out()` move the X-ray eye out of the beam path.
|
||||
1. `omny.tomo_alignment_scan()` perform the alignment scan. When the first scan is running, switch to a matlab session and run `SPEC_ptycho_align` again. Click left and right. The third click can define the height of the scan, but is not needed and ignored by default. The widest horizontal field of view will be printed at the end of the matlab session.
|
||||
1. `omny.read_alignment_offset()` Load alignment parameters calculated in matlab.
|
||||
|
||||
### Tomographic Measurement
|
||||
|
||||
Now that the sample is aligned, the tomographic measurement can be performed.
|
||||
1. `omny.tomo_parameters()` adjust the scan parameters for the tomographic scan. This includes the parameters for ptychographic scans of projections plus the strategy for angular sampling. The vertical shift adjusts the field of view, up (positive) or down (negative). After adjusting the numbers, type again `omny.tomo_parameters()` and verify that they are correct.
|
||||
1. `omny.tomo_scan_projection(angle)` perform a ptychographic scan at the rotation angle <angle>, e.g. at zero degrees. When happy with the scan parameters launch the tomographic measurement by `omny.tomo_scan()`.
|
||||
1. Before changing to the next sample sample, verify that all subtomograms were completely acquired using the `tomo_recons matlab` script.
|
||||
|
||||
### If something went wrong…
|
||||
Special cases:
|
||||
If the gripper or another stage got stuck during transfer. Ctrl+c and then
|
||||
`umv(dev.otransy, -1.5)` followed by
|
||||
`omny._otransfer_gripper_to_park_z()`, which will move the gripper to its parking position.
|
||||
|
||||
If the above fails for the vertical movement of the gripper _Ctrl+C_.
|
||||
Try moving up and down a bit `umvr(dev.otransy,0.5)`, `umvr(dev.otransy,-0.5)`, potentially requires a _ctrl+C_ again if stuck.
|
||||
Then, `umv(dev.ootransy,-1.5)` followed by
|
||||
`omny._otransfer_gripper_to_park_z()`, which will move the gripper to its parking position.
|
||||
|
||||
If this error happens after a sample was mounted or unmounted, it is important to chech that the sample storage is correct `omny.otransfer_storage()`.
|
||||
|
||||
(user.ptychography.omny.samples)=
|
||||
### Sample storage and transfer
|
||||
|
||||
Following commands will provide help within BEC:
|
||||
- `omny.otransfer_help()` print help related to sample transfer
|
||||
- `dev.omny_samples.help()` print help related to sample storage
|
||||
|
||||
#### Managing sample storage
|
||||
|
||||
The sample holders used are [OMNY pins](https://www.dora.lib4ri.ch/psi/islandora/object/psi:4528). These are instsalled in sample transfer shuttles, which can load up to six pins. These shuttles are transferred via a vacuum load lock to the vacuum chamber. The loading procedure can be handled at room temperature or under cryogenic conditions.
|
||||
The thee __shuttles__ that exist are named __“A”, “B”, “C”__. The __pin positions__ within a shuttle are number __1 to 6__ according to the following sketch:
|
||||
|
||||
```{figure} omny_shuttle.png
|
||||
OMNY sample shuttle
|
||||
```
|
||||
|
||||
In addition to the shuttle positions, there are __fixed positions in OMNY__ which have numbers __larger than 10__. Such fixed positions are treated as system __“O”__.
|
||||
|
||||
Each shuttle can be placed in a __parking slot__ in OMNY. The parking slots are numbered as displayed below (oparkz slot). Slots 1 and 2 are at room temperature. Slots 3 to 6 are at cryogenic temperature.
|
||||
|
||||
```{figure} omny_parking.png
|
||||
OMNY parking station
|
||||
```
|
||||
|
||||
The status of the sample storage has to be correct in BEC. This means that the status of OMNY pins within OMNY ("O") as well as the shuttles has to be correct, the pin status within the shuttles ("A", "B", "C"), as well as the status of the shuttles within the OMNY parking.
|
||||
This loading status is handled via a OMNY samples device: `dev.omny_samples`
|
||||
|
||||
Within the BEC client session `dev.omny_samples.help()` will display all required commands with a short explanation.
|
||||
|
||||
To get an overview use `dev.omny_samples.show_all()` or `omny.otransfer_storage()`
|
||||
|
||||
Modify a slot position of systems "A", "B", "C", "O":
|
||||
`dev.omny_samples.unset_sample_slot('system',position)` free a sample position.
|
||||
`dev.omny_samples.set_sample_slot('system',position,'name')` set a sample position. The sample has to get a _name_.
|
||||
|
||||
There are two __special sample slots__:
|
||||
If a sample is in the __gripper__ and the information has to be manually changed use
|
||||
`dev.omny_samples.unset_sample_in_gripper()`
|
||||
`dev.omny_samples.set_sample_in_gripper('name')`
|
||||
|
||||
In the case of the sample stage position, the commands are
|
||||
`dev.omny_samples.unset_sample_in_samplestage()`
|
||||
`dev.omny_samples.set_sample_in_samplestage('name')`
|
||||
|
||||
The shuttles are mounted in the parking station. Typically oparkz slot 3 is used for shuttle A, slot 4 for shuttle B, slot 5 for shuttle C. If that status has to be modified, the following commands can be used:
|
||||
`dev.omny_samples.unset_shuttle_slot(slot_nr)`
|
||||
`dev.omny_samples.set_shuttle_slot(container, slot_nr)`
|
||||
Here is an _example_: dev.omny_samples.set_shuttle_slot('A',2)
|
||||
|
||||
#### Sample transfer
|
||||
|
||||
Once the sample places are set correctly and checked by using `omny.otransfer_storage()`, the following commands are available for sample change. To pick a sample from a parking slot, the parking slot stage has to be moved to the correct parking slot position. If a parking position is active, this information is displayed in sample storage overview.
|
||||
|
||||
| Command | Explanation |
|
||||
| --- | --- |
|
||||
| `omny.otransfer_help()` | print a brief help |
|
||||
| `omny.otransfer_park_slot(slot)` | drive the __parking station__ to place for sample transfer from _<slot>_ |
|
||||
| `omny.otransfer_park_loadlock_slot(slot)` | drive the __parking station__ to load _<slot>_ with the loadlock |
|
||||
| `omny.otransfer_get_sample(position)` | pick with the gripper from _<position>_ |
|
||||
| `omny.otransfer_put_sample(position)` | put with the gripper to _<position>_ |
|
||||
|
||||
For transfer the __sample stage__ is refered to as _position_ 0.
|
||||
|
||||
Advanced commands ... in case something goes wrong
|
||||
| Command | Explanation |
|
||||
| --- | --- |
|
||||
| `omny._otransfer_gripper_up()` | move gripper up |
|
||||
| `omny._otransfer_gripper_to_park_z()` | move gripper up and to parking position |
|
||||
| `omny._otransfer_ensure_shuttle_closed()` | close shuttle of parking station |
|
||||
| `omny._oshield_ST_close()` | close shield of sample stage |
|
||||
|
||||
When closing a shuttle of the shield, the gripper will be moved to the parking position prior closing.
|
||||
|
||||
### Status of OMNY
|
||||
|
||||
To see the status of the insrument, following commands can be used. Most of the components mentioned below are controlled via devices with naming starting with omny. TAB completion on dev.omny can be a quick way to find the commands.
|
||||
|
||||
#### Cameras
|
||||
|
||||
During operation the BEC GUI will show the relevant cameras or progress information. To manually switch view TAB completion on `omny.omnygui_` will show all options to control the GUI. Most useful
|
||||
|
||||
- `omny.omnygui_show_omnycam_parking()`
|
||||
- `omny.omnygui_show_omnycam_samplestage()`
|
||||
- `omny.omnygui_show_progress()`
|
||||
|
||||
#### Vacuum status
|
||||
|
||||
The status of the vacuum system of OMNY can be displayed by `omny.vcs_show_all()`.
|
||||
`omny.vcs_valves_in_measurement_position()` will report if all valves are in the correct position for X-ray beam to enter and propagate to the detector.
|
||||
|
||||
#### Temperatures
|
||||
|
||||
The status of all temperature measurements can be displayed by `omny.temperatures_show_all()`
|
||||
|
||||
It will display a table for the instrument and sample environment.
|
||||
|
||||
Example in warm state
|
||||
|
||||
| Channel | Name | Temperature | Setpoint | Unit | AlarmState |
|
||||
|---------|-----------------------|-------------|----------|-------|------------|
|
||||
| 8 | XEye Chamber | 22.60 | | degC | |
|
||||
| 9 | Kuehlsystem RT ZufOSA | 22.80 | 23.00 | degC | |
|
||||
| 10 | OSA_HaltZul_517 | 384.15 | | K | |
|
||||
| 16 | XEye Air | 22.60 | | degC | |
|
||||
| 17 | SampleShield_RT_440 | 23.00 | 23.00 | degC | |
|
||||
| 18 | DeltaA_RT | 26.00 | 26.00 | degC | |
|
||||
| 19 | DeltaB_RT | 26.00 | 26.00 | degC | |
|
||||
| 20 | DeltaC_RT | 26.00 | 26.00 | degC | |
|
||||
| 21 | Haube_ST_RT | 23.00 | 23.00 | degC | |
|
||||
| 22 | Delta_Basisplatte | 21.40 | | degC | |
|
||||
| 23 | InterfBridge | 22.50 | | degC | |
|
||||
| 24 | XEye Cam | 23.30 | | degC | |
|
||||
| 25 | OSA_HSupp_RT_403 | 25.00 | 25.00 | degC | |
|
||||
| 27 | OSA_Supp_RT_404 | 25.00 | 25.00 | degC | |
|
||||
| 28 | ST_Shield_1 | 384.15 | | K | Alarm |
|
||||
| 29 | ST_Shield_2 | 384.15 | | K | Alarm |
|
||||
| 30 | OSA_CoolConn_407 | 384.15 | | K | Alarm |
|
||||
| 31 | OSA_Holder_406 | 384.15 | | K | Alarm |
|
||||
| 35 | Gripper_Halter_460 | 25.40 | 25.00 | degC | |
|
||||
| 36 | Gripper_Flex_A | -8999.00 | 25.00 | degC | Alarm |
|
||||
| 37 | Gripper_Flex_B | 24.60 | 25.00 | degC | |
|
||||
| 38 | Gripper_A | 384.15 | | K | Alarm |
|
||||
| 39 | Gripper_B | 384.15 | | K | Alarm |
|
||||
| 41 | FZP | 30.00 | 30.00 | degC | |
|
||||
| 42 | Park_RT_A | 25.10 | 25.00 | degC | |
|
||||
| 44 | Park_RT_B | 25.30 | 25.00 | degC | |
|
||||
| 45 | BaseBlock | 21.00 | | degC | |
|
||||
| 46 | Park_Cryo_R | 384.15 | | K | Alarm |
|
||||
| 47 | Park_Cryo_L | 384.15 | | K | Alarm |
|
||||
|
||||
OMNY Cryo Temperature Controller
|
||||
|
||||
| Channel | Name | Temperature | Setpoint | Unit |
|
||||
|---------|-------|-------------|----------|------|
|
||||
| 1 | ChanA | 297.95 | 300.00 | K |
|
||||
| 2 | ChanB | 297.61 | 299.00 | K |
|
||||
| 3 | ChanC | 0.00 | 0.00 | K |
|
||||
| 4 | ChanD | 294.47 | 0.00 | K |
|
||||
Cryo controller is running in open loop.
|
||||
|
||||
ChanA and ChanD are sample temperatures, and ChanB is the bottom of the cryo link, meaning the head of the cryostat.
|
||||
|
||||
|
||||
#### Dewar
|
||||
|
||||
The status of the dewar and nitrogen flow can be displayed by `omny.dewar_show_all()`
|
||||
|
||||
## How to setup OMNY (software)
|
||||
|
||||
This part of the manual describes the software structure in more detail.
|
||||
|
||||
### start the realtime feedback loop and BEC with OMNY
|
||||
|
||||
The nano-positioning is controlled by a feedback loop running on a real-time linux based computer. With all related hardware connected, this loop has to be started manually.
|
||||
|
||||
1. Login to the computer by `ssh control@mpc3217`. The password is "engine".
|
||||
1. `cd OMNY/OMNY/`
|
||||
1. `./startOMNY`
|
||||
|
||||
Once the loop has started, it is possible to start bec with the OMNY configuration file.
|
||||
|
||||
Loading the OMNY configuration (this command will load the OMNY configuration only - isolated from the beamline)
|
||||
`bec.config.update_session_with_file("/bec/csaxs_bec/csaxs_bec/device_configs/flomni_config.yaml")`
|
||||
|
||||
Loading the OMNY scripts
|
||||
`from csaxs_bec.bec_ipython_client.plugins.omny import OMNY`
|
||||
`omny = OMNY(bec)`
|
||||
|
||||
If the realtime system is restarted, BEC will lose communication. To restart:
|
||||
`omny.rt_off()` … then wait a 10 seconds
|
||||
`omny.rt_on()`
|
||||
|
||||
### Initialization of the stages
|
||||
|
||||
The stages of OMNY are referenced in respect to their endswitches and reference marks. The stages have to be initialized at the beginning of a run or when the Galil motor controllers have been reset or restarted. To see the status of the stages following commands are available:
|
||||
|
||||
Show the status of all galil controllers (all stepper motor and rotation stage)
|
||||
`dev.osamx.controller.galil_show_all()`
|
||||
|
||||
In case referencing of the OMNY stages is required, run
|
||||
`omny.omny_init_stages(autoconfirm, autoretry)`
|
||||
|
||||
The process will regularly prompt the user for OK. At safe states this can be automatically done by setting _autoconfirm=1_.
|
||||
In case referencing fails, another attempt will be made after prompting the user. This can also be automatically done for certain number of times using the parameter autoretry.
|
||||
We typically use
|
||||
`omny.omny_init_stages(autoconfirm=1, autoretry=2)`
|
||||
|
||||
### Interferometer
|
||||
|
||||
If the realtime system is restarted, BEC will lose communication. To restart:
|
||||
`omny.rt_off()` … then wait a 10 seconds
|
||||
`omny.rt_on()`
|
||||
|
||||
To show the signal of the interferometers:
|
||||
`omny.show_signal_strength_interferometer()`
|
||||
Typical values with proper alignment, sample stage at the measurement position and laser tracker running are
|
||||
| Channel | Name | Value |
|
||||
|---------|-----------|----------|
|
||||
| 1 | OSA FZP Y | 5500 |
|
||||
| 2 | ST OSA Y | 2500 |
|
||||
| 3 | OSA FZP X | 4000 |
|
||||
| 4 | ST OSA X | 9000 |
|
||||
| 5 | Angle | 2500 |
|
||||
|
||||
|
||||
#### Laser tracker commands
|
||||
|
||||
The horizontal interferometer is built according to the [tracking interferometer](https://www.dora.lib4ri.ch/psi/islandora/object/psi:7524). The tracker can be controlled by following commands. During commissioning of the setup it is worthy to check the status, but during general operation these commands should not be required.
|
||||
|
||||
- `omny.laser_tracker_show_all()`
|
||||
- `omny.laser_tracker_on()`
|
||||
- `omny.laser_tracker_off()`
|
||||
|
||||
When the PSD signal of the tracker (PSD not signalstrength!) is too low, enabling the laser tracker will not be successful. One can use `omny.interferometer_tweak_otrack()` to manually tweak the coarse stages of the tracker. Once signal is reached the tracker can be enabled. This should only be required during commissioning of OMNY.
|
||||
|
||||
#### Interferometer alignment
|
||||
|
||||
Several mirrors in OMNY are motorized. Aligning the interferometer can thus be done via software. To enter alignment mode use
|
||||
`omny.interferometer_tweaking()`
|
||||
Select the channel by using number keys __1 to 7__ and the __arrow keys__ to tweak.
|
||||
The tweaking mode can be exited by pressing __q to quit__.
|
||||
Some mirrors are regularly automatically aligned, such as the horizontal mirror of the OSA. This automatic alignment can also be manually executed by `omny.omny_interferometer_align_tracking()`
|
||||
|
||||
#### Interferometer feedback commands
|
||||
|
||||
The closed loop control of the Piezo stages can be controlled by
|
||||
- `omny.feedback_enable_with_reset()`
|
||||
_There is also an enable without reset, which is used during tomography scans, when using coarse stages to increase the scan range. It should not be required to use manually._
|
||||
- `omny.feedback_disable()`
|
||||
- `omny.feedback_status()`
|
||||
|
||||
|
||||
### X-ray optics alignment, near-field and far-field ptychography
|
||||
|
||||
The positions of the optics stages are stored as stage parameters and are thus linked to the configuration file.
|
||||
Example: The OSAx “in” position can be reviewed by `dev.oosax.user_parameter`
|
||||
Update the value by (example "oosax", "in") by `dev.oosax.update_user_parameter({"in":value})`
|
||||
|
||||
For __near-field__ and __far-field__ separate optics parameters are stored. Example:
|
||||
dev.oosax.user_parameter returns {'near_field_in': 3.2044, 'far_field_in': 3.022}
|
||||
Update the value by (example "oosax", "near_field_in")
|
||||
dev.oosax.update_user_parameter({"near_field_in":value})
|
||||
|
||||
The __global variable omny.near_field__ controls whether near- or far-field settings are used. To switch `omny.near-field=False` or `omny.near-field=True`.
|
||||
|
||||
`omny.ofzp_info()` shows info about the available FZPs at the current energy of the beamline. Optional parameter energy in keV to get values at a different energy.
|
||||
Example: `omny.ofzp_info(6.2)`
|
||||
|
||||
__Laser feedback will be disabled and thus fine alignment lost if commands are used that move optics stages!__
|
||||
|
||||
Following functions exist to move the optics in and out, with self-explaining naming.
|
||||
- `omny.optics_in()`
|
||||
- `omny.ofzp_in()`
|
||||
- `omny.ofzp_out()`
|
||||
- `omny.oosa_in()`
|
||||
- `omny.oosa_out()`
|
||||
- `omny.oosa_move_out_of_shield()`
|
||||
|
||||
#### OMNY Fermat scan
|
||||
|
||||
The basic scan function can be called by `scans.omny_fermat_scan()` and offers a detailed doc string for further details (`scans.omny_fermat_scan?`). A prerequisite for scanning is a running feedback system. The scan has following parameters.
|
||||
|
||||
| Parameters | |
|
||||
| --- | --- |
|
||||
| fovx (float) | Fov in the piezo plane (i.e. piezo range). Max 200 um |
|
||||
| fovy (float) | Fov in the piezo plane (i.e. piezo range). Max 100 um |
|
||||
| cenx (float) | center position in x |
|
||||
| ceny (float) | center position in y |
|
||||
| exp_time (float) | exposure time |
|
||||
| step (float) | stepsize |
|
||||
| zshift (float) | shift in z |
|
||||
| angle (float) | rotation angle (will rotate first) |
|
||||
| corridor_size (float) | corridor size for the corridor optimization. Default 3 um |
|
||||
|
||||
Example:
|
||||
`scans.omny_fermat_scan(fovx=20, fovy=25, cenx=0.02, ceny=0, zshift=0, angle=0, step=0.5, exp_time=0.01)`
|
||||
|
||||
#### Overview of the alignment steps
|
||||
|
||||
There are several corrections applied to maintain the sample in the FOV:
|
||||
1. Mirror calibration
|
||||
1. X-ray eye alignment
|
||||
1. Ptychography fine alignment (improvement of the X-ray eye alignment step)
|
||||
1. Vertical shifts from tomography reconstruction (for very small vertical FOV)
|
||||
|
||||
#### XrayEye and sample alignment
|
||||
|
||||
Within a usual work-flow the movement of the X-ray eye is mostly moved automatically to the correct position. For manual movements use
|
||||
| Command | Explanation |
|
||||
| --- | --- |
|
||||
| omny.oeye_xray_in() | move to the fluorescense microscope in |
|
||||
| omny.oeye_cam_in() | move the camera showing the samplestage from downstream in |
|
||||
| omny.oeye_out() | move out, X-rays can reach the X-ray detector |
|
||||
|
||||
The _in_ and _out_ positions are stored as user parameters in the stage definition. Get the values by
|
||||
`dev.oeyex.user_parameter`
|
||||
`dev.oeyey.user_parameter`
|
||||
|
||||
Update the values by, example for oeyex and in position
|
||||
`dev.oeyex.update_user_parameter({"xray_in":value})`
|
||||
|
||||
To refresh the frame of the xray eye windows software
|
||||
`omny.xrayeye_update_frame()`
|
||||
|
||||
To start the xray eye alignment (and clear any previous alignment)
|
||||
`omny.xrayeye_alignment_start()`
|
||||
|
||||
To load the fit parameters from directory _dir_path_ computed by _SPEC_ptycho_align.m_ in Matlab run
|
||||
`omny.read_alignment_offset(dir_path='',setup="omny")`
|
||||
|
||||
To load from a specific directory, specify it as parameter. Example:
|
||||
`omny.read_alignment_offset(dir_path="/bec/align",setup="omny")`
|
||||
|
||||
The loading routine uses default values for the vertical alignment for setup. This behavior can be changed (e.g. for getting new default values) by the parameter `use_vertical_default_values=False`.
|
||||
|
||||
At each projection, the angular dependent is computed by
|
||||
`omny.get_alignment_offset(angle)`, with _angle_ in degrees.
|
||||
|
||||
The alignment can be cleared by
|
||||
`omny.reset_tomo_alignment_fit()`
|
||||
|
||||
#### Fine alignment
|
||||
|
||||
The alginment obtained by the X-ray eye can be refinde by recording ptychography projections at 45 deg. intervals. For this, adjust the tomo parameters by
|
||||
`omny.tomo_parameters()`
|
||||
|
||||
Next, run the alignment scan by
|
||||
`omny.tomo_alignment_scan()`
|
||||
|
||||
Reconstruct the scan and use SPEC_ptycho_align.m to obtain improved fit parameters. The new parameters can be loaded by
|
||||
`omny.read_alignment_offset()`
|
||||
|
||||
For a __very__ tight vertical field of view, a fine vertical alignment based on outputs generated from early tomography reconstructions can be used. A corresponding file can be generated by the tomography reconstruction script and can be loaded by the following two methods:
|
||||
`omny.read_additional_correction_y()`
|
||||
`omny.read_additional_correction_y2()`
|
||||
One __important__ note: The first method is by default loading a mirror correction file automatically. If the tomogram is using that data, do not overwrite it, use the secondary correction instead.
|
||||
|
||||
The scan offsets are computed at each projection by
|
||||
`omny.compute_additional_correction_y(angle)`
|
||||
`omny.compute_additional_correction_y2(angle)`
|
||||
|
||||
The additional correct can be __reset__ by
|
||||
`omny.reset_correction()`
|
||||
It will automatically load the default mirror correction file as primary correction! To reset and not load any correction, which might be useful to obtain a new default correction file, run
|
||||
`omny.reset_correction(use_default_correction=False)`
|
||||
|
||||
#### Scanning of projections
|
||||
|
||||
At any stage of the alignment process it is possible to scan a projection.
|
||||
|
||||
Define the scan parameters by `omny.tomo_parameters()`
|
||||
|
||||
Run a scan at _angle_ (in degrees, 0 to 180) by `omny.tomo_scan_projection(angle)`
|
||||
|
||||
### Tomography
|
||||
|
||||
The tomo parameters have to be set by
|
||||
`omny.tomo_parameters()`
|
||||
|
||||
Once satisfied with the alignment, the tomography scan can be started by
|
||||
`omny.tomo_scan()`
|
||||
|
||||
Three modes for angular sampling are implemented and they have different optional parameters for the tomo_scan method:
|
||||
| tomography mode | parameters and defaults |
|
||||
| --- | --- |
|
||||
| 2 sub-tomograms | subtomo_start=1, start_angle=None |
|
||||
| Golden ratio tomography (sorted in bunches) | projection_number=None |
|
||||
| Equally spaced with golden starting angle | projection_number=None |
|
||||
|
||||
The parameters can be used to __restart an interrupted acquisition__.
|
||||
In case of eight equally spaced sub-tomograms, an individual sub tomogram can be scanned by flomni.sub_tomo_scan(subtomo_number, start_angle). If the start angle is not specified, it will be computed depending on the subtomo_number, which is ranging from 1 to 2.
|
||||
|
||||
__Mechanical wear is an issue with lifetime of dry vacuum stages. Thus for standard acquisitions that do not have VERY strong arguments that require a different mode, two sub-tomograms has to be performed.__
|
||||
BIN
docs/user/ptychography/omny_parking.png
Normal file
BIN
docs/user/ptychography/omny_parking.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 307 KiB |
BIN
docs/user/ptychography/omny_shuttle.png
Normal file
BIN
docs/user/ptychography/omny_shuttle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
72
docs/user/ptychography/ptychography.md
Normal file
72
docs/user/ptychography/ptychography.md
Normal file
@@ -0,0 +1,72 @@
|
||||
(user.ptychography)=
|
||||
# Ptychography
|
||||
Welcome to the ptychography section of the cSAXS beamline.
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
maxdepth: 2
|
||||
hidden: true
|
||||
---
|
||||
|
||||
flomni/
|
||||
lamni/
|
||||
omny/
|
||||
reconstructions/
|
||||
|
||||
```
|
||||
|
||||
|
||||
***
|
||||
|
||||
````{grid} 2
|
||||
:gutter: 5
|
||||
|
||||
```{grid-item-card}
|
||||
:link: user.ptychography.flomni
|
||||
:link-type: ref
|
||||
:img-top: /assets/biotech.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## flOMNI
|
||||
|
||||
All about the flOMNI instrument
|
||||
```
|
||||
|
||||
```{grid-item-card}
|
||||
:link: user.ptychography.lamni
|
||||
:link-type: ref
|
||||
:img-top: /assets/biotech.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## LamNI
|
||||
|
||||
All about the LamNI instrument
|
||||
```
|
||||
|
||||
```{grid-item-card}
|
||||
:link: user.ptychography.omny
|
||||
:link-type: ref
|
||||
:img-top: /assets/biotech.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## OMNY
|
||||
|
||||
All about the OMNY instrument
|
||||
```
|
||||
|
||||
```{grid-item-card}
|
||||
:link: user.ptychography.reconstructions
|
||||
:link-type: ref
|
||||
:img-top: /assets/receipt_long.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## Ptychoshelves
|
||||
|
||||
All about ptychography reconstructions
|
||||
```
|
||||
|
||||
````
|
||||
4
docs/user/ptychography/reconstructions.md
Normal file
4
docs/user/ptychography/reconstructions.md
Normal file
@@ -0,0 +1,4 @@
|
||||
(user.ptychography.reconstructions)=
|
||||
# Ptychoshelves
|
||||
|
||||
Check it out [here](https://www.dora.lib4ri.ch/psi/islandora/object/psi%3A31264).
|
||||
5
docs/user/saxs/saxs.md
Normal file
5
docs/user/saxs/saxs.md
Normal file
@@ -0,0 +1,5 @@
|
||||
(user.saxs)=
|
||||
# Saxs
|
||||
|
||||
|
||||
## Beamtime allocation
|
||||
59
docs/user/user.md
Normal file
59
docs/user/user.md
Normal file
@@ -0,0 +1,59 @@
|
||||
(user)=
|
||||
# User
|
||||
Welcome to the User section of the cSAXS beamline.
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
maxdepth: 2
|
||||
hidden: true
|
||||
---
|
||||
|
||||
before_you_arrive/before_you_arrive.md
|
||||
ptychography/ptychography.md
|
||||
saxs/saxs.md
|
||||
|
||||
```
|
||||
|
||||
|
||||
***
|
||||
|
||||
````{grid} 2
|
||||
:gutter: 5
|
||||
|
||||
```{grid-item-card}
|
||||
:link: user.before_you_arrive
|
||||
:link-type: ref
|
||||
:img-top: /assets/receipt_long.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## Before you arrive
|
||||
|
||||
Learn what to do before you arrive to the beamline.
|
||||
```
|
||||
|
||||
```{grid-item-card}
|
||||
:link: user.ptychography
|
||||
:link-type: ref
|
||||
:img-top: /assets/biotech.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## Ptychography
|
||||
|
||||
All about ptychography measurements and reconstructions.
|
||||
```
|
||||
|
||||
```{grid-item-card}
|
||||
:link: user.saxs
|
||||
:link-type: ref
|
||||
:img-top: /assets/biotech.svg
|
||||
:text-align: center
|
||||
:class-item: index-card
|
||||
|
||||
## SAXS
|
||||
|
||||
All about SAXS measurements and analysis.
|
||||
```
|
||||
|
||||
````
|
||||
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
||||
[project]
|
||||
name = "csaxs_bec"
|
||||
version = "0.0.0"
|
||||
description = "Custom device implementations based on the ophyd hardware abstraction layer"
|
||||
description = "The cSAXS plugin repository for BEC"
|
||||
requires-python = ">=3.10"
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
@@ -18,26 +18,31 @@ dependencies = [
|
||||
"bec_server",
|
||||
"ophyd_devices",
|
||||
"std_daq_client",
|
||||
"jfjoch-client",
|
||||
"rich",
|
||||
"pyepics",
|
||||
"pyueye", # for the IDS uEye camera
|
||||
"bec_widgets",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"black",
|
||||
"copier",
|
||||
"isort",
|
||||
"coverage",
|
||||
"pylint",
|
||||
"pytest",
|
||||
"pytest-random-order",
|
||||
"pytest-redis",
|
||||
"ophyd_devices",
|
||||
"bec_server",
|
||||
]
|
||||
|
||||
[project.entry-points."bec"]
|
||||
plugin_bec = "csaxs_bec"
|
||||
|
||||
[project.entry-points."bec.deployment.device_server"]
|
||||
plugin_ds_startup = "csaxs_bec.deployment.device_server.startup:run"
|
||||
plugin_ds_startup = "csaxs_bec.deployments.device_server.startup:run"
|
||||
|
||||
[project.entry-points."bec.file_writer"]
|
||||
plugin_file_writer = "csaxs_bec.file_writer"
|
||||
@@ -45,12 +50,18 @@ plugin_file_writer = "csaxs_bec.file_writer"
|
||||
[project.entry-points."bec.scans"]
|
||||
plugin_scans = "csaxs_bec.scans"
|
||||
|
||||
[project.entry-points."bec.scans.metadata_schema"]
|
||||
plugin_metadata_schema = "csaxs_bec.scans.metadata_schema"
|
||||
|
||||
[project.entry-points."bec.ipython_client_startup"]
|
||||
plugin_ipython_client_pre = "csaxs_bec.bec_ipython_client.startup.pre_startup"
|
||||
plugin_ipython_client_post = "csaxs_bec.bec_ipython_client.startup"
|
||||
|
||||
[project.entry-points."bec.widgets"]
|
||||
plugin_widgets = "csaxs_bec.bec_widgets"
|
||||
[project.entry-points."bec.widgets.auto_updates"]
|
||||
plugin_widgets_update = "csaxs_bec.bec_widgets.auto_updates"
|
||||
|
||||
[project.entry-points."bec.widgets.user_widgets"]
|
||||
plugin_widgets = "csaxs_bec.bec_widgets.widgets"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
include = ["*"]
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
# Getting Started with Testing using pytest
|
||||
|
||||
BEC is using the [pytest](https://docs.pytest.org/en/8.0.x/) framework.
|
||||
It can be install via
|
||||
``` bash
|
||||
BEC is using the [pytest](https://docs.pytest.org/en/latest/) framework.
|
||||
It can be installed via
|
||||
|
||||
```bash
|
||||
pip install pytest
|
||||
```
|
||||
in your *python environment*.
|
||||
|
||||
in your _python environment_.
|
||||
We note that pytest is part of the optional-dependencies `[dev]` of the plugin package.
|
||||
|
||||
## Introduction
|
||||
|
||||
Tests in this package should be stored in the `tests` directory.
|
||||
We suggest to sort tests of different submodules, i.e. `scans` or `devices` in the respective folder structure, and to folow a naming convention of `<test_module_name.py>`.
|
||||
It is mandatory for test files to begin with `test_` for pytest to discover them.
|
||||
|
||||
To run all tests, navigate to the directory of the plugin from the command line, and run the command
|
||||
To run all tests, navigate to the directory of the plugin from the command line, and run the command
|
||||
|
||||
``` bash
|
||||
```bash
|
||||
pytest -v --random-order ./tests
|
||||
```
|
||||
|
||||
Note, the python environment needs to be active.
|
||||
The additional arg `-v` allows pytest to run in verbose mode which provides more detailed information about the tests being run.
|
||||
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
|
||||
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
|
||||
|
||||
## Test examples
|
||||
|
||||
Writing tests can be quite specific for the given function.
|
||||
Writing tests can be quite specific for the given function.
|
||||
We recommend writing tests as isolated as possible, i.e. try to test single functions instead of full classes.
|
||||
A very useful class to enable isolated testing is [MagicMock](https://docs.python.org/3/library/unittest.mock.html).
|
||||
In addition, we also recommend to take a look at the [How-to guides from pytest](https://docs.pytest.org/en/8.0.x/how-to/index.html).
|
||||
|
||||
|
||||
@@ -28,7 +28,10 @@ class RTMock(DeviceBase):
|
||||
|
||||
def test_save_frame(bec_client_mock):
|
||||
client = bec_client_mock
|
||||
client.device_manager.devices.xeye = DeviceBase(name="xeye", config={})
|
||||
client.device_manager.devices.xeye = DeviceBase(
|
||||
name="xeye",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
lamni = LamNI(client)
|
||||
align = XrayEyeAlign(client, lamni)
|
||||
with mock.patch(
|
||||
@@ -43,7 +46,10 @@ def test_update_frame(bec_client_mock):
|
||||
epics_get = "csaxs_bec.bec_ipython_client.plugins.LamNI.x_ray_eye_align.epics_get"
|
||||
fshopen = "csaxs_bec.bec_ipython_client.plugins.LamNI.x_ray_eye_align.fshopen"
|
||||
client = bec_client_mock
|
||||
client.device_manager.devices.xeye = DeviceBase(name="xeye", config={})
|
||||
client.device_manager.devices.xeye = DeviceBase(
|
||||
name="xeye",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
lamni = LamNI(client)
|
||||
align = XrayEyeAlign(client, lamni)
|
||||
with mock.patch(epics_put) as epics_put_mock:
|
||||
@@ -64,10 +70,16 @@ def test_update_frame(bec_client_mock):
|
||||
|
||||
def test_disable_rt_feedback(bec_client_mock):
|
||||
client = bec_client_mock
|
||||
client.device_manager.devices.xeye = DeviceBase(name="xeye", config={})
|
||||
client.device_manager.devices.xeye = DeviceBase(
|
||||
name="xeye",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
lamni = LamNI(client)
|
||||
align = XrayEyeAlign(client, lamni)
|
||||
client.device_manager.devices.rtx = RTMock(name="rtx", config={})
|
||||
client.device_manager.devices.rtx = RTMock(
|
||||
name="rtx",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
with mock.patch.object(
|
||||
align.device_manager.devices.rtx.controller, "feedback_disable"
|
||||
) as fdb_disable:
|
||||
@@ -77,10 +89,16 @@ def test_disable_rt_feedback(bec_client_mock):
|
||||
|
||||
def test_enable_rt_feedback(bec_client_mock):
|
||||
client = bec_client_mock
|
||||
client.device_manager.devices.xeye = DeviceBase(name="xeye", config={})
|
||||
client.device_manager.devices.xeye = DeviceBase(
|
||||
name="xeye",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
lamni = LamNI(client)
|
||||
align = XrayEyeAlign(client, lamni)
|
||||
client.device_manager.devices.rtx = RTMock(name="rtx", config={})
|
||||
client.device_manager.devices.rtx = RTMock(
|
||||
name="rtx",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
with mock.patch.object(
|
||||
align.device_manager.devices.rtx.controller, "feedback_enable_with_reset"
|
||||
) as fdb_enable:
|
||||
@@ -96,10 +114,16 @@ def test_tomo_rotate(bec_client_mock):
|
||||
client._update_namespace_callback = mock.MagicMock()
|
||||
client.callbacks = mock.MagicMock()
|
||||
client.load_high_level_interface("bec_hli")
|
||||
client.device_manager.devices.xeye = DeviceBase(name="xeye", config={})
|
||||
client.device_manager.devices.xeye = DeviceBase(
|
||||
name="xeye",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
lamni = LamNI(client)
|
||||
align = XrayEyeAlign(client, lamni)
|
||||
client.device_manager.devices.lsamrot = RTMock(name="lsamrot", config={})
|
||||
client.device_manager.devices.lsamrot = RTMock(
|
||||
name="lsamrot",
|
||||
config={"enabled": True, "deviceClass": "test_class", "readoutPriority": "baseline"},
|
||||
)
|
||||
with mock.patch.object(builtins, "umv") as umv:
|
||||
align.tomo_rotate(5)
|
||||
umv.assert_called_once_with(client.device_manager.devices.lsamrot, 5)
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
# Getting Started with Testing using pytest
|
||||
|
||||
BEC is using the [pytest](https://docs.pytest.org/en/8.0.x/) framework.
|
||||
It can be install via
|
||||
``` bash
|
||||
BEC is using the [pytest](https://docs.pytest.org/en/latest/) framework.
|
||||
It can be installed via
|
||||
|
||||
```bash
|
||||
pip install pytest
|
||||
```
|
||||
in your *python environment*.
|
||||
|
||||
in your _python environment_.
|
||||
We note that pytest is part of the optional-dependencies `[dev]` of the plugin package.
|
||||
|
||||
## Introduction
|
||||
|
||||
Tests in this package should be stored in the `tests` directory.
|
||||
We suggest to sort tests of different submodules, i.e. `scans` or `devices` in the respective folder structure, and to folow a naming convention of `<test_module_name.py>`.
|
||||
It is mandatory for test files to begin with `test_` for pytest to discover them.
|
||||
|
||||
To run all tests, navigate to the directory of the plugin from the command line, and run the command
|
||||
To run all tests, navigate to the directory of the plugin from the command line, and run the command
|
||||
|
||||
``` bash
|
||||
```bash
|
||||
pytest -v --random-order ./tests
|
||||
```
|
||||
|
||||
Note, the python environment needs to be active.
|
||||
The additional arg `-v` allows pytest to run in verbose mode which provides more detailed information about the tests being run.
|
||||
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
|
||||
The argument `--random-order` instructs pytest to run the tests in random order, which is the default in the CI pipelines.
|
||||
|
||||
## Test examples
|
||||
|
||||
Writing tests can be quite specific for the given function.
|
||||
Writing tests can be quite specific for the given function.
|
||||
We recommend writing tests as isolated as possible, i.e. try to test single functions instead of full classes.
|
||||
A very useful class to enable isolated testing is [MagicMock](https://docs.python.org/3/library/unittest.mock.html).
|
||||
In addition, we also recommend to take a look at the [How-to guides from pytest](https://docs.pytest.org/en/8.0.x/how-to/index.html).
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user