Compare commits
1 Commits
refactor/m
...
update_bl_
| Author | SHA1 | Date | |
|---|---|---|---|
| cc2e0ecaa3 |
@@ -1,9 +0,0 @@
|
||||
# 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.2.2
|
||||
_src_path: https://github.com/bec-project/plugin_copier_template.git
|
||||
make_commit: false
|
||||
project_name: csaxs_bec
|
||||
widget_plugins_input: []
|
||||
@@ -1,3 +0,0 @@
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
semantic-release changelog -D version_variable=$SCRIPT_DIR/../../semantic_release/__init__.py:__version__
|
||||
semantic-release version -D version_variable=$SCRIPT_DIR/../../semantic_release/__init__.py:__version__
|
||||
@@ -1,3 +1,2 @@
|
||||
black --line-length=100 $(git diff --cached --name-only --diff-filter=ACM -- '*.py')
|
||||
isort --line-length=100 --profile=black --multi-line=3 --trailing-comma $(git diff --cached --name-only --diff-filter=ACM -- '*.py')
|
||||
git add $(git diff --cached --name-only --diff-filter=ACM -- '*.py')
|
||||
black --line-length=100 $(git diff --cached --name-only --diff-filter=ACM)
|
||||
git add $(git diff --cached --name-only --diff-filter=ACM)
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
name: CI for csaxs_bec
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
BEC_WIDGETS_BRANCH:
|
||||
description: "Branch of BEC Widgets to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
BEC_CORE_BRANCH:
|
||||
description: "Branch of BEC Core to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
OPHYD_DEVICES_BRANCH:
|
||||
description: "Branch of Ophyd Devices to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
BEC_PLUGIN_REPO_BRANCH:
|
||||
description: "Branch of the BEC Plugin Repository to install"
|
||||
required: false
|
||||
type: string
|
||||
default: "main"
|
||||
PYTHON_VERSION:
|
||||
description: "Python version to use"
|
||||
required: false
|
||||
type: string
|
||||
default: "3.11"
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
QTWEBENGINE_DISABLE_SANDBOX: 1
|
||||
QT_QPA_PLATFORM: "offscreen"
|
||||
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "${{ inputs.PYTHON_VERSION || '3.11' }}"
|
||||
|
||||
- name: Checkout BEC Core
|
||||
run: git clone --depth 1 --branch "${{ inputs.BEC_CORE_BRANCH || 'main' }}" https://github.com/bec-project/bec.git ./bec
|
||||
|
||||
- name: Checkout Ophyd Devices
|
||||
run: git clone --depth 1 --branch "${{ inputs.OPHYD_DEVICES_BRANCH || 'main' }}" https://github.com/bec-project/ophyd_devices.git ./ophyd_devices
|
||||
|
||||
- name: Checkout BEC Widgets
|
||||
run: git clone --depth 1 --branch "${{ inputs.BEC_WIDGETS_BRANCH || 'main' }}" https://github.com/bec-project/bec_widgets.git ./bec_widgets
|
||||
|
||||
- name: Checkout BEC Plugin Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: bec/csaxs_bec
|
||||
ref: "${{ inputs.BEC_PLUGIN_REPO_BRANCH || github.head_ref || github.sha }}"
|
||||
path: ./csaxs_bec
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgl1 libegl1 x11-utils libxkbcommon-x11-0 libdbus-1-3 xvfb
|
||||
sudo apt-get -y install libnss3 libxdamage1 libasound2t64 libatomic1 libxcursor1
|
||||
|
||||
- name: Install Python dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
pip install uv
|
||||
uv pip install --system -e ./ophyd_devices
|
||||
uv pip install --system -e ./bec/bec_lib[dev]
|
||||
uv pip install --system -e ./bec/bec_ipython_client
|
||||
uv pip install --system -e ./bec/bec_server[dev]
|
||||
uv pip install --system -e ./bec_widgets[dev,pyside6]
|
||||
uv pip install --system -e ./csaxs_bec
|
||||
|
||||
- name: Run Pytest with Coverage
|
||||
id: coverage
|
||||
run: pytest --random-order --cov=./csaxs_bec --cov-config=./csaxs_bec/pyproject.toml --cov-branch --cov-report=xml --no-cov-on-fail ./csaxs_bec/tests/ || test $? -eq 5
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,9 +8,6 @@
|
||||
**/.pytest_cache
|
||||
**/*.egg*
|
||||
|
||||
# recovery_config files
|
||||
recovery_config_*
|
||||
|
||||
# file writer data
|
||||
**.h5
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
include:
|
||||
- project: bec/awi_utils
|
||||
file: /templates/plugin-repo-template.yml
|
||||
inputs:
|
||||
name: "csaxs"
|
||||
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/
|
||||
@@ -1,29 +0,0 @@
|
||||
# .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
29
LICENSE
@@ -1,29 +0,0 @@
|
||||
|
||||
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.
|
||||
69
README.md
69
README.md
@@ -6,12 +6,15 @@ You might want to run cSAXS copy scripts before in case you want to have the for
|
||||
|
||||
## Overview
|
||||
|
||||
- Clone cSAXS BEC repository into e-account (e.g. into ~/Data10/software/.)
|
||||
- Start Epics iocs
|
||||
- Start BEC, BEC server and load/modify the device config with relevant hardware
|
||||
- BEC commands
|
||||
1. Clone cSAXS BEC repository into e-account (e.g. into ~/Data10/software/.)
|
||||
2. Install BEC
|
||||
3. Start Epics iocs
|
||||
4. Start BEC, BEC server and load/modify the device config with relevant hardware
|
||||
5. BEC commands
|
||||
6. Start BEC widgets (GUI for motor control, eiger live plot)
|
||||
7. Troubleshooting and common problems
|
||||
|
||||
## Clone cSAXS BEC repository
|
||||
## 1. Clone cSAXS BEC repository
|
||||
|
||||
Clone the current cSAXS BEC repository from GIT into the new e-account.
|
||||
Create directory
|
||||
@@ -21,9 +24,19 @@ cd ~/Data10/software
|
||||
```
|
||||
Clone repository
|
||||
```bash
|
||||
git clone https://gitlab.psi.ch/bec/csaxs_bec.git
|
||||
git clone https://gitlab.psi.ch/bec/csaxs-bec.git
|
||||
```
|
||||
## Start epics iocs
|
||||
|
||||
## 2. Install BEC
|
||||
|
||||
There is a bash sript in the followin directory.
|
||||
Go to the directory and run the script on pc15543 logged in as the e-account (BEC server):
|
||||
```bash
|
||||
ssh pc15543
|
||||
cd ~/Data10/software/csaxs-bec/bin/
|
||||
./setup_bec.sh
|
||||
```
|
||||
## 3. Start epics iocs
|
||||
|
||||
You can start up the iocs while the *./setup_bec.sh* script is running. Be aware though that the scripts requires you to interact with it.
|
||||
|
||||
@@ -81,7 +94,7 @@ iocsh -7.0.6 startup.script
|
||||
```
|
||||
Be aware -7.0.6 is referring to the current epics version and might change in future (SLS 2.0)
|
||||
|
||||
## Start BEC, BEC server and load device config
|
||||
## 4. Start BEC, BEC server and load device config
|
||||
|
||||
Step 1 needs to have finished for continuing with these steps.
|
||||
What remains now is to start the bec server. Connect to pc15543 and open a new terminal to run:
|
||||
@@ -114,7 +127,7 @@ bec.config.save_current_session('~/Data10/software/current_config.yaml')
|
||||
```
|
||||
The second command is helpful if you adjust limits of motors, which will then be stored in the config and loaded if a reload of the configuration is needed.
|
||||
|
||||
## BEC commands
|
||||
## 5. BEC commands
|
||||
|
||||
A number of commands that are useful:
|
||||
|
||||
@@ -134,3 +147,41 @@ scans.line_scan(dev.samx, -1, 1, dev.samy, -1, 1, steps=20, exp_time=0.5, readou
|
||||
scans.sgalil_grid(start_y = , end_y = , interval_y = , start_x=, end_x=, interval_x =, exp_time=0.5, readout_time=3e-3, relative=True)
|
||||
```
|
||||
|
||||
## 6. Start BEC widgets (GUI for motor control, eiger live plot)
|
||||
|
||||
To start the BEC widgets, the first step is to make the bec_widgets_venv using the start startup script.
|
||||
Follow the commands below:
|
||||
``` bash
|
||||
cd ~/Data10/software/csaxs-bec/bin
|
||||
./setup_bec_widgets.sh
|
||||
```
|
||||
Afterwards, activate the environment on either cons-01 comp-1/2
|
||||
``` bash
|
||||
cd ~/Data10/software/
|
||||
source activate bec_widgets_venv/bin/activate
|
||||
```
|
||||
Each Plot needs their own shell with activate environment
|
||||
|
||||
1. Eiger Plot
|
||||
``` bash
|
||||
cd ~/Data10/software/bec-widgets/bec_widgets/examples/eiger_plot
|
||||
python eiger_plot.py
|
||||
```
|
||||
2. Motor Controller
|
||||
``` bash
|
||||
cd ~/Data10/software/bec-widgets/bec_widgets/examples/motor_movement
|
||||
python motor_example.py --config csaxs_config.yaml
|
||||
```
|
||||
|
||||
## 7. Troubleshooting and common problems
|
||||
|
||||
Sometimes the data backend for the Eiger gets stuck or misses frames, this will result in an error
|
||||
``` python
|
||||
raise EigerTimeoutError(
|
||||
ophyd_devices.epics.devices.eiger9m_csaxs.EigerTimeoutError: Reached timeout with detector state 1, std_daq state FINISHED and received frames of 100 for the file writer)
|
||||
```
|
||||
This happens more likely after CTRL C of a scan. To recover from this more reliably, perform the an acquisition in burst mode with 100 frames, little exposure until no error message is raised after. This can be up to 3 times from former experience.
|
||||
``` bash
|
||||
scans.acquire(exp_time=0.02, frames_per_trigger=100, readout_time= 3e-3)
|
||||
```
|
||||
Afterwards, you should be good to continue with 2D gridscans.
|
||||
|
||||
1
bec_plugins/__init__.py
Normal file
1
bec_plugins/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .bec_client import *
|
||||
1
bec_plugins/bec_client/__init__.py
Normal file
1
bec_plugins/bec_client/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .plugins import *
|
||||
245
bec_plugins/bec_client/high_level_interface/spec_hli.py
Normal file
245
bec_plugins/bec_client/high_level_interface/spec_hli.py
Normal file
@@ -0,0 +1,245 @@
|
||||
from bec_lib.devicemanager import Device
|
||||
from bec_lib.scan_report import ScanReport
|
||||
|
||||
# pylint:disable=undefined-variable
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
def dscan(
|
||||
motor1: Device, m1_from: float, m1_to: float, steps: int, exp_time: float, **kwargs
|
||||
) -> ScanReport:
|
||||
"""Relative line scan with one device.
|
||||
|
||||
Args:
|
||||
motor1 (Device): Device that should be scanned.
|
||||
m1_from (float): Start position relative to the current position.
|
||||
m1_to (float): End position relative to the current position.
|
||||
steps (int): Number of steps.
|
||||
exp_time (float): Exposure time.
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> dscan(dev.motor1, -5, 5, 10, 0.1)
|
||||
"""
|
||||
return scans.line_scan(
|
||||
motor1, m1_from, m1_to, steps=steps, exp_time=exp_time, relative=True, **kwargs
|
||||
)
|
||||
|
||||
|
||||
def d2scan(
|
||||
motor1: Device,
|
||||
m1_from: float,
|
||||
m1_to: float,
|
||||
motor2: Device,
|
||||
m2_from: float,
|
||||
m2_to: float,
|
||||
steps: int,
|
||||
exp_time: float,
|
||||
**kwargs
|
||||
) -> ScanReport:
|
||||
"""Relative line scan with two devices.
|
||||
|
||||
Args:
|
||||
motor1 (Device): First device that should be scanned.
|
||||
m1_from (float): Start position of the first device relative to its current position.
|
||||
m1_to (float): End position of the first device relative to its current position.
|
||||
motor2 (Device): Second device that should be scanned.
|
||||
m2_from (float): Start position of the second device relative to its current position.
|
||||
m2_to (float): End position of the second device relative to its current position.
|
||||
steps (int): Number of steps.
|
||||
exp_time (float): Exposure time
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> d2scan(dev.motor1, -5, 5, dev.motor2, -8, 8, 10, 0.1)
|
||||
"""
|
||||
return scans.line_scan(
|
||||
motor1,
|
||||
m1_from,
|
||||
m1_to,
|
||||
motor2,
|
||||
m2_from,
|
||||
m2_to,
|
||||
steps=steps,
|
||||
exp_time=exp_time,
|
||||
relative=True,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
def ascan(motor1, m1_from, m1_to, steps, exp_time, **kwargs):
|
||||
"""Absolute line scan with one device.
|
||||
|
||||
Args:
|
||||
motor1 (Device): Device that should be scanned.
|
||||
m1_from (float): Start position.
|
||||
m1_to (float): End position.
|
||||
steps (int): Number of steps.
|
||||
exp_time (float): Exposure time.
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> ascan(dev.motor1, -5, 5, 10, 0.1)
|
||||
"""
|
||||
return scans.line_scan(
|
||||
motor1, m1_from, m1_to, steps=steps, exp_time=exp_time, relative=False, **kwargs
|
||||
)
|
||||
|
||||
|
||||
def a2scan(motor1, m1_from, m1_to, motor2, m2_from, m2_to, steps, exp_time, **kwargs):
|
||||
"""Absolute line scan with two devices.
|
||||
|
||||
Args:
|
||||
motor1 (Device): First device that should be scanned.
|
||||
m1_from (float): Start position of the first device.
|
||||
m1_to (float): End position of the first device.
|
||||
motor2 (Device): Second device that should be scanned.
|
||||
m2_from (float): Start position of the second device.
|
||||
m2_to (float): End position of the second device.
|
||||
steps (int): Number of steps.
|
||||
exp_time (float): Exposure time
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> a2scan(dev.motor1, -5, 5, dev.motor2, -8, 8, 10, 0.1)
|
||||
"""
|
||||
return scans.line_scan(
|
||||
motor1,
|
||||
m1_from,
|
||||
m1_to,
|
||||
motor2,
|
||||
m2_from,
|
||||
m2_to,
|
||||
steps=steps,
|
||||
exp_time=exp_time,
|
||||
relative=False,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
def dmesh(motor1, m1_from, m1_to, m1_steps, motor2, m2_from, m2_to, m2_steps, exp_time, **kwargs):
|
||||
"""Relative mesh scan (grid scan) with two devices.
|
||||
|
||||
Args:
|
||||
motor1 (Device): First device that should be scanned.
|
||||
m1_from (float): Start position of the first device relative to its current position.
|
||||
m1_to (float): End position of the first device relative to its current position.
|
||||
m1_steps (int): Number of steps for motor1.
|
||||
motor2 (Device): Second device that should be scanned.
|
||||
m2_from (float): Start position of the second device relative to its current position.
|
||||
m2_to (float): End position of the second device relative to its current position.
|
||||
m2_steps (int): Number of steps for motor2.
|
||||
exp_time (float): Exposure time
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> dmesh(dev.motor1, -5, 5, 10, dev.motor2, -8, 8, 10, 0.1)
|
||||
"""
|
||||
return scans.grid_scan(
|
||||
motor1,
|
||||
m1_from,
|
||||
m1_to,
|
||||
m1_steps,
|
||||
motor2,
|
||||
m2_from,
|
||||
m2_to,
|
||||
m2_steps,
|
||||
exp_time=exp_time,
|
||||
relative=True,
|
||||
)
|
||||
|
||||
|
||||
def amesh(motor1, m1_from, m1_to, m1_steps, motor2, m2_from, m2_to, m2_steps, exp_time, **kwargs):
|
||||
"""Absolute mesh scan (grid scan) with two devices.
|
||||
|
||||
Args:
|
||||
motor1 (Device): First device that should be scanned.
|
||||
m1_from (float): Start position of the first device.
|
||||
m1_to (float): End position of the first device.
|
||||
m1_steps (int): Number of steps for motor1.
|
||||
motor2 (Device): Second device that should be scanned.
|
||||
m2_from (float): Start position of the second device.
|
||||
m2_to (float): End position of the second device.
|
||||
m2_steps (int): Number of steps for motor2.
|
||||
exp_time (float): Exposure time
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> amesh(dev.motor1, -5, 5, 10, dev.motor2, -8, 8, 10, 0.1)
|
||||
"""
|
||||
return scans.grid_scan(
|
||||
motor1,
|
||||
m1_from,
|
||||
m1_to,
|
||||
m1_steps,
|
||||
motor2,
|
||||
m2_from,
|
||||
m2_to,
|
||||
m2_steps,
|
||||
exp_time=exp_time,
|
||||
relative=False,
|
||||
)
|
||||
|
||||
|
||||
def umv(*args) -> ScanReport:
|
||||
"""Updated absolute move (i.e. blocking) for one or more devices.
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> umv(dev.samx, 1)
|
||||
>>> umv(dev.samx, 1, dev.samy, 2)
|
||||
"""
|
||||
return scans.umv(*args, relative=False)
|
||||
|
||||
|
||||
def umvr(*args) -> ScanReport:
|
||||
"""Updated relative move (i.e. blocking) for one or more devices.
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> umvr(dev.samx, 1)
|
||||
>>> umvr(dev.samx, 1, dev.samy, 2)
|
||||
"""
|
||||
return scans.umv(*args, relative=True)
|
||||
|
||||
|
||||
def mv(*args) -> ScanReport:
|
||||
"""Absolute move for one or more devices.
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> mv(dev.samx, 1)
|
||||
>>> mv(dev.samx, 1, dev.samy, 2)
|
||||
"""
|
||||
return scans.mv(*args, relative=False)
|
||||
|
||||
|
||||
def mvr(*args) -> ScanReport:
|
||||
"""Relative move for one or more devices.
|
||||
|
||||
Returns:
|
||||
ScanReport: Status object.
|
||||
|
||||
Examples:
|
||||
>>> mvr(dev.samx, 1)
|
||||
>>> mvr(dev.samx, 1, dev.samy, 2)
|
||||
"""
|
||||
return scans.mv(*args, relative=True)
|
||||
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
2
bec_plugins/bec_client/plugins/LamNI/__init__.py
Normal file
2
bec_plugins/bec_client/plugins/LamNI/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .load_additional_correction import lamni_read_additional_correction
|
||||
from .x_ray_eye_align import LamNI, XrayEyeAlign, MagLamNI, DataDrivenLamNI
|
||||
269
bec_plugins/bec_client/plugins/LamNI/bl_show_all.mac
Normal file
269
bec_plugins/bec_client/plugins/LamNI/bl_show_all.mac
Normal file
@@ -0,0 +1,269 @@
|
||||
def bl_show_all '{
|
||||
local gap
|
||||
|
||||
printf("beamline status at %s:\n",date())
|
||||
|
||||
if (!_bl_hall_temperature_ok()) {
|
||||
bl_hall_temperature
|
||||
printf("\n")
|
||||
}
|
||||
|
||||
if (_bl_sls_status_unusual()) {
|
||||
bl_sls_status
|
||||
} else {
|
||||
bl_ring_current
|
||||
}
|
||||
bl_chk_beam _show
|
||||
printf("\n")
|
||||
|
||||
printf("U19 ID gap : ",gap)
|
||||
gap = _id_get_gap_mm()
|
||||
if (gap >= 8) {
|
||||
text_bf
|
||||
}
|
||||
printf("%.3f mm\n",gap)
|
||||
text_non_bf
|
||||
|
||||
if (!_id_loss_rate_ok()) {
|
||||
id_loss_rate
|
||||
}
|
||||
|
||||
bl_shutter_status
|
||||
|
||||
if (_bl_cvd_filter_open()) {
|
||||
text_bf
|
||||
printf("CVD diamond filter : open / out\n")
|
||||
text_non_bf
|
||||
}
|
||||
|
||||
if (!_bl_xbox_valve_es1_open()) {
|
||||
bl_xbox_valve_es1 _show
|
||||
}
|
||||
|
||||
if (_bl_ln2_non_standard()) {
|
||||
text_bf
|
||||
printf("\nNon standard liquid nitrogen cooling-warning parameters occur. Please report this to your local contact.\n")
|
||||
text_non_bf
|
||||
printf("The macro bl_ln2_warn can be used to control this e-mail warning feature.\n")
|
||||
bl_ln2_warn "show"
|
||||
printf("\n")
|
||||
}
|
||||
|
||||
printf("\n")
|
||||
bl_flight_tube_pressure
|
||||
printf("\n")
|
||||
|
||||
bl_attended _show
|
||||
|
||||
_bl_check_alarm_records(1,1)
|
||||
|
||||
printf("\n")
|
||||
bl_op_msg
|
||||
}'
|
||||
|
||||
|
||||
def _bl_hall_temperature_ok() '{
|
||||
local temp_ok
|
||||
local stat
|
||||
|
||||
temp_ok = 1
|
||||
|
||||
# EH T02 average temperature
|
||||
stat = epics_get("ILUUL-02AV:TEMP")
|
||||
if ((stat < 23.0) || (stat > 26.0)) {
|
||||
temp_ok = 0
|
||||
}
|
||||
|
||||
# EH T02 temperature at T0204 axis 16
|
||||
stat = epics_get("ILUUL-0200-EB104:TEMP")
|
||||
if ((stat < 23.0) || (stat > 26.0)) {
|
||||
temp_ok = 0
|
||||
}
|
||||
|
||||
# EH T02 temperature at T0205 axis 18
|
||||
stat = epics_get("ILUUL-0200-EB105:TEMP")
|
||||
if ((stat < 23.0) || (stat > 26.0)) {
|
||||
temp_ok = 0
|
||||
}
|
||||
|
||||
return (temp_ok)
|
||||
}'
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def bl_hall_temperature '{
|
||||
local stat
|
||||
|
||||
stat = epics_get("ILUUL-02AV:TEMP")
|
||||
printf("hall T02 average temperature : ")
|
||||
if ((stat < 23.0) || (stat > 25.0)) {
|
||||
text_bf
|
||||
}
|
||||
printf("%.2f deg.C\n",stat)
|
||||
text_non_bf
|
||||
|
||||
stat = epics_get("ILUUL-0200-EB104:TEMP")
|
||||
printf("hall temperature at T0204 axis 16 : ")
|
||||
if ((stat < 23) || (stat > 25)) {
|
||||
text_bf
|
||||
}
|
||||
printf("%.2f deg.C\n",stat)
|
||||
text_non_bf
|
||||
|
||||
stat = epics_get("ILUUL-0200-EB105:TEMP")
|
||||
printf("hall temperature at T0205 axis 18 : ")
|
||||
if ((stat < 23) || (stat > 25)) {
|
||||
text_bf
|
||||
}
|
||||
printf("%.2f deg.C\n",stat)
|
||||
text_non_bf
|
||||
|
||||
# stat = epics_get("ILUUL-0300-EB102:TEMP")
|
||||
# printf("EH T03 temperature at T0302 axis 21: ")
|
||||
# if ((stat < 23) || (stat > 25)) {
|
||||
# text_bf
|
||||
# }
|
||||
# printf("%.2f deg.C\n",stat)
|
||||
# text_non_bf
|
||||
|
||||
}'
|
||||
|
||||
def _bl_sls_status_unusual() '{
|
||||
local unusual
|
||||
local stat
|
||||
|
||||
unusual = 0
|
||||
|
||||
stat = epics_get("X12SA-SR-VAC:SETPOINT")
|
||||
if (stat != "OK") {
|
||||
unusual = 1
|
||||
}
|
||||
|
||||
stat = epics_get("ACOAU-ACCU:OP-MODE.VAL")
|
||||
if ((stat != "Light Available") && (stat != "Light-Available")) {
|
||||
unusual = 1
|
||||
}
|
||||
|
||||
stat = epics_get("ALIRF-GUN:INJ-MODE")
|
||||
if (stat != "TOP-UP") {
|
||||
unusual = 1
|
||||
}
|
||||
|
||||
# current threshold
|
||||
stat = epics_get("ALIRF-GUN:CUR-LOWLIM")
|
||||
if (stat < 350) {
|
||||
unusual = 1
|
||||
}
|
||||
|
||||
# current deadband
|
||||
stat = epics_get("ALIRF-GUN:CUR-DBAND")
|
||||
if (stat > 2) {
|
||||
unusual = 1
|
||||
}
|
||||
|
||||
# orbit feedback mode
|
||||
stat = epics_get("ARIDI-BPM:OFB-MODE")
|
||||
if (stat != "fast") {
|
||||
unusual = 1
|
||||
}
|
||||
|
||||
# fast orbit feedback
|
||||
stat = epics_get("ARIDI-BPM:FOFBSTATUS-G")
|
||||
if (stat != "running") {
|
||||
unusual = 1
|
||||
}
|
||||
|
||||
return(unusual)
|
||||
}'
|
||||
|
||||
def bl_sls_status '{
|
||||
local stat
|
||||
|
||||
stat = epics_get("ACOAU-ACCU:OP-MODE.VAL")
|
||||
printf("SLS status : ")
|
||||
if ((stat != "Light Available") && (stat != "Light-Available")) {
|
||||
text_bf
|
||||
}
|
||||
printf("%s\n",stat)
|
||||
text_non_bf
|
||||
|
||||
stat = epics_get("ALIRF-GUN:INJ-MODE")
|
||||
printf("SLS injection mode : ")
|
||||
if (stat != "TOP-UP") {
|
||||
text_bf
|
||||
}
|
||||
printf("%s\n",stat)
|
||||
text_non_bf
|
||||
|
||||
stat = epics_get("ALIRF-GUN:CUR-LOWLIM")
|
||||
printf("SLS current threshold : ")
|
||||
if (stat < 350) {
|
||||
text_bf
|
||||
}
|
||||
printf("%7.3f\n",stat)
|
||||
text_non_bf
|
||||
|
||||
stat = epics_get("ALIRF-GUN:CUR-DBAND")
|
||||
printf("SLS current deadband : ")
|
||||
if (stat > 2) {
|
||||
text_bf
|
||||
}
|
||||
printf("%7.3f\n",stat)
|
||||
text_non_bf
|
||||
|
||||
stat = epics_get("ACORF-FILL:PAT-SELECT")
|
||||
printf("SLS filling pattern : ")
|
||||
printf("%s\n",stat)
|
||||
|
||||
bl_ring_current
|
||||
|
||||
stat = epics_get("ARIDI-PCT:TAU-HOUR")
|
||||
printf("SLS filling life time : ")
|
||||
printf("%.2f h\n",stat)
|
||||
|
||||
stat = epics_get("ARIDI-BPM:OFB-MODE")
|
||||
printf("orbit feedback mode : ")
|
||||
if (stat != "fast") {
|
||||
text_bf
|
||||
}
|
||||
printf("%s\n",stat)
|
||||
text_non_bf
|
||||
|
||||
stat = epics_get("ARIDI-BPM:FOFBSTATUS-G")
|
||||
printf("fast orbit feedback : ")
|
||||
if (stat != "running") {
|
||||
text_bf
|
||||
}
|
||||
printf("%s\n",stat)
|
||||
text_non_bf
|
||||
|
||||
}'
|
||||
|
||||
def _bl_get_ring_current() '{
|
||||
return epics_get("ARIDI-PCT:CURRENT")
|
||||
}'
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def _bl_no_ring_current() '{
|
||||
# set an arbitrary current limit of 100mA as no-beam limit
|
||||
if (_bl_get_ring_current() < 100) {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}'
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def bl_ring_current '{
|
||||
local curr
|
||||
|
||||
curr = _bl_get_ring_current()
|
||||
|
||||
if (curr < 300) {
|
||||
text_bf
|
||||
}
|
||||
printf("SLS ring current : %.3f mA\n",curr)
|
||||
text_non_bf
|
||||
}'
|
||||
161
bec_plugins/bec_client/plugins/LamNI/lamni_optics_mixin.py
Normal file
161
bec_plugins/bec_client/plugins/LamNI/lamni_optics_mixin.py
Normal file
@@ -0,0 +1,161 @@
|
||||
import builtins
|
||||
import time
|
||||
|
||||
from rich import box
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
from bec_client.plugins.cSAXS import epics_get, epics_put, fshclose
|
||||
|
||||
# import builtins to avoid linter errors
|
||||
dev = builtins.__dict__.get("dev")
|
||||
umv = builtins.__dict__.get("umv")
|
||||
bec = builtins.__dict__.get("bec")
|
||||
|
||||
|
||||
class LamNIOpticsMixin:
|
||||
@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 leye_out(self):
|
||||
self.loptics_in()
|
||||
fshclose()
|
||||
leyey_out = self._get_user_param_safe("leyey", "out")
|
||||
umv(dev.leyey, leyey_out)
|
||||
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 2)
|
||||
# move rotation stage to zero to avoid problems with wires
|
||||
umv(dev.lsamrot, 0)
|
||||
umv(dev.dttrz, 5854, dev.fttrz, 2395)
|
||||
|
||||
def leye_in(self):
|
||||
bec.queue.next_dataset_number += 1
|
||||
# move rotation stage to zero to avoid problems with wires
|
||||
umv(dev.lsamrot, 0)
|
||||
umv(dev.dttrz, 6419.677, dev.fttrz, 2959.979)
|
||||
while True:
|
||||
moved_out = (input("Did the flight tube move out? (Y/n)") or "y").lower()
|
||||
if moved_out == "y":
|
||||
break
|
||||
if moved_out == "n":
|
||||
return
|
||||
leyex_in = self._get_user_param_safe("leyex", "in")
|
||||
leyey_in = self._get_user_param_safe("leyey", "in")
|
||||
umv(dev.leyex, leyex_in, dev.leyey, leyey_in)
|
||||
self.align.update_frame()
|
||||
|
||||
def _lfzp_in(self):
|
||||
loptx_in = self._get_user_param_safe("loptx", "in")
|
||||
lopty_in = self._get_user_param_safe("lopty", "in")
|
||||
umv(
|
||||
dev.loptx, loptx_in, dev.lopty, lopty_in
|
||||
) # for 7.2567 keV and 150 mu, 60 nm fzp, loptz 83.6000 for propagation 1.4 mm
|
||||
|
||||
def lfzp_in(self):
|
||||
"""
|
||||
move in the lamni zone plate.
|
||||
This will disable rt feedback, move the FZP and re-enabled the feedback.
|
||||
"""
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
|
||||
self._lfzp_in()
|
||||
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def loptics_in(self):
|
||||
"""
|
||||
Move in the lamni optics, including the FZP and the OSA.
|
||||
"""
|
||||
self.lfzp_in()
|
||||
self.losa_in()
|
||||
|
||||
def loptics_out(self):
|
||||
"""Move out the lamni optics"""
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
|
||||
# self.lcs_out()
|
||||
self.losa_out()
|
||||
loptx_out = self._get_user_param_safe("loptx", "out")
|
||||
lopty_out = self._get_user_param_safe("lopty", "out")
|
||||
umv(dev.loptx, loptx_out, dev.lopty, lopty_out)
|
||||
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
time.sleep(1)
|
||||
dev.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def lcs_in(self):
|
||||
# umv lcsx -1.852 lcsy -0.095
|
||||
pass
|
||||
|
||||
def lcs_out(self):
|
||||
umv(dev.lcsy, 3)
|
||||
|
||||
def losa_in(self):
|
||||
# 6.2 keV, 170 um FZP
|
||||
# umv(dev.losax, -1.4450000, dev.losay, -0.1800)
|
||||
# umv(dev.losaz, -1)
|
||||
# 6.7, 170
|
||||
# umv(dev.losax, -1.4850, dev.losay, -0.1930)
|
||||
# umv(dev.losaz, 1.0000)
|
||||
# 7.2, 150
|
||||
losax_in = self._get_user_param_safe("losax", "in")
|
||||
losay_in = self._get_user_param_safe("losay", "in")
|
||||
losaz_in = self._get_user_param_safe("losaz", "in")
|
||||
umv(dev.losax, losax_in, dev.losay, losay_in)
|
||||
umv(dev.losaz, losaz_in)
|
||||
# 11 kev
|
||||
# umv(dev.losax, -1.161000, dev.losay, -0.196)
|
||||
# umv(dev.losaz, 1.0000)
|
||||
|
||||
def losa_out(self):
|
||||
losay_out = self._get_user_param_safe("losay", "out")
|
||||
losaz_out = self._get_user_param_safe("losaz", "out")
|
||||
umv(dev.losaz, losaz_out)
|
||||
umv(dev.losay, losay_out)
|
||||
|
||||
def lfzp_info(self):
|
||||
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:",
|
||||
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
|
||||
beam_size = (
|
||||
-diameter / (focal_distance * 1000) * (focal_distance * 1000 - distance) * 1e6
|
||||
)
|
||||
table.add_row(
|
||||
f"{diameter*1e6:.2f} microns",
|
||||
f"{focal_distance:.2f} mm",
|
||||
f"{beam_size:.2f} microns",
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
print("OSA Information:")
|
||||
# print(f"Current losaz %.1f\n", A[losaz])
|
||||
# print("The OSA will collide with the sample plane at %.1f\n\n", 89.3-A[loptz])
|
||||
print(
|
||||
"The numbers presented here are for a sample in the plane of the lamni sample holder.\n"
|
||||
)
|
||||
23
bec_plugins/bec_client/plugins/LamNI/load_additional_correction.py
Executable file
23
bec_plugins/bec_client/plugins/LamNI/load_additional_correction.py
Executable file
@@ -0,0 +1,23 @@
|
||||
def lamni_read_additional_correction():
|
||||
# "additional_correction_shift"
|
||||
# [0][] x , [1][] y, [2][] angle, [3][0] number of elements
|
||||
import numpy as np
|
||||
|
||||
with open("correction_lamni_um_S01405_.txt", "r") as f:
|
||||
num_elements = f.readline()
|
||||
int_num_elements = int(num_elements.split(" ")[2])
|
||||
print(int_num_elements)
|
||||
corr_pos_x = []
|
||||
corr_pos_y = []
|
||||
corr_angle = []
|
||||
for j in range(0, int_num_elements * 3):
|
||||
line = f.readline()
|
||||
value = line.split(" ")[2]
|
||||
name = line.split(" ")[0].split("[")[0]
|
||||
if name == "corr_pos_x":
|
||||
corr_pos_x.append(value)
|
||||
elif name == "corr_pos_y":
|
||||
corr_pos_y.append(value)
|
||||
elif name == "corr_angle":
|
||||
corr_angle.append(value)
|
||||
return (corr_pos_x, corr_pos_y, corr_angle, num_elements)
|
||||
1332
bec_plugins/bec_client/plugins/LamNI/x_ray_eye_align.py
Normal file
1332
bec_plugins/bec_client/plugins/LamNI/x_ray_eye_align.py
Normal file
File diff suppressed because it is too large
Load Diff
3
bec_plugins/bec_client/plugins/__init__.py
Normal file
3
bec_plugins/bec_client/plugins/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .cSAXS import *
|
||||
|
||||
# from .LamNI import *
|
||||
1
bec_plugins/bec_client/plugins/cSAXS/__init__.py
Normal file
1
bec_plugins/bec_client/plugins/cSAXS/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .cSAXS_beamline import fshopen, fshclose, fshstatus, epics_get, epics_put
|
||||
@@ -1,9 +1,10 @@
|
||||
import builtins
|
||||
|
||||
from bec_ipython_client.beamline_mixin import BeamlineShowInfo
|
||||
from rich import box
|
||||
from rich.table import Table
|
||||
|
||||
from bec_client.beamline_mixin import BeamlineShowInfo
|
||||
|
||||
|
||||
class BeamlineInfo(BeamlineShowInfo):
|
||||
def show(self):
|
||||
@@ -16,13 +16,14 @@ parse the --session argument, add the following lines to the script:
|
||||
|
||||
if args.session == "my_session":
|
||||
print("Loading my_session session")
|
||||
from bec_plugins.bec_ipython_client.plugins.my_session import *
|
||||
from bec_plugins.bec_client.plugins.my_session import *
|
||||
else:
|
||||
print("Loading default session")
|
||||
from bec_plugins.bec_ipython_client.plugins.default_session import *
|
||||
from bec_plugins.bec_client.plugins.default_session import *
|
||||
"""
|
||||
|
||||
# pylint: disable=invalid-name, unused-import, import-error, undefined-variable, unused-variable, unused-argument, no-name-in-module
|
||||
import argparse
|
||||
|
||||
from bec_lib import bec_logger
|
||||
|
||||
@@ -30,39 +31,46 @@ logger = bec_logger.logger
|
||||
|
||||
logger.info("Using the cSAXS startup script.")
|
||||
|
||||
# pylint: disable=import-error
|
||||
_args = _main_dict["args"]
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--session", help="Session name", type=str, default="cSAXS")
|
||||
args = parser.parse_args()
|
||||
|
||||
_session_name = "cSAXS"
|
||||
if _args.session.lower() == "lamni":
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import *
|
||||
from csaxs_bec.bec_ipython_client.plugins.LamNI import *
|
||||
if args.session == "LamNI":
|
||||
print("Loading LamNI session")
|
||||
from bec_plugins.bec_client.plugins.cSAXS import *
|
||||
from bec_plugins.bec_client.plugins.LamNI import *
|
||||
|
||||
_session_name = "LamNI"
|
||||
lamni = LamNI(bec)
|
||||
logger.success("LamNI session loaded.")
|
||||
|
||||
elif _args.session.lower() == "csaxs":
|
||||
elif args.session == "cSAXS":
|
||||
print("Loading cSAXS session")
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import *
|
||||
|
||||
logger.success("cSAXS session loaded.")
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.tool_box.debug_tools import DebugTools
|
||||
|
||||
debug = DebugTools()
|
||||
logger.success("Debug tools loaded. Use 'debug' to access them.")
|
||||
from bec_plugins.bec_client.plugins.cSAXS import *
|
||||
|
||||
|
||||
# SETUP BEAMLINE INFO
|
||||
from bec_ipython_client.plugins.SLS.sls_info import OperatorInfo, SLSInfo
|
||||
from bec_client.plugins.SLS.sls_info import OperatorInfo, SLSInfo
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS.beamline_info import BeamlineInfo
|
||||
from bec_plugins.bec_client.plugins.cSAXS.beamline_info import BeamlineInfo
|
||||
|
||||
bec._beamline_mixin._bl_info_register(BeamlineInfo)
|
||||
bec._beamline_mixin._bl_info_register(SLSInfo)
|
||||
bec._beamline_mixin._bl_info_register(OperatorInfo)
|
||||
|
||||
# SETUP PROMPTS
|
||||
bec._ip.prompts.session_name = _session_name
|
||||
bec._ip.prompts.username = args.session
|
||||
bec._ip.prompts.status = 1
|
||||
|
||||
|
||||
# REGISTER BEAMLINE CHECKS
|
||||
from bec_lib.bl_conditions import (
|
||||
FastOrbitFeedbackCondition,
|
||||
LightAvailableCondition,
|
||||
ShutterCondition,
|
||||
)
|
||||
|
||||
# _fast_orbit_feedback_condition = FastOrbitFeedbackCondition(dev.sls_fast_orbit_feedback)
|
||||
_light_available_condition = LightAvailableCondition(dev.sls_machine_status)
|
||||
_shutter_condition = ShutterCondition(dev.x12sa_es1_shutter_status)
|
||||
# bec.bl_checks.register(_fast_orbit_feedback_condition)
|
||||
bec.bl_checks.register(_light_available_condition)
|
||||
bec.bl_checks.register(_shutter_condition)
|
||||
25
bec_plugins/bec_client/startup/pre_startup.py
Normal file
25
bec_plugins/bec_client/startup/pre_startup.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
Pre-startup script for BEC client. This script is executed before the BEC client
|
||||
is started. It can be used to set up the BEC client configuration. The script is
|
||||
executed in the global namespace of the BEC client. This means that all
|
||||
variables defined here are available in the BEC client.
|
||||
|
||||
To set up the BEC client configuration, use the ServiceConfig class. For example,
|
||||
to set the configuration file path, add the following lines to the script:
|
||||
|
||||
import pathlib
|
||||
from bec_lib import ServiceConfig
|
||||
|
||||
current_path = pathlib.Path(__file__).parent.resolve()
|
||||
CONFIG_PATH = f"{current_path}/<path_to_my_config_file.yaml>"
|
||||
|
||||
config = ServiceConfig(CONFIG_PATH)
|
||||
|
||||
If this startup script defined a ServiceConfig object, the BEC client will use
|
||||
it to configure itself. Otherwise, the BEC client will use the default config.
|
||||
"""
|
||||
|
||||
# example:
|
||||
# current_path = pathlib.Path(__file__).parent.resolve()
|
||||
# CONFIG_PATH = f"{current_path}/../../../bec_config.yaml"
|
||||
# config = ServiceConfig(CONFIG_PATH)
|
||||
2742
bec_plugins/device_configs/bec_device_config_sastt.yaml
Executable file
2742
bec_plugins/device_configs/bec_device_config_sastt.yaml
Executable file
File diff suppressed because it is too large
Load Diff
3027
bec_plugins/device_configs/config_session_start_e20632.yaml
Normal file
3027
bec_plugins/device_configs/config_session_start_e20632.yaml
Normal file
File diff suppressed because it is too large
Load Diff
3056
bec_plugins/device_configs/e21125_lamni_config.yaml
Normal file
3056
bec_plugins/device_configs/e21125_lamni_config.yaml
Normal file
File diff suppressed because it is too large
Load Diff
152
bec_plugins/device_configs/lamni_config.py
Normal file
152
bec_plugins/device_configs/lamni_config.py
Normal file
@@ -0,0 +1,152 @@
|
||||
import yaml
|
||||
|
||||
# TODO: fix imports, those classes are located in .../bec/scibec/init_scibec/configs/config.py
|
||||
# (see also lamni_config.py in bec repository)
|
||||
from .config import DemoConfig, X12SAConfig
|
||||
|
||||
|
||||
class LamNIConfig(DemoConfig, X12SAConfig):
|
||||
def run(self):
|
||||
# self.write_galil_motors()
|
||||
# self.write_rt_motors()
|
||||
# self.write_smaract_motors()
|
||||
# self.write_eiger1p5m()
|
||||
self.write_x12sa_status()
|
||||
self.write_sls_status()
|
||||
self.load_csaxs_config()
|
||||
# self.write_sim_user_motors()
|
||||
# self.write_sim_beamline_motors()
|
||||
# self.write_sim_beamline_monitors()
|
||||
|
||||
def write_galil_motors(self):
|
||||
lamni_galil_motors = [
|
||||
("lsamx", "A", -1, 0.5, {"center": 8.768000}),
|
||||
("lsamy", "B", 1, 0.5, {"center": 10.041000}),
|
||||
("lsamrot", "C", 1, 0.5, {}),
|
||||
("loptz", "D", -1, 0.5, {}),
|
||||
("loptx", "E", 1, 0.5, {"in": -0.8380, "out": -0.699}),
|
||||
("lopty", "F", 1, 0.5, {"in": 3.3540, "out": 3.53}),
|
||||
("leyex", "G", -1, 0.001, {"in": 14.117000}),
|
||||
("leyey", "H", -1, 0.001, {"in": 48.069000, "out": 0.5}),
|
||||
]
|
||||
out = {}
|
||||
for m in lamni_galil_motors:
|
||||
out[m[0]] = dict(
|
||||
{
|
||||
"status": {"enabled": True, "enabled_set": True},
|
||||
"deviceClass": "GalilMotor",
|
||||
"deviceConfig": {
|
||||
"axis_Id": m[1],
|
||||
"name": m[0],
|
||||
"labels": m[0],
|
||||
"host": "mpc2680.psi.ch",
|
||||
"port": 8081,
|
||||
"sign": m[2],
|
||||
"limits": [0, 0],
|
||||
"tolerance": m[3],
|
||||
"device_access": True,
|
||||
"device_mapping": {"rt": "rtx"},
|
||||
},
|
||||
"acquisitionConfig": {
|
||||
"schedule": "sync",
|
||||
"acquisitionGroup": "motor",
|
||||
"readoutPriority": "baseline",
|
||||
},
|
||||
"deviceTags": ["lamni"],
|
||||
}
|
||||
)
|
||||
if m[4]:
|
||||
out[m[0]]["userParameter"] = m[4]
|
||||
self.write_section(out, "LamNI Galil motors")
|
||||
|
||||
def write_rt_motors(self):
|
||||
lamni_rt_motors = [
|
||||
("rtx", "A", 1),
|
||||
("rty", "B", 1),
|
||||
]
|
||||
out = dict()
|
||||
for m in lamni_rt_motors:
|
||||
out[m[0]] = dict(
|
||||
{
|
||||
"status": {"enabled": True, "enabled_set": True},
|
||||
"deviceClass": "RtLamniMotor",
|
||||
"deviceConfig": {
|
||||
"axis_Id": m[1],
|
||||
"name": m[0],
|
||||
"labels": m[0],
|
||||
"host": "mpc2680.psi.ch",
|
||||
"port": 3333,
|
||||
"limits": [0, 0],
|
||||
"sign": m[2],
|
||||
"device_access": True,
|
||||
},
|
||||
"acquisitionConfig": {
|
||||
"schedule": "sync",
|
||||
"acquisitionGroup": "motor",
|
||||
"readoutPriority": "baseline",
|
||||
},
|
||||
"deviceTags": ["lamni"],
|
||||
}
|
||||
)
|
||||
self.write_section(out, "LamNI RT")
|
||||
|
||||
def write_smaract_motors(self):
|
||||
lamni_smaract_motors = [
|
||||
("losax", "A", -1, {"in": -0.848000}),
|
||||
("losay", "B", -1, {"in": 0.135000, "out": 3.8}),
|
||||
("losaz", "C", 1, {"in": -1, "out": -3}),
|
||||
("lcsx", "D", -1, {}),
|
||||
("lcsy", "E", -1, {}),
|
||||
]
|
||||
out = dict()
|
||||
for m in lamni_smaract_motors:
|
||||
out[m[0]] = dict(
|
||||
{
|
||||
"status": {"enabled": True, "enabled_set": True},
|
||||
"deviceClass": "SmaractMotor",
|
||||
"deviceConfig": {
|
||||
"axis_Id": m[1],
|
||||
"name": m[0],
|
||||
"labels": m[0],
|
||||
"host": "mpc2680.psi.ch",
|
||||
"port": 8085,
|
||||
"limits": [0, 0],
|
||||
"sign": m[2],
|
||||
"tolerance": 0.05,
|
||||
},
|
||||
"acquisitionConfig": {
|
||||
"schedule": "sync",
|
||||
"acquisitionGroup": "motor",
|
||||
"readoutPriority": "baseline",
|
||||
},
|
||||
"deviceTags": ["lamni"],
|
||||
}
|
||||
)
|
||||
if m[3]:
|
||||
out[m[0]]["userParameter"] = m[3]
|
||||
self.write_section(out, "LamNI SmarAct motors")
|
||||
|
||||
def write_eiger1p5m(self):
|
||||
out = {
|
||||
"eiger1p5m": {
|
||||
"description": "Eiger 1.5M in vacuum detector, in-house developed, PSI",
|
||||
"status": {"enabled": True, "enabled_set": True},
|
||||
"deviceClass": "Eiger1p5MDetector",
|
||||
"deviceConfig": {"device_access": True, "name": "eiger1p5m"},
|
||||
"acquisitionConfig": {
|
||||
"schedule": "sync",
|
||||
"acquisitionGroup": "detector",
|
||||
"readoutPriority": "monitored",
|
||||
},
|
||||
"deviceTags": ["detector"],
|
||||
}
|
||||
}
|
||||
self.write_section(out, "LamNI Eiger 1.5M in vacuum")
|
||||
|
||||
def load_csaxs_config(self):
|
||||
CONFIG_PATH = "./init_scibec/configs/test_config_cSAXS.yaml"
|
||||
content = {}
|
||||
with open(CONFIG_PATH, "r") as csaxs_config_file:
|
||||
content = yaml.safe_load(csaxs_config_file.read())
|
||||
|
||||
self.write_section(content, "Default cSAXS config")
|
||||
2326
bec_plugins/device_configs/test_config_cSAXS.yaml
Normal file
2326
bec_plugins/device_configs/test_config_cSAXS.yaml
Normal file
File diff suppressed because it is too large
Load Diff
11
bec_plugins/device_server/startup.py
Normal file
11
bec_plugins/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()
|
||||
@@ -23,10 +23,9 @@ but they are executed in a specific order:
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from bec_lib import bec_logger
|
||||
from bec_lib.endpoints import MessageEndpoints
|
||||
from bec_server.scan_server.errors import ScanAbortion
|
||||
from bec_server.scan_server.scans import RequestBase, ScanArgType, ScanBase
|
||||
from bec_lib import MessageEndpoints, bec_logger, messages
|
||||
from scan_server.errors import ScanAbortion
|
||||
from scan_server.scans import RequestBase, ScanArgType, ScanBase
|
||||
|
||||
MOVEMENT_SCALE_X = np.sin(np.radians(15)) * np.cos(np.radians(30))
|
||||
MOVEMENT_SCALE_Y = np.cos(np.radians(15))
|
||||
@@ -97,8 +96,8 @@ class LamNIMixin:
|
||||
coarse_move_req_x = np.abs(lsamx_current - move_x)
|
||||
coarse_move_req_y = np.abs(lsamy_current - move_y)
|
||||
|
||||
self.device_manager.devices.lsamx.read_only = False
|
||||
self.device_manager.devices.lsamy.read_only = False
|
||||
self.device_manager.devices.lsamx.enabled_set = True
|
||||
self.device_manager.devices.lsamy.enabled_set = True
|
||||
|
||||
if (
|
||||
np.abs(y_drift) > 150
|
||||
@@ -110,8 +109,9 @@ class LamNIMixin:
|
||||
logger.info(
|
||||
f"Compensating {[val/1000 for val in lamni_to_stage_coordinates(x_drift,y_drift)]}"
|
||||
)
|
||||
yield from self.stubs.set(device="lsamx", value=move_x)
|
||||
yield from self.stubs.set(device="lsamy", value=move_y)
|
||||
yield from self.stubs.set_and_wait(
|
||||
device=["lsamx", "lsamy"], positions=[move_x, move_y]
|
||||
)
|
||||
|
||||
time.sleep(0.01)
|
||||
rtx_current = yield from self.stubs.send_rpc_and_wait("rtx", "readback.get")
|
||||
@@ -126,14 +126,12 @@ class LamNIMixin:
|
||||
x_drift2 = x_center_expect * 1000 - rtx_current
|
||||
y_drift2 = y_center_expect * 1000 - rty_current
|
||||
logger.info(
|
||||
f"Uncompensated drift of setup after first iteration is x={x_drift2:.3f},"
|
||||
f" y={y_drift2:.3f}"
|
||||
f"Uncompensated drift of setup after first iteration is x={x_drift2:.3f}, y={y_drift2:.3f}"
|
||||
)
|
||||
|
||||
if np.abs(x_drift2) > 5 or np.abs(y_drift2) > 5:
|
||||
logger.info(
|
||||
"Compensating second iteration"
|
||||
f" {[val/1000 for val in lamni_to_stage_coordinates(x_drift2,y_drift2)]}"
|
||||
f"Compensating second iteration {[val/1000 for val in lamni_to_stage_coordinates(x_drift2,y_drift2)]}"
|
||||
)
|
||||
move_x = (
|
||||
x_stage
|
||||
@@ -147,28 +145,26 @@ 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(device="lsamx", value=move_x)
|
||||
yield from self.stubs.set(device="lsamy", value=move_y)
|
||||
|
||||
yield from self.stubs.set_and_wait(
|
||||
device=["lsamx", "lsamy"], positions=[move_x, 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")
|
||||
|
||||
logger.info(
|
||||
f"New scan center interferometer after second iteration {rtx_current:.3f},"
|
||||
f" {rty_current:.3f} microns"
|
||||
f"New scan center interferometer after second iteration {rtx_current:.3f}, {rty_current:.3f} microns"
|
||||
)
|
||||
x_drift2 = x_center_expect * 1000 - rtx_current
|
||||
y_drift2 = y_center_expect * 1000 - rty_current
|
||||
logger.info(
|
||||
f"Uncompensated drift of setup after second iteration is x={x_drift2:.3f},"
|
||||
f" y={y_drift2:.3f}"
|
||||
f"Uncompensated drift of setup after second iteration is x={x_drift2:.3f}, y={y_drift2:.3f}"
|
||||
)
|
||||
else:
|
||||
logger.info("No second iteration required")
|
||||
|
||||
self.device_manager.devices.lsamx.read_only = True
|
||||
self.device_manager.devices.lsamy.read_only = True
|
||||
self.device_manager.devices.lsamx.enabled_set = False
|
||||
self.device_manager.devices.lsamy.enabled_set = False
|
||||
|
||||
yield from self.stubs.send_rpc_and_wait("rtx", "controller.feedback_enable_without_reset")
|
||||
|
||||
@@ -178,12 +174,8 @@ class LamNIMoveToScanCenter(RequestBase, LamNIMixin):
|
||||
scan_report_hint = None
|
||||
scan_type = "step"
|
||||
required_kwargs = []
|
||||
arg_input = {
|
||||
"shift_x": ScanArgType.FLOAT,
|
||||
"shift_y": ScanArgType.FLOAT,
|
||||
"angle": ScanArgType.FLOAT,
|
||||
}
|
||||
arg_bundle_size = {"bundle": len(arg_input), "min": 1, "max": 1}
|
||||
arg_input = [ScanArgType.FLOAT, ScanArgType.FLOAT, ScanArgType.FLOAT]
|
||||
arg_bundle_size = None
|
||||
|
||||
def __init__(self, *args, parameter=None, **kwargs):
|
||||
"""
|
||||
@@ -207,10 +199,10 @@ class LamNIFermatScan(ScanBase, LamNIMixin):
|
||||
scan_report_hint = "table"
|
||||
scan_type = "step"
|
||||
required_kwargs = ["fov_size", "exp_time", "step", "angle"]
|
||||
arg_input = {}
|
||||
arg_bundle_size = {"bundle": len(arg_input), "min": None, "max": None}
|
||||
arg_input = []
|
||||
arg_bundle_size = None
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
def __init__(self, *args, parameter=None, **kwargs):
|
||||
"""
|
||||
A LamNI scan following Fermat's spiral.
|
||||
|
||||
@@ -365,8 +357,7 @@ class LamNIFermatScan(ScanBase, LamNIMixin):
|
||||
self.stitch_x, self.stitch_y, self.angle
|
||||
)
|
||||
logger.info(
|
||||
f"Total shift [mm] {_shfitx+x_stitch_shift/1000+self.shift_x},"
|
||||
f" {_shfity+y_stitch_shift/1000+self.shift_y}"
|
||||
f"Total shift [mm] {_shfitx+x_stitch_shift/1000+self.shift_x}, {_shfity+y_stitch_shift/1000+self.shift_y}"
|
||||
)
|
||||
return (
|
||||
_shfitx + x_stitch_shift / 1000 + self.shift_x,
|
||||
@@ -443,7 +434,7 @@ class LamNIFermatScan(ScanBase, LamNIMixin):
|
||||
}
|
||||
}
|
||||
)
|
||||
yield from self.stubs.set(device="lsamrot", value=angle)
|
||||
yield from self.stubs.set_and_wait(device=["lsamrot"], positions=[angle])
|
||||
|
||||
def scan_core(self):
|
||||
if self.scan_type == "step":
|
||||
@@ -456,18 +447,17 @@ 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(group="monitored")
|
||||
msg = self.device_manager.connector.get(MessageEndpoints.device_status("rt_scan"))
|
||||
yield from self.stubs.read_and_wait(group="primary", wait_group="readout_primary")
|
||||
msg = self.device_manager.producer.get(MessageEndpoints.device_status("rt_scan"))
|
||||
if msg:
|
||||
status = msg
|
||||
status = messages.DeviceStatusMessage.loads(msg)
|
||||
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 LamNI readout:"
|
||||
f" {status.metadata.get('error')}"
|
||||
f"An error occured during the LamNI readout: {status.metadata.get('error')}"
|
||||
)
|
||||
|
||||
time.sleep(1)
|
||||
@@ -25,9 +25,8 @@ but they are executed in a specific order:
|
||||
|
||||
# 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 FlyScanBase, RequestBase, ScanArgType, ScanBase
|
||||
# from bec_lib import MessageEndpoints, bec_logger, messages
|
||||
# from scan_server.errors import ScanAbortion
|
||||
# from scan_server.scans import FlyScanBase, RequestBase, ScanArgType, ScanBase
|
||||
|
||||
# logger = bec_logger.logger
|
||||
182
bec_plugins/utils/csaxs_post_archive.py
Executable file
182
bec_plugins/utils/csaxs_post_archive.py
Executable file
@@ -0,0 +1,182 @@
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import requests
|
||||
|
||||
from bec_lib.file_utils import FileWriterMixin
|
||||
#from bec_lib.bec_service import SERVICE_CONFIG
|
||||
|
||||
|
||||
class csaxs_archiver:
|
||||
"""Class to archive data from a beamtime.
|
||||
To run this script from a shell, go to discovery.psi.ch and copy your token.
|
||||
Complement the information in user_input below in the if __name__ == __main__ part of the script.
|
||||
Afterwards, get a Keberos token (kinit) for yourself in the shell.
|
||||
Activate the bec_venv by doing "source bec_venv/bin/activate" and then run this code via python $filename.
|
||||
As a last step, adjust the dictionary below in if __name__ == '__main__' with your token as well as information about the experiment
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
start_scan: int,
|
||||
stop_scan: int,
|
||||
base_path: str,
|
||||
log_path: str,
|
||||
eacc: str,
|
||||
pi: str,
|
||||
pi_email: str,
|
||||
token: str,
|
||||
type: str = "raw",
|
||||
overwrite: bool = False,
|
||||
online: bool = True,
|
||||
):
|
||||
self.start_scan = start_scan
|
||||
self.stop_scan = stop_scan
|
||||
self.log_path = os.path.expanduser(log_path)
|
||||
self.eacc = eacc
|
||||
self.pi = pi
|
||||
self.pi_email = pi_email
|
||||
self.token = token
|
||||
self.type = type
|
||||
self.overwrite = overwrite
|
||||
self.online = online
|
||||
|
||||
#from bec_lib.bec_service import SERVICE_CONFIG
|
||||
#SERVICE_CONFIG.config["service_config"]["file_writer"]
|
||||
self._load_datacatalogue_module()
|
||||
self._create_directory(base_path)
|
||||
self._disable_mail_confirmation()
|
||||
|
||||
self.service_cfg = {'base_path' : f'{self.base_path}'}
|
||||
|
||||
self.file_writer = FileWriterMixin(self.service_cfg)
|
||||
|
||||
def _disable_mail_confirmation(self):
|
||||
# Define the URL and payload
|
||||
url = "https://dacat.psi.ch/api/v3/Policies/updatewhere"
|
||||
payload = {
|
||||
"ownerGroupList": f'p{self.eacc[1:]}',
|
||||
"data": '{"archiveEmailNotification": false, "accessGroups": ["slscsaxs"]}'
|
||||
}
|
||||
|
||||
# Define headers
|
||||
headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
# Add the access_token to the URL
|
||||
url += "?access_token=" + self.token
|
||||
|
||||
# Make a POST request
|
||||
print(url, payload, headers)
|
||||
response = requests.post(url, data=payload, headers=headers)
|
||||
|
||||
# Check the response
|
||||
if response.status_code == 200:
|
||||
print("Request was successful.")
|
||||
print(response.json())
|
||||
else:
|
||||
print("Request failed with status code:", response.status_code)
|
||||
print(response.text)
|
||||
|
||||
def _create_directory(self, base_path: str) -> None:
|
||||
if self.online:
|
||||
self.base_path = os.path.expanduser("~/Data10")
|
||||
else:
|
||||
self.base_path = base_path
|
||||
|
||||
if not os.path.exists(self.log_path):
|
||||
os.makedirs(self.log_path)
|
||||
|
||||
def _load_datacatalogue_module(self):
|
||||
command = 'module add datacatalog/1.1.9'
|
||||
os.popen(command)
|
||||
# result = subprocess.run(
|
||||
# command,
|
||||
# shell=False,
|
||||
# stdout=subprocess.PIPE,
|
||||
# stderr=subprocess.PIPE,
|
||||
# universal_newlines=True,
|
||||
# )
|
||||
# if result.returncode == 0:
|
||||
# print(f"Command {command} was succesful")
|
||||
# else:
|
||||
# print(f"Failed to run command {command} with return message {result.returncode}")
|
||||
|
||||
def prep_metadata(self, scannr: int) -> dict:
|
||||
user_metadata = {}
|
||||
user_metadata.update(
|
||||
{
|
||||
"principalInvestigator": self.pi_email,
|
||||
"owner": self.pi,
|
||||
"ownerEmail": self.pi_email,
|
||||
"sourceFolder": self.base_path,
|
||||
"creationLocation": "/PSI/SLS/CSAXS",
|
||||
"type": "raw",
|
||||
"ownerGroup": f"p{self.eacc.strip('e')}",
|
||||
"datasetName": f"S{scannr:05d}",
|
||||
}
|
||||
)
|
||||
return user_metadata
|
||||
|
||||
def _write_ingestion_log(self, scannr: int) -> None:
|
||||
...
|
||||
|
||||
def run_for_all_scans(self):
|
||||
for scan in range(self.start_scan, self.stop_scan + 1):
|
||||
print(f"Start ingestion for scan {scan}")
|
||||
fname = os.path.join(os.path.expanduser(self.log_path), f"ingestion_log_S{scan:05d}")
|
||||
self.datafile_name = f"{fname}.txt"
|
||||
if os.path.isfile(self.datafile_name) and not self.overwrite == True:
|
||||
print(
|
||||
f"Skipping scan {scan}, already ingested due to logs, moving on to next scan {scan+1}"
|
||||
)
|
||||
continue
|
||||
|
||||
user_metadata = self.prep_metadata(scan)
|
||||
|
||||
# Write metadata file in json file
|
||||
self.metadata_file = f"{fname}.json"
|
||||
with open(self.metadata_file, "w") as file:
|
||||
json.dump(user_metadata, file)
|
||||
|
||||
# Compile datapath based on structure a cSAXS
|
||||
datadir_path = os.path.join('data', self.file_writer.get_scan_directory(scan, 1000, 5))
|
||||
print(f"Archiving directory {datadir_path}")
|
||||
if not os.path.isdir(os.path.join(self.base_path, datadir_path)):
|
||||
print(f"Did not find directory {datadir_path}, skipping scan {scan}")
|
||||
continue
|
||||
|
||||
# Create datafile path for archiving
|
||||
with open(self.datafile_name, "w") as file:
|
||||
file.write(datadir_path)
|
||||
|
||||
print(f"Starting ingestion for S#{scan}")
|
||||
command = f'datasetIngestor -allowexistingsource -ingest -autoarchive -noninteractive -token {self.token} {self.metadata_file} {self.datafile_name}'
|
||||
rtr = os.popen(command)
|
||||
|
||||
#with open(os.path.join(fname,'_log.txt'), "w") as file:
|
||||
# print(f'Writing reponse to file')
|
||||
# file.write(rtr.read())
|
||||
# result = subprocess.run(command, shell=False, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines=True)
|
||||
# if result.returncode == 0:
|
||||
# print(f"Command {command} was succesful")
|
||||
# else:
|
||||
# print(f"Failed to run command {command} with return message {result.returncode}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Generate dictionary with user input.
|
||||
user_input = {
|
||||
"base_path": "~/Data10",
|
||||
"eacc": "e20638",
|
||||
"pi": "Emma Sparr",
|
||||
"pi_email": "emma.sparr@fkem1.lu.se",
|
||||
'log_path' : '~/Data10/documentation/ingestion_logs/',
|
||||
'token' : 'YK8gkmQmEVxVxjiA57D6tVmpBVs7T235nWEuBT0behN9BPM2BdWARWPPgEsQVrPe',
|
||||
'start_scan' : 1,
|
||||
'stop_scan' : 450,
|
||||
}
|
||||
archiver = csaxs_archiver(**user_input)
|
||||
archiver.run_for_all_scans()
|
||||
88
bec_plugins/utils/saxs_params.py
Executable file
88
bec_plugins/utils/saxs_params.py
Executable file
@@ -0,0 +1,88 @@
|
||||
import csv
|
||||
import os
|
||||
from collections import defaultdict
|
||||
from collections.abc import Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
class ScanItem:
|
||||
def __init__(self, offset_xy: Callable) -> None:
|
||||
self.start_entry = None
|
||||
self.end_entry = None
|
||||
self.offset_xy = offset_xy
|
||||
|
||||
def to_scan_params(self) -> dict:
|
||||
scan_params = {
|
||||
"start_x": float(self.start_entry["X"]) + self.offset_xy()[0],
|
||||
"start_y": float(self.start_entry["Y"]) + self.offset_xy()[1],
|
||||
"end_x": float(self.end_entry["X"]) + self.offset_xy()[0],
|
||||
"end_y": float(self.end_entry["Y"]) + self.offset_xy()[1],
|
||||
"interval_x": int(
|
||||
np.round(
|
||||
np.abs(float(self.start_entry["X"]) - float(self.end_entry["X"]))
|
||||
/ (float(self.start_entry["step_x [mu]"]) * 1e-3)
|
||||
)
|
||||
),
|
||||
"interval_y": int(
|
||||
np.round(
|
||||
np.abs(float(self.start_entry["Y"]) - float(self.end_entry["Y"]))
|
||||
/ (float(self.start_entry["step_y [mu]"]) * 1e-3)
|
||||
)
|
||||
),
|
||||
"exp_time": float(self.start_entry["exp_time [s]"]),
|
||||
"readout_time": 3e-3,
|
||||
"md": {"sample_name": self.start_entry["sample name"]},
|
||||
}
|
||||
if scan_params["interval_x"] < 1 or scan_params["interval_x"] < 1:
|
||||
raise ValueError("Bugger off...")
|
||||
return scan_params
|
||||
|
||||
|
||||
class SAXSParams:
|
||||
def __init__(self, offset: Callable):
|
||||
self.offset_xy = offset
|
||||
self.data = defaultdict(lambda: ScanItem(offset))
|
||||
|
||||
def load_from_csv(self, file_path: str) -> None:
|
||||
"""
|
||||
Load the acquisition parameter from a csv file.
|
||||
"""
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
raise FileNotFoundError(
|
||||
f"The specified CSV file could not be found. Please check that the given path is correct: {file_path}."
|
||||
)
|
||||
|
||||
data_transposed = defaultdict(lambda: [])
|
||||
with open(os.path.expanduser(file_path), "r") as file:
|
||||
csv_reader = csv.DictReader(file)
|
||||
for row in csv_reader:
|
||||
for key, val in row.items():
|
||||
data_transposed[key].append(val)
|
||||
if int(row["start"]):
|
||||
self.data[row["sample name"]].start_entry = row
|
||||
else:
|
||||
self.data[row["sample name"]].end_entry = row
|
||||
self._check_params(dict(data_transposed))
|
||||
|
||||
def _check_params(self, data_transposed: dict) -> dict:
|
||||
sample_names = set(data_transposed["sample name"])
|
||||
if len(data_transposed["start"]) != len(sample_names) * 2:
|
||||
raise ValueError(
|
||||
f"The given params file does not provide N*2 start/stop positions. Found {len(sample_names)} samples and {len(data_transposed['start'])} start/stop positions."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from pprint import pprint
|
||||
|
||||
INPUT_FILE = "/sls/X12SA/data/e21206/Data10/software/test_script.csv"
|
||||
|
||||
def my_offset():
|
||||
return [0, 0]
|
||||
|
||||
params = SAXSParams(my_offset)
|
||||
params.load_from_csv(INPUT_FILE)
|
||||
for key in params.data:
|
||||
pprint(params.data[key].to_scan_params())
|
||||
@@ -1,7 +1,3 @@
|
||||
""" Script used for parsing scan parameters from a CSV file as created by the motormap GUI.
|
||||
This needs to be reviewed and tested during the deployment phase."""
|
||||
|
||||
# pylint: skip-file
|
||||
import csv
|
||||
import os
|
||||
from collections import defaultdict
|
||||
13
bec_plugins/utils/service_config.py
Executable file
13
bec_plugins/utils/service_config.py
Executable file
@@ -0,0 +1,13 @@
|
||||
import yaml
|
||||
|
||||
CONFIG_PATH = "/sls/X12SA/data/gac-x12saop/bec/config/bec_service_config.yaml"
|
||||
|
||||
|
||||
def load_service_config() -> dict:
|
||||
"""Load the service configuration from the YAML file."""
|
||||
with open(CONFIG_PATH, "r", encoding="utf-8") as stream:
|
||||
try:
|
||||
config = yaml.safe_load(stream)
|
||||
except yaml.YAMLError as exc:
|
||||
print(exc)
|
||||
return config
|
||||
1
bin/.gitignore
vendored
1
bin/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
# Add anything you don't want to check in to git, e.g. very large files
|
||||
@@ -3,9 +3,8 @@ from __future__ import annotations
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from bec_lib import bec_logger, messages
|
||||
from bec_lib.endpoints import MessageEndpoints
|
||||
from bec_lib.redis_connector import MessageObject, RedisConnector
|
||||
from bec_lib import MessageEndpoints, RedisConnector, bec_logger, messages
|
||||
from bec_lib.redis_connector import MessageObject
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
@@ -13,6 +12,7 @@ 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"""
|
||||
@@ -27,7 +27,7 @@ class PilatusConverter:
|
||||
message (MessageObject): Message object
|
||||
parent (PilatusConverter): Parent object
|
||||
"""
|
||||
msg = message.value
|
||||
msg = messages.MessageReader.loads(message.value)
|
||||
print(msg)
|
||||
if not msg:
|
||||
return
|
||||
@@ -56,9 +56,10 @@ class PilatusConverter:
|
||||
"""
|
||||
Start the consumer.
|
||||
"""
|
||||
self._connector.register(
|
||||
file_consumer = self._connector.consumer(
|
||||
MessageEndpoints.file_event("pilatus_2"), cb=self.on_new_message, parent=self
|
||||
)
|
||||
file_consumer.start()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
5
bin/open_tunnel.sh
Executable file
5
bin/open_tunnel.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
|
||||
for i in `seq 1 8`
|
||||
do
|
||||
ssh -N -R 6379:localhost:6379 x12sa-cn-$i &
|
||||
done
|
||||
48
bin/setup_bec.sh
Executable file
48
bin/setup_bec.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
|
||||
if [ "pc15543.psi.ch" != "$(hostname)" ]; then
|
||||
echo "Please run this script on pc15543"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
module use unstable
|
||||
module add psi-python311/2024.02
|
||||
echo module add tmux/3.2 >> ~/.bashrc
|
||||
echo module add redis/7.0.12 >> ~/.bashrc
|
||||
|
||||
source ~/.bashrc
|
||||
|
||||
cd ~/Data10
|
||||
mkdir -p software/
|
||||
mkdir -p ~/bec/scripts
|
||||
cd software
|
||||
|
||||
git clone https://gitlab.psi.ch/bec/bec.git
|
||||
git clone https://gitlab.psi.ch/bec/ophyd_devices.git
|
||||
git clone https://gitlab.psi.ch/bec/bec-widgets.git
|
||||
|
||||
python -m venv ./bec_venv
|
||||
source ./bec_venv/bin/activate
|
||||
|
||||
cd bec
|
||||
git checkout sastt-online-changes
|
||||
pip install -e ./bec_server[dev]
|
||||
|
||||
cd ../csaxs-bec
|
||||
pip install -e .[dev]
|
||||
|
||||
#redis-server --protected-mode no &
|
||||
|
||||
read -p "Do you want to set the current BEC account to $(whoami)? (yes/no) " yn
|
||||
|
||||
val=$(whoami)
|
||||
|
||||
case $yn in
|
||||
yes ) echo ok, setting account to $val;
|
||||
redis-cli SET internal/account:val $val;;
|
||||
no ) echo ;;
|
||||
* ) echo invalid response;
|
||||
exit 1;;
|
||||
esac
|
||||
|
||||
|
||||
$(pwd)/open_tunnel.sh
|
||||
17
bin/setup_bec_widgets.sh
Executable file
17
bin/setup_bec_widgets.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
module use unstable
|
||||
module add psi-python311/2024.02
|
||||
|
||||
cd ~/Data10/software
|
||||
python -m venv ./bec_widgets_venv
|
||||
source ./bec_widgets_venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
cd ~/Data10/software/bec/bec_lib
|
||||
pip install -e .
|
||||
|
||||
cd ~/Data10/software/csaxs-bec
|
||||
pip install -e .
|
||||
|
||||
cd ~/Data10/software/bec-widgets
|
||||
pip install -e .
|
||||
|
||||
echo "For the moment widgets only run on beamline consoles comp1/2 and cons1"
|
||||
@@ -1,6 +0,0 @@
|
||||
from .alignment import XrayEyeAlign
|
||||
from .lamni import LamNI
|
||||
from .lamni_optics_mixin import LamNIInitError, LaMNIInitStages, LamNIOpticsMixin
|
||||
__all__ = [
|
||||
"LamNI", "XrayEyeAlign", "LamNIInitError", "LaMNIInitStages", "LamNIOpticsMixin"
|
||||
]
|
||||
@@ -1,461 +0,0 @@
|
||||
import builtins
|
||||
import time
|
||||
from collections import defaultdict
|
||||
|
||||
import numpy as np
|
||||
from bec_lib import bec_logger
|
||||
from typeguard import typechecked
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get, epics_put, fshopen
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
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 XrayEyeAlign:
|
||||
# pixel calibration, multiply to get mm
|
||||
# PIXEL_CALIBRATION = 0.2/209 #.2 with binning
|
||||
PIXEL_CALIBRATION = 0.2 / 218 # .2 with binning
|
||||
|
||||
def __init__(self, client, lamni) -> None:
|
||||
self.client = client
|
||||
self.lamni = lamni
|
||||
self.device_manager = client.device_manager
|
||||
self.scans = client.scans
|
||||
self.alignment_values = defaultdict(list)
|
||||
self._reset_init_values()
|
||||
self.corr_pos_x = []
|
||||
self.corr_pos_y = []
|
||||
self.corr_angle = []
|
||||
self.corr_pos_x_2 = []
|
||||
self.corr_pos_y_2 = []
|
||||
self.corr_angle_2 = []
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Correction reset
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def reset_correction(self):
|
||||
self.corr_pos_x = []
|
||||
self.corr_pos_y = []
|
||||
self.corr_angle = []
|
||||
|
||||
def reset_correction_2(self):
|
||||
self.corr_pos_x_2 = []
|
||||
self.corr_pos_y_2 = []
|
||||
self.corr_angle_2 = []
|
||||
|
||||
def reset_xray_eye_correction(self):
|
||||
self.client.delete_global_var("tomo_fit_xray_eye")
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# FOV offset properties
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@property
|
||||
def tomo_fovx_offset(self):
|
||||
val = self.client.get_global_var("tomo_fov_offset")
|
||||
if val is None:
|
||||
return 0.0
|
||||
return val[0] / 1000
|
||||
|
||||
@tomo_fovx_offset.setter
|
||||
@typechecked
|
||||
def tomo_fovx_offset(self, val: float):
|
||||
val_old = self.client.get_global_var("tomo_fov_offset")
|
||||
if val_old is None:
|
||||
val_old = [0.0, 0.0]
|
||||
self.client.set_global_var("tomo_fov_offset", [val * 1000, val_old[1]])
|
||||
|
||||
@property
|
||||
def tomo_fovy_offset(self):
|
||||
val = self.client.get_global_var("tomo_fov_offset")
|
||||
if val is None:
|
||||
return 0.0
|
||||
return val[1] / 1000
|
||||
|
||||
@tomo_fovy_offset.setter
|
||||
@typechecked
|
||||
def tomo_fovy_offset(self, val: float):
|
||||
val_old = self.client.get_global_var("tomo_fov_offset")
|
||||
if val_old is None:
|
||||
val_old = [0.0, 0.0]
|
||||
self.client.set_global_var("tomo_fov_offset", [val_old[0], val * 1000])
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Internal helpers
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _reset_init_values(self):
|
||||
self.shift_xy = [0, 0]
|
||||
self._xray_fov_xy = [0, 0]
|
||||
|
||||
def _disable_rt_feedback(self):
|
||||
self.device_manager.devices.rtx.controller.feedback_disable()
|
||||
|
||||
def _enable_rt_feedback(self):
|
||||
self.device_manager.devices.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def tomo_rotate(self, val: float):
|
||||
# pylint: disable=undefined-variable
|
||||
umv(self.device_manager.devices.lsamrot, val)
|
||||
|
||||
def get_tomo_angle(self):
|
||||
return self.device_manager.devices.lsamrot.readback.read()["lsamrot"]["value"]
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# X-ray eye camera control
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
print("got new frame")
|
||||
|
||||
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)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Alignment procedure
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def align(self):
|
||||
self._reset_init_values()
|
||||
self.reset_correction()
|
||||
self.reset_correction_2()
|
||||
|
||||
self._disable_rt_feedback()
|
||||
epics_put("XOMNYI-XEYE-PIXELSIZE:0", self.PIXEL_CALIBRATION)
|
||||
self._enable_rt_feedback()
|
||||
|
||||
self.movement_buttons_enabled = False
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 0)
|
||||
self.send_message("please wait...")
|
||||
epics_put("XOMNYI-XEYE-SAMPLENAME:0.DESC", "Let us LAMNI...")
|
||||
|
||||
self._disable_rt_feedback()
|
||||
k = 0
|
||||
|
||||
self.lamni.lfzp_in()
|
||||
self.update_frame()
|
||||
|
||||
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.")
|
||||
|
||||
while True:
|
||||
if epics_get("XOMNYI-XEYE-SUBMIT:0") == 1:
|
||||
val_x = epics_get(f"XOMNYI-XEYE-XVAL_X:{k}") * self.PIXEL_CALIBRATION # in mm
|
||||
val_y = epics_get(f"XOMNYI-XEYE-YVAL_Y:{k}") * self.PIXEL_CALIBRATION # in mm
|
||||
self.alignment_values[k] = [val_x, val_y]
|
||||
print(
|
||||
f"Clicked position {k}: x {self.alignment_values[k][0]}, y"
|
||||
f" {self.alignment_values[k][1]}"
|
||||
)
|
||||
|
||||
if k == 0: # received center value of FZP
|
||||
self.send_message("please wait ...")
|
||||
self.lamni.loptics_out()
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1)
|
||||
self.movement_buttons_enabled = False
|
||||
print("Moving sample in, FZP out")
|
||||
|
||||
self._disable_rt_feedback()
|
||||
time.sleep(0.3)
|
||||
self._enable_rt_feedback()
|
||||
time.sleep(0.3)
|
||||
|
||||
self.update_frame()
|
||||
self.send_message("Go and find the sample")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
|
||||
self.movement_buttons_enabled = True
|
||||
|
||||
elif k == 1: # received sample center value at samrot 0
|
||||
msg = (
|
||||
f"Base shift values from movement are x {self.shift_xy[0]}, y"
|
||||
f" {self.shift_xy[1]}"
|
||||
)
|
||||
print(msg)
|
||||
logger.info(msg)
|
||||
self.shift_xy[0] += (
|
||||
self.alignment_values[0][0] - self.alignment_values[1][0]
|
||||
) * 1000
|
||||
self.shift_xy[1] += (
|
||||
self.alignment_values[1][1] - self.alignment_values[0][1]
|
||||
) * 1000
|
||||
print(
|
||||
"Base shift values from movement and clicked position are x"
|
||||
f" {self.shift_xy[0]}, y {self.shift_xy[1]}"
|
||||
)
|
||||
|
||||
self.scans.lamni_move_to_scan_center(
|
||||
self.shift_xy[0] / 1000, self.shift_xy[1] / 1000, self.get_tomo_angle()
|
||||
).wait()
|
||||
|
||||
self.send_message("please wait ...")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1)
|
||||
self.movement_buttons_enabled = False
|
||||
time.sleep(1)
|
||||
|
||||
self.scans.lamni_move_to_scan_center(
|
||||
self.shift_xy[0] / 1000, self.shift_xy[1] / 1000, self.get_tomo_angle()
|
||||
).wait()
|
||||
|
||||
epics_put("XOMNYI-XEYE-ANGLE:0", self.get_tomo_angle())
|
||||
self.update_frame()
|
||||
self.send_message("Submit sample center and FOV (0 deg)")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
|
||||
self.update_fov(k)
|
||||
|
||||
elif 1 < k < 10: # received sample center value at samrot 0 ... 315
|
||||
self.send_message("please wait ...")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1)
|
||||
|
||||
self._disable_rt_feedback()
|
||||
self.tomo_rotate((k - 1) * 45 - 45 / 2)
|
||||
self.scans.lamni_move_to_scan_center(
|
||||
self.shift_xy[0] / 1000, self.shift_xy[1] / 1000, self.get_tomo_angle()
|
||||
).wait()
|
||||
self._disable_rt_feedback()
|
||||
self.tomo_rotate((k - 1) * 45)
|
||||
self.scans.lamni_move_to_scan_center(
|
||||
self.shift_xy[0] / 1000, self.shift_xy[1] / 1000, self.get_tomo_angle()
|
||||
).wait()
|
||||
|
||||
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 == 10: # received sample center value at samrot 270, done
|
||||
self.send_message("done...")
|
||||
epics_put("XOMNYI-XEYE-SUBMIT:0", -1)
|
||||
self.movement_buttons_enabled = False
|
||||
self.update_fov(k)
|
||||
break
|
||||
|
||||
k += 1
|
||||
epics_put("XOMNYI-XEYE-STEP:0", k)
|
||||
|
||||
if k < 2:
|
||||
_xrayeyalignmvx = epics_get("XOMNYI-XEYE-MVX:0")
|
||||
_xrayeyalignmvy = epics_get("XOMNYI-XEYE-MVY:0")
|
||||
if _xrayeyalignmvx != 0 or _xrayeyalignmvy != 0:
|
||||
self.shift_xy[0] = self.shift_xy[0] + _xrayeyalignmvx
|
||||
self.shift_xy[1] = self.shift_xy[1] + _xrayeyalignmvy
|
||||
self.scans.lamni_move_to_scan_center(
|
||||
self.shift_xy[0] / 1000, self.shift_xy[1] / 1000, self.get_tomo_angle()
|
||||
).wait()
|
||||
print(
|
||||
f"Current center horizontal {self.shift_xy[0]} vertical {self.shift_xy[1]}"
|
||||
)
|
||||
epics_put("XOMNYI-XEYE-MVY:0", 0)
|
||||
epics_put("XOMNYI-XEYE-MVX:0", 0)
|
||||
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
|
||||
print(
|
||||
f"The largest field of view from the xrayeyealign was \nfovx = {fovx:.0f} microns,"
|
||||
f" fovy = {fovy:.0f} microns"
|
||||
)
|
||||
print("Use matlab routine to fit the current alignment...")
|
||||
print(
|
||||
"This additional shift is applied to the base shift values\n which are x"
|
||||
f" {self.shift_xy[0]}, y {self.shift_xy[1]}"
|
||||
)
|
||||
|
||||
self._disable_rt_feedback()
|
||||
self.tomo_rotate(0)
|
||||
|
||||
print(
|
||||
"\n\nNEXT LOAD ALIGNMENT PARAMETERS\nby running"
|
||||
" lamni.align.read_xray_eye_correction()\n"
|
||||
)
|
||||
|
||||
self.client.set_global_var("tomo_fov_offset", self.shift_xy)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Alignment output
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def write_output(self):
|
||||
import os
|
||||
with open(
|
||||
os.path.expanduser("~/Data10/specES1/internal/xrayeye_alignmentvalues"), "w"
|
||||
) as alignment_values_file:
|
||||
alignment_values_file.write("angle\thorizontal\tvertical\n")
|
||||
for k in range(2, 11):
|
||||
fovx_offset = (self.alignment_values[0][0] - self.alignment_values[k][0]) * 1000
|
||||
fovy_offset = (self.alignment_values[k][1] - self.alignment_values[0][1]) * 1000
|
||||
print(
|
||||
f"Writing to file new alignment: number {k}, value x {fovx_offset}, y"
|
||||
f" {fovy_offset}"
|
||||
)
|
||||
alignment_values_file.write(f"{(k-2)*45}\t{fovx_offset}\t{fovy_offset}\n")
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# X-ray eye sinusoidal correction (loaded from MATLAB fit files)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def read_xray_eye_correction(self, dir_path=None):
|
||||
import os
|
||||
if dir_path is None:
|
||||
dir_path = os.path.expanduser("~/Data10/specES1/internal/")
|
||||
tomo_fit_xray_eye = np.zeros((2, 3))
|
||||
for i, axis in enumerate(["x", "y"]):
|
||||
for j, coeff in enumerate(["A", "B", "C"]):
|
||||
with open(os.path.join(dir_path, f"ptychotomoalign_{coeff}{axis}.txt"), "r") as f:
|
||||
tomo_fit_xray_eye[i][j] = f.readline()
|
||||
|
||||
self.client.set_global_var("tomo_fit_xray_eye", tomo_fit_xray_eye.tolist())
|
||||
# x amp, phase, offset, y amp, phase, offset
|
||||
# 0 0 0 1 0 2 1 0 1 1 1 2
|
||||
print("New alignment parameters loaded from X-ray eye")
|
||||
print(
|
||||
f"X Amplitude {tomo_fit_xray_eye[0][0]}, "
|
||||
f"X Phase {tomo_fit_xray_eye[0][1]}, "
|
||||
f"X Offset {tomo_fit_xray_eye[0][2]}, "
|
||||
f"Y Amplitude {tomo_fit_xray_eye[1][0]}, "
|
||||
f"Y Phase {tomo_fit_xray_eye[1][1]}, "
|
||||
f"Y Offset {tomo_fit_xray_eye[1][2]}"
|
||||
)
|
||||
|
||||
def lamni_compute_additional_correction_xeye_mu(self, angle):
|
||||
"""Compute sinusoidal correction from the X-ray eye fit for the given angle."""
|
||||
tomo_fit_xray_eye = self.client.get_global_var("tomo_fit_xray_eye")
|
||||
if tomo_fit_xray_eye is None:
|
||||
print("Not applying any additional correction. No x-ray eye data available.\n")
|
||||
return (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_fit_xray_eye[0][0] * np.sin(np.radians(angle) + tomo_fit_xray_eye[0][1])
|
||||
+ tomo_fit_xray_eye[0][2]
|
||||
) / 1000
|
||||
correction_y = (
|
||||
tomo_fit_xray_eye[1][0] * np.sin(np.radians(angle) + tomo_fit_xray_eye[1][1])
|
||||
+ tomo_fit_xray_eye[1][2]
|
||||
) / 1000
|
||||
|
||||
print(f"Xeye correction x {correction_x}, y {correction_y} for angle {angle}\n")
|
||||
return (correction_x, correction_y)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Additional lookup-table corrections (iteration 1 and 2)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def read_additional_correction(self, correction_file: str):
|
||||
self.corr_pos_x, self.corr_pos_y, self.corr_angle = self._read_correction_file_xy(
|
||||
correction_file
|
||||
)
|
||||
|
||||
def read_additional_correction_2(self, correction_file: str):
|
||||
self.corr_pos_x_2, self.corr_pos_y_2, self.corr_angle_2 = self._read_correction_file_xy(
|
||||
correction_file
|
||||
)
|
||||
|
||||
def _read_correction_file_xy(self, correction_file: str):
|
||||
"""Parse a correction file that contains corr_pos_x, corr_pos_y and corr_angle entries."""
|
||||
with open(correction_file, "r") as f:
|
||||
num_elements = f.readline()
|
||||
int_num_elements = int(num_elements.split(" ")[2])
|
||||
print(int_num_elements)
|
||||
corr_pos_x = []
|
||||
corr_pos_y = []
|
||||
corr_angle = []
|
||||
for j in range(0, int_num_elements * 3):
|
||||
line = f.readline()
|
||||
value = line.split(" ")[2]
|
||||
name = line.split(" ")[0].split("[")[0]
|
||||
if name == "corr_pos_x":
|
||||
corr_pos_x.append(float(value) / 1000)
|
||||
elif name == "corr_pos_y":
|
||||
corr_pos_y.append(float(value) / 1000)
|
||||
elif name == "corr_angle":
|
||||
corr_angle.append(float(value))
|
||||
return corr_pos_x, corr_pos_y, corr_angle
|
||||
|
||||
def compute_additional_correction(self, angle):
|
||||
return self._compute_correction_xy(
|
||||
angle, self.corr_pos_x, self.corr_pos_y, self.corr_angle, label="1"
|
||||
)
|
||||
|
||||
def compute_additional_correction_2(self, angle):
|
||||
return self._compute_correction_xy(
|
||||
angle, self.corr_pos_x_2, self.corr_pos_y_2, self.corr_angle_2, label="2"
|
||||
)
|
||||
|
||||
def _compute_correction_xy(self, angle, corr_pos_x, corr_pos_y, corr_angle, label=""):
|
||||
"""Find the correction for the closest angle in the lookup table."""
|
||||
if not corr_pos_x:
|
||||
print(f"Not applying additional correction {label}. No data available.\n")
|
||||
return (0, 0)
|
||||
|
||||
shift_x = corr_pos_x[0]
|
||||
shift_y = corr_pos_y[0]
|
||||
angledelta = np.fabs(corr_angle[0] - angle)
|
||||
|
||||
for j in range(1, len(corr_pos_x)):
|
||||
newangledelta = np.fabs(corr_angle[j] - angle)
|
||||
if newangledelta < angledelta:
|
||||
shift_x = corr_pos_x[j]
|
||||
shift_y = corr_pos_y[j]
|
||||
angledelta = newangledelta
|
||||
|
||||
if shift_x == 0 and angle < corr_angle[0]:
|
||||
shift_x = corr_pos_x[0]
|
||||
shift_y = corr_pos_y[0]
|
||||
|
||||
if shift_x == 0 and angle > corr_angle[-1]:
|
||||
shift_x = corr_pos_x[-1]
|
||||
shift_y = corr_pos_y[-1]
|
||||
|
||||
print(f"Additional correction shifts {label}: {shift_x} {shift_y}")
|
||||
return (shift_x, shift_y)
|
||||
@@ -1,211 +0,0 @@
|
||||
"""
|
||||
extra_tomo.py
|
||||
=============
|
||||
Specialist LamNI subclasses for specific experimental configurations.
|
||||
Import explicitly when needed, e.g.:
|
||||
|
||||
from csaxs_bec...extra_tomo import MagLamNI
|
||||
from csaxs_bec...extra_tomo import DataDrivenLamNI
|
||||
"""
|
||||
|
||||
import builtins
|
||||
import datetime
|
||||
import os
|
||||
import time
|
||||
|
||||
import h5py
|
||||
import numpy as np
|
||||
from bec_lib import bec_logger
|
||||
from bec_lib.alarm_handler import AlarmBase
|
||||
|
||||
from .lamni import LamNI
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
if builtins.__dict__.get("bec") is not None:
|
||||
bec = builtins.__dict__.get("bec")
|
||||
dev = builtins.__dict__.get("dev")
|
||||
umv = builtins.__dict__.get("umv")
|
||||
scans = builtins.__dict__.get("scans")
|
||||
|
||||
|
||||
class MagLamNI(LamNI):
|
||||
"""LamNI subclass for magnetic experiments (XMCD).
|
||||
|
||||
Adds a slow rotation helper and allows injection of a custom
|
||||
per-angle callback via the ``lamni_at_each_angle`` builtin.
|
||||
"""
|
||||
|
||||
def sub_tomo_scan(self, subtomo_number, start_angle=None):
|
||||
super().sub_tomo_scan(subtomo_number, start_angle)
|
||||
# self.rotate_slowly(0)
|
||||
|
||||
def rotate_slowly(self, angle, step_size=20):
|
||||
"""Rotate to target angle in small steps to avoid mechanical stress."""
|
||||
current_angle = dev.lsamrot.read(cached=True)["value"]
|
||||
steps = int(np.ceil(np.abs(current_angle - angle) / step_size)) + 1
|
||||
for target_angle in np.linspace(current_angle, angle, steps, endpoint=True):
|
||||
umv(dev.lsamrot, target_angle)
|
||||
scans.lamni_move_to_scan_center(
|
||||
self.align.tomo_fovx_offset, self.align.tomo_fovy_offset, target_angle
|
||||
)
|
||||
|
||||
def _at_each_angle(self, angle: float) -> None:
|
||||
if "lamni_at_each_angle" in builtins.__dict__:
|
||||
# pylint: disable=undefined-variable
|
||||
lamni_at_each_angle(self, angle)
|
||||
return
|
||||
|
||||
self.tomo_scan_projection(angle)
|
||||
self.tomo_reconstruct()
|
||||
|
||||
|
||||
class DataDrivenLamNI(LamNI):
|
||||
"""LamNI subclass that reads per-projection scan parameters from an HDF5 file.
|
||||
|
||||
Instead of a fixed FOV and step size for the whole tomogram, each
|
||||
projection can have individual values for step size, loptz position
|
||||
and lateral shifts, as specified in a datadriven_params.h5 file.
|
||||
"""
|
||||
|
||||
def __init__(self, client):
|
||||
super().__init__(client)
|
||||
self.tomo_data = {}
|
||||
|
||||
def tomo_scan(
|
||||
self,
|
||||
subtomo_start=1,
|
||||
start_index=None,
|
||||
fname="~/Data10/data_driven_config/datadriven_params.h5",
|
||||
):
|
||||
"""Start a data-driven tomo scan.
|
||||
|
||||
Args:
|
||||
subtomo_start (int): Unused; kept for API compatibility. Use start_index to resume.
|
||||
start_index (int, optional): Skip projections before this index. Defaults to None.
|
||||
fname (str): Path to the HDF5 parameter file. Defaults to the standard location.
|
||||
"""
|
||||
bec = builtins.__dict__.get("bec")
|
||||
scans = builtins.__dict__.get("scans")
|
||||
|
||||
fname = os.path.expanduser(fname)
|
||||
if not os.path.exists(fname):
|
||||
raise FileNotFoundError(f"Could not find datadriven params file in {fname}.")
|
||||
|
||||
content = f"Loading tomo parameters from {fname}."
|
||||
logger.warning(content)
|
||||
msg = bec.logbook.LogbookMessage()
|
||||
msg.add_text(content).add_tag(["Data_driven_file", "BEC"])
|
||||
self.client.logbook.send_logbook_message(msg)
|
||||
|
||||
self._update_tomo_data_from_file(fname)
|
||||
self._current_special_angles = self.special_angles.copy()
|
||||
|
||||
if subtomo_start == 1 and start_index is None:
|
||||
self.tomo_id = self.add_sample_database(
|
||||
self.sample_name,
|
||||
str(datetime.date.today()),
|
||||
bec.active_account.decode(),
|
||||
bec.queue.next_scan_number,
|
||||
"lamni",
|
||||
"test additional info",
|
||||
"BEC",
|
||||
)
|
||||
self.write_pdf_report()
|
||||
|
||||
with scans.dataset_id_on_hold:
|
||||
self.sub_tomo_data_driven(start_index)
|
||||
|
||||
def sub_tomo_scan(self, subtomo_number=None, start_angle=None):
|
||||
raise NotImplementedError(
|
||||
"Cannot run sub_tomo_scan with DataDrivenLamNI. "
|
||||
"Use lamni.tomo_scan(start_index=<N>) to resume instead."
|
||||
)
|
||||
|
||||
def _at_each_angle(
|
||||
self, angle=None, stepsize=None, loptz_pos=None, manual_shift_x=0, manual_shift_y=0
|
||||
):
|
||||
self.manual_shift_x = manual_shift_x
|
||||
self.manual_shift_y = manual_shift_y
|
||||
self.tomo_shellstep = stepsize
|
||||
if loptz_pos is not None:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
umv(dev.loptz, loptz_pos)
|
||||
super()._at_each_angle(angle=angle)
|
||||
|
||||
def sub_tomo_data_driven(self, start_index=None):
|
||||
"""Iterate over all projections defined in the loaded HDF5 parameter file."""
|
||||
for scan_index, scan_data in enumerate(zip(*self.tomo_data.values())):
|
||||
if start_index and scan_index < start_index:
|
||||
continue
|
||||
(
|
||||
angle,
|
||||
stepsize,
|
||||
loptz_pos,
|
||||
propagation_distance,
|
||||
manual_shift_x,
|
||||
manual_shift_y,
|
||||
subtomo_number,
|
||||
) = scan_data
|
||||
bec.metadata.update(
|
||||
{key: float(val) for key, val in zip(self.tomo_data.keys(), scan_data)}
|
||||
)
|
||||
successful = False
|
||||
error_caught = False
|
||||
if 0 <= angle < 360.05:
|
||||
print(f"Starting LamNI scan for angle {angle}")
|
||||
while not successful:
|
||||
self._start_beam_check()
|
||||
if not self.special_angles:
|
||||
self._current_special_angles = []
|
||||
if self._current_special_angles:
|
||||
next_special_angle = self._current_special_angles[0]
|
||||
if np.isclose(angle, next_special_angle, atol=0.5):
|
||||
self._current_special_angles.pop(0)
|
||||
num_repeats = self.special_angle_repeats
|
||||
else:
|
||||
num_repeats = 1
|
||||
try:
|
||||
start_scan_number = bec.queue.next_scan_number
|
||||
for i in range(num_repeats):
|
||||
self._at_each_angle(
|
||||
float(angle),
|
||||
stepsize=float(stepsize),
|
||||
loptz_pos=float(loptz_pos),
|
||||
manual_shift_x=float(manual_shift_x),
|
||||
manual_shift_y=float(manual_shift_y),
|
||||
)
|
||||
error_caught = False
|
||||
except AlarmBase as exc:
|
||||
if exc.alarm_type == "TimeoutError":
|
||||
bec.queue.request_queue_reset()
|
||||
time.sleep(2)
|
||||
error_caught = True
|
||||
else:
|
||||
raise exc
|
||||
|
||||
if self._was_beam_okay() and not error_caught:
|
||||
successful = True
|
||||
else:
|
||||
self._wait_for_beamline_checks()
|
||||
|
||||
end_scan_number = bec.queue.next_scan_number
|
||||
for scan_nr in range(start_scan_number, end_scan_number):
|
||||
self._write_tomo_scan_number(scan_nr, angle, subtomo_number)
|
||||
|
||||
def _update_tomo_data_from_file(self, fname: str) -> None:
|
||||
"""Load projection parameters from the HDF5 file into self.tomo_data."""
|
||||
with h5py.File(fname, "r") as file:
|
||||
self.tomo_data["theta"] = np.array([*file["theta"]]).flatten()
|
||||
self.tomo_data["stepsize"] = np.array([*file["stepsize"]]).flatten()
|
||||
self.tomo_data["loptz"] = np.array([*file["loptz"]]).flatten()
|
||||
self.tomo_data["propagation_distance"] = np.array(
|
||||
[*file["relative_propagation_distance"]]
|
||||
).flatten()
|
||||
self.tomo_data["manual_shift_x"] = np.array([*file["manual_shift_x"]]).flatten()
|
||||
self.tomo_data["manual_shift_y"] = np.array([*file["manual_shift_y"]]).flatten()
|
||||
self.tomo_data["subtomo_id"] = np.array([*file["subtomo_id"]]).flatten()
|
||||
|
||||
shapes = [data.shape for data in self.tomo_data.values()]
|
||||
if len(set(shapes)) > 1:
|
||||
raise ValueError(f"Tomo data file has entries of inconsistent lengths: {shapes}.")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,290 +0,0 @@
|
||||
import builtins
|
||||
import time
|
||||
|
||||
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
|
||||
from csaxs_bec.bec_ipython_client.plugins.omny.omny_general_tools import OMNYTools
|
||||
|
||||
dev = builtins.__dict__.get("dev")
|
||||
umv = builtins.__dict__.get("umv")
|
||||
bec = builtins.__dict__.get("bec")
|
||||
|
||||
|
||||
class LamNIInitError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class LaMNIInitStages:
|
||||
"""Handles hardware initialization and referencing of LamNI stages."""
|
||||
|
||||
def __init__(self, client):
|
||||
super().__init__()
|
||||
self.client = client
|
||||
self.OMNYTools = OMNYTools(self.client)
|
||||
|
||||
def lamni_init_stages(self):
|
||||
|
||||
if self.OMNYTools.yesno("Start initialization of LamNI stages. OK?"):
|
||||
print("starting...")
|
||||
dev.lsamrot.enabled = True
|
||||
else:
|
||||
return
|
||||
|
||||
if self.check_all_axes_of_lamni_referenced():
|
||||
if self.OMNYTools.yesno("All axes are referenced. Continue anyways?"):
|
||||
print("ok then...")
|
||||
else:
|
||||
return
|
||||
|
||||
axis_id_lsamrot = dev.lsamrot._config["deviceConfig"].get("axis_Id")
|
||||
if dev.lsamrot.controller.get_motor_limit_switch(axis_id_lsamrot)[1] == False:
|
||||
if self.OMNYTools.yesno("The rotation stage will be moved to one limit"):
|
||||
print("starting...")
|
||||
else:
|
||||
return
|
||||
|
||||
self.drive_axis_to_limit(dev.lsamrot, "forward")
|
||||
dev.lsamrot.enabled = False
|
||||
print("Now hard reboot the controller and run the initialization routine again.")
|
||||
print("The controller will be disabled in bec. To enable dev.lsamrot.enabled=True")
|
||||
return
|
||||
|
||||
if self.OMNYTools.yesno(
|
||||
"Init of loptz. Can the stage move to the upstream limit without collision?"
|
||||
):
|
||||
print("ok then...")
|
||||
else:
|
||||
return
|
||||
|
||||
print("Referencing loptz")
|
||||
self.drive_axis_to_limit(dev.loptz, "forward")
|
||||
self.find_reference_mark(dev.loptz)
|
||||
|
||||
print("Referencing loptx")
|
||||
self.drive_axis_to_limit(dev.loptx, "reverse")
|
||||
self.find_reference_mark(dev.loptx)
|
||||
|
||||
print("Referencing lopty")
|
||||
self.drive_axis_to_limit(dev.lopty, "forward")
|
||||
self.find_reference_mark(dev.lopty)
|
||||
|
||||
print("Referencing lsamx")
|
||||
self.drive_axis_to_limit(dev.lsamx, "forward")
|
||||
self.find_reference_mark(dev.lsamx)
|
||||
|
||||
print("Referencing lsamy")
|
||||
self.drive_axis_to_limit(dev.lsamy, "reverse")
|
||||
self.find_reference_mark(dev.lsamy)
|
||||
|
||||
print("Referencing lsamrot")
|
||||
self.drive_axis_to_limit(dev.lsamrot, "reverse")
|
||||
time.sleep(0.1)
|
||||
self.find_reference_mark(dev.lsamrot)
|
||||
|
||||
if self.OMNYTools.yesno(
|
||||
"Init of leye. Can the stage move to -x limit without collision?"
|
||||
):
|
||||
print("starting...")
|
||||
else:
|
||||
return
|
||||
|
||||
print("Referencing leyex")
|
||||
self.drive_axis_to_limit(dev.leyex, "forward")
|
||||
print("Referencing leyey")
|
||||
self.drive_axis_to_limit(dev.leyey, "forward")
|
||||
|
||||
print("Init of Smaract stages")
|
||||
dev.losax.controller.find_reference_mark(2, 0, 1000, 1)
|
||||
time.sleep(1)
|
||||
dev.losax.controller.find_reference_mark(0, 0, 1000, 1)
|
||||
time.sleep(1)
|
||||
dev.losax.controller.find_reference_mark(1, 0, 1000, 1)
|
||||
time.sleep(1)
|
||||
|
||||
self._align_setup()
|
||||
|
||||
def find_reference_mark(self, device):
|
||||
axis_id = device._config["deviceConfig"].get("axis_Id")
|
||||
axis_id_numeric = self.axis_id_to_numeric(axis_id)
|
||||
device.controller.find_reference(axis_id_numeric)
|
||||
|
||||
def drive_axis_to_limit(self, device, direction):
|
||||
axis_id = device._config["deviceConfig"].get("axis_Id")
|
||||
axis_id_numeric = self.axis_id_to_numeric(axis_id)
|
||||
device.controller.drive_axis_to_limit(axis_id_numeric, direction)
|
||||
|
||||
def axis_id_to_numeric(self, axis_id) -> int:
|
||||
return ord(axis_id.lower()) - 97
|
||||
|
||||
def _align_setup(self):
|
||||
if self.OMNYTools.yesno("Start moving stages to default initial positions?"):
|
||||
print("Start moving stages...")
|
||||
else:
|
||||
print("Stopping.")
|
||||
return
|
||||
|
||||
lsamx_center = dev.lsamx.user_parameter.get("center")
|
||||
if lsamx_center is None:
|
||||
raise LamNIInitError(
|
||||
"Could not find a lsamx center position. Please check your device config."
|
||||
)
|
||||
lsamy_center = dev.lsamy.user_parameter.get("center")
|
||||
if lsamy_center is None:
|
||||
raise LamNIInitError(
|
||||
"Could not find a lsamy center position. Please check your device config."
|
||||
)
|
||||
umv(dev.lsamx, lsamx_center, dev.lsamy, lsamy_center, dev.loptx, -0.3, dev.lopty, 0)
|
||||
umv(dev.losax, -1)
|
||||
umv(dev.loptz, 82.25)
|
||||
umv(dev.lsamrot, -1)
|
||||
umv(dev.lsamrot, 0)
|
||||
|
||||
time.sleep(2)
|
||||
dev.rtx.controller.feedback_disable_and_even_reset_lamni_angle_interferometer()
|
||||
|
||||
def check_all_axes_of_lamni_referenced(self):
|
||||
if (
|
||||
dev.losax.controller.axis_is_referenced(0)
|
||||
& dev.losax.controller.axis_is_referenced(1)
|
||||
& dev.losax.controller.axis_is_referenced(2)
|
||||
& dev.lsamx.controller.all_axes_referenced()
|
||||
):
|
||||
print("All axes of LamNI are referenced.")
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class LamNIOpticsMixin:
|
||||
"""Optics movement methods: FZP, OSA, central stop and X-ray eye."""
|
||||
|
||||
@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 leye_out(self):
|
||||
self.loptics_in()
|
||||
fshclose()
|
||||
leyey_out = self._get_user_param_safe("leyey", "out")
|
||||
umv(dev.leyey, leyey_out)
|
||||
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 2)
|
||||
umv(dev.lsamrot, 0)
|
||||
umv(dev.dttrz, 5854, dev.fttrz, 2395)
|
||||
|
||||
def leye_in(self):
|
||||
bec.queue.next_dataset_number += 1
|
||||
umv(dev.lsamrot, 0)
|
||||
umv(dev.dttrz, 6419.677, dev.fttrz, 2959.979)
|
||||
while True:
|
||||
moved_out = (input("Did the flight tube move out? (Y/n)") or "y").lower()
|
||||
if moved_out == "y":
|
||||
break
|
||||
if moved_out == "n":
|
||||
return
|
||||
leyex_in = self._get_user_param_safe("leyex", "in")
|
||||
leyey_in = self._get_user_param_safe("leyey", "in")
|
||||
umv(dev.leyex, leyex_in, dev.leyey, leyey_in)
|
||||
self.align.update_frame()
|
||||
|
||||
def _lfzp_in(self):
|
||||
loptx_in = self._get_user_param_safe("loptx", "in")
|
||||
lopty_in = self._get_user_param_safe("lopty", "in")
|
||||
umv(dev.loptx, loptx_in, dev.lopty, lopty_in)
|
||||
|
||||
def lfzp_in(self):
|
||||
"""Move in the LamNI zone plate, disabling/re-enabling RT feedback around the move."""
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
|
||||
self._lfzp_in()
|
||||
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def loptics_in(self):
|
||||
"""Move in the LamNI optics (FZP + OSA)."""
|
||||
self.lfzp_in()
|
||||
self.losa_in()
|
||||
|
||||
def loptics_out(self):
|
||||
"""Move out the LamNI optics."""
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
|
||||
self.losa_out()
|
||||
loptx_out = self._get_user_param_safe("loptx", "out")
|
||||
lopty_out = self._get_user_param_safe("lopty", "out")
|
||||
umv(dev.loptx, loptx_out, dev.lopty, lopty_out)
|
||||
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
time.sleep(1)
|
||||
dev.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def lcs_in(self):
|
||||
pass
|
||||
|
||||
def lcs_out(self):
|
||||
umv(dev.lcsy, 3)
|
||||
|
||||
def losa_in(self):
|
||||
losax_in = self._get_user_param_safe("losax", "in")
|
||||
losay_in = self._get_user_param_safe("losay", "in")
|
||||
losaz_in = self._get_user_param_safe("losaz", "in")
|
||||
umv(dev.losax, losax_in, dev.losay, losay_in)
|
||||
umv(dev.losaz, losaz_in)
|
||||
|
||||
def losa_out(self):
|
||||
losay_out = self._get_user_param_safe("losay", "out")
|
||||
losaz_out = self._get_user_param_safe("losaz", "out")
|
||||
umv(dev.losaz, losaz_out)
|
||||
umv(dev.losay, losay_out)
|
||||
|
||||
def lfzp_info(self, mokev_val=-1):
|
||||
if mokev_val == -1:
|
||||
try:
|
||||
mokev_val = dev.mokev.readback.get()
|
||||
except Exception:
|
||||
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]
|
||||
|
||||
console = Console()
|
||||
table = Table(
|
||||
title=f"At the current energy of {mokev_val:.4f} keV we have following options:",
|
||||
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
|
||||
beam_size = (
|
||||
-diameter / (focal_distance * 1000) * (focal_distance * 1000 - distance) * 1e6
|
||||
)
|
||||
table.add_row(
|
||||
f"{diameter*1e6:.2f} microns",
|
||||
f"{focal_distance:.2f} mm",
|
||||
f"{beam_size:.2f} microns",
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
print(
|
||||
"The numbers presented here are for a sample in the plane of the lamni sample holder.\n"
|
||||
)
|
||||
@@ -1,2 +0,0 @@
|
||||
from .cSAXS_beamline import epics_get, epics_put, fshclose, fshopen, fshstatus
|
||||
from .csaxs_bl_checks import cSAXSBeamlineChecks
|
||||
@@ -1,41 +0,0 @@
|
||||
# import builtins
|
||||
# import datetime
|
||||
# import os
|
||||
# import subprocess
|
||||
# import time
|
||||
# from pathlib import Path
|
||||
|
||||
# import numpy as np
|
||||
from bec_lib import bec_logger
|
||||
# from bec_lib.alarm_handler import AlarmBase
|
||||
# from bec_lib.pdf_writer import PDFWriter
|
||||
from typeguard import typechecked
|
||||
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS.smaract import cSAXSInitSmaractStages
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS.smaract import cSAXSSmaract
|
||||
from csaxs_bec.bec_ipython_client.plugins.omny.omny_general_tools import OMNYTools
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS.filter_transmission import cSAXSFilterTransmission
|
||||
class cSAXSError(Exception):
|
||||
pass
|
||||
|
||||
class cSAXS(
|
||||
cSAXSInitSmaractStages,
|
||||
cSAXSSmaract,
|
||||
cSAXSFilterTransmission,
|
||||
):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
self.device_manager = client.device_manager
|
||||
self.OMNYTools = OMNYTools(self.client)
|
||||
super().__init__(client=client)
|
||||
|
||||
|
||||
# this is the csaxs master file that imports all routines from csaxs
|
||||
# can be imported in the bec client by
|
||||
# run in bec from folder /sls/x12sa/config/bec/production/csaxs_bec
|
||||
# from csaxs_bec.bec_ipython_client.plugins.cSAXS.cSAXS import cSAXS
|
||||
# csaxs = cSAXS(bec)
|
||||
#
|
||||
# then all commands can be accessed by for example
|
||||
# csaxs._cSAXS_smaract_stages_.....
|
||||
@@ -1,122 +0,0 @@
|
||||
import builtins
|
||||
import datetime
|
||||
import threading
|
||||
import time
|
||||
|
||||
from bec_lib import bec_logger
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
if builtins.__dict__.get("bec"):
|
||||
bec = builtins.__dict__.get("bec")
|
||||
|
||||
|
||||
class cSAXSBeamlineChecks:
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.check_shutter = True
|
||||
self.check_light_available = True
|
||||
self.check_fofb = True
|
||||
self._check_msgs = []
|
||||
self._beam_is_okay = True
|
||||
self._stop_beam_check_event = None
|
||||
self.beam_check_thread = None
|
||||
|
||||
def get_beamline_checks_enabled(self):
|
||||
print(
|
||||
f"Shutter: {self.check_shutter}\nFOFB: {self.check_fofb}\nLight available:"
|
||||
f" {self.check_light_available}"
|
||||
)
|
||||
|
||||
@property
|
||||
def beamline_checks_enabled(self):
|
||||
return {
|
||||
"shutter": self.check_shutter,
|
||||
"fofb": self.check_fofb,
|
||||
"light available": self.check_light_available,
|
||||
}
|
||||
|
||||
@beamline_checks_enabled.setter
|
||||
def beamline_checks_enabled(self, val: bool):
|
||||
self.check_shutter = val
|
||||
self.check_light_available = val
|
||||
self.check_fofb = val
|
||||
self.get_beamline_checks_enabled()
|
||||
|
||||
def _run_beamline_checks(self):
|
||||
msgs = []
|
||||
dev = builtins.__dict__.get("dev")
|
||||
try:
|
||||
if self.check_shutter:
|
||||
shutter_val = dev.x12sa_es1_shutter_status.read(cached=True)
|
||||
if shutter_val["value"].lower() != "open":
|
||||
self._beam_is_okay = False
|
||||
msgs.append("Check beam failed: Shutter is closed.")
|
||||
if self.check_light_available:
|
||||
machine_status = dev.sls_machine_status.read(cached=True)
|
||||
if machine_status["value"] not in ["Light Available", "Light-Available"]:
|
||||
self._beam_is_okay = False
|
||||
msgs.append("Check beam failed: Light not available.")
|
||||
if self.check_fofb:
|
||||
fast_orbit_feedback = dev.sls_fast_orbit_feedback.read(cached=True)
|
||||
if fast_orbit_feedback["value"] != "running":
|
||||
self._beam_is_okay = False
|
||||
msgs.append("Check beam failed: Fast orbit feedback is not running.")
|
||||
except Exception:
|
||||
logger.warning("Failed to check beam.")
|
||||
return msgs
|
||||
|
||||
def _check_beam(self):
|
||||
while not self._stop_beam_check_event.is_set():
|
||||
self._check_msgs = self._run_beamline_checks()
|
||||
|
||||
if not self._beam_is_okay:
|
||||
self._stop_beam_check_event.set()
|
||||
time.sleep(1)
|
||||
|
||||
def _start_beam_check(self):
|
||||
self._beam_is_okay = True
|
||||
self._stop_beam_check_event = threading.Event()
|
||||
|
||||
self.beam_check_thread = threading.Thread(target=self._check_beam, daemon=True)
|
||||
self.beam_check_thread.start()
|
||||
|
||||
def _was_beam_okay(self):
|
||||
self._stop_beam_check_event.set()
|
||||
self.beam_check_thread.join()
|
||||
return self._beam_is_okay
|
||||
|
||||
def _print_beamline_checks(self):
|
||||
for msg in self._check_msgs:
|
||||
logger.warning(msg)
|
||||
|
||||
def _wait_for_beamline_checks(self):
|
||||
self._print_beamline_checks()
|
||||
try:
|
||||
msg = bec.logbook.LogbookMessage()
|
||||
msg.add_text(
|
||||
"<p><mark class='pen-red'><strong>Beamline checks failed at"
|
||||
f" {str(datetime.datetime.now())}: {''.join(self._check_msgs)}</strong></mark></p>"
|
||||
).add_tag(["BEC", "beam_check"])
|
||||
bec.logbook.send_logbook_message(msg)
|
||||
except Exception:
|
||||
logger.warning("Failed to send update to SciLog.")
|
||||
|
||||
while True:
|
||||
self._beam_is_okay = True
|
||||
self._check_msgs = self._run_beamline_checks()
|
||||
if self._beam_is_okay:
|
||||
break
|
||||
self._print_beamline_checks()
|
||||
time.sleep(1)
|
||||
|
||||
try:
|
||||
msg = bec.logbook.LogbookMessage()
|
||||
msg.add_text(
|
||||
"<p><mark class='pen-red'><strong>Operation resumed at"
|
||||
f" {str(datetime.datetime.now())}.</strong></mark></p>"
|
||||
).add_tag(["BEC", "beam_check"])
|
||||
bec.logbook.send_logbook_message(msg)
|
||||
except Exception:
|
||||
logger.warning("Failed to send update to SciLog.")
|
||||
@@ -1,601 +0,0 @@
|
||||
4000.00 10.5509
|
||||
4012.90 10.6470
|
||||
4025.83 10.7440
|
||||
4038.81 10.8418
|
||||
4051.83 10.9406
|
||||
4064.90 11.0404
|
||||
4078.00 11.1410
|
||||
4091.15 11.2426
|
||||
4104.34 11.3451
|
||||
4117.57 11.4487
|
||||
4130.85 11.5532
|
||||
4144.17 11.6587
|
||||
4157.53 11.7652
|
||||
4170.93 11.8726
|
||||
4184.38 11.9811
|
||||
4197.87 12.0906
|
||||
4211.41 12.2011
|
||||
4224.98 12.3126
|
||||
4238.60 12.4252
|
||||
4252.27 12.5389
|
||||
4265.98 12.6536
|
||||
4279.73 12.7694
|
||||
4293.53 12.8863
|
||||
4307.37 13.0042
|
||||
4321.26 13.1234
|
||||
4335.19 13.2436
|
||||
4349.17 13.3650
|
||||
4363.19 13.4875
|
||||
4377.26 13.6111
|
||||
4391.37 13.7360
|
||||
4405.53 13.8620
|
||||
4419.73 13.9892
|
||||
4433.98 14.1175
|
||||
4448.28 14.2470
|
||||
4462.62 14.3779
|
||||
4477.01 14.5099
|
||||
4491.44 14.6432
|
||||
4505.92 14.7777
|
||||
4520.45 14.9135
|
||||
4535.02 15.0507
|
||||
4549.65 15.1891
|
||||
4564.31 15.3289
|
||||
4579.03 15.4699
|
||||
4593.79 15.6123
|
||||
4608.60 15.7560
|
||||
4623.46 15.9010
|
||||
4638.37 16.0473
|
||||
4653.32 16.1950
|
||||
4668.33 16.3442
|
||||
4683.38 16.4948
|
||||
4698.48 16.6468
|
||||
4713.62 16.8002
|
||||
4728.82 16.9551
|
||||
4744.07 17.1114
|
||||
4759.36 17.2693
|
||||
4774.71 17.4287
|
||||
4790.10 17.5895
|
||||
4805.54 17.7519
|
||||
4821.04 17.9157
|
||||
4836.58 18.0811
|
||||
4852.17 18.2481
|
||||
4867.82 18.4166
|
||||
4883.51 18.5866
|
||||
4899.26 18.7583
|
||||
4915.05 18.9317
|
||||
4930.90 19.1069
|
||||
4946.80 19.2836
|
||||
4962.75 19.4619
|
||||
4978.75 19.6419
|
||||
4994.80 19.8237
|
||||
5010.90 20.0072
|
||||
5027.06 20.1924
|
||||
5043.26 20.3793
|
||||
5059.52 20.5680
|
||||
5075.84 20.7585
|
||||
5092.20 20.9507
|
||||
5108.62 21.1448
|
||||
5125.09 21.3406
|
||||
5141.61 21.5384
|
||||
5158.19 21.7383
|
||||
5174.82 21.9400
|
||||
5191.50 22.1436
|
||||
5208.24 22.3491
|
||||
5225.03 22.5565
|
||||
5241.88 22.7659
|
||||
5258.78 22.9772
|
||||
5275.73 23.1905
|
||||
5292.74 23.4057
|
||||
5309.81 23.6231
|
||||
5326.93 23.8425
|
||||
5344.10 24.0641
|
||||
5361.33 24.2876
|
||||
5378.62 24.5133
|
||||
5395.96 24.7411
|
||||
5413.35 24.9712
|
||||
5430.81 25.2034
|
||||
5448.32 25.4377
|
||||
5465.88 25.6742
|
||||
5483.50 25.9131
|
||||
5501.18 26.1546
|
||||
5518.92 26.3982
|
||||
5536.71 26.6441
|
||||
5554.56 26.8923
|
||||
5572.47 27.1429
|
||||
5590.44 27.3957
|
||||
5608.46 27.6508
|
||||
5626.54 27.9084
|
||||
5644.68 28.1683
|
||||
5662.88 28.4308
|
||||
5681.14 28.6958
|
||||
5699.46 28.9633
|
||||
5717.83 29.2334
|
||||
5736.27 29.5059
|
||||
5754.76 29.7811
|
||||
5773.31 30.0590
|
||||
5791.93 30.3395
|
||||
5810.60 30.6226
|
||||
5829.33 30.9083
|
||||
5848.13 31.1968
|
||||
5866.98 31.4883
|
||||
5885.90 31.7823
|
||||
5904.88 32.0791
|
||||
5923.91 32.3787
|
||||
5943.01 32.6814
|
||||
5962.17 32.9873
|
||||
5981.40 33.2960
|
||||
6000.68 33.6076
|
||||
6020.03 33.9221
|
||||
6039.44 34.2394
|
||||
6058.91 34.5595
|
||||
6078.44 34.8826
|
||||
6098.04 35.2086
|
||||
6117.70 35.5378
|
||||
6137.42 35.8704
|
||||
6157.21 36.2065
|
||||
6177.06 36.5457
|
||||
6196.98 36.8881
|
||||
6216.96 37.2338
|
||||
6237.00 37.5828
|
||||
6257.11 37.9350
|
||||
6277.28 38.2906
|
||||
6297.52 38.6496
|
||||
6317.82 39.0118
|
||||
6338.19 39.3777
|
||||
6358.63 39.7471
|
||||
6379.13 40.1200
|
||||
6399.69 40.4964
|
||||
6420.33 40.8763
|
||||
6441.03 41.2599
|
||||
6461.79 41.6472
|
||||
6482.63 42.0382
|
||||
6503.53 42.4328
|
||||
6524.49 42.8311
|
||||
6545.53 43.2333
|
||||
6566.63 43.6396
|
||||
6587.80 44.0496
|
||||
6609.04 44.4635
|
||||
6630.35 44.8813
|
||||
6651.73 45.3031
|
||||
6673.17 45.7289
|
||||
6694.69 46.1588
|
||||
6716.27 46.5926
|
||||
6737.93 47.0306
|
||||
6759.65 47.4730
|
||||
6781.44 47.9197
|
||||
6803.31 48.3706
|
||||
6825.24 48.8258
|
||||
6847.25 49.2852
|
||||
6869.32 49.7491
|
||||
6891.47 50.2174
|
||||
6913.69 50.6902
|
||||
6935.98 51.1675
|
||||
6958.34 51.6491
|
||||
6980.77 52.1356
|
||||
7003.28 52.6268
|
||||
7025.86 53.1226
|
||||
7048.51 53.6231
|
||||
7071.24 54.1282
|
||||
7094.03 54.6384
|
||||
7116.91 55.1537
|
||||
7139.85 55.6736
|
||||
7162.87 56.1985
|
||||
7185.96 56.7283
|
||||
7209.13 57.2635
|
||||
7232.38 57.8038
|
||||
7255.69 58.3491
|
||||
7279.09 58.8996
|
||||
7302.55 59.4554
|
||||
7326.10 60.0165
|
||||
7349.72 60.5832
|
||||
7373.41 61.1551
|
||||
7397.19 61.7324
|
||||
7421.03 62.3153
|
||||
7444.96 62.9039
|
||||
7468.96 63.4982
|
||||
7493.04 64.0981
|
||||
7517.20 64.7037
|
||||
7541.44 65.3149
|
||||
7565.75 65.9323
|
||||
7590.14 66.5556
|
||||
7614.62 67.1849
|
||||
7639.17 67.8201
|
||||
7663.79 68.4612
|
||||
7688.50 69.1087
|
||||
7713.29 69.7625
|
||||
7738.16 70.4224
|
||||
7763.11 71.0884
|
||||
7788.14 71.7608
|
||||
7813.25 72.4400
|
||||
7838.44 73.1259
|
||||
7863.71 73.8182
|
||||
7889.06 74.5170
|
||||
7914.50 75.2224
|
||||
7940.01 75.9348
|
||||
7965.61 76.6538
|
||||
7991.29 77.3796
|
||||
8017.06 78.1123
|
||||
8042.91 78.8520
|
||||
8068.84 79.5991
|
||||
8094.85 80.3534
|
||||
8120.95 81.1149
|
||||
8147.13 81.8836
|
||||
8173.40 82.6595
|
||||
8199.75 83.4434
|
||||
8226.19 84.2349
|
||||
8252.71 85.0338
|
||||
8279.32 85.8404
|
||||
8306.01 86.6546
|
||||
8332.79 87.4766
|
||||
8359.65 88.3065
|
||||
8386.60 89.1443
|
||||
8413.64 89.9900
|
||||
8440.77 90.8436
|
||||
8467.98 91.7062
|
||||
8495.29 92.5774
|
||||
8522.67 93.4567
|
||||
8550.15 94.3443
|
||||
8577.72 95.2403
|
||||
8605.37 96.1451
|
||||
8633.12 97.0584
|
||||
8660.95 97.9803
|
||||
8688.87 98.9109
|
||||
8716.89 99.8503
|
||||
8744.99 100.799
|
||||
8773.19 101.757
|
||||
8801.47 102.724
|
||||
8829.85 103.700
|
||||
8858.32 104.686
|
||||
8886.88 105.681
|
||||
8915.53 106.687
|
||||
8944.27 107.701
|
||||
8973.11 108.726
|
||||
9002.04 109.760
|
||||
9031.06 110.804
|
||||
9060.18 111.859
|
||||
9089.39 112.924
|
||||
9118.69 113.998
|
||||
9148.09 115.083
|
||||
9177.59 116.179
|
||||
9207.18 117.285
|
||||
9236.86 118.401
|
||||
9266.64 119.529
|
||||
9296.52 120.666
|
||||
9326.49 121.816
|
||||
9356.56 122.976
|
||||
9386.72 124.148
|
||||
9416.99 125.330
|
||||
9447.35 126.524
|
||||
9477.81 127.730
|
||||
9508.37 128.946
|
||||
9539.02 130.174
|
||||
9569.78 131.414
|
||||
9600.63 132.666
|
||||
9631.58 133.931
|
||||
9662.63 135.209
|
||||
9693.79 136.498
|
||||
9725.04 137.800
|
||||
9756.39 139.115
|
||||
9787.85 140.441
|
||||
9819.41 141.780
|
||||
9851.07 143.131
|
||||
9882.83 144.496
|
||||
9914.69 145.873
|
||||
9946.65 147.265
|
||||
9978.72 148.671
|
||||
10010.9 150.090
|
||||
10043.2 151.522
|
||||
10075.5 152.968
|
||||
10108.0 154.429
|
||||
10140.6 155.904
|
||||
10173.3 157.393
|
||||
10206.1 158.896
|
||||
10239.0 160.413
|
||||
10272.0 161.946
|
||||
10305.2 163.493
|
||||
10338.4 165.055
|
||||
10371.7 166.632
|
||||
10405.1 168.224
|
||||
10438.7 169.832
|
||||
10472.3 171.455
|
||||
10506.1 173.093
|
||||
10540.0 174.747
|
||||
10574.0 176.417
|
||||
10608.1 178.104
|
||||
10642.3 179.808
|
||||
10676.6 181.527
|
||||
10711.0 183.263
|
||||
10745.5 185.015
|
||||
10780.2 186.785
|
||||
10814.9 188.572
|
||||
10849.8 190.376
|
||||
10884.8 192.197
|
||||
10919.9 194.035
|
||||
10955.1 195.892
|
||||
10990.4 197.767
|
||||
11025.8 199.659
|
||||
11061.4 201.570
|
||||
11097.0 203.498
|
||||
11132.8 205.447
|
||||
11168.7 207.414
|
||||
11204.7 209.400
|
||||
11240.8 211.405
|
||||
11277.1 213.429
|
||||
11313.4 215.474
|
||||
11349.9 217.538
|
||||
11386.5 219.622
|
||||
11423.2 221.725
|
||||
11460.0 223.849
|
||||
11497.0 225.994
|
||||
11534.1 228.159
|
||||
11571.2 230.344
|
||||
11608.6 232.550
|
||||
11646.0 234.778
|
||||
11683.5 237.028
|
||||
11721.2 239.300
|
||||
11759.0 241.593
|
||||
11796.9 243.908
|
||||
11834.9 246.246
|
||||
11873.1 248.607
|
||||
11911.4 250.991
|
||||
11949.8 253.398
|
||||
11988.3 255.827
|
||||
12026.9 258.280
|
||||
12065.7 260.757
|
||||
12104.6 263.257
|
||||
12143.7 265.781
|
||||
12182.8 268.329
|
||||
12222.1 270.902
|
||||
12261.5 273.502
|
||||
12301.0 276.126
|
||||
12340.7 278.776
|
||||
12380.5 281.450
|
||||
12420.4 284.150
|
||||
12460.4 286.877
|
||||
12500.6 289.629
|
||||
12540.9 292.408
|
||||
12581.3 295.212
|
||||
12621.9 298.045
|
||||
12662.6 300.906
|
||||
12703.4 303.794
|
||||
12744.4 306.709
|
||||
12785.5 309.653
|
||||
12826.7 312.624
|
||||
12868.0 315.625
|
||||
12909.5 318.655
|
||||
12951.1 321.713
|
||||
12992.9 324.800
|
||||
13034.8 327.917
|
||||
13076.8 331.067
|
||||
13119.0 334.246
|
||||
13161.3 337.456
|
||||
13203.7 340.696
|
||||
13246.3 343.968
|
||||
13289.0 347.271
|
||||
13331.8 350.607
|
||||
13374.8 353.973
|
||||
13417.9 357.371
|
||||
13461.2 360.802
|
||||
13504.6 364.269
|
||||
13548.1 367.769
|
||||
13591.8 371.301
|
||||
13635.6 374.867
|
||||
13679.6 378.467
|
||||
13723.7 382.103
|
||||
13767.9 385.773
|
||||
13812.3 389.478
|
||||
13856.9 393.217
|
||||
13901.5 396.994
|
||||
13946.4 400.809
|
||||
13991.3 404.660
|
||||
14036.4 408.548
|
||||
14081.7 412.472
|
||||
14127.1 416.434
|
||||
14172.6 420.436
|
||||
14218.3 424.475
|
||||
14264.2 428.552
|
||||
14310.2 432.668
|
||||
14356.3 436.824
|
||||
14402.6 441.022
|
||||
14449.0 445.260
|
||||
14495.6 449.539
|
||||
14542.3 453.858
|
||||
14589.2 458.217
|
||||
14636.2 462.619
|
||||
14683.4 467.064
|
||||
14730.8 471.549
|
||||
14778.3 476.076
|
||||
14825.9 480.648
|
||||
14873.7 485.268
|
||||
14921.7 489.931
|
||||
14969.8 494.637
|
||||
15018.0 499.389
|
||||
15066.5 504.191
|
||||
15115.0 509.040
|
||||
15163.8 513.935
|
||||
15212.7 518.876
|
||||
15261.7 523.864
|
||||
15310.9 528.901
|
||||
15360.3 533.988
|
||||
15409.8 539.123
|
||||
15459.5 544.306
|
||||
15509.3 549.539
|
||||
15559.3 554.823
|
||||
15609.5 560.159
|
||||
15659.8 565.546
|
||||
15710.3 570.984
|
||||
15761.0 576.473
|
||||
15811.8 582.014
|
||||
15862.7 587.611
|
||||
15913.9 593.262
|
||||
15965.2 598.964
|
||||
16016.7 604.719
|
||||
16068.3 610.531
|
||||
16120.1 616.402
|
||||
16172.1 622.326
|
||||
16224.2 628.306
|
||||
16276.5 634.342
|
||||
16329.0 640.437
|
||||
16381.7 646.596
|
||||
16434.5 652.811
|
||||
16487.5 659.084
|
||||
16540.6 665.416
|
||||
16593.9 671.811
|
||||
16647.4 678.268
|
||||
16701.1 684.786
|
||||
16755.0 691.364
|
||||
16809.0 698.004
|
||||
16863.2 704.710
|
||||
16917.5 711.482
|
||||
16972.1 718.318
|
||||
17026.8 725.217
|
||||
17081.7 732.182
|
||||
17136.8 739.214
|
||||
17192.0 746.315
|
||||
17247.4 753.482
|
||||
17303.1 760.717
|
||||
17358.8 768.018
|
||||
17414.8 775.391
|
||||
17470.9 782.836
|
||||
17527.3 790.351
|
||||
17583.8 797.934
|
||||
17640.5 805.587
|
||||
17697.4 813.318
|
||||
17754.4 821.128
|
||||
17811.6 829.008
|
||||
17869.1 836.961
|
||||
17926.7 844.987
|
||||
17984.5 853.094
|
||||
18042.5 861.278
|
||||
18100.6 869.538
|
||||
18159.0 877.874
|
||||
18217.5 886.286
|
||||
18276.3 894.784
|
||||
18335.2 903.364
|
||||
18394.3 912.023
|
||||
18453.6 920.761
|
||||
18513.1 929.582
|
||||
18572.8 938.489
|
||||
18632.7 947.484
|
||||
18692.8 956.561
|
||||
18753.0 965.723
|
||||
18813.5 974.967
|
||||
18874.1 984.303
|
||||
18935.0 993.729
|
||||
18996.0 1003.24
|
||||
19057.3 1012.84
|
||||
19118.7 1022.53
|
||||
19180.4 1032.31
|
||||
19242.2 1042.19
|
||||
19304.2 1052.16
|
||||
19366.5 1062.22
|
||||
19428.9 1072.37
|
||||
19491.6 1082.63
|
||||
19554.4 1092.98
|
||||
19617.4 1103.42
|
||||
19680.7 1113.96
|
||||
19744.1 1124.59
|
||||
19807.8 1135.38
|
||||
19871.7 1146.29
|
||||
19935.7 1157.29
|
||||
20000.0 1168.40
|
||||
20081.3 1182.56
|
||||
20162.8 1196.82
|
||||
20244.8 1211.23
|
||||
20327.0 1225.81
|
||||
20409.6 1240.55
|
||||
20492.5 1255.47
|
||||
20575.8 1270.57
|
||||
20659.4 1285.83
|
||||
20743.3 1301.26
|
||||
20827.6 1316.88
|
||||
20912.2 1332.67
|
||||
20997.2 1348.64
|
||||
21082.5 1364.79
|
||||
21168.1 1381.13
|
||||
21254.1 1397.65
|
||||
21340.5 1414.36
|
||||
21427.2 1431.26
|
||||
21514.3 1448.35
|
||||
21601.7 1465.63
|
||||
21689.4 1483.11
|
||||
21777.6 1500.78
|
||||
21866.0 1518.66
|
||||
21954.9 1536.73
|
||||
22044.1 1555.01
|
||||
22133.6 1573.50
|
||||
22223.6 1592.19
|
||||
22313.9 1611.09
|
||||
22404.5 1630.19
|
||||
22495.5 1649.51
|
||||
22586.9 1669.05
|
||||
22678.7 1688.80
|
||||
22770.8 1708.77
|
||||
22863.4 1728.96
|
||||
22956.3 1749.38
|
||||
23049.5 1770.02
|
||||
23143.2 1790.88
|
||||
23237.2 1811.97
|
||||
23331.6 1833.30
|
||||
23426.4 1854.85
|
||||
23521.6 1876.64
|
||||
23617.1 1898.66
|
||||
23713.1 1920.93
|
||||
23809.4 1943.44
|
||||
23906.2 1966.19
|
||||
24003.3 1989.19
|
||||
24100.8 2012.43
|
||||
24198.7 2035.93
|
||||
24297.1 2059.67
|
||||
24395.8 2083.67
|
||||
24494.9 2107.92
|
||||
24594.4 2132.44
|
||||
24694.3 2157.20
|
||||
24794.7 2182.24
|
||||
24895.4 2207.53
|
||||
24996.6 2233.09
|
||||
25098.1 2258.92
|
||||
25200.1 2285.02
|
||||
25302.5 2311.40
|
||||
25405.3 2338.05
|
||||
25508.5 2364.98
|
||||
25612.1 2392.19
|
||||
25716.2 2419.68
|
||||
25820.7 2447.45
|
||||
25925.6 2475.50
|
||||
26030.9 2503.85
|
||||
26136.7 2532.50
|
||||
26242.9 2561.42
|
||||
26349.5 2590.64
|
||||
26456.5 2620.16
|
||||
26564.0 2649.97
|
||||
26672.0 2680.08
|
||||
26780.3 2710.49
|
||||
26889.1 2741.21
|
||||
26998.4 2772.24
|
||||
27108.1 2803.57
|
||||
27218.2 2835.21
|
||||
27328.8 2867.17
|
||||
27439.8 2899.44
|
||||
27551.3 2932.02
|
||||
27663.2 2964.91
|
||||
27775.6 2998.14
|
||||
27888.5 3031.69
|
||||
28001.8 3065.56
|
||||
28115.6 3099.75
|
||||
28229.8 3134.27
|
||||
28344.5 3169.12
|
||||
28459.6 3204.30
|
||||
28575.3 3239.80
|
||||
28691.4 3275.66
|
||||
28807.9 3311.85
|
||||
28925.0 3348.37
|
||||
29042.5 3385.23
|
||||
29160.5 3422.44
|
||||
29279.0 3459.98
|
||||
29397.9 3497.87
|
||||
29517.4 3536.09
|
||||
29637.3 3574.69
|
||||
29757.7 3613.62
|
||||
29878.6 3652.90
|
||||
30000.0 3692.52
|
||||
@@ -1,713 +0,0 @@
|
||||
cr Density=7.19, Angle=90.deg
|
||||
Photon Energy (eV), Atten Length (microns)
|
||||
4000.00 7.36948
|
||||
4012.90 7.43487
|
||||
4025.83 7.50083
|
||||
4038.81 7.56737
|
||||
4051.83 7.63450
|
||||
4064.90 7.70224
|
||||
4078.00 7.77057
|
||||
4091.15 7.83951
|
||||
4104.34 7.90905
|
||||
4117.57 7.97916
|
||||
4130.85 8.04989
|
||||
4144.17 8.12124
|
||||
4157.53 8.19322
|
||||
4170.93 8.26584
|
||||
4184.38 8.33903
|
||||
4197.87 8.41287
|
||||
4211.41 8.48736
|
||||
4224.98 8.56251
|
||||
4238.60 8.63834
|
||||
4252.27 8.71478
|
||||
4265.98 8.79189
|
||||
4279.73 8.86969
|
||||
4293.53 8.94819
|
||||
4307.37 9.02737
|
||||
4321.26 9.10723
|
||||
4335.19 9.18779
|
||||
4349.17 9.26908
|
||||
4363.19 9.35108
|
||||
4377.26 9.43379
|
||||
4391.37 9.51723
|
||||
4405.53 9.60141
|
||||
4419.73 9.68634
|
||||
4433.98 9.77201
|
||||
4448.28 9.85842
|
||||
4462.62 9.94550
|
||||
4477.01 10.0334
|
||||
4491.44 10.1220
|
||||
4505.92 10.2114
|
||||
4520.45 10.3016
|
||||
4535.02 10.3923
|
||||
4549.65 10.4839
|
||||
4564.31 10.5763
|
||||
4579.03 10.6695
|
||||
4593.79 10.7635
|
||||
4608.60 10.8584
|
||||
4623.46 10.9541
|
||||
4638.37 11.0507
|
||||
4653.32 11.1481
|
||||
4668.33 11.2464
|
||||
4683.38 11.3454
|
||||
4698.48 11.4454
|
||||
4713.62 11.5462
|
||||
4728.82 11.6479
|
||||
4744.07 11.7504
|
||||
4759.36 11.8538
|
||||
4774.71 11.9581
|
||||
4790.10 12.0633
|
||||
4805.54 12.1694
|
||||
4821.04 12.2764
|
||||
4836.58 12.3843
|
||||
4852.17 12.4932
|
||||
4867.82 12.6031
|
||||
4883.51 12.7139
|
||||
4899.26 12.8256
|
||||
4915.05 12.9381
|
||||
4930.90 13.0516
|
||||
4946.80 13.1662
|
||||
4962.75 13.2817
|
||||
4978.75 13.3982
|
||||
4994.80 13.5157
|
||||
5010.90 13.6342
|
||||
5027.06 13.7537
|
||||
5043.26 13.8743
|
||||
5059.52 13.9959
|
||||
5075.84 14.1184
|
||||
5092.20 14.2419
|
||||
5108.62 14.3665
|
||||
5125.09 14.4922
|
||||
5141.61 14.6190
|
||||
5158.19 14.7468
|
||||
5174.82 14.8758
|
||||
5191.50 15.0059
|
||||
5208.24 15.1371
|
||||
5225.03 15.2694
|
||||
5241.88 15.4027
|
||||
5258.78 15.5371
|
||||
5275.73 15.6728
|
||||
5292.74 15.8096
|
||||
5309.81 15.9475
|
||||
5326.93 16.0865
|
||||
5344.10 16.2268
|
||||
5361.33 16.3682
|
||||
5378.62 16.5109
|
||||
5395.96 16.6547
|
||||
5413.35 16.7997
|
||||
5430.81 16.9460
|
||||
5448.32 17.0935
|
||||
5465.88 17.2423
|
||||
5483.50 17.3923
|
||||
5501.18 17.5434
|
||||
5518.92 17.6959
|
||||
5536.71 17.8497
|
||||
5554.56 18.0048
|
||||
5572.47 18.1612
|
||||
5590.44 18.3188
|
||||
5608.46 18.4778
|
||||
5626.54 18.6382
|
||||
5644.68 18.7999
|
||||
5662.88 18.9630
|
||||
5681.14 19.1272
|
||||
5699.46 19.2929
|
||||
5717.83 19.4600
|
||||
5736.27 19.6286
|
||||
5754.76 19.7984
|
||||
5773.31 19.9696
|
||||
5791.93 20.1423
|
||||
5810.60 20.3164
|
||||
5829.33 20.4921
|
||||
5848.13 20.6691
|
||||
5866.98 20.8476
|
||||
5885.90 21.0276
|
||||
5904.88 21.2091
|
||||
5923.91 21.3922
|
||||
5943.01 21.5768
|
||||
5962.17 21.7631
|
||||
5981.40 21.9510
|
||||
5985.00 21.9863
|
||||
5985.10 21.9873
|
||||
5985.20 21.9883
|
||||
5985.30 21.9892
|
||||
5985.40 21.9902
|
||||
5985.50 21.9912
|
||||
5985.60 21.9922
|
||||
5985.70 21.9932
|
||||
5985.80 21.9941
|
||||
5985.90 21.9951
|
||||
5986.00 21.9961
|
||||
5986.10 21.9971
|
||||
5986.20 21.9981
|
||||
5986.30 21.9990
|
||||
5986.40 22.0000
|
||||
5986.50 22.0010
|
||||
5986.60 22.0020
|
||||
5986.70 22.0030
|
||||
5986.80 22.0040
|
||||
5986.90 22.0049
|
||||
5987.00 22.0059
|
||||
5987.10 22.0069
|
||||
5987.20 22.0079
|
||||
5987.30 22.0088
|
||||
5987.40 22.0098
|
||||
5987.50 22.0108
|
||||
5987.60 22.0118
|
||||
5987.70 22.0128
|
||||
5987.80 22.0138
|
||||
5987.90 22.0147
|
||||
5988.00 22.0157
|
||||
5988.10 22.0167
|
||||
5988.20 22.0177
|
||||
5988.30 22.0187
|
||||
5988.40 22.0196
|
||||
5988.50 22.0206
|
||||
5988.60 22.0216
|
||||
5988.70 22.0226
|
||||
5988.80 22.0236
|
||||
5988.90 22.0245
|
||||
5989.00 22.0255
|
||||
5989.10 22.0265
|
||||
5989.11 20.7400
|
||||
5989.12 18.3877
|
||||
5989.13 16.3020
|
||||
5989.14 14.4528
|
||||
5989.15 13.6083
|
||||
5989.16 12.0645
|
||||
5989.17 10.6957
|
||||
5989.18 9.48212
|
||||
5989.19 8.40620
|
||||
5989.20 7.91492
|
||||
5989.30 2.84297
|
||||
5989.40 2.67688
|
||||
5989.50 2.67699
|
||||
5989.60 2.67710
|
||||
5989.70 2.67720
|
||||
5989.80 2.67732
|
||||
5989.90 2.67742
|
||||
5990.00 2.67753
|
||||
5990.10 2.67764
|
||||
5990.20 2.67775
|
||||
5990.30 2.67786
|
||||
5990.40 2.67797
|
||||
5990.50 2.67808
|
||||
5990.60 2.67819
|
||||
5990.70 2.67829
|
||||
5990.80 2.67841
|
||||
5990.90 2.67851
|
||||
5991.00 2.67862
|
||||
5991.10 2.67874
|
||||
5991.20 2.67884
|
||||
5991.30 2.67895
|
||||
5991.40 2.67906
|
||||
5991.50 2.67917
|
||||
5991.60 2.67928
|
||||
5991.70 2.67939
|
||||
5991.80 2.67950
|
||||
5991.90 2.67961
|
||||
5992.00 2.67972
|
||||
5992.10 2.67983
|
||||
5992.20 2.67993
|
||||
5992.30 2.68004
|
||||
5992.40 2.68015
|
||||
5992.50 2.68026
|
||||
5992.60 2.68037
|
||||
5992.70 2.68048
|
||||
5992.80 2.68059
|
||||
5992.90 2.68070
|
||||
5993.00 2.68081
|
||||
5993.10 2.68092
|
||||
5993.20 2.68103
|
||||
5993.30 2.68114
|
||||
5993.40 2.68124
|
||||
5993.50 2.68136
|
||||
5993.60 2.68146
|
||||
5993.70 2.68157
|
||||
5993.80 2.68168
|
||||
5993.90 2.68179
|
||||
5994.00 2.68190
|
||||
5994.10 2.68201
|
||||
5994.20 2.68212
|
||||
5994.30 2.68223
|
||||
5994.40 2.68234
|
||||
5994.50 2.68245
|
||||
5994.60 2.68256
|
||||
5994.70 2.68267
|
||||
5994.80 2.68277
|
||||
5994.90 2.68289
|
||||
5995.00 2.68299
|
||||
6000.68 2.68920
|
||||
6020.03 2.71041
|
||||
6039.44 2.73179
|
||||
6058.91 2.75333
|
||||
6078.44 2.77504
|
||||
6098.04 2.79692
|
||||
6117.70 2.81898
|
||||
6137.42 2.84127
|
||||
6157.21 2.86379
|
||||
6177.06 2.88648
|
||||
6196.98 2.90936
|
||||
6216.96 2.93243
|
||||
6237.00 2.95574
|
||||
6257.11 2.97929
|
||||
6277.28 3.00304
|
||||
6297.52 3.02698
|
||||
6317.82 3.05110
|
||||
6338.19 3.07550
|
||||
6358.63 3.10015
|
||||
6379.13 3.12500
|
||||
6399.69 3.15005
|
||||
6420.33 3.17530
|
||||
6441.03 3.20082
|
||||
6461.79 3.22661
|
||||
6482.63 3.25261
|
||||
6503.53 3.27882
|
||||
6524.49 3.30523
|
||||
6545.53 3.33194
|
||||
6566.63 3.35893
|
||||
6587.80 3.38613
|
||||
6609.04 3.41355
|
||||
6630.35 3.44119
|
||||
6651.73 3.46915
|
||||
6673.17 3.49738
|
||||
6694.69 3.52584
|
||||
6716.27 3.55453
|
||||
6737.93 3.58346
|
||||
6759.65 3.61269
|
||||
6781.44 3.64220
|
||||
6803.31 3.67196
|
||||
6825.24 3.70197
|
||||
6847.25 3.73221
|
||||
6869.32 3.76280
|
||||
6891.47 3.79370
|
||||
6913.69 3.82485
|
||||
6935.98 3.85626
|
||||
6958.34 3.88793
|
||||
6980.77 3.91995
|
||||
7003.28 3.95230
|
||||
7025.86 3.98491
|
||||
7048.51 4.01779
|
||||
7071.24 4.05094
|
||||
7094.03 4.08445
|
||||
7116.91 4.11828
|
||||
7139.85 4.15239
|
||||
7162.87 4.18677
|
||||
7185.96 4.22145
|
||||
7209.13 4.25650
|
||||
7232.38 4.29188
|
||||
7255.69 4.32756
|
||||
7279.09 4.36353
|
||||
7302.55 4.39981
|
||||
7326.10 4.43648
|
||||
7349.72 4.47351
|
||||
7373.41 4.51084
|
||||
7397.19 4.54849
|
||||
7421.03 4.58645
|
||||
7444.96 4.62485
|
||||
7468.96 4.66363
|
||||
7493.04 4.70273
|
||||
7517.20 4.74216
|
||||
7541.44 4.78192
|
||||
7565.75 4.82210
|
||||
7590.14 4.86264
|
||||
7614.62 4.90353
|
||||
7639.17 4.94475
|
||||
7663.79 4.98633
|
||||
7688.50 5.02838
|
||||
7713.29 5.07085
|
||||
7738.16 5.11367
|
||||
7763.11 5.15684
|
||||
7788.14 5.20039
|
||||
7813.25 5.24440
|
||||
7838.44 5.28883
|
||||
7863.71 5.33362
|
||||
7889.06 5.37880
|
||||
7914.50 5.42435
|
||||
7940.01 5.47042
|
||||
7965.61 5.51690
|
||||
7991.29 5.56378
|
||||
8017.06 5.61105
|
||||
8042.91 5.65874
|
||||
8068.84 5.70693
|
||||
8094.85 5.75557
|
||||
8120.95 5.80462
|
||||
8147.13 5.85410
|
||||
8173.40 5.90399
|
||||
8199.75 5.95444
|
||||
8226.19 6.00537
|
||||
8252.71 6.05673
|
||||
8279.32 6.10854
|
||||
8306.01 6.16078
|
||||
8332.79 6.21357
|
||||
8359.65 6.26684
|
||||
8386.60 6.32058
|
||||
8413.64 6.37477
|
||||
8440.77 6.42942
|
||||
8467.98 6.48472
|
||||
8495.29 6.54056
|
||||
8522.67 6.59686
|
||||
8550.15 6.65365
|
||||
8577.72 6.71093
|
||||
8605.37 6.76883
|
||||
8633.12 6.82725
|
||||
8660.95 6.88617
|
||||
8688.87 6.94559
|
||||
8716.89 7.00554
|
||||
8744.99 7.06612
|
||||
8773.19 7.12724
|
||||
8801.47 7.18888
|
||||
8829.85 7.25106
|
||||
8858.32 7.31379
|
||||
8886.88 7.37722
|
||||
8915.53 7.44124
|
||||
8944.27 7.50581
|
||||
8973.11 7.57095
|
||||
9002.04 7.63665
|
||||
9031.06 7.70305
|
||||
9060.18 7.77005
|
||||
9089.39 7.83764
|
||||
9118.69 7.90581
|
||||
9148.09 7.97457
|
||||
9177.59 8.04414
|
||||
9207.18 8.11433
|
||||
9236.86 8.18516
|
||||
9266.64 8.25659
|
||||
9296.52 8.32864
|
||||
9326.49 8.40145
|
||||
9356.56 8.47492
|
||||
9386.72 8.54902
|
||||
9416.99 8.62377
|
||||
9447.35 8.69918
|
||||
9477.81 8.77535
|
||||
9508.37 8.85219
|
||||
9539.02 8.92970
|
||||
9569.78 9.00788
|
||||
9600.63 9.08677
|
||||
9631.58 9.16655
|
||||
9662.63 9.24704
|
||||
9693.79 9.32825
|
||||
9725.04 9.41018
|
||||
9756.39 9.49281
|
||||
9787.85 9.57645
|
||||
9819.41 9.66083
|
||||
9851.07 9.74598
|
||||
9882.83 9.83186
|
||||
9914.69 9.91849
|
||||
9946.65 10.0060
|
||||
9978.72 10.0943
|
||||
10010.9 10.1834
|
||||
10043.2 10.2733
|
||||
10075.5 10.3640
|
||||
10108.0 10.4556
|
||||
10140.6 10.5481
|
||||
10173.3 10.6413
|
||||
10206.1 10.7354
|
||||
10239.0 10.8303
|
||||
10272.0 10.9263
|
||||
10305.2 11.0231
|
||||
10338.4 11.1208
|
||||
10371.7 11.2194
|
||||
10405.1 11.3188
|
||||
10438.7 11.4194
|
||||
10472.3 11.5208
|
||||
10506.1 11.6230
|
||||
10540.0 11.7262
|
||||
10574.0 11.8304
|
||||
10608.1 11.9356
|
||||
10642.3 12.0418
|
||||
10676.6 12.1490
|
||||
10711.0 12.2571
|
||||
10745.5 12.3661
|
||||
10780.2 12.4764
|
||||
10814.9 12.5876
|
||||
10849.8 12.6998
|
||||
10884.8 12.8130
|
||||
10919.9 12.9272
|
||||
10955.1 13.0427
|
||||
10990.4 13.1592
|
||||
11025.8 13.2768
|
||||
11061.4 13.3954
|
||||
11097.0 13.5150
|
||||
11132.8 13.6360
|
||||
11168.7 13.7580
|
||||
11204.7 13.8811
|
||||
11240.8 14.0053
|
||||
11277.1 14.1307
|
||||
11313.4 14.2574
|
||||
11349.9 14.3852
|
||||
11386.5 14.5142
|
||||
11423.2 14.6443
|
||||
11460.0 14.7757
|
||||
11497.0 14.9083
|
||||
11534.1 15.0422
|
||||
11571.2 15.1773
|
||||
11608.6 15.3135
|
||||
11646.0 15.4511
|
||||
11683.5 15.5901
|
||||
11721.2 15.7303
|
||||
11759.0 15.8718
|
||||
11796.9 16.0146
|
||||
11834.9 16.1587
|
||||
11873.1 16.3043
|
||||
11911.4 16.4513
|
||||
11949.8 16.5995
|
||||
11988.3 16.7491
|
||||
12026.9 16.9000
|
||||
12065.7 17.0525
|
||||
12104.6 17.2064
|
||||
12143.7 17.3617
|
||||
12182.8 17.5184
|
||||
12222.1 17.6765
|
||||
12261.5 17.8363
|
||||
12301.0 17.9976
|
||||
12340.7 18.1603
|
||||
12380.5 18.3245
|
||||
12420.4 18.4901
|
||||
12460.4 18.6575
|
||||
12500.6 18.8264
|
||||
12540.9 18.9968
|
||||
12581.3 19.1688
|
||||
12621.9 19.3424
|
||||
12662.6 19.5177
|
||||
12703.4 19.6947
|
||||
12744.4 19.8733
|
||||
12785.5 20.0535
|
||||
12826.7 20.2353
|
||||
12868.0 20.4190
|
||||
12909.5 20.6044
|
||||
12951.1 20.7915
|
||||
12992.9 20.9802
|
||||
13034.8 21.1708
|
||||
13076.8 21.3633
|
||||
13119.0 21.5576
|
||||
13161.3 21.7536
|
||||
13203.7 21.9515
|
||||
13246.3 22.1512
|
||||
13289.0 22.3528
|
||||
13331.8 22.5564
|
||||
13374.8 22.7618
|
||||
13417.9 22.9690
|
||||
13461.2 23.1782
|
||||
13504.6 23.3896
|
||||
13548.1 23.6029
|
||||
13591.8 23.8181
|
||||
13635.6 24.0353
|
||||
13679.6 24.2545
|
||||
13723.7 24.4759
|
||||
13767.9 24.6994
|
||||
13812.3 24.9248
|
||||
13856.9 25.1523
|
||||
13901.5 25.3820
|
||||
13946.4 25.6141
|
||||
13991.3 25.8482
|
||||
14036.4 26.0845
|
||||
14081.7 26.3230
|
||||
14127.1 26.5638
|
||||
14172.6 26.8069
|
||||
14218.3 27.0522
|
||||
14264.2 27.2998
|
||||
14310.2 27.5497
|
||||
14356.3 27.8019
|
||||
14402.6 28.0567
|
||||
14449.0 28.3139
|
||||
14495.6 28.5734
|
||||
14542.3 28.8353
|
||||
14589.2 29.0996
|
||||
14636.2 29.3665
|
||||
14683.4 29.6359
|
||||
14730.8 29.9077
|
||||
14778.3 30.1820
|
||||
14825.9 30.4590
|
||||
14873.7 30.7388
|
||||
14921.7 31.0211
|
||||
14969.8 31.3061
|
||||
15018.0 31.5936
|
||||
15066.5 31.8840
|
||||
15115.0 32.1772
|
||||
15163.8 32.4731
|
||||
15212.7 32.7717
|
||||
15261.7 33.0731
|
||||
15310.9 33.3774
|
||||
15360.3 33.6847
|
||||
15409.8 33.9948
|
||||
15459.5 34.3078
|
||||
15509.3 34.6237
|
||||
15559.3 34.9426
|
||||
15609.5 35.2647
|
||||
15659.8 35.5897
|
||||
15710.3 35.9178
|
||||
15761.0 36.2488
|
||||
15811.8 36.5830
|
||||
15862.7 36.9205
|
||||
15913.9 37.2612
|
||||
15965.2 37.6049
|
||||
16016.7 37.9518
|
||||
16068.3 38.3020
|
||||
16120.1 38.6557
|
||||
16172.1 39.0126
|
||||
16224.2 39.3728
|
||||
16276.5 39.7363
|
||||
16329.0 40.1034
|
||||
16381.7 40.4742
|
||||
16434.5 40.8483
|
||||
16487.5 41.2259
|
||||
16540.6 41.6069
|
||||
16593.9 41.9918
|
||||
16647.4 42.3803
|
||||
16701.1 42.7724
|
||||
16755.0 43.1681
|
||||
16809.0 43.5676
|
||||
16863.2 43.9708
|
||||
16917.5 44.3781
|
||||
16972.1 44.7890
|
||||
17026.8 45.2038
|
||||
17081.7 45.6225
|
||||
17136.8 46.0452
|
||||
17192.0 46.4720
|
||||
17247.4 46.9028
|
||||
17303.1 47.3376
|
||||
17358.8 47.7763
|
||||
17414.8 48.2193
|
||||
17470.9 48.6665
|
||||
17527.3 49.1180
|
||||
17583.8 49.5735
|
||||
17640.5 50.0333
|
||||
17697.4 50.4976
|
||||
17754.4 50.9666
|
||||
17811.6 51.4398
|
||||
17869.1 51.9174
|
||||
17926.7 52.3995
|
||||
17984.5 52.8862
|
||||
18042.5 53.3776
|
||||
18100.6 53.8735
|
||||
18159.0 54.3740
|
||||
18217.5 54.8791
|
||||
18276.3 55.3893
|
||||
18335.2 55.9043
|
||||
18394.3 56.4241
|
||||
18453.6 56.9488
|
||||
18513.1 57.4783
|
||||
18572.8 58.0130
|
||||
18632.7 58.5529
|
||||
18692.8 59.0978
|
||||
18753.0 59.6479
|
||||
18813.5 60.2029
|
||||
18874.1 60.7633
|
||||
18935.0 61.3292
|
||||
18996.0 61.9003
|
||||
19057.3 62.4767
|
||||
19118.7 63.0584
|
||||
19180.4 63.6458
|
||||
19242.2 64.2390
|
||||
19304.2 64.8376
|
||||
19366.5 65.4417
|
||||
19428.9 66.0514
|
||||
19491.6 66.6670
|
||||
19554.4 67.2887
|
||||
19617.4 67.9160
|
||||
19680.7 68.5491
|
||||
19744.1 69.1881
|
||||
19807.8 69.8335
|
||||
19871.7 70.4851
|
||||
19935.7 71.1427
|
||||
20000.0 71.8064
|
||||
20081.3 72.6515
|
||||
20162.8 73.5071
|
||||
20244.8 74.3726
|
||||
20327.0 75.2484
|
||||
20409.6 76.1342
|
||||
20492.5 77.0315
|
||||
20575.8 77.9393
|
||||
20659.4 78.8575
|
||||
20743.3 79.7867
|
||||
20827.6 80.7275
|
||||
20912.2 81.6791
|
||||
20997.2 82.6420
|
||||
21082.5 83.6161
|
||||
21168.1 84.6024
|
||||
21254.1 85.6003
|
||||
21340.5 86.6097
|
||||
21427.2 87.6312
|
||||
21514.3 88.6652
|
||||
21601.7 89.7114
|
||||
21689.4 90.7699
|
||||
21777.6 91.8408
|
||||
21866.0 92.9252
|
||||
21954.9 94.0222
|
||||
22044.1 95.1321
|
||||
22133.6 96.2552
|
||||
22223.6 97.3920
|
||||
22313.9 98.5423
|
||||
22404.5 99.7058
|
||||
22495.5 100.883
|
||||
22586.9 102.075
|
||||
22678.7 103.281
|
||||
22770.8 104.501
|
||||
22863.4 105.736
|
||||
22956.3 106.986
|
||||
23049.5 108.250
|
||||
23143.2 109.529
|
||||
23237.2 110.824
|
||||
23331.6 112.134
|
||||
23426.4 113.459
|
||||
23521.6 114.800
|
||||
23617.1 116.157
|
||||
23713.1 117.531
|
||||
23809.4 118.921
|
||||
23906.2 120.327
|
||||
24003.3 121.750
|
||||
24100.8 123.190
|
||||
24198.7 124.647
|
||||
24297.1 126.121
|
||||
24395.8 127.612
|
||||
24494.9 129.122
|
||||
24594.4 130.649
|
||||
24694.3 132.194
|
||||
24794.7 133.758
|
||||
24895.4 135.340
|
||||
24996.6 136.941
|
||||
25098.1 138.561
|
||||
25200.1 140.200
|
||||
25302.5 141.859
|
||||
25405.3 143.537
|
||||
25508.5 145.235
|
||||
25612.1 146.954
|
||||
25716.2 148.693
|
||||
25820.7 150.452
|
||||
25925.6 152.232
|
||||
26030.9 154.033
|
||||
26136.7 155.856
|
||||
26242.9 157.700
|
||||
26349.5 159.566
|
||||
26456.5 161.454
|
||||
26564.0 163.364
|
||||
26672.0 165.297
|
||||
26780.3 167.252
|
||||
26889.1 169.231
|
||||
26998.4 171.233
|
||||
27108.1 173.258
|
||||
27218.2 175.308
|
||||
27328.8 177.381
|
||||
27439.8 179.479
|
||||
27551.3 181.602
|
||||
27663.2 183.749
|
||||
27775.6 185.923
|
||||
27888.5 188.122
|
||||
28001.8 190.346
|
||||
28115.6 192.597
|
||||
28229.8 194.874
|
||||
28344.5 197.178
|
||||
28459.6 199.509
|
||||
28575.3 201.867
|
||||
28691.4 204.253
|
||||
28807.9 206.667
|
||||
28925.0 209.110
|
||||
29042.5 211.580
|
||||
29160.5 214.080
|
||||
29279.0 216.610
|
||||
29397.9 219.169
|
||||
29517.4 221.758
|
||||
29637.3 224.377
|
||||
29757.7 227.027
|
||||
29878.6 229.707
|
||||
30000.0 232.418
|
||||
@@ -1,636 +0,0 @@
|
||||
4000.00 3.25746
|
||||
4016.15 3.29307
|
||||
4032.37 3.32906
|
||||
4048.65 3.36546
|
||||
4065.00 3.40227
|
||||
4081.41 3.43947
|
||||
4097.89 3.47709
|
||||
4114.44 3.51514
|
||||
4131.06 3.55362
|
||||
4147.74 3.59251
|
||||
4164.48 3.63183
|
||||
4181.30 3.67160
|
||||
4198.18 3.71182
|
||||
4215.14 3.75247
|
||||
4232.16 3.79357
|
||||
4249.25 3.83514
|
||||
4266.40 3.87716
|
||||
4283.63 3.91965
|
||||
4300.93 3.96259
|
||||
4318.29 4.00604
|
||||
4335.73 4.04997
|
||||
4353.24 4.09438
|
||||
4370.82 4.13928
|
||||
4388.47 4.18468
|
||||
4406.19 4.23059
|
||||
4423.98 4.27699
|
||||
4441.84 4.32391
|
||||
4459.78 4.37138
|
||||
4477.79 4.41938
|
||||
4495.87 4.46791
|
||||
4514.02 4.51696
|
||||
4532.25 4.56663
|
||||
4550.55 4.61685
|
||||
4568.93 4.66763
|
||||
4587.37 4.71896
|
||||
4605.90 4.77084
|
||||
4624.50 4.82328
|
||||
4643.17 4.87629
|
||||
4661.92 4.92989
|
||||
4680.74 4.98413
|
||||
4699.64 5.03898
|
||||
4718.62 5.09443
|
||||
4737.67 5.15049
|
||||
4756.80 5.20723
|
||||
4776.01 5.26461
|
||||
4795.30 5.32262
|
||||
4814.66 5.38126
|
||||
4834.10 5.44057
|
||||
4853.62 5.50053
|
||||
4873.22 5.56116
|
||||
4892.90 5.62244
|
||||
4912.65 5.68447
|
||||
4932.49 5.74717
|
||||
4952.41 5.81058
|
||||
4972.41 5.87468
|
||||
4992.48 5.93953
|
||||
5012.64 6.00510
|
||||
5032.88 6.07139
|
||||
5053.21 6.13842
|
||||
5073.61 6.20623
|
||||
5094.10 6.27479
|
||||
5114.67 6.34412
|
||||
5135.32 6.41420
|
||||
5156.06 6.48511
|
||||
5176.88 6.55680
|
||||
5197.78 6.62929
|
||||
5218.77 6.70258
|
||||
5239.84 6.77683
|
||||
5261.00 6.85190
|
||||
5282.24 6.92781
|
||||
5303.57 7.00455
|
||||
5324.99 7.08208
|
||||
5346.49 7.16047
|
||||
5368.08 7.23972
|
||||
5389.76 7.31986
|
||||
5411.52 7.40104
|
||||
5433.37 7.48313
|
||||
5455.31 7.56613
|
||||
5477.34 7.65005
|
||||
5499.46 7.73501
|
||||
5521.66 7.82091
|
||||
5543.96 7.90777
|
||||
5566.34 7.99558
|
||||
5588.82 8.08432
|
||||
5611.39 8.17404
|
||||
5634.05 8.26476
|
||||
5656.80 8.35649
|
||||
5679.64 8.44953
|
||||
5702.57 8.54360
|
||||
5725.60 8.63871
|
||||
5748.72 8.73487
|
||||
5771.93 8.83200
|
||||
5795.24 8.93022
|
||||
5818.64 9.02952
|
||||
5842.13 9.12998
|
||||
5865.72 9.23186
|
||||
5889.41 9.33488
|
||||
5913.19 9.43905
|
||||
5937.07 9.54436
|
||||
5961.04 9.65080
|
||||
5985.11 9.75840
|
||||
6009.28 9.86722
|
||||
6033.54 9.97725
|
||||
6057.91 10.0886
|
||||
6082.37 10.2012
|
||||
6106.93 10.3150
|
||||
6131.59 10.4301
|
||||
6156.35 10.5469
|
||||
6181.21 10.6649
|
||||
6206.17 10.7843
|
||||
6231.23 10.9050
|
||||
6256.39 11.0271
|
||||
6281.65 11.1506
|
||||
6307.01 11.2754
|
||||
6332.48 11.4017
|
||||
6358.05 11.5295
|
||||
6383.73 11.6588
|
||||
6409.50 11.7895
|
||||
6435.38 11.9216
|
||||
6461.37 12.0555
|
||||
6487.46 12.1909
|
||||
6513.66 12.3278
|
||||
6539.96 12.4663
|
||||
6566.37 12.6064
|
||||
6592.88 12.7481
|
||||
6619.50 12.8914
|
||||
6646.23 13.0364
|
||||
6673.07 13.1831
|
||||
6700.01 13.3316
|
||||
6727.07 13.4816
|
||||
6754.23 13.6334
|
||||
6781.50 13.7871
|
||||
6808.89 13.9425
|
||||
6836.38 14.0996
|
||||
6863.99 14.2586
|
||||
6891.70 14.4197
|
||||
6919.53 14.5825
|
||||
6947.47 14.7472
|
||||
6975.53 14.9137
|
||||
7003.69 15.0824
|
||||
7031.97 15.2530
|
||||
7060.37 15.4255
|
||||
7088.88 15.6001
|
||||
7117.50 15.7768
|
||||
7146.24 15.9555
|
||||
7175.10 16.1362
|
||||
7204.07 16.3191
|
||||
7233.16 16.5043
|
||||
7262.37 16.6916
|
||||
7291.69 16.8810
|
||||
7321.13 17.0726
|
||||
7350.70 17.2667
|
||||
7380.38 17.4630
|
||||
7410.18 17.6615
|
||||
7440.10 17.8624
|
||||
7470.14 18.0658
|
||||
7500.31 18.2715
|
||||
7530.59 18.4796
|
||||
7561.00 18.6902
|
||||
7591.53 18.9034
|
||||
7622.19 19.1191
|
||||
7652.96 19.3372
|
||||
7683.87 19.5580
|
||||
7714.89 19.7815
|
||||
7746.05 20.0076
|
||||
7777.32 20.2363
|
||||
7808.73 20.4678
|
||||
7840.26 20.7023
|
||||
7871.92 20.9395
|
||||
7903.70 21.1793
|
||||
7935.62 21.4222
|
||||
7967.66 21.6681
|
||||
7999.84 21.9168
|
||||
8032.14 22.1684
|
||||
8064.57 22.4232
|
||||
8097.14 22.6812
|
||||
8129.83 22.9422
|
||||
8162.66 23.2061
|
||||
8195.62 23.4734
|
||||
8228.71 23.7441
|
||||
8261.94 24.0178
|
||||
8295.30 24.2947
|
||||
8328.80 24.5752
|
||||
8362.43 24.8594
|
||||
8396.20 25.1467
|
||||
8430.10 25.4374
|
||||
8464.14 25.7318
|
||||
8498.32 26.0300
|
||||
8532.63 26.3316
|
||||
8567.09 26.6368
|
||||
8601.68 26.9458
|
||||
8636.41 27.2589
|
||||
8671.29 27.5756
|
||||
8706.30 27.8960
|
||||
8741.46 28.2205
|
||||
8776.75 28.5491
|
||||
8812.19 28.8816
|
||||
8847.78 29.2179
|
||||
8883.50 29.5581
|
||||
8919.37 29.9023
|
||||
8955.00 30.2467
|
||||
8956.00 30.2564
|
||||
8957.00 30.2661
|
||||
8958.00 30.2758
|
||||
8958.99 30.2855
|
||||
8959.99 30.2952
|
||||
8960.99 30.3049
|
||||
8961.99 30.3146
|
||||
8962.99 30.3243
|
||||
8963.99 30.3340
|
||||
8964.99 30.3438
|
||||
8965.99 30.3535
|
||||
8966.98 30.3632
|
||||
8967.98 30.3729
|
||||
8968.98 30.3826
|
||||
8969.98 30.3924
|
||||
8970.98 30.4021
|
||||
8971.98 30.4118
|
||||
8972.98 30.4216
|
||||
8973.98 30.4313
|
||||
8974.98 30.4411
|
||||
8975.98 30.4508
|
||||
8976.98 30.4605
|
||||
8977.98 30.4703
|
||||
8978.00 30.4705
|
||||
8978.01 30.4706
|
||||
8978.02 30.4706
|
||||
8978.03 30.4708
|
||||
8978.04 30.4709
|
||||
8978.05 30.4710
|
||||
8978.06 30.4710
|
||||
8978.07 30.4711
|
||||
8978.08 30.4712
|
||||
8978.09 30.4714
|
||||
8978.10 30.4715
|
||||
8978.11 30.4715
|
||||
8978.12 30.4716
|
||||
8978.13 30.4717
|
||||
8978.14 30.4718
|
||||
8978.15 30.4720
|
||||
8978.16 30.4720
|
||||
8978.17 30.4721
|
||||
8978.18 30.4722
|
||||
8978.19 30.4723
|
||||
8978.20 30.4724
|
||||
8978.21 30.4725
|
||||
8978.22 30.4726
|
||||
8978.23 30.4727
|
||||
8978.24 30.4728
|
||||
8978.25 30.4729
|
||||
8978.26 30.4730
|
||||
8978.27 30.4731
|
||||
8978.28 30.4732
|
||||
8978.29 30.4733
|
||||
8978.30 30.4734
|
||||
8978.31 30.4735
|
||||
8978.32 30.4736
|
||||
8978.33 30.4737
|
||||
8978.34 30.4738
|
||||
8978.35 30.4739
|
||||
8978.36 30.4740
|
||||
8978.37 30.4741
|
||||
8978.38 30.4741
|
||||
8978.39 30.4743
|
||||
8978.40 30.4744
|
||||
8978.41 30.4745
|
||||
8978.42 30.4746
|
||||
8978.43 30.4746
|
||||
8978.44 30.4747
|
||||
8978.45 30.4749
|
||||
8978.46 30.4750
|
||||
8978.47 30.4751
|
||||
8978.48 30.4751
|
||||
8978.49 30.4752
|
||||
8978.50 30.4753
|
||||
8978.51 30.4755
|
||||
8978.52 30.4756
|
||||
8978.53 30.4756
|
||||
8978.54 30.4757
|
||||
8978.55 30.4758
|
||||
8978.56 30.4759
|
||||
8978.57 30.4761
|
||||
8978.58 30.4761
|
||||
8978.59 30.4762
|
||||
8978.60 30.4763
|
||||
8978.61 30.4764
|
||||
8978.62 30.4765
|
||||
8978.63 30.4766
|
||||
8978.64 30.4767
|
||||
8978.65 30.4768
|
||||
8978.66 30.4769
|
||||
8978.67 30.4770
|
||||
8978.68 30.4771
|
||||
8978.69 30.4772
|
||||
8978.70 30.4773
|
||||
8978.71 30.4774
|
||||
8978.72 30.4775
|
||||
8978.73 30.4776
|
||||
8978.74 30.4777
|
||||
8978.75 30.4778
|
||||
8978.76 30.4779
|
||||
8978.77 30.4780
|
||||
8978.78 30.4781
|
||||
8978.79 30.4782
|
||||
8978.80 30.4782
|
||||
8978.81 25.6979
|
||||
8978.82 23.5962
|
||||
8978.83 21.6663
|
||||
8978.84 19.8939
|
||||
8978.85 18.2664
|
||||
8978.86 15.3995
|
||||
8978.87 14.1393
|
||||
8978.88 12.9822
|
||||
8978.89 11.9197
|
||||
8978.90 10.9441
|
||||
8978.91 10.0483
|
||||
8978.92 9.22574
|
||||
8978.93 7.77706
|
||||
8978.94 7.14036
|
||||
8978.95 6.55577
|
||||
8978.96 6.01902
|
||||
8978.97 5.52620
|
||||
8978.98 4.65827
|
||||
8978.99 4.27683
|
||||
8979.00 3.92662
|
||||
8979.99 3.92768
|
||||
8980.99 3.92876
|
||||
8981.99 3.92983
|
||||
8982.99 3.93091
|
||||
8983.99 3.93198
|
||||
8984.99 3.93306
|
||||
8985.99 3.93414
|
||||
8987.00 3.93522
|
||||
8988.00 3.93630
|
||||
8989.00 3.93738
|
||||
8990.00 3.93846
|
||||
8991.55 3.94013
|
||||
9027.86 3.97936
|
||||
9064.31 4.01898
|
||||
9100.91 4.05900
|
||||
9137.66 4.09942
|
||||
9174.56 4.14035
|
||||
9211.61 4.18176
|
||||
9248.80 4.22359
|
||||
9286.15 4.26582
|
||||
9323.65 4.30865
|
||||
9361.29 4.35198
|
||||
9399.09 4.39576
|
||||
9437.05 4.43996
|
||||
9475.15 4.48477
|
||||
9513.41 4.53010
|
||||
9551.83 4.57590
|
||||
9590.40 4.62215
|
||||
9629.12 4.66903
|
||||
9668.00 4.71646
|
||||
9707.04 4.76436
|
||||
9746.24 4.81275
|
||||
9785.59 4.86176
|
||||
9825.11 4.91132
|
||||
9864.78 4.96138
|
||||
9904.61 5.01195
|
||||
9944.61 5.06327
|
||||
9984.76 5.11518
|
||||
10025.1 5.16764
|
||||
10065.6 5.22063
|
||||
10106.2 5.27433
|
||||
10147.0 5.32865
|
||||
10188.0 5.38352
|
||||
10229.1 5.43896
|
||||
10270.4 5.49516
|
||||
10311.9 5.55200
|
||||
10353.5 5.60942
|
||||
10395.3 5.66744
|
||||
10437.3 5.72624
|
||||
10479.5 5.78571
|
||||
10521.8 5.84579
|
||||
10564.3 5.90650
|
||||
10606.9 5.96803
|
||||
10649.8 6.03027
|
||||
10692.8 6.09315
|
||||
10735.9 6.15668
|
||||
10779.3 6.22107
|
||||
10822.8 6.28618
|
||||
10866.5 6.35197
|
||||
10910.4 6.41844
|
||||
10954.5 6.48583
|
||||
10998.7 6.55397
|
||||
11043.1 6.62282
|
||||
11087.7 6.69240
|
||||
11132.5 6.76293
|
||||
11177.4 6.83425
|
||||
11222.5 6.90631
|
||||
11267.9 6.97914
|
||||
11313.4 7.05296
|
||||
11359.0 7.12760
|
||||
11404.9 7.20304
|
||||
11451.0 7.27925
|
||||
11497.2 7.35650
|
||||
11543.6 7.43459
|
||||
11590.2 7.51351
|
||||
11637.0 7.59326
|
||||
11684.0 7.67411
|
||||
11731.2 7.75584
|
||||
11778.6 7.83845
|
||||
11826.1 7.92193
|
||||
11873.9 8.00656
|
||||
11921.8 8.09211
|
||||
11970.0 8.17857
|
||||
12018.3 8.26597
|
||||
12066.8 8.35453
|
||||
12115.6 8.44406
|
||||
12164.5 8.53453
|
||||
12213.6 8.62599
|
||||
12262.9 8.71873
|
||||
12312.4 8.81246
|
||||
12362.2 8.90721
|
||||
12412.1 9.00296
|
||||
12462.2 9.10001
|
||||
12512.5 9.19810
|
||||
12563.0 9.29726
|
||||
12613.8 9.39747
|
||||
12664.7 9.49907
|
||||
12715.8 9.60177
|
||||
12767.2 9.70556
|
||||
12818.7 9.81049
|
||||
12870.5 9.91679
|
||||
12922.5 10.0243
|
||||
12974.7 10.1329
|
||||
13027.0 10.2427
|
||||
13079.6 10.3541
|
||||
13132.5 10.4666
|
||||
13185.5 10.5804
|
||||
13238.7 10.6954
|
||||
13292.2 10.8119
|
||||
13345.9 10.9297
|
||||
13399.8 11.0488
|
||||
13453.9 11.1692
|
||||
13508.2 11.2912
|
||||
13562.7 11.4146
|
||||
13617.5 11.5393
|
||||
13672.5 11.6654
|
||||
13727.7 11.7931
|
||||
13783.1 11.9222
|
||||
13838.8 12.0527
|
||||
13894.7 12.1847
|
||||
13950.8 12.3184
|
||||
14007.1 12.4536
|
||||
14063.7 12.5903
|
||||
14120.4 12.7285
|
||||
14177.5 12.8685
|
||||
14234.7 13.0101
|
||||
14292.2 13.1532
|
||||
14349.9 13.2979
|
||||
14407.8 13.4445
|
||||
14466.0 13.5928
|
||||
14524.4 13.7426
|
||||
14583.1 13.8942
|
||||
14642.0 14.0477
|
||||
14701.1 14.2028
|
||||
14760.5 14.3597
|
||||
14820.1 14.5184
|
||||
14879.9 14.6791
|
||||
14940.0 14.8416
|
||||
15000.3 15.0059
|
||||
15060.9 15.1721
|
||||
15121.7 15.3405
|
||||
15182.8 15.5106
|
||||
15244.1 15.6827
|
||||
15305.6 15.8567
|
||||
15367.4 16.0330
|
||||
15429.5 16.2112
|
||||
15491.8 16.3915
|
||||
15554.3 16.5738
|
||||
15617.1 16.7584
|
||||
15680.2 16.9451
|
||||
15743.5 17.1338
|
||||
15807.1 17.3247
|
||||
15870.9 17.5180
|
||||
15935.0 17.7135
|
||||
15999.3 17.9111
|
||||
16063.9 18.1110
|
||||
16128.8 18.3135
|
||||
16193.9 18.5181
|
||||
16259.3 18.7251
|
||||
16325.0 18.9345
|
||||
16390.9 19.1466
|
||||
16457.1 19.3610
|
||||
16523.5 19.5778
|
||||
16590.3 19.7971
|
||||
16657.3 20.0192
|
||||
16724.5 20.2438
|
||||
16792.0 20.4708
|
||||
16859.9 20.7006
|
||||
16927.9 20.9332
|
||||
16996.3 21.1684
|
||||
17064.9 21.4062
|
||||
17133.8 21.6469
|
||||
17203.0 21.8905
|
||||
17272.5 22.1368
|
||||
17342.2 22.3859
|
||||
17412.2 22.6380
|
||||
17482.6 22.8931
|
||||
17553.1 23.1511
|
||||
17624.0 23.4120
|
||||
17695.2 23.6760
|
||||
17766.6 23.9434
|
||||
17838.4 24.2137
|
||||
17910.4 24.4870
|
||||
17982.7 24.7637
|
||||
18055.3 25.0436
|
||||
18128.3 25.3268
|
||||
18201.5 25.6131
|
||||
18275.0 25.9029
|
||||
18348.7 26.1961
|
||||
18422.8 26.4927
|
||||
18497.2 26.7925
|
||||
18571.9 27.0961
|
||||
18646.9 27.4033
|
||||
18722.2 27.7139
|
||||
18797.8 28.0281
|
||||
18873.7 28.3461
|
||||
18949.9 28.6679
|
||||
19026.4 28.9934
|
||||
19103.3 29.3226
|
||||
19180.4 29.6557
|
||||
19257.8 29.9929
|
||||
19335.6 30.3339
|
||||
19413.7 30.6787
|
||||
19492.1 31.0276
|
||||
19570.8 31.3807
|
||||
19649.8 31.7378
|
||||
19729.2 32.0989
|
||||
19808.8 32.4645
|
||||
19888.8 32.8345
|
||||
19969.1 33.2087
|
||||
20049.8 33.5872
|
||||
20130.7 33.9702
|
||||
20212.0 34.3579
|
||||
20293.6 34.7499
|
||||
20375.6 35.1465
|
||||
20457.8 35.5478
|
||||
20540.4 35.9540
|
||||
20623.4 36.3648
|
||||
20706.7 36.7803
|
||||
20790.3 37.2008
|
||||
20874.2 37.6263
|
||||
20958.5 38.0566
|
||||
21043.1 38.4918
|
||||
21128.1 38.9324
|
||||
21213.4 39.3782
|
||||
21299.1 39.8291
|
||||
21385.1 40.2851
|
||||
21471.4 40.7466
|
||||
21558.1 41.2136
|
||||
21645.2 41.6859
|
||||
21732.6 42.1637
|
||||
21820.3 42.6473
|
||||
21908.5 43.1366
|
||||
21996.9 43.6316
|
||||
22085.7 44.1322
|
||||
22174.9 44.6389
|
||||
22264.5 45.1516
|
||||
22354.4 45.6702
|
||||
22444.6 46.1946
|
||||
22535.3 46.7256
|
||||
22626.3 47.2627
|
||||
22717.6 47.8060
|
||||
22809.4 48.3556
|
||||
22901.5 48.9118
|
||||
22993.9 49.4746
|
||||
23086.8 50.0438
|
||||
23180.0 50.6196
|
||||
23273.6 51.2024
|
||||
23367.6 51.7921
|
||||
23461.9 52.3884
|
||||
23556.7 52.9916
|
||||
23651.8 53.6023
|
||||
23747.3 54.2201
|
||||
23843.2 54.8451
|
||||
23939.5 55.4771
|
||||
24036.1 56.1170
|
||||
24133.2 56.7643
|
||||
24230.6 57.4191
|
||||
24328.5 58.0813
|
||||
24426.7 58.7517
|
||||
24525.3 59.4300
|
||||
24624.4 60.1159
|
||||
24723.8 60.8098
|
||||
24823.6 61.5120
|
||||
24923.9 62.2226
|
||||
25024.5 62.9412
|
||||
25125.6 63.6682
|
||||
25227.0 64.4041
|
||||
25328.9 65.1487
|
||||
25431.2 65.9019
|
||||
25533.9 66.6635
|
||||
25637.0 67.4347
|
||||
25740.5 68.2147
|
||||
25844.4 69.0037
|
||||
25948.8 69.8017
|
||||
26053.6 70.6097
|
||||
26158.8 71.4271
|
||||
26264.4 72.2539
|
||||
26370.4 73.0902
|
||||
26476.9 73.9366
|
||||
26583.8 74.7929
|
||||
26691.2 75.6589
|
||||
26799.0 76.5350
|
||||
26907.2 77.4217
|
||||
27015.8 78.3188
|
||||
27124.9 79.2263
|
||||
27234.4 80.1439
|
||||
27344.4 81.0731
|
||||
27454.8 82.0129
|
||||
27565.7 82.9636
|
||||
27677.0 83.9250
|
||||
27788.7 84.8986
|
||||
27901.0 85.8832
|
||||
28013.6 86.8793
|
||||
28126.7 87.8868
|
||||
28240.3 88.9064
|
||||
28354.3 89.9379
|
||||
28468.8 90.9811
|
||||
28583.8 92.0364
|
||||
28699.2 93.1048
|
||||
28815.1 94.1855
|
||||
28931.4 95.2785
|
||||
29048.3 96.3842
|
||||
29165.6 97.5036
|
||||
29283.3 98.6356
|
||||
29401.6 99.7807
|
||||
29520.3 100.939
|
||||
29639.5 102.111
|
||||
29759.2 103.297
|
||||
29879.4 104.497
|
||||
30000.0 105.710
|
||||
@@ -1,601 +0,0 @@
|
||||
4000.00 75.3048
|
||||
4012.90 76.0470
|
||||
4025.83 76.7964
|
||||
4038.81 77.5538
|
||||
4051.83 78.3243
|
||||
4064.90 79.1027
|
||||
4078.00 79.8886
|
||||
4091.15 80.6822
|
||||
4104.34 81.4839
|
||||
4117.57 82.2946
|
||||
4130.85 83.1132
|
||||
4144.17 83.9400
|
||||
4157.53 84.7749
|
||||
4170.93 85.6183
|
||||
4184.38 86.4702
|
||||
4197.87 87.3304
|
||||
4211.41 88.1993
|
||||
4224.98 89.0767
|
||||
4238.60 89.9631
|
||||
4252.27 90.8593
|
||||
4265.98 91.7644
|
||||
4279.73 92.6785
|
||||
4293.53 93.6018
|
||||
4307.37 94.5342
|
||||
4321.26 95.4763
|
||||
4335.19 96.4277
|
||||
4349.17 97.3888
|
||||
4363.19 98.3592
|
||||
4377.26 99.3393
|
||||
4391.37 100.330
|
||||
4405.53 101.330
|
||||
4419.73 102.341
|
||||
4433.98 103.361
|
||||
4448.28 104.392
|
||||
4462.62 105.433
|
||||
4477.01 106.486
|
||||
4491.44 107.549
|
||||
4505.92 108.622
|
||||
4520.45 109.706
|
||||
4535.02 110.802
|
||||
4549.65 111.909
|
||||
4564.31 113.026
|
||||
4579.03 114.155
|
||||
4593.79 115.296
|
||||
4608.60 116.449
|
||||
4623.46 117.613
|
||||
4638.37 118.789
|
||||
4653.32 119.976
|
||||
4668.33 121.176
|
||||
4683.38 122.388
|
||||
4698.48 123.612
|
||||
4713.62 124.848
|
||||
4728.82 126.097
|
||||
4744.07 127.358
|
||||
4759.36 128.632
|
||||
4774.71 129.920
|
||||
4790.10 131.220
|
||||
4805.54 132.533
|
||||
4821.04 133.859
|
||||
4836.58 135.200
|
||||
4852.17 136.554
|
||||
4867.82 137.921
|
||||
4883.51 139.302
|
||||
4899.26 140.697
|
||||
4915.05 142.107
|
||||
4930.90 143.531
|
||||
4946.80 144.969
|
||||
4962.75 146.421
|
||||
4978.75 147.888
|
||||
4994.80 149.371
|
||||
5010.90 150.869
|
||||
5027.06 152.382
|
||||
5043.26 153.910
|
||||
5059.52 155.454
|
||||
5075.84 157.014
|
||||
5092.20 158.590
|
||||
5108.62 160.181
|
||||
5125.09 161.789
|
||||
5141.61 163.412
|
||||
5158.19 165.053
|
||||
5174.82 166.709
|
||||
5191.50 168.382
|
||||
5208.24 170.072
|
||||
5225.03 171.779
|
||||
5241.88 173.505
|
||||
5258.78 175.249
|
||||
5275.73 177.010
|
||||
5292.74 178.788
|
||||
5309.81 180.584
|
||||
5326.93 182.400
|
||||
5344.10 184.235
|
||||
5361.33 186.087
|
||||
5378.62 187.958
|
||||
5395.96 189.848
|
||||
5413.35 191.759
|
||||
5430.81 193.689
|
||||
5448.32 195.638
|
||||
5465.88 197.606
|
||||
5483.50 199.595
|
||||
5501.18 201.604
|
||||
5518.92 203.634
|
||||
5536.71 205.683
|
||||
5554.56 207.753
|
||||
5572.47 209.844
|
||||
5590.44 211.955
|
||||
5608.46 214.088
|
||||
5626.54 216.241
|
||||
5644.68 218.416
|
||||
5662.88 220.614
|
||||
5681.14 222.837
|
||||
5699.46 225.082
|
||||
5717.83 227.350
|
||||
5736.27 229.639
|
||||
5754.76 231.953
|
||||
5773.31 234.292
|
||||
5791.93 236.655
|
||||
5810.60 239.040
|
||||
5829.33 241.449
|
||||
5848.13 243.884
|
||||
5866.98 246.346
|
||||
5885.90 248.831
|
||||
5904.88 251.341
|
||||
5923.91 253.876
|
||||
5943.01 256.437
|
||||
5962.17 259.024
|
||||
5981.40 261.636
|
||||
6000.68 264.273
|
||||
6020.03 266.939
|
||||
6039.44 269.632
|
||||
6058.91 272.352
|
||||
6078.44 275.100
|
||||
6098.04 277.874
|
||||
6117.70 280.677
|
||||
6137.42 283.510
|
||||
6157.21 286.375
|
||||
6177.06 289.268
|
||||
6196.98 292.190
|
||||
6216.96 295.141
|
||||
6237.00 298.122
|
||||
6257.11 301.134
|
||||
6277.28 304.176
|
||||
6297.52 307.249
|
||||
6317.82 310.352
|
||||
6338.19 313.487
|
||||
6358.63 316.655
|
||||
6379.13 319.855
|
||||
6399.69 323.086
|
||||
6420.33 326.349
|
||||
6441.03 329.647
|
||||
6461.79 332.980
|
||||
6482.63 336.345
|
||||
6503.53 339.744
|
||||
6524.49 343.176
|
||||
6545.53 346.645
|
||||
6566.63 350.150
|
||||
6587.80 353.689
|
||||
6609.04 357.264
|
||||
6630.35 360.873
|
||||
6651.73 364.522
|
||||
6673.17 368.208
|
||||
6694.69 371.931
|
||||
6716.27 375.690
|
||||
6737.93 379.487
|
||||
6759.65 383.324
|
||||
6781.44 387.200
|
||||
6803.31 391.114
|
||||
6825.24 395.068
|
||||
6847.25 399.060
|
||||
6869.32 403.095
|
||||
6891.47 407.171
|
||||
6913.69 411.288
|
||||
6935.98 415.446
|
||||
6958.34 419.644
|
||||
6980.77 423.888
|
||||
7003.28 428.176
|
||||
7025.86 432.507
|
||||
7048.51 436.880
|
||||
7071.24 441.297
|
||||
7094.03 445.759
|
||||
7116.91 450.268
|
||||
7139.85 454.820
|
||||
7162.87 459.417
|
||||
7185.96 464.060
|
||||
7209.13 468.753
|
||||
7232.38 473.493
|
||||
7255.69 478.280
|
||||
7279.09 483.113
|
||||
7302.55 487.996
|
||||
7326.10 492.927
|
||||
7349.72 497.909
|
||||
7373.41 502.939
|
||||
7397.19 508.019
|
||||
7421.03 513.150
|
||||
7444.96 518.336
|
||||
7468.96 523.575
|
||||
7493.04 528.866
|
||||
7517.20 534.209
|
||||
7541.44 539.604
|
||||
7565.75 545.056
|
||||
7590.14 550.562
|
||||
7614.62 556.123
|
||||
7639.17 561.737
|
||||
7663.79 567.406
|
||||
7688.50 573.135
|
||||
7713.29 578.922
|
||||
7738.16 584.765
|
||||
7763.11 590.665
|
||||
7788.14 596.622
|
||||
7813.25 602.644
|
||||
7838.44 608.728
|
||||
7863.71 614.870
|
||||
7889.06 621.071
|
||||
7914.50 627.333
|
||||
7940.01 633.662
|
||||
7965.61 640.054
|
||||
7991.29 646.507
|
||||
8017.06 653.027
|
||||
8042.91 659.613
|
||||
8068.84 666.267
|
||||
8094.85 672.988
|
||||
8120.95 679.774
|
||||
8147.13 686.627
|
||||
8173.40 693.545
|
||||
8199.75 700.536
|
||||
8226.19 707.596
|
||||
8252.71 714.725
|
||||
8279.32 721.924
|
||||
8306.01 729.191
|
||||
8332.79 736.537
|
||||
8359.65 743.956
|
||||
8386.60 751.447
|
||||
8413.64 759.010
|
||||
8440.77 766.645
|
||||
8467.98 774.359
|
||||
8495.29 782.151
|
||||
8522.67 790.016
|
||||
8550.15 797.956
|
||||
8577.72 805.973
|
||||
8605.37 814.075
|
||||
8633.12 822.254
|
||||
8660.95 830.511
|
||||
8688.87 838.848
|
||||
8716.89 847.264
|
||||
8744.99 855.773
|
||||
8773.19 864.364
|
||||
8801.47 873.036
|
||||
8829.85 881.791
|
||||
8858.32 890.632
|
||||
8886.88 899.564
|
||||
8915.53 908.583
|
||||
8944.27 917.687
|
||||
8973.11 926.879
|
||||
9002.04 936.156
|
||||
9031.06 945.529
|
||||
9060.18 954.991
|
||||
9089.39 964.544
|
||||
9118.69 974.186
|
||||
9148.09 983.918
|
||||
9177.59 993.754
|
||||
9207.18 1003.68
|
||||
9236.86 1013.71
|
||||
9266.64 1023.83
|
||||
9296.52 1034.04
|
||||
9326.49 1044.35
|
||||
9356.56 1054.77
|
||||
9386.72 1065.27
|
||||
9416.99 1075.88
|
||||
9447.35 1086.59
|
||||
9477.81 1097.41
|
||||
9508.37 1108.33
|
||||
9539.02 1119.35
|
||||
9569.78 1130.47
|
||||
9600.63 1141.70
|
||||
9631.58 1153.05
|
||||
9662.63 1164.51
|
||||
9693.79 1176.07
|
||||
9725.04 1187.74
|
||||
9756.39 1199.52
|
||||
9787.85 1211.41
|
||||
9819.41 1223.40
|
||||
9851.07 1235.52
|
||||
9882.83 1247.73
|
||||
9914.69 1260.07
|
||||
9946.65 1272.53
|
||||
9978.72 1285.10
|
||||
10010.9 1297.80
|
||||
10043.2 1310.62
|
||||
10075.5 1323.56
|
||||
10108.0 1336.63
|
||||
10140.6 1349.82
|
||||
10173.3 1363.12
|
||||
10206.1 1376.55
|
||||
10239.0 1390.10
|
||||
10272.0 1403.79
|
||||
10305.2 1417.60
|
||||
10338.4 1431.54
|
||||
10371.7 1445.60
|
||||
10405.1 1459.79
|
||||
10438.7 1474.12
|
||||
10472.3 1488.58
|
||||
10506.1 1503.17
|
||||
10540.0 1517.88
|
||||
10574.0 1532.73
|
||||
10608.1 1547.73
|
||||
10642.3 1562.86
|
||||
10676.6 1578.12
|
||||
10711.0 1593.52
|
||||
10745.5 1609.05
|
||||
10780.2 1624.73
|
||||
10814.9 1640.56
|
||||
10849.8 1656.52
|
||||
10884.8 1672.62
|
||||
10919.9 1688.86
|
||||
10955.1 1705.26
|
||||
10990.4 1721.80
|
||||
11025.8 1738.48
|
||||
11061.4 1755.31
|
||||
11097.0 1772.28
|
||||
11132.8 1789.42
|
||||
11168.7 1806.71
|
||||
11204.7 1824.15
|
||||
11240.8 1841.73
|
||||
11277.1 1859.47
|
||||
11313.4 1877.37
|
||||
11349.9 1895.43
|
||||
11386.5 1913.64
|
||||
11423.2 1932.00
|
||||
11460.0 1950.51
|
||||
11497.0 1969.20
|
||||
11534.1 1988.04
|
||||
11571.2 2007.04
|
||||
11608.6 2026.20
|
||||
11646.0 2045.52
|
||||
11683.5 2065.01
|
||||
11721.2 2084.67
|
||||
11759.0 2104.49
|
||||
11796.9 2124.47
|
||||
11834.9 2144.61
|
||||
11873.1 2164.94
|
||||
11911.4 2185.44
|
||||
11949.8 2206.10
|
||||
11988.3 2226.93
|
||||
12026.9 2247.93
|
||||
12065.7 2269.10
|
||||
12104.6 2290.45
|
||||
12143.7 2311.97
|
||||
12182.8 2333.66
|
||||
12222.1 2355.52
|
||||
12261.5 2377.58
|
||||
12301.0 2399.82
|
||||
12340.7 2422.23
|
||||
12380.5 2444.81
|
||||
12420.4 2467.57
|
||||
12460.4 2490.52
|
||||
12500.6 2513.65
|
||||
12540.9 2536.95
|
||||
12581.3 2560.43
|
||||
12621.9 2584.10
|
||||
12662.6 2607.97
|
||||
12703.4 2632.01
|
||||
12744.4 2656.23
|
||||
12785.5 2680.65
|
||||
12826.7 2705.24
|
||||
12868.0 2730.02
|
||||
12909.5 2754.99
|
||||
12951.1 2780.15
|
||||
12992.9 2805.48
|
||||
13034.8 2831.01
|
||||
13076.8 2856.75
|
||||
13119.0 2882.68
|
||||
13161.3 2908.79
|
||||
13203.7 2935.09
|
||||
13246.3 2961.58
|
||||
13289.0 2988.27
|
||||
13331.8 3015.16
|
||||
13374.8 3042.22
|
||||
13417.9 3069.48
|
||||
13461.2 3096.93
|
||||
13504.6 3124.59
|
||||
13548.1 3152.44
|
||||
13591.8 3180.48
|
||||
13635.6 3208.71
|
||||
13679.6 3237.14
|
||||
13723.7 3265.77
|
||||
13767.9 3294.58
|
||||
13812.3 3323.59
|
||||
13856.9 3352.79
|
||||
13901.5 3382.19
|
||||
13946.4 3411.80
|
||||
13991.3 3441.60
|
||||
14036.4 3471.59
|
||||
14081.7 3501.78
|
||||
14127.1 3532.17
|
||||
14172.6 3562.75
|
||||
14218.3 3593.52
|
||||
14264.2 3624.49
|
||||
14310.2 3655.65
|
||||
14356.3 3687.00
|
||||
14402.6 3718.57
|
||||
14449.0 3750.32
|
||||
14495.6 3782.27
|
||||
14542.3 3814.41
|
||||
14589.2 3846.74
|
||||
14636.2 3879.25
|
||||
14683.4 3911.97
|
||||
14730.8 3944.86
|
||||
14778.3 3977.94
|
||||
14825.9 4011.22
|
||||
14873.7 4044.71
|
||||
14921.7 4078.38
|
||||
14969.8 4112.24
|
||||
15018.0 4146.37
|
||||
15066.5 4180.85
|
||||
15115.0 4215.54
|
||||
15163.8 4250.41
|
||||
15212.7 4285.47
|
||||
15261.7 4320.73
|
||||
15310.9 4356.18
|
||||
15360.3 4391.83
|
||||
15409.8 4427.67
|
||||
15459.5 4463.69
|
||||
15509.3 4499.91
|
||||
15559.3 4536.31
|
||||
15609.5 4572.91
|
||||
15659.8 4609.69
|
||||
15710.3 4646.67
|
||||
15761.0 4683.81
|
||||
15811.8 4721.14
|
||||
15862.7 4758.65
|
||||
15913.9 4796.35
|
||||
15965.2 4834.22
|
||||
16016.7 4872.26
|
||||
16068.3 4910.49
|
||||
16120.1 4948.89
|
||||
16172.1 4987.46
|
||||
16224.2 5026.21
|
||||
16276.5 5065.12
|
||||
16329.0 5104.21
|
||||
16381.7 5143.49
|
||||
16434.5 5182.92
|
||||
16487.5 5222.51
|
||||
16540.6 5262.27
|
||||
16593.9 5302.21
|
||||
16647.4 5342.29
|
||||
16701.1 5382.53
|
||||
16755.0 5422.93
|
||||
16809.0 5463.49
|
||||
16863.2 5504.19
|
||||
16917.5 5545.04
|
||||
16972.1 5586.05
|
||||
17026.8 5627.20
|
||||
17081.7 5668.50
|
||||
17136.8 5709.94
|
||||
17192.0 5751.52
|
||||
17247.4 5793.24
|
||||
17303.1 5835.11
|
||||
17358.8 5877.10
|
||||
17414.8 5919.21
|
||||
17470.9 5961.44
|
||||
17527.3 6003.81
|
||||
17583.8 6046.29
|
||||
17640.5 6088.90
|
||||
17697.4 6131.63
|
||||
17754.4 6174.50
|
||||
17811.6 6217.47
|
||||
17869.1 6260.56
|
||||
17926.7 6303.76
|
||||
17984.5 6347.06
|
||||
18042.5 6390.45
|
||||
18100.6 6433.93
|
||||
18159.0 6477.52
|
||||
18217.5 6521.21
|
||||
18276.3 6565.00
|
||||
18335.2 6608.85
|
||||
18394.3 6652.80
|
||||
18453.6 6696.84
|
||||
18513.1 6740.98
|
||||
18572.8 6785.17
|
||||
18632.7 6829.43
|
||||
18692.8 6873.77
|
||||
18753.0 6918.19
|
||||
18813.5 6962.68
|
||||
18874.1 7007.21
|
||||
18935.0 7051.79
|
||||
18996.0 7096.45
|
||||
19057.3 7141.15
|
||||
19118.7 7185.91
|
||||
19180.4 7230.70
|
||||
19242.2 7275.52
|
||||
19304.2 7320.39
|
||||
19366.5 7365.30
|
||||
19428.9 7410.25
|
||||
19491.6 7455.20
|
||||
19554.4 7500.17
|
||||
19617.4 7545.17
|
||||
19680.7 7590.19
|
||||
19744.1 7635.24
|
||||
19807.8 7676.69
|
||||
19871.7 7716.04
|
||||
19935.7 7755.41
|
||||
20000.0 7794.78
|
||||
20081.3 7845.79
|
||||
20162.8 7905.30
|
||||
20244.8 7965.51
|
||||
20327.0 8025.78
|
||||
20409.6 8086.09
|
||||
20492.5 8146.39
|
||||
20575.8 8206.73
|
||||
20659.4 8267.08
|
||||
20743.3 8327.46
|
||||
20827.6 8387.78
|
||||
20912.2 8448.09
|
||||
20997.2 8508.41
|
||||
21082.5 8568.71
|
||||
21168.1 8628.96
|
||||
21254.1 8689.19
|
||||
21340.5 8749.37
|
||||
21427.2 8809.53
|
||||
21514.3 8869.58
|
||||
21601.7 8929.59
|
||||
21689.4 8989.56
|
||||
21777.6 9049.44
|
||||
21866.0 9109.23
|
||||
21954.9 9168.94
|
||||
22044.1 9228.57
|
||||
22133.6 9288.12
|
||||
22223.6 9347.52
|
||||
22313.9 9406.82
|
||||
22404.5 9466.02
|
||||
22495.5 9525.10
|
||||
22586.9 9584.02
|
||||
22678.7 9642.81
|
||||
22770.8 9701.49
|
||||
22863.4 9760.01
|
||||
22956.3 9818.35
|
||||
23049.5 9876.55
|
||||
23143.2 9934.59
|
||||
23237.2 9992.46
|
||||
23331.6 10050.1
|
||||
23426.4 10107.6
|
||||
23521.6 10165.0
|
||||
23617.1 10222.1
|
||||
23713.1 10279.0
|
||||
23809.4 10335.7
|
||||
23906.2 10392.3
|
||||
24003.3 10448.6
|
||||
24100.8 10504.6
|
||||
24198.7 10560.5
|
||||
24297.1 10616.1
|
||||
24395.8 10671.5
|
||||
24494.9 10726.7
|
||||
24594.4 10781.6
|
||||
24694.3 10836.3
|
||||
24794.7 10890.7
|
||||
24895.4 10944.8
|
||||
24996.6 10998.7
|
||||
25098.1 11052.4
|
||||
25200.1 11105.7
|
||||
25302.5 11158.8
|
||||
25405.3 11211.6
|
||||
25508.5 11264.2
|
||||
25612.1 11316.4
|
||||
25716.2 11368.4
|
||||
25820.7 11420.0
|
||||
25925.6 11471.4
|
||||
26030.9 11522.5
|
||||
26136.7 11573.3
|
||||
26242.9 11623.8
|
||||
26349.5 11673.9
|
||||
26456.5 11723.8
|
||||
26564.0 11773.3
|
||||
26672.0 11822.5
|
||||
26780.3 11871.4
|
||||
26889.1 11920.0
|
||||
26998.4 11968.2
|
||||
27108.1 12016.1
|
||||
27218.2 12063.7
|
||||
27328.8 12111.0
|
||||
27439.8 12157.9
|
||||
27551.3 12204.5
|
||||
27663.2 12250.7
|
||||
27775.6 12296.6
|
||||
27888.5 12342.2
|
||||
28001.8 12387.4
|
||||
28115.6 12432.3
|
||||
28229.8 12476.8
|
||||
28344.5 12520.9
|
||||
28459.6 12564.8
|
||||
28575.3 12608.3
|
||||
28691.4 12651.4
|
||||
28807.9 12694.1
|
||||
28925.0 12736.5
|
||||
29042.5 12778.6
|
||||
29160.5 12820.3
|
||||
29279.0 12861.6
|
||||
29397.9 12902.6
|
||||
29517.4 12943.3
|
||||
29637.3 12983.5
|
||||
29757.7 13023.4
|
||||
29878.6 13062.9
|
||||
30000.0 13102.1
|
||||
@@ -1,654 +0,0 @@
|
||||
4000.00 4.18514
|
||||
4032.00 4.27608
|
||||
4064.00 4.36835
|
||||
4096.00 4.46188
|
||||
4128.00 4.55672
|
||||
4160.00 4.65282
|
||||
4192.00 4.75023
|
||||
4224.00 4.84893
|
||||
4256.00 4.94900
|
||||
4288.00 5.05041
|
||||
4320.00 5.15311
|
||||
4352.00 5.25711
|
||||
4384.00 5.36245
|
||||
4416.00 5.46917
|
||||
4448.00 5.57723
|
||||
4480.00 5.68671
|
||||
4512.00 5.79754
|
||||
4544.00 5.90984
|
||||
4576.00 6.02351
|
||||
4608.00 6.13856
|
||||
4640.00 6.25497
|
||||
4672.00 6.37280
|
||||
4704.00 6.49212
|
||||
4736.00 6.61284
|
||||
4768.00 6.73496
|
||||
4800.00 6.85847
|
||||
4832.00 6.98349
|
||||
4864.00 7.10998
|
||||
4896.00 7.23792
|
||||
4928.00 7.36743
|
||||
4960.00 7.49840
|
||||
4992.00 7.63088
|
||||
5024.00 7.76488
|
||||
5056.00 7.90034
|
||||
5088.00 8.03728
|
||||
5120.00 8.17572
|
||||
5152.00 8.31572
|
||||
5184.00 8.45730
|
||||
5216.00 8.60040
|
||||
5248.00 8.74518
|
||||
5280.00 8.89151
|
||||
5312.00 9.03937
|
||||
5344.00 9.18870
|
||||
5376.00 9.33957
|
||||
5408.00 9.49208
|
||||
5440.00 9.64620
|
||||
5472.00 9.80192
|
||||
5504.00 9.95941
|
||||
5536.00 10.1185
|
||||
5568.00 10.2793
|
||||
5600.00 10.4416
|
||||
5632.00 10.6056
|
||||
5664.00 10.7712
|
||||
5696.00 10.9384
|
||||
5728.00 11.1073
|
||||
5760.00 11.2779
|
||||
5792.00 11.4503
|
||||
5824.00 11.6244
|
||||
5856.00 11.8001
|
||||
5888.00 11.9775
|
||||
5920.00 12.1565
|
||||
5952.00 12.3374
|
||||
5984.00 12.5200
|
||||
6016.00 12.7044
|
||||
6048.00 12.8905
|
||||
6080.00 13.0784
|
||||
6112.00 13.2679
|
||||
6144.00 13.4594
|
||||
6176.00 13.6526
|
||||
6208.00 13.8477
|
||||
6240.00 14.0445
|
||||
6272.00 14.2430
|
||||
6304.00 14.4433
|
||||
6336.00 14.6454
|
||||
6368.00 14.8494
|
||||
6400.00 15.0552
|
||||
6432.00 15.2628
|
||||
6464.00 15.4728
|
||||
6496.00 15.6846
|
||||
6528.00 15.8982
|
||||
6560.00 16.1135
|
||||
6592.00 16.3306
|
||||
6624.00 16.5496
|
||||
6656.00 16.7704
|
||||
6688.00 16.9930
|
||||
6720.00 17.2175
|
||||
6752.00 17.4439
|
||||
6784.00 17.6725
|
||||
6816.00 17.9030
|
||||
6848.00 18.1353
|
||||
6880.00 18.3699
|
||||
6912.00 18.6065
|
||||
6944.00 18.8451
|
||||
6976.00 19.0856
|
||||
7008.00 19.3280
|
||||
7040.00 19.5724
|
||||
7072.00 19.8187
|
||||
7104.00 20.0672
|
||||
7136.00 20.3177
|
||||
7168.00 20.5701
|
||||
7200.00 20.8246
|
||||
7232.00 21.0813
|
||||
7264.00 21.3400
|
||||
7296.00 21.6007
|
||||
7328.00 21.8635
|
||||
7360.00 22.1284
|
||||
7392.00 22.3954
|
||||
7424.00 22.6644
|
||||
7456.00 22.9356
|
||||
7488.00 23.2089
|
||||
7520.00 23.4843
|
||||
7552.00 23.7618
|
||||
7584.00 24.0416
|
||||
7616.00 24.3234
|
||||
7648.00 24.6073
|
||||
7680.00 24.8934
|
||||
7712.00 25.1819
|
||||
7744.00 25.4725
|
||||
7776.00 25.7652
|
||||
7808.00 26.0601
|
||||
7840.00 26.3574
|
||||
7872.00 26.6568
|
||||
7904.00 26.9584
|
||||
7936.00 27.2623
|
||||
7968.00 27.5685
|
||||
8000.00 27.8769
|
||||
8032.00 28.1875
|
||||
8064.00 28.5004
|
||||
8096.00 28.8157
|
||||
8128.00 29.1332
|
||||
8160.00 29.4529
|
||||
8192.00 29.7750
|
||||
8224.00 30.0995
|
||||
8256.00 30.4263
|
||||
8288.00 30.7553
|
||||
8320.00 31.0867
|
||||
8352.00 31.4206
|
||||
8384.00 31.7567
|
||||
8416.00 32.0952
|
||||
8448.00 32.4360
|
||||
8480.00 32.7795
|
||||
8512.00 33.1254
|
||||
8544.00 33.4736
|
||||
8576.00 33.8241
|
||||
8608.00 34.1772
|
||||
8640.00 34.5327
|
||||
8672.00 34.8906
|
||||
8704.00 35.2508
|
||||
8736.00 35.6136
|
||||
8768.00 35.9790
|
||||
8800.00 36.3468
|
||||
8832.00 36.7170
|
||||
8864.00 37.0896
|
||||
8896.00 37.4651
|
||||
8928.00 37.8431
|
||||
8960.00 38.2235
|
||||
8992.00 38.6063
|
||||
9024.00 38.9918
|
||||
9056.00 39.3799
|
||||
9088.00 39.7704
|
||||
9120.00 40.1635
|
||||
9152.00 40.5591
|
||||
9184.00 40.9576
|
||||
9216.00 41.3587
|
||||
9248.00 41.7624
|
||||
9280.00 42.1685
|
||||
9312.00 42.5773
|
||||
9344.00 42.9889
|
||||
9376.00 43.4031
|
||||
9408.00 43.8199
|
||||
9440.00 44.2392
|
||||
9472.00 44.6616
|
||||
9504.00 45.0866
|
||||
9536.00 45.5144
|
||||
9568.00 45.9447
|
||||
9600.00 46.3776
|
||||
9632.00 46.8134
|
||||
9664.00 47.2520
|
||||
9696.00 47.6933
|
||||
9728.00 48.1371
|
||||
9760.00 48.5836
|
||||
9792.00 49.0336
|
||||
9824.00 49.4863
|
||||
9856.00 49.9416
|
||||
9888.00 50.3996
|
||||
9920.00 50.8604
|
||||
9952.00 51.3245
|
||||
9984.00 51.7913
|
||||
10016.0 52.2608
|
||||
10048.0 52.7331
|
||||
10080.0 53.2082
|
||||
10112.0 53.6867
|
||||
10144.0 54.1679
|
||||
10176.0 54.6518
|
||||
10208.0 55.1386
|
||||
10240.0 55.6281
|
||||
10272.0 56.1213
|
||||
10304.0 56.6173
|
||||
10336.0 57.1161
|
||||
10368.0 57.6177
|
||||
10400.0 58.1222
|
||||
10432.0 58.6302
|
||||
10464.0 59.1412
|
||||
10496.0 59.6551
|
||||
10528.0 60.1718
|
||||
10560.0 60.6913
|
||||
10592.0 61.2144
|
||||
10624.0 61.7407
|
||||
10656.0 62.2698
|
||||
10688.0 62.8019
|
||||
10720.0 63.3370
|
||||
10752.0 63.8753
|
||||
10784.0 64.4172
|
||||
10816.0 64.9622
|
||||
10848.0 65.5099
|
||||
10880.0 66.0608
|
||||
10912.0 66.6146
|
||||
10944.0 67.1722
|
||||
10976.0 67.7332
|
||||
11008.0 68.2969
|
||||
11040.0 68.8638
|
||||
11072.0 69.4338
|
||||
11090.0 69.7556
|
||||
11090.4 69.7628
|
||||
11090.8 69.7700
|
||||
11091.2 69.7772
|
||||
11091.6 69.7843
|
||||
11092.0 69.7914
|
||||
11092.4 69.7986
|
||||
11092.8 69.8058
|
||||
11093.2 69.8130
|
||||
11093.6 69.8202
|
||||
11094.0 69.8273
|
||||
11094.4 69.8345
|
||||
11094.8 69.8417
|
||||
11095.2 69.8489
|
||||
11095.6 69.8561
|
||||
11096.0 69.8632
|
||||
11096.4 69.8704
|
||||
11096.8 69.8777
|
||||
11097.2 69.8849
|
||||
11097.6 69.8921
|
||||
11098.0 69.8992
|
||||
11098.4 69.9064
|
||||
11098.8 69.9136
|
||||
11099.2 69.9209
|
||||
11099.6 69.9280
|
||||
11100.0 69.9352
|
||||
11100.4 69.9424
|
||||
11100.8 69.9496
|
||||
11101.2 69.9569
|
||||
11101.6 69.9640
|
||||
11102.0 69.9712
|
||||
11102.4 69.9784
|
||||
11102.8 69.9857
|
||||
11103.0 69.9893
|
||||
11103.1 26.8271
|
||||
11103.2 9.23223
|
||||
11103.3 9.23243
|
||||
11103.6 9.23305
|
||||
11104.0 9.23389
|
||||
11104.4 9.23473
|
||||
11104.8 9.23557
|
||||
11105.2 9.23639
|
||||
11105.6 9.23724
|
||||
11106.0 9.23807
|
||||
11106.4 9.23891
|
||||
11106.8 9.23974
|
||||
11107.2 9.24058
|
||||
11107.6 9.24142
|
||||
11108.0 9.24226
|
||||
11108.4 9.24310
|
||||
11108.8 9.24392
|
||||
11109.2 9.24476
|
||||
11109.6 9.24560
|
||||
11110.0 9.24644
|
||||
11136.0 9.30092
|
||||
11168.0 9.36821
|
||||
11200.0 9.43583
|
||||
11232.0 9.50371
|
||||
11264.0 9.57189
|
||||
11296.0 9.64038
|
||||
11328.0 9.70916
|
||||
11360.0 9.77823
|
||||
11392.0 9.84760
|
||||
11424.0 9.91726
|
||||
11456.0 9.98722
|
||||
11488.0 10.0578
|
||||
11520.0 10.1286
|
||||
11552.0 10.1998
|
||||
11584.0 10.2712
|
||||
11616.0 10.3430
|
||||
11648.0 10.4151
|
||||
11680.0 10.4878
|
||||
11712.0 10.5608
|
||||
11744.0 10.6341
|
||||
11776.0 10.7077
|
||||
11808.0 10.7816
|
||||
11840.0 10.8559
|
||||
11872.0 10.9307
|
||||
11904.0 11.0059
|
||||
11936.0 11.0814
|
||||
11968.0 11.1572
|
||||
12000.0 11.2333
|
||||
12032.0 11.3098
|
||||
12064.0 11.3868
|
||||
12096.0 11.4641
|
||||
12128.0 11.5417
|
||||
12160.0 11.6197
|
||||
12192.0 11.6980
|
||||
12224.0 11.7767
|
||||
12256.0 11.8560
|
||||
12288.0 11.9356
|
||||
12320.0 12.0155
|
||||
12352.0 12.0958
|
||||
12384.0 12.1763
|
||||
12416.0 12.2573
|
||||
12448.0 12.3388
|
||||
12480.0 12.4206
|
||||
12512.0 12.5028
|
||||
12544.0 12.5853
|
||||
12576.0 12.6681
|
||||
12608.0 12.7513
|
||||
12640.0 12.8351
|
||||
12672.0 12.9192
|
||||
12704.0 13.0037
|
||||
12736.0 13.0885
|
||||
12768.0 13.1737
|
||||
12800.0 13.2592
|
||||
12832.0 13.3452
|
||||
12864.0 13.4316
|
||||
12896.0 13.5184
|
||||
12928.0 13.6056
|
||||
12960.0 13.6931
|
||||
12992.0 13.7809
|
||||
13024.0 13.8691
|
||||
13056.0 13.9580
|
||||
13088.0 14.0472
|
||||
13120.0 14.1368
|
||||
13152.0 14.2267
|
||||
13184.0 14.3170
|
||||
13216.0 14.4076
|
||||
13248.0 14.4987
|
||||
13280.0 14.5903
|
||||
13312.0 14.6823
|
||||
13344.0 14.7746
|
||||
13376.0 14.8673
|
||||
13408.0 14.9603
|
||||
13440.0 15.0537
|
||||
13472.0 15.1477
|
||||
13504.0 15.2421
|
||||
13536.0 15.3369
|
||||
13568.0 15.4321
|
||||
13600.0 15.5276
|
||||
13632.0 15.6235
|
||||
13664.0 15.7198
|
||||
13696.0 15.8166
|
||||
13728.0 15.9139
|
||||
13760.0 16.0115
|
||||
13792.0 16.1095
|
||||
13824.0 16.2079
|
||||
13856.0 16.3066
|
||||
13888.0 16.4057
|
||||
13920.0 16.5056
|
||||
13952.0 16.6057
|
||||
13984.0 16.7063
|
||||
14016.0 16.8072
|
||||
14048.0 16.9086
|
||||
14080.0 17.0102
|
||||
14112.0 17.1123
|
||||
14144.0 17.2151
|
||||
14176.0 17.3182
|
||||
14208.0 17.4217
|
||||
14240.0 17.5256
|
||||
14272.0 17.6298
|
||||
14304.0 17.7345
|
||||
14336.0 17.8395
|
||||
14368.0 17.9452
|
||||
14400.0 18.0513
|
||||
14432.0 18.1578
|
||||
14464.0 18.2648
|
||||
14496.0 18.3721
|
||||
14528.0 18.4797
|
||||
14560.0 18.5878
|
||||
14592.0 18.6965
|
||||
14624.0 18.8056
|
||||
14656.0 18.9151
|
||||
14688.0 19.0250
|
||||
14720.0 19.1353
|
||||
14752.0 19.2461
|
||||
14784.0 19.3572
|
||||
14816.0 19.4687
|
||||
14848.0 19.5810
|
||||
14880.0 19.6936
|
||||
14912.0 19.8067
|
||||
14944.0 19.9201
|
||||
14976.0 20.0340
|
||||
15008.0 20.1483
|
||||
15040.0 20.2629
|
||||
15072.0 20.3782
|
||||
15104.0 20.4940
|
||||
15136.0 20.6102
|
||||
15168.0 20.7268
|
||||
15200.0 20.8439
|
||||
15232.0 20.9613
|
||||
15264.0 21.0791
|
||||
15296.0 21.1974
|
||||
15328.0 21.3164
|
||||
15360.0 21.4357
|
||||
15392.0 21.5556
|
||||
15424.0 21.6758
|
||||
15456.0 21.7964
|
||||
15488.0 21.9174
|
||||
15520.0 22.0389
|
||||
15552.0 22.1609
|
||||
15584.0 22.2836
|
||||
15616.0 22.4066
|
||||
15648.0 22.5301
|
||||
15680.0 22.6540
|
||||
15712.0 22.7783
|
||||
15744.0 22.9031
|
||||
15776.0 23.0283
|
||||
15808.0 23.1540
|
||||
15840.0 23.2804
|
||||
15872.0 23.4071
|
||||
15904.0 23.5343
|
||||
15936.0 23.6620
|
||||
15968.0 23.7900
|
||||
16000.0 23.9185
|
||||
16032.0 24.0474
|
||||
16064.0 24.1769
|
||||
16096.0 24.3070
|
||||
16128.0 24.4375
|
||||
16160.0 24.5685
|
||||
16192.0 24.6998
|
||||
16224.0 24.8317
|
||||
16256.0 24.9640
|
||||
16288.0 25.0967
|
||||
16320.0 25.2300
|
||||
16352.0 25.3639
|
||||
16384.0 25.4983
|
||||
16416.0 25.6331
|
||||
16448.0 25.7683
|
||||
16480.0 25.9041
|
||||
16512.0 26.0402
|
||||
16544.0 26.1768
|
||||
16576.0 26.3140
|
||||
16608.0 26.4518
|
||||
16640.0 26.5901
|
||||
16672.0 26.7288
|
||||
16704.0 26.8680
|
||||
16736.0 27.0076
|
||||
16768.0 27.1477
|
||||
16800.0 27.2883
|
||||
16832.0 27.4292
|
||||
16864.0 27.5710
|
||||
16896.0 27.7132
|
||||
16928.0 27.8559
|
||||
16960.0 27.9990
|
||||
16992.0 28.1426
|
||||
17024.0 28.2867
|
||||
17056.0 28.4312
|
||||
17088.0 28.5762
|
||||
17120.0 28.7218
|
||||
17152.0 28.8680
|
||||
17184.0 29.0147
|
||||
17216.0 29.1619
|
||||
17248.0 29.3096
|
||||
17280.0 29.4577
|
||||
17312.0 29.6063
|
||||
17344.0 29.7553
|
||||
17376.0 29.9049
|
||||
17408.0 30.0551
|
||||
17440.0 30.2058
|
||||
17472.0 30.3571
|
||||
17504.0 30.5087
|
||||
17536.0 30.6609
|
||||
17568.0 30.8135
|
||||
17600.0 30.9667
|
||||
17632.0 31.1203
|
||||
17664.0 31.2744
|
||||
17696.0 31.4293
|
||||
17728.0 31.5847
|
||||
17760.0 31.7406
|
||||
17792.0 31.8969
|
||||
17824.0 32.0539
|
||||
17856.0 32.2112
|
||||
17888.0 32.3690
|
||||
17920.0 32.5274
|
||||
17952.0 32.6862
|
||||
17984.0 32.8457
|
||||
18016.0 33.0058
|
||||
18048.0 33.1663
|
||||
18080.0 33.3274
|
||||
18112.0 33.4889
|
||||
18144.0 33.6510
|
||||
18176.0 33.8135
|
||||
18208.0 33.9765
|
||||
18240.0 34.1400
|
||||
18272.0 34.3043
|
||||
18304.0 34.4691
|
||||
18336.0 34.6345
|
||||
18368.0 34.8003
|
||||
18400.0 34.9667
|
||||
18432.0 35.1335
|
||||
18464.0 35.3009
|
||||
18496.0 35.4688
|
||||
18528.0 35.6371
|
||||
18560.0 35.8062
|
||||
18592.0 35.9758
|
||||
18624.0 36.1461
|
||||
18656.0 36.3168
|
||||
18688.0 36.4880
|
||||
18720.0 36.6597
|
||||
18752.0 36.8320
|
||||
18784.0 37.0047
|
||||
18816.0 37.1780
|
||||
18848.0 37.3518
|
||||
18880.0 37.5264
|
||||
18912.0 37.7016
|
||||
18944.0 37.8772
|
||||
18976.0 38.0533
|
||||
19008.0 38.2300
|
||||
19040.0 38.4072
|
||||
19072.0 38.5849
|
||||
19104.0 38.7631
|
||||
19136.0 38.9418
|
||||
19168.0 39.1213
|
||||
19200.0 39.3014
|
||||
19232.0 39.4821
|
||||
19264.0 39.6633
|
||||
19296.0 39.8449
|
||||
19328.0 40.0272
|
||||
19360.0 40.2099
|
||||
19392.0 40.3932
|
||||
19424.0 40.5770
|
||||
19456.0 40.7613
|
||||
19488.0 40.9464
|
||||
19520.0 41.1321
|
||||
19552.0 41.3183
|
||||
19584.0 41.5051
|
||||
19616.0 41.6923
|
||||
19648.0 41.8801
|
||||
19680.0 42.0685
|
||||
19712.0 42.2573
|
||||
19744.0 42.4468
|
||||
19776.0 42.6368
|
||||
19808.0 42.8276
|
||||
19840.0 43.0190
|
||||
19872.0 43.2109
|
||||
19904.0 43.4034
|
||||
19936.0 43.5964
|
||||
19968.0 43.7899
|
||||
20000.0 43.9840
|
||||
20081.3 44.4794
|
||||
20162.8 44.9811
|
||||
20244.8 45.4884
|
||||
20327.0 46.0015
|
||||
20409.6 46.5203
|
||||
20492.5 47.0458
|
||||
20575.8 47.5773
|
||||
20659.4 48.1147
|
||||
20743.3 48.6582
|
||||
20827.6 49.2087
|
||||
20912.2 49.7653
|
||||
20997.2 50.3283
|
||||
21082.5 50.8976
|
||||
21168.1 51.4742
|
||||
21254.1 52.0573
|
||||
21340.5 52.6470
|
||||
21427.2 53.2434
|
||||
21514.3 53.8472
|
||||
21601.7 54.4579
|
||||
21689.4 55.0755
|
||||
21777.6 55.7001
|
||||
21866.0 56.3329
|
||||
21954.9 56.9726
|
||||
22044.1 57.6197
|
||||
22133.6 58.2743
|
||||
22223.6 58.9369
|
||||
22313.9 59.6071
|
||||
22404.5 60.2848
|
||||
22495.5 60.9705
|
||||
22586.9 61.6647
|
||||
22678.7 62.3667
|
||||
22770.8 63.0767
|
||||
22863.4 63.7950
|
||||
22956.3 64.5220
|
||||
23049.5 65.2573
|
||||
23143.2 66.0009
|
||||
23237.2 66.7533
|
||||
23331.6 67.5151
|
||||
23426.4 68.2854
|
||||
23521.6 69.0646
|
||||
23617.1 69.8528
|
||||
23713.1 70.6508
|
||||
23809.4 71.4578
|
||||
23906.2 72.2739
|
||||
24003.3 73.0998
|
||||
24100.8 73.9355
|
||||
24198.7 74.7810
|
||||
24297.1 75.6360
|
||||
24395.8 76.5011
|
||||
24494.9 77.3767
|
||||
24594.4 78.2624
|
||||
24694.3 79.1580
|
||||
24794.7 80.0644
|
||||
24895.4 80.9815
|
||||
24996.6 81.9092
|
||||
25098.1 82.8474
|
||||
25200.1 83.7969
|
||||
25302.5 84.7579
|
||||
25405.3 85.7297
|
||||
25508.5 86.7128
|
||||
25612.1 87.7077
|
||||
25716.2 88.7142
|
||||
25820.7 89.7324
|
||||
25925.6 90.7621
|
||||
26030.9 91.8045
|
||||
26136.7 92.8592
|
||||
26242.9 93.9258
|
||||
26349.5 95.0048
|
||||
26456.5 96.0966
|
||||
26564.0 97.2014
|
||||
26672.0 98.3188
|
||||
26780.3 99.4487
|
||||
26889.1 100.593
|
||||
26998.4 101.750
|
||||
27108.1 102.920
|
||||
27218.2 104.104
|
||||
27328.8 105.303
|
||||
27439.8 106.515
|
||||
27551.3 107.741
|
||||
27663.2 108.981
|
||||
27775.6 110.237
|
||||
27888.5 111.507
|
||||
28001.8 112.791
|
||||
28115.6 114.091
|
||||
28229.8 115.406
|
||||
28344.5 116.736
|
||||
28459.6 118.082
|
||||
28575.3 119.443
|
||||
28691.4 120.821
|
||||
28807.9 122.214
|
||||
28925.0 123.624
|
||||
29042.5 125.050
|
||||
29160.5 126.493
|
||||
29279.0 127.953
|
||||
29397.9 129.430
|
||||
29517.4 130.924
|
||||
29637.3 132.436
|
||||
29757.7 133.965
|
||||
29878.6 135.512
|
||||
30000.0 137.076
|
||||
@@ -1,601 +0,0 @@
|
||||
4000.00 9.62277
|
||||
4032.00 9.83842
|
||||
4064.00 10.0573
|
||||
4096.00 10.2794
|
||||
4128.00 10.5051
|
||||
4160.00 10.7339
|
||||
4192.00 10.9660
|
||||
4224.00 11.2014
|
||||
4256.00 11.4403
|
||||
4288.00 11.6826
|
||||
4320.00 11.9284
|
||||
4352.00 12.1776
|
||||
4384.00 12.4304
|
||||
4416.00 12.6865
|
||||
4448.00 12.9464
|
||||
4480.00 13.2098
|
||||
4512.00 13.4767
|
||||
4544.00 13.7474
|
||||
4576.00 14.0215
|
||||
4608.00 14.2994
|
||||
4640.00 14.5809
|
||||
4672.00 14.8664
|
||||
4704.00 15.1555
|
||||
4736.00 15.4484
|
||||
4768.00 15.7450
|
||||
4800.00 16.0453
|
||||
4832.00 16.3495
|
||||
4864.00 16.6575
|
||||
4896.00 16.9695
|
||||
4928.00 17.2853
|
||||
4960.00 17.6050
|
||||
4992.00 17.9287
|
||||
5024.00 18.2562
|
||||
5056.00 18.5883
|
||||
5088.00 18.9244
|
||||
5120.00 19.2644
|
||||
5152.00 19.6086
|
||||
5184.00 19.9567
|
||||
5216.00 20.3089
|
||||
5248.00 20.6651
|
||||
5280.00 21.0254
|
||||
5312.00 21.3903
|
||||
5344.00 21.7594
|
||||
5376.00 22.1326
|
||||
5408.00 22.5101
|
||||
5440.00 22.8918
|
||||
5472.00 23.2781
|
||||
5504.00 23.6687
|
||||
5536.00 24.0635
|
||||
5568.00 24.4631
|
||||
5600.00 24.8670
|
||||
5632.00 25.2752
|
||||
5664.00 25.6881
|
||||
5696.00 26.1054
|
||||
5728.00 26.5272
|
||||
5760.00 26.9536
|
||||
5792.00 27.3845
|
||||
5824.00 27.8199
|
||||
5856.00 28.2600
|
||||
5888.00 28.7046
|
||||
5920.00 29.1541
|
||||
5952.00 29.6085
|
||||
5984.00 30.0675
|
||||
6016.00 30.5313
|
||||
6048.00 31.0001
|
||||
6080.00 31.4734
|
||||
6112.00 31.9515
|
||||
6144.00 32.4345
|
||||
6176.00 32.9223
|
||||
6208.00 33.4148
|
||||
6240.00 33.9124
|
||||
6272.00 34.4149
|
||||
6304.00 34.9221
|
||||
6336.00 35.4342
|
||||
6368.00 35.9524
|
||||
6400.00 36.4762
|
||||
6432.00 37.0050
|
||||
6464.00 37.5379
|
||||
6496.00 38.0757
|
||||
6528.00 38.6185
|
||||
6560.00 39.1667
|
||||
6592.00 39.7202
|
||||
6624.00 40.2787
|
||||
6656.00 40.8428
|
||||
6688.00 41.4125
|
||||
6720.00 41.9874
|
||||
6752.00 42.5676
|
||||
6784.00 43.1532
|
||||
6816.00 43.7441
|
||||
6848.00 44.3403
|
||||
6880.00 44.9420
|
||||
6912.00 45.5490
|
||||
6944.00 46.1614
|
||||
6976.00 46.7793
|
||||
7008.00 47.4032
|
||||
7040.00 48.0324
|
||||
7072.00 48.6671
|
||||
7104.00 49.3076
|
||||
7136.00 49.9537
|
||||
7168.00 50.6054
|
||||
7200.00 51.2625
|
||||
7232.00 51.9256
|
||||
7264.00 52.5944
|
||||
7296.00 53.2688
|
||||
7328.00 53.9491
|
||||
7360.00 54.6357
|
||||
7392.00 55.3279
|
||||
7424.00 56.0259
|
||||
7456.00 56.7298
|
||||
7488.00 57.4395
|
||||
7520.00 58.1551
|
||||
7552.00 58.8764
|
||||
7584.00 59.6041
|
||||
7616.00 60.3376
|
||||
7648.00 61.0770
|
||||
7680.00 61.8224
|
||||
7712.00 62.5745
|
||||
7744.00 63.3325
|
||||
7776.00 64.0965
|
||||
7808.00 64.8666
|
||||
7840.00 65.6432
|
||||
7872.00 66.4257
|
||||
7904.00 67.2144
|
||||
7936.00 68.0094
|
||||
7968.00 68.8110
|
||||
8000.00 69.6188
|
||||
8032.00 70.4328
|
||||
8064.00 71.2532
|
||||
8096.00 72.0802
|
||||
8128.00 72.9134
|
||||
8160.00 73.7529
|
||||
8192.00 74.5991
|
||||
8224.00 75.4518
|
||||
8256.00 76.3108
|
||||
8288.00 77.1762
|
||||
8320.00 78.0482
|
||||
8352.00 78.9273
|
||||
8384.00 79.8130
|
||||
8416.00 80.7051
|
||||
8448.00 81.6036
|
||||
8480.00 82.5091
|
||||
8512.00 83.4214
|
||||
8544.00 84.3400
|
||||
8576.00 85.2654
|
||||
8608.00 86.1981
|
||||
8640.00 87.1375
|
||||
8672.00 88.0838
|
||||
8704.00 89.0367
|
||||
8736.00 89.9967
|
||||
8768.00 90.9639
|
||||
8800.00 91.9378
|
||||
8832.00 92.9185
|
||||
8864.00 93.9060
|
||||
8896.00 94.9009
|
||||
8928.00 95.9025
|
||||
8960.00 96.9111
|
||||
8992.00 97.9265
|
||||
9024.00 98.9496
|
||||
9056.00 99.9804
|
||||
9088.00 101.018
|
||||
9120.00 102.063
|
||||
9152.00 103.115
|
||||
9184.00 104.174
|
||||
9216.00 105.240
|
||||
9248.00 106.314
|
||||
9280.00 107.395
|
||||
9312.00 108.483
|
||||
9344.00 109.578
|
||||
9376.00 110.681
|
||||
9408.00 111.791
|
||||
9440.00 112.909
|
||||
9472.00 114.034
|
||||
9504.00 115.168
|
||||
9536.00 116.308
|
||||
9568.00 117.457
|
||||
9600.00 118.612
|
||||
9632.00 119.776
|
||||
9664.00 120.947
|
||||
9696.00 122.125
|
||||
9728.00 123.311
|
||||
9760.00 124.505
|
||||
9792.00 125.707
|
||||
9824.00 126.917
|
||||
9856.00 128.134
|
||||
9888.00 129.358
|
||||
9920.00 130.591
|
||||
9952.00 131.832
|
||||
9984.00 133.080
|
||||
10016.0 134.336
|
||||
10048.0 135.601
|
||||
10080.0 136.872
|
||||
10112.0 138.154
|
||||
10144.0 139.442
|
||||
10176.0 140.739
|
||||
10208.0 142.044
|
||||
10240.0 143.356
|
||||
10272.0 144.677
|
||||
10304.0 146.006
|
||||
10336.0 147.343
|
||||
10368.0 148.687
|
||||
10400.0 150.040
|
||||
10432.0 151.402
|
||||
10464.0 152.773
|
||||
10496.0 154.152
|
||||
10528.0 155.538
|
||||
10560.0 156.933
|
||||
10592.0 158.336
|
||||
10624.0 159.748
|
||||
10656.0 161.168
|
||||
10688.0 162.596
|
||||
10720.0 164.032
|
||||
10752.0 165.477
|
||||
10784.0 166.932
|
||||
10816.0 168.395
|
||||
10848.0 169.867
|
||||
10880.0 171.346
|
||||
10912.0 172.835
|
||||
10944.0 174.332
|
||||
10976.0 175.837
|
||||
11008.0 177.351
|
||||
11040.0 178.873
|
||||
11072.0 180.404
|
||||
11104.0 181.944
|
||||
11136.0 183.494
|
||||
11168.0 185.052
|
||||
11200.0 186.620
|
||||
11232.0 188.195
|
||||
11264.0 189.780
|
||||
11296.0 191.374
|
||||
11328.0 192.976
|
||||
11360.0 194.588
|
||||
11392.0 196.209
|
||||
11424.0 197.838
|
||||
11456.0 199.475
|
||||
11488.0 201.123
|
||||
11520.0 202.780
|
||||
11552.0 204.446
|
||||
11584.0 206.121
|
||||
11616.0 207.805
|
||||
11648.0 209.497
|
||||
11680.0 211.201
|
||||
11712.0 212.913
|
||||
11744.0 214.634
|
||||
11776.0 216.365
|
||||
11808.0 218.104
|
||||
11840.0 219.853
|
||||
11872.0 221.612
|
||||
11904.0 223.381
|
||||
11936.0 225.158
|
||||
11968.0 226.944
|
||||
12000.0 228.740
|
||||
12032.0 230.545
|
||||
12064.0 232.361
|
||||
12096.0 234.186
|
||||
12128.0 236.020
|
||||
12160.0 237.864
|
||||
12192.0 239.716
|
||||
12224.0 241.579
|
||||
12256.0 243.451
|
||||
12288.0 245.333
|
||||
12320.0 247.226
|
||||
12352.0 249.127
|
||||
12384.0 251.038
|
||||
12416.0 252.958
|
||||
12448.0 254.890
|
||||
12480.0 256.832
|
||||
12512.0 258.783
|
||||
12544.0 260.744
|
||||
12576.0 262.715
|
||||
12608.0 264.695
|
||||
12640.0 266.686
|
||||
12672.0 268.687
|
||||
12704.0 270.697
|
||||
12736.0 272.718
|
||||
12768.0 274.748
|
||||
12800.0 276.788
|
||||
12832.0 278.839
|
||||
12864.0 280.900
|
||||
12896.0 282.971
|
||||
12928.0 285.053
|
||||
12960.0 287.144
|
||||
12992.0 289.246
|
||||
13024.0 291.357
|
||||
13056.0 293.479
|
||||
13088.0 295.612
|
||||
13120.0 297.754
|
||||
13152.0 299.907
|
||||
13184.0 302.069
|
||||
13216.0 304.242
|
||||
13248.0 306.425
|
||||
13280.0 308.621
|
||||
13312.0 310.827
|
||||
13344.0 313.044
|
||||
13376.0 315.270
|
||||
13408.0 317.508
|
||||
13440.0 319.755
|
||||
13472.0 322.013
|
||||
13504.0 324.282
|
||||
13536.0 326.561
|
||||
13568.0 328.850
|
||||
13600.0 331.150
|
||||
13632.0 333.460
|
||||
13664.0 335.781
|
||||
13696.0 338.114
|
||||
13728.0 340.458
|
||||
13760.0 342.813
|
||||
13792.0 345.178
|
||||
13824.0 347.554
|
||||
13856.0 349.940
|
||||
13888.0 352.337
|
||||
13920.0 354.747
|
||||
13952.0 357.167
|
||||
13984.0 359.599
|
||||
14016.0 362.041
|
||||
14048.0 364.494
|
||||
14080.0 366.957
|
||||
14112.0 369.432
|
||||
14144.0 371.917
|
||||
14176.0 374.414
|
||||
14208.0 376.922
|
||||
14240.0 379.440
|
||||
14272.0 381.970
|
||||
14304.0 384.509
|
||||
14336.0 387.061
|
||||
14368.0 389.625
|
||||
14400.0 392.202
|
||||
14432.0 394.789
|
||||
14464.0 397.388
|
||||
14496.0 399.998
|
||||
14528.0 402.618
|
||||
14560.0 405.251
|
||||
14592.0 407.895
|
||||
14624.0 410.550
|
||||
14656.0 413.216
|
||||
14688.0 415.894
|
||||
14720.0 418.584
|
||||
14752.0 421.285
|
||||
14784.0 423.996
|
||||
14816.0 426.719
|
||||
14848.0 429.456
|
||||
14880.0 432.204
|
||||
14912.0 434.963
|
||||
14944.0 437.734
|
||||
14976.0 440.516
|
||||
15008.0 443.310
|
||||
15040.0 446.117
|
||||
15072.0 448.937
|
||||
15104.0 451.769
|
||||
15136.0 454.612
|
||||
15168.0 457.468
|
||||
15200.0 460.335
|
||||
15232.0 463.213
|
||||
15264.0 466.102
|
||||
15296.0 469.003
|
||||
15328.0 471.919
|
||||
15360.0 474.845
|
||||
15392.0 477.785
|
||||
15424.0 480.734
|
||||
15456.0 483.697
|
||||
15488.0 486.670
|
||||
15520.0 489.657
|
||||
15552.0 492.654
|
||||
15584.0 495.668
|
||||
15616.0 498.692
|
||||
15648.0 501.728
|
||||
15680.0 504.777
|
||||
15712.0 507.838
|
||||
15744.0 510.910
|
||||
15776.0 513.994
|
||||
15808.0 517.091
|
||||
15840.0 520.202
|
||||
15872.0 523.325
|
||||
15904.0 526.460
|
||||
15936.0 529.607
|
||||
15968.0 532.766
|
||||
16000.0 535.937
|
||||
16032.0 539.120
|
||||
16064.0 542.317
|
||||
16096.0 545.528
|
||||
16128.0 548.751
|
||||
16160.0 551.986
|
||||
16192.0 555.233
|
||||
16224.0 558.493
|
||||
16256.0 561.765
|
||||
16288.0 565.049
|
||||
16320.0 568.346
|
||||
16352.0 571.658
|
||||
16384.0 574.983
|
||||
16416.0 578.320
|
||||
16448.0 581.669
|
||||
16480.0 585.031
|
||||
16512.0 588.405
|
||||
16544.0 591.791
|
||||
16576.0 595.191
|
||||
16608.0 598.605
|
||||
16640.0 602.032
|
||||
16672.0 605.472
|
||||
16704.0 608.925
|
||||
16736.0 612.389
|
||||
16768.0 615.866
|
||||
16800.0 619.357
|
||||
16832.0 622.859
|
||||
16864.0 626.377
|
||||
16896.0 629.907
|
||||
16928.0 633.450
|
||||
16960.0 637.007
|
||||
16992.0 640.575
|
||||
17024.0 644.157
|
||||
17056.0 647.751
|
||||
17088.0 651.359
|
||||
17120.0 654.980
|
||||
17152.0 658.617
|
||||
17184.0 662.267
|
||||
17216.0 665.931
|
||||
17248.0 669.607
|
||||
17280.0 673.296
|
||||
17312.0 676.998
|
||||
17344.0 680.712
|
||||
17376.0 684.440
|
||||
17408.0 688.184
|
||||
17440.0 691.941
|
||||
17472.0 695.713
|
||||
17504.0 699.495
|
||||
17536.0 703.292
|
||||
17568.0 707.102
|
||||
17600.0 710.925
|
||||
17632.0 714.761
|
||||
17664.0 718.610
|
||||
17696.0 722.475
|
||||
17728.0 726.355
|
||||
17760.0 730.248
|
||||
17792.0 734.153
|
||||
17824.0 738.073
|
||||
17856.0 742.005
|
||||
17888.0 745.950
|
||||
17920.0 749.909
|
||||
17952.0 753.881
|
||||
17984.0 757.869
|
||||
18016.0 761.873
|
||||
18048.0 765.889
|
||||
18080.0 769.919
|
||||
18112.0 773.963
|
||||
18144.0 778.019
|
||||
18176.0 782.090
|
||||
18208.0 786.173
|
||||
18240.0 790.271
|
||||
18272.0 794.384
|
||||
18304.0 798.512
|
||||
18336.0 802.655
|
||||
18368.0 806.810
|
||||
18400.0 810.978
|
||||
18432.0 815.161
|
||||
18464.0 819.358
|
||||
18496.0 823.568
|
||||
18528.0 827.792
|
||||
18560.0 832.031
|
||||
18592.0 836.287
|
||||
18624.0 840.558
|
||||
18656.0 844.842
|
||||
18688.0 849.140
|
||||
18720.0 853.452
|
||||
18752.0 857.777
|
||||
18784.0 862.116
|
||||
18816.0 866.467
|
||||
18848.0 870.834
|
||||
18880.0 875.220
|
||||
18912.0 879.619
|
||||
18944.0 884.030
|
||||
18976.0 888.457
|
||||
19008.0 892.897
|
||||
19040.0 897.352
|
||||
19072.0 901.820
|
||||
19104.0 906.300
|
||||
19136.0 910.796
|
||||
19168.0 915.308
|
||||
19200.0 919.837
|
||||
19232.0 924.381
|
||||
19264.0 928.937
|
||||
19296.0 933.507
|
||||
19328.0 938.093
|
||||
19360.0 942.690
|
||||
19392.0 947.303
|
||||
19424.0 951.930
|
||||
19456.0 956.571
|
||||
19488.0 961.231
|
||||
19520.0 965.908
|
||||
19552.0 970.597
|
||||
19584.0 975.302
|
||||
19616.0 980.021
|
||||
19648.0 984.753
|
||||
19680.0 989.501
|
||||
19712.0 994.261
|
||||
19744.0 999.036
|
||||
19776.0 1003.83
|
||||
19808.0 1008.64
|
||||
19840.0 1013.46
|
||||
19872.0 1018.30
|
||||
19904.0 1023.16
|
||||
19936.0 1028.03
|
||||
19968.0 1032.91
|
||||
20000.0 1037.81
|
||||
20081.3 1050.33
|
||||
20162.8 1063.00
|
||||
20244.8 1075.81
|
||||
20327.0 1088.77
|
||||
20409.6 1101.88
|
||||
20492.5 1115.15
|
||||
20575.8 1128.57
|
||||
20659.4 1142.15
|
||||
20743.3 1155.88
|
||||
20827.6 1169.78
|
||||
20912.2 1183.84
|
||||
20997.2 1198.06
|
||||
21082.5 1212.45
|
||||
21168.1 1227.01
|
||||
21254.1 1241.73
|
||||
21340.5 1256.62
|
||||
21427.2 1271.69
|
||||
21514.3 1286.92
|
||||
21601.7 1302.34
|
||||
21689.4 1317.93
|
||||
21777.6 1333.69
|
||||
21866.0 1349.65
|
||||
21954.9 1365.78
|
||||
22044.1 1382.10
|
||||
22133.6 1398.61
|
||||
22223.6 1415.31
|
||||
22313.9 1432.20
|
||||
22404.5 1449.27
|
||||
22495.5 1466.55
|
||||
22586.9 1484.02
|
||||
22678.7 1501.69
|
||||
22770.8 1519.56
|
||||
22863.4 1537.63
|
||||
22956.3 1555.91
|
||||
23049.5 1574.40
|
||||
23143.2 1593.09
|
||||
23237.2 1611.99
|
||||
23331.6 1631.11
|
||||
23426.4 1650.44
|
||||
23521.6 1669.98
|
||||
23617.1 1689.75
|
||||
23713.1 1709.74
|
||||
23809.4 1729.95
|
||||
23906.2 1750.38
|
||||
24003.3 1771.04
|
||||
24100.8 1791.94
|
||||
24198.7 1813.06
|
||||
24297.1 1834.42
|
||||
24395.8 1856.01
|
||||
24494.9 1877.85
|
||||
24594.4 1899.93
|
||||
24694.3 1922.25
|
||||
24794.7 1944.81
|
||||
24895.4 1967.62
|
||||
24996.6 1990.69
|
||||
25098.1 2014.00
|
||||
25200.1 2037.56
|
||||
25302.5 2061.38
|
||||
25405.3 2085.46
|
||||
25508.5 2109.80
|
||||
25612.1 2134.41
|
||||
25716.2 2159.29
|
||||
25820.7 2184.43
|
||||
25925.6 2209.84
|
||||
26030.9 2235.52
|
||||
26136.7 2261.48
|
||||
26242.9 2287.71
|
||||
26349.5 2314.22
|
||||
26456.5 2341.01
|
||||
26564.0 2368.09
|
||||
26672.0 2395.46
|
||||
26780.3 2423.11
|
||||
26889.1 2451.06
|
||||
26998.4 2479.30
|
||||
27108.1 2507.82
|
||||
27218.2 2536.65
|
||||
27328.8 2565.78
|
||||
27439.8 2595.22
|
||||
27551.3 2624.97
|
||||
27663.2 2655.01
|
||||
27775.6 2685.37
|
||||
27888.5 2716.04
|
||||
28001.8 2747.03
|
||||
28115.6 2778.33
|
||||
28229.8 2809.95
|
||||
28344.5 2841.89
|
||||
28459.6 2874.14
|
||||
28575.3 2906.73
|
||||
28691.4 2939.65
|
||||
28807.9 2972.90
|
||||
28925.0 3006.49
|
||||
29042.5 3040.40
|
||||
29160.5 3074.66
|
||||
29279.0 3109.27
|
||||
29397.9 3144.20
|
||||
29517.4 3179.48
|
||||
29637.3 3215.11
|
||||
29757.7 3251.08
|
||||
29878.6 3287.40
|
||||
30000.0 3324.06
|
||||
@@ -1,689 +0,0 @@
|
||||
4000.00 14.6403
|
||||
4012.90 14.7694
|
||||
4025.83 14.8996
|
||||
4038.81 15.0310
|
||||
4051.83 15.1635
|
||||
4064.90 15.2972
|
||||
4078.00 15.4320
|
||||
4091.15 15.5680
|
||||
4104.34 15.7050
|
||||
4117.57 15.8433
|
||||
4130.85 15.9828
|
||||
4144.17 16.1237
|
||||
4157.53 16.2662
|
||||
4170.93 16.4100
|
||||
4184.38 16.5550
|
||||
4197.87 16.7012
|
||||
4211.41 16.8485
|
||||
4224.98 16.9972
|
||||
4238.60 17.1472
|
||||
4252.27 17.2985
|
||||
4265.98 17.4509
|
||||
4279.73 17.6047
|
||||
4293.53 17.7599
|
||||
4307.37 17.9166
|
||||
4321.26 18.0750
|
||||
4335.19 18.2347
|
||||
4349.17 18.3959
|
||||
4363.19 18.5586
|
||||
4377.26 18.7226
|
||||
4391.37 18.8881
|
||||
4405.53 19.0551
|
||||
4419.73 19.2235
|
||||
4433.98 19.3933
|
||||
4448.28 19.5646
|
||||
4462.62 19.7375
|
||||
4477.01 19.9119
|
||||
4491.44 20.0878
|
||||
4505.92 20.2653
|
||||
4520.45 20.4443
|
||||
4535.02 20.6251
|
||||
4549.65 20.8077
|
||||
4564.31 20.9919
|
||||
4579.03 21.1778
|
||||
4593.79 21.3654
|
||||
4608.60 21.5546
|
||||
4623.46 21.7455
|
||||
4638.37 21.9381
|
||||
4653.32 22.1324
|
||||
4668.33 22.3285
|
||||
4683.38 22.5262
|
||||
4698.48 22.7258
|
||||
4713.62 22.9271
|
||||
4728.82 23.1303
|
||||
4744.07 23.3353
|
||||
4759.36 23.5420
|
||||
4774.71 23.7507
|
||||
4790.10 23.9613
|
||||
4805.54 24.1737
|
||||
4821.04 24.3880
|
||||
4836.58 24.6042
|
||||
4852.17 24.8225
|
||||
4867.82 25.0427
|
||||
4883.51 25.2649
|
||||
4899.26 25.4891
|
||||
4915.05 25.7153
|
||||
4930.90 25.9436
|
||||
4946.80 26.1739
|
||||
4960.00 26.3662
|
||||
4960.20 26.3691
|
||||
4960.40 26.3720
|
||||
4960.60 26.3750
|
||||
4960.80 26.3779
|
||||
4961.00 26.3808
|
||||
4961.20 26.3837
|
||||
4961.40 26.3866
|
||||
4961.60 26.3896
|
||||
4961.80 26.3925
|
||||
4962.00 26.3954
|
||||
4962.20 26.3983
|
||||
4962.40 26.4012
|
||||
4962.60 26.4041
|
||||
4962.80 26.4071
|
||||
4963.00 26.4100
|
||||
4963.20 26.4129
|
||||
4963.40 26.4158
|
||||
4963.60 26.4188
|
||||
4963.80 26.4217
|
||||
4964.00 26.4246
|
||||
4964.20 26.4275
|
||||
4964.40 26.4304
|
||||
4964.60 26.4334
|
||||
4964.80 26.4363
|
||||
4965.00 26.4392
|
||||
4965.20 26.4421
|
||||
4965.40 26.4451
|
||||
4965.60 26.4480
|
||||
4965.80 26.4509
|
||||
4966.00 26.4539
|
||||
4966.20 26.4568
|
||||
4966.21 26.4570
|
||||
4966.22 26.4571
|
||||
4966.23 26.4573
|
||||
4966.24 26.4574
|
||||
4966.25 26.4576
|
||||
4966.26 26.4577
|
||||
4966.27 26.4579
|
||||
4966.28 26.4580
|
||||
4966.29 26.4581
|
||||
4966.30 26.4583
|
||||
4966.31 23.8848
|
||||
4966.32 21.5614
|
||||
4966.33 19.4639
|
||||
4966.34 16.6939
|
||||
4966.35 15.0697
|
||||
4966.36 13.6035
|
||||
4966.37 12.2799
|
||||
4966.38 11.0851
|
||||
4966.39 10.0065
|
||||
4966.40 9.03278
|
||||
4966.41 8.15382
|
||||
4966.42 7.36037
|
||||
4966.43 6.31256
|
||||
4966.44 5.69825
|
||||
4966.45 5.14372
|
||||
4966.46 4.64315
|
||||
4966.47 4.19129
|
||||
4966.48 3.78339
|
||||
4966.49 3.41519
|
||||
4966.50 3.08282
|
||||
4966.51 3.08283
|
||||
4966.52 3.08285
|
||||
4966.53 3.08287
|
||||
4966.54 3.08288
|
||||
4966.55 3.08290
|
||||
4966.56 3.08291
|
||||
4966.57 3.08293
|
||||
4966.58 3.08294
|
||||
4966.59 3.08296
|
||||
4966.60 3.08297
|
||||
4966.80 3.08327
|
||||
4967.00 3.08358
|
||||
4967.20 3.08388
|
||||
4967.40 3.08419
|
||||
4967.60 3.08449
|
||||
4967.80 3.08479
|
||||
4968.00 3.08510
|
||||
4968.20 3.08540
|
||||
4968.40 3.08570
|
||||
4968.60 3.08601
|
||||
4968.80 3.08631
|
||||
4969.00 3.08662
|
||||
4969.20 3.08692
|
||||
4969.40 3.08722
|
||||
4969.60 3.08753
|
||||
4969.80 3.08783
|
||||
4970.00 3.08814
|
||||
4978.75 3.10144
|
||||
4994.80 3.12596
|
||||
5010.90 3.15067
|
||||
5027.06 3.17557
|
||||
5043.26 3.20067
|
||||
5059.52 3.22597
|
||||
5075.84 3.25146
|
||||
5092.20 3.27716
|
||||
5108.62 3.30319
|
||||
5125.09 3.32942
|
||||
5141.61 3.35585
|
||||
5158.19 3.38250
|
||||
5174.82 3.40948
|
||||
5191.50 3.43668
|
||||
5208.24 3.46410
|
||||
5225.03 3.49173
|
||||
5241.88 3.51971
|
||||
5258.78 3.54792
|
||||
5275.73 3.57634
|
||||
5292.74 3.60500
|
||||
5309.81 3.63399
|
||||
5326.93 3.66323
|
||||
5344.10 3.69270
|
||||
5361.33 3.72241
|
||||
5378.62 3.75246
|
||||
5395.96 3.78276
|
||||
5413.35 3.81331
|
||||
5430.81 3.84410
|
||||
5448.32 3.87526
|
||||
5465.88 3.90668
|
||||
5483.50 3.93837
|
||||
5501.18 3.97031
|
||||
5518.92 4.00261
|
||||
5536.71 4.03521
|
||||
5554.56 4.06807
|
||||
5572.47 4.10120
|
||||
5590.44 4.13469
|
||||
5608.46 4.16849
|
||||
5626.54 4.20255
|
||||
5644.68 4.23691
|
||||
5662.88 4.27164
|
||||
5681.14 4.30669
|
||||
5699.46 4.34202
|
||||
5717.83 4.37766
|
||||
5736.27 4.41366
|
||||
5754.76 4.44998
|
||||
5773.31 4.48660
|
||||
5791.93 4.52352
|
||||
5810.60 4.56084
|
||||
5829.33 4.59850
|
||||
5848.13 4.63647
|
||||
5866.98 4.67476
|
||||
5885.90 4.71346
|
||||
5904.88 4.75253
|
||||
5923.91 4.79192
|
||||
5943.01 4.83164
|
||||
5962.17 4.87178
|
||||
5981.40 4.91229
|
||||
6000.68 4.95315
|
||||
6020.03 4.99434
|
||||
6039.44 5.03595
|
||||
6058.91 5.07795
|
||||
6078.44 5.12030
|
||||
6098.04 5.16301
|
||||
6117.70 5.20616
|
||||
6137.42 5.24972
|
||||
6157.21 5.29365
|
||||
6177.06 5.33794
|
||||
6196.98 5.38268
|
||||
6216.96 5.42785
|
||||
6237.00 5.47339
|
||||
6257.11 5.51932
|
||||
6277.28 5.56570
|
||||
6297.52 5.61256
|
||||
6317.82 5.65980
|
||||
6338.19 5.70744
|
||||
6358.63 5.75555
|
||||
6379.13 5.80417
|
||||
6399.69 5.85320
|
||||
6420.33 5.90263
|
||||
6441.03 5.95254
|
||||
6461.79 6.00294
|
||||
6482.63 6.05376
|
||||
6503.53 6.10501
|
||||
6524.49 6.15675
|
||||
6545.53 6.20899
|
||||
6566.63 6.26170
|
||||
6587.80 6.31484
|
||||
6609.04 6.36848
|
||||
6630.35 6.42265
|
||||
6651.73 6.47729
|
||||
6673.17 6.53239
|
||||
6694.69 6.58802
|
||||
6716.27 6.64423
|
||||
6737.93 6.70093
|
||||
6759.65 6.75810
|
||||
6781.44 6.81583
|
||||
6803.31 6.87416
|
||||
6825.24 6.93301
|
||||
6847.25 6.99235
|
||||
6869.32 7.05223
|
||||
6891.47 7.11270
|
||||
6913.69 7.17368
|
||||
6935.98 7.23521
|
||||
6958.34 7.29728
|
||||
6980.77 7.35997
|
||||
7003.28 7.42321
|
||||
7025.86 7.48699
|
||||
7048.51 7.55137
|
||||
7071.24 7.61644
|
||||
7094.03 7.68207
|
||||
7116.91 7.74827
|
||||
7139.85 7.81507
|
||||
7162.87 7.88255
|
||||
7185.96 7.95061
|
||||
7209.13 8.01927
|
||||
7232.38 8.08853
|
||||
7255.69 8.15854
|
||||
7279.09 8.22916
|
||||
7302.55 8.30039
|
||||
7326.10 8.37226
|
||||
7349.72 8.44491
|
||||
7373.41 8.51819
|
||||
7397.19 8.59211
|
||||
7421.03 8.66669
|
||||
7444.96 8.74202
|
||||
7468.96 8.81801
|
||||
7493.04 8.89466
|
||||
7517.20 8.97199
|
||||
7541.44 9.05018
|
||||
7565.75 9.12905
|
||||
7590.14 9.20861
|
||||
7614.62 9.28887
|
||||
7639.17 9.36994
|
||||
7663.79 9.45172
|
||||
7688.50 9.53421
|
||||
7713.29 9.61744
|
||||
7738.16 9.70154
|
||||
7763.11 9.78637
|
||||
7788.14 9.87195
|
||||
7813.25 9.95827
|
||||
7838.44 10.0456
|
||||
7863.71 10.1336
|
||||
7889.06 10.2224
|
||||
7914.50 10.3120
|
||||
7940.01 10.4025
|
||||
7965.61 10.4937
|
||||
7991.29 10.5858
|
||||
8017.06 10.6786
|
||||
8042.91 10.7726
|
||||
8068.84 10.8674
|
||||
8094.85 10.9630
|
||||
8120.95 11.0595
|
||||
8147.13 11.1570
|
||||
8173.40 11.2553
|
||||
8199.75 11.3545
|
||||
8226.19 11.4546
|
||||
8252.71 11.5557
|
||||
8279.32 11.6578
|
||||
8306.01 11.7607
|
||||
8332.79 11.8646
|
||||
8359.65 11.9695
|
||||
8386.60 12.0754
|
||||
8413.64 12.1822
|
||||
8440.77 12.2900
|
||||
8467.98 12.3988
|
||||
8495.29 12.5087
|
||||
8522.67 12.6195
|
||||
8550.15 12.7312
|
||||
8577.72 12.8441
|
||||
8605.37 12.9580
|
||||
8633.12 13.0730
|
||||
8660.95 13.1889
|
||||
8688.87 13.3061
|
||||
8716.89 13.4244
|
||||
8744.99 13.5438
|
||||
8773.19 13.6643
|
||||
8801.47 13.7858
|
||||
8829.85 13.9084
|
||||
8858.32 14.0320
|
||||
8886.88 14.1568
|
||||
8915.53 14.2830
|
||||
8944.27 14.4105
|
||||
8973.11 14.5392
|
||||
9002.04 14.6689
|
||||
9031.06 14.7999
|
||||
9060.18 14.9320
|
||||
9089.39 15.0654
|
||||
9118.69 15.1999
|
||||
9148.09 15.3357
|
||||
9177.59 15.4728
|
||||
9207.18 15.6112
|
||||
9236.86 15.7509
|
||||
9266.64 15.8917
|
||||
9296.52 16.0339
|
||||
9326.49 16.1773
|
||||
9356.56 16.3221
|
||||
9386.72 16.4684
|
||||
9416.99 16.6162
|
||||
9447.35 16.7655
|
||||
9477.81 16.9160
|
||||
9508.37 17.0680
|
||||
9539.02 17.2213
|
||||
9569.78 17.3760
|
||||
9600.63 17.5322
|
||||
9631.58 17.6897
|
||||
9662.63 17.8488
|
||||
9693.79 18.0092
|
||||
9725.04 18.1712
|
||||
9756.39 18.3347
|
||||
9787.85 18.4999
|
||||
9819.41 18.6666
|
||||
9851.07 18.8348
|
||||
9882.83 19.0044
|
||||
9914.69 19.1758
|
||||
9946.65 19.3488
|
||||
9978.72 19.5234
|
||||
10010.9 19.6996
|
||||
10043.2 19.8773
|
||||
10075.5 20.0569
|
||||
10108.0 20.2382
|
||||
10140.6 20.4211
|
||||
10173.3 20.6057
|
||||
10206.1 20.7920
|
||||
10239.0 20.9800
|
||||
10272.0 21.1700
|
||||
10305.2 21.3616
|
||||
10338.4 21.5550
|
||||
10371.7 21.7500
|
||||
10405.1 21.9471
|
||||
10438.7 22.1461
|
||||
10472.3 22.3469
|
||||
10506.1 22.5495
|
||||
10540.0 22.7540
|
||||
10574.0 22.9605
|
||||
10608.1 23.1689
|
||||
10642.3 23.3792
|
||||
10676.6 23.5915
|
||||
10711.0 23.8057
|
||||
10745.5 24.0220
|
||||
10780.2 24.2404
|
||||
10814.9 24.4608
|
||||
10849.8 24.6833
|
||||
10884.8 24.9077
|
||||
10919.9 25.1343
|
||||
10955.1 25.3632
|
||||
10990.4 25.5942
|
||||
11025.8 25.8273
|
||||
11061.4 26.0625
|
||||
11097.0 26.3000
|
||||
11132.8 26.5398
|
||||
11168.7 26.7818
|
||||
11204.7 27.0260
|
||||
11240.8 27.2724
|
||||
11277.1 27.5212
|
||||
11313.4 27.7726
|
||||
11349.9 28.0262
|
||||
11386.5 28.2822
|
||||
11423.2 28.5405
|
||||
11460.0 28.8013
|
||||
11497.0 29.0646
|
||||
11534.1 29.3304
|
||||
11571.2 29.5985
|
||||
11608.6 29.8691
|
||||
11646.0 30.1424
|
||||
11683.5 30.4183
|
||||
11721.2 30.6966
|
||||
11759.0 30.9775
|
||||
11796.9 31.2610
|
||||
11834.9 31.5474
|
||||
11873.1 31.8366
|
||||
11911.4 32.1285
|
||||
11949.8 32.4231
|
||||
11988.3 32.7203
|
||||
12026.9 33.0205
|
||||
12065.7 33.3236
|
||||
12104.6 33.6295
|
||||
12143.7 33.9381
|
||||
12182.8 34.2496
|
||||
12222.1 34.5641
|
||||
12261.5 34.8817
|
||||
12301.0 35.2022
|
||||
12340.7 35.5256
|
||||
12380.5 35.8520
|
||||
12420.4 36.1816
|
||||
12460.4 36.5144
|
||||
12500.6 36.8503
|
||||
12540.9 37.1892
|
||||
12581.3 37.5312
|
||||
12621.9 37.8768
|
||||
12662.6 38.2256
|
||||
12703.4 38.5776
|
||||
12744.4 38.9329
|
||||
12785.5 39.2915
|
||||
12826.7 39.6536
|
||||
12868.0 40.0192
|
||||
12909.5 40.3881
|
||||
12951.1 40.7605
|
||||
12992.9 41.1363
|
||||
13034.8 41.5159
|
||||
13076.8 41.8991
|
||||
13119.0 42.2859
|
||||
13161.3 42.6762
|
||||
13203.7 43.0702
|
||||
13246.3 43.4679
|
||||
13289.0 43.8695
|
||||
13331.8 44.2748
|
||||
13374.8 44.6838
|
||||
13417.9 45.0965
|
||||
13461.2 45.5134
|
||||
13504.6 45.9344
|
||||
13548.1 46.3592
|
||||
13591.8 46.7880
|
||||
13635.6 47.2206
|
||||
13679.6 47.6577
|
||||
13723.7 48.0990
|
||||
13767.9 48.5443
|
||||
13812.3 48.9937
|
||||
13856.9 49.4473
|
||||
13901.5 49.9055
|
||||
13946.4 50.3679
|
||||
13991.3 50.8346
|
||||
14036.4 51.3056
|
||||
14081.7 51.7811
|
||||
14127.1 52.2613
|
||||
14172.6 52.7460
|
||||
14218.3 53.2352
|
||||
14264.2 53.7291
|
||||
14310.2 54.2274
|
||||
14356.3 54.7308
|
||||
14402.6 55.2389
|
||||
14449.0 55.7517
|
||||
14495.6 56.2693
|
||||
14542.3 56.7917
|
||||
14589.2 57.3192
|
||||
14636.2 57.8518
|
||||
14683.4 58.3893
|
||||
14730.8 58.9317
|
||||
14778.3 59.4792
|
||||
14825.9 60.0323
|
||||
14873.7 60.5908
|
||||
14921.7 61.1543
|
||||
14969.8 61.7231
|
||||
15018.0 62.2972
|
||||
15066.5 62.8770
|
||||
15115.0 63.4622
|
||||
15163.8 64.0528
|
||||
15212.7 64.6489
|
||||
15261.7 65.2506
|
||||
15310.9 65.8585
|
||||
15360.3 66.4721
|
||||
15409.8 67.0915
|
||||
15459.5 67.7166
|
||||
15509.3 68.3476
|
||||
15559.3 68.9847
|
||||
15609.5 69.6277
|
||||
15659.8 70.2767
|
||||
15710.3 70.9319
|
||||
15761.0 71.5930
|
||||
15811.8 72.2610
|
||||
15862.7 72.9353
|
||||
15913.9 73.6160
|
||||
15965.2 74.3028
|
||||
16016.7 74.9961
|
||||
16068.3 75.6963
|
||||
16120.1 76.4033
|
||||
16172.1 77.1167
|
||||
16224.2 77.8368
|
||||
16276.5 78.5635
|
||||
16329.0 79.2975
|
||||
16381.7 80.0384
|
||||
16434.5 80.7861
|
||||
16487.5 81.5408
|
||||
16540.6 82.3025
|
||||
16593.9 83.0723
|
||||
16647.4 83.8492
|
||||
16701.1 84.6333
|
||||
16755.0 85.4248
|
||||
16809.0 86.2237
|
||||
16863.2 87.0304
|
||||
16917.5 87.8445
|
||||
16972.1 88.6662
|
||||
17026.8 89.4956
|
||||
17081.7 90.3328
|
||||
17136.8 91.1786
|
||||
17192.0 92.0322
|
||||
17247.4 92.8938
|
||||
17303.1 93.7636
|
||||
17358.8 94.6414
|
||||
17414.8 95.5282
|
||||
17470.9 96.4233
|
||||
17527.3 97.3269
|
||||
17583.8 98.2387
|
||||
17640.5 99.1590
|
||||
17697.4 100.088
|
||||
17754.4 101.027
|
||||
17811.6 101.973
|
||||
17869.1 102.929
|
||||
17926.7 103.893
|
||||
17984.5 104.868
|
||||
18042.5 105.852
|
||||
18100.6 106.844
|
||||
18159.0 107.846
|
||||
18217.5 108.858
|
||||
18276.3 109.879
|
||||
18335.2 110.911
|
||||
18394.3 111.951
|
||||
18453.6 113.002
|
||||
18513.1 114.062
|
||||
18572.8 115.133
|
||||
18632.7 116.214
|
||||
18692.8 117.305
|
||||
18753.0 118.406
|
||||
18813.5 119.518
|
||||
18874.1 120.640
|
||||
18935.0 121.773
|
||||
18996.0 122.917
|
||||
19057.3 124.071
|
||||
19118.7 125.236
|
||||
19180.4 126.413
|
||||
19242.2 127.601
|
||||
19304.2 128.800
|
||||
19366.5 130.010
|
||||
19428.9 131.232
|
||||
19491.6 132.465
|
||||
19554.4 133.710
|
||||
19617.4 134.967
|
||||
19680.7 136.235
|
||||
19744.1 137.516
|
||||
19807.8 138.809
|
||||
19871.7 140.115
|
||||
19935.7 141.432
|
||||
20000.0 142.762
|
||||
20081.3 144.456
|
||||
20162.8 146.170
|
||||
20244.8 147.905
|
||||
20327.0 149.660
|
||||
20409.6 151.436
|
||||
20492.5 153.234
|
||||
20575.8 155.052
|
||||
20659.4 156.892
|
||||
20743.3 158.755
|
||||
20827.6 160.641
|
||||
20912.2 162.549
|
||||
20997.2 164.479
|
||||
21082.5 166.432
|
||||
21168.1 168.409
|
||||
21254.1 170.409
|
||||
21340.5 172.433
|
||||
21427.2 174.481
|
||||
21514.3 176.554
|
||||
21601.7 178.652
|
||||
21689.4 180.774
|
||||
21777.6 182.922
|
||||
21866.0 185.095
|
||||
21954.9 187.294
|
||||
22044.1 189.520
|
||||
22133.6 191.772
|
||||
22223.6 194.051
|
||||
22313.9 196.357
|
||||
22404.5 198.690
|
||||
22495.5 201.051
|
||||
22586.9 203.441
|
||||
22678.7 205.858
|
||||
22770.8 208.305
|
||||
22863.4 210.781
|
||||
22956.3 213.287
|
||||
23049.5 215.822
|
||||
23143.2 218.387
|
||||
23237.2 220.984
|
||||
23331.6 223.611
|
||||
23426.4 226.269
|
||||
23521.6 228.958
|
||||
23617.1 231.679
|
||||
23713.1 234.433
|
||||
23809.4 237.220
|
||||
23906.2 240.038
|
||||
24003.3 242.892
|
||||
24100.8 245.779
|
||||
24198.7 248.701
|
||||
24297.1 251.656
|
||||
24395.8 254.648
|
||||
24494.9 257.675
|
||||
24594.4 260.737
|
||||
24694.3 263.835
|
||||
24794.7 266.971
|
||||
24895.4 270.144
|
||||
24996.6 273.355
|
||||
25098.1 276.603
|
||||
25200.1 279.890
|
||||
25302.5 283.216
|
||||
25405.3 286.580
|
||||
25508.5 289.984
|
||||
25612.1 293.430
|
||||
25716.2 296.915
|
||||
25820.7 300.442
|
||||
25925.6 304.009
|
||||
26030.9 307.621
|
||||
26136.7 311.275
|
||||
26242.9 314.971
|
||||
26349.5 318.710
|
||||
26456.5 322.494
|
||||
26564.0 326.323
|
||||
26672.0 330.195
|
||||
26780.3 334.113
|
||||
26889.1 338.079
|
||||
26998.4 342.092
|
||||
27108.1 346.150
|
||||
27218.2 350.256
|
||||
27328.8 354.412
|
||||
27439.8 358.616
|
||||
27551.3 362.869
|
||||
27663.2 367.171
|
||||
27775.6 371.526
|
||||
27888.5 375.930
|
||||
28001.8 380.385
|
||||
28115.6 384.893
|
||||
28229.8 389.455
|
||||
28344.5 394.070
|
||||
28459.6 398.738
|
||||
28575.3 403.460
|
||||
28691.4 408.239
|
||||
28807.9 413.071
|
||||
28925.0 417.960
|
||||
29042.5 422.906
|
||||
29160.5 427.911
|
||||
29279.0 432.974
|
||||
29397.9 438.094
|
||||
29517.4 443.275
|
||||
29637.3 448.518
|
||||
29757.7 453.821
|
||||
29878.6 459.184
|
||||
30000.0 464.610
|
||||
@@ -1,901 +0,0 @@
|
||||
4000.00 1.79125
|
||||
4012.90 1.80643
|
||||
4025.83 1.82173
|
||||
4038.81 1.83717
|
||||
4051.83 1.85277
|
||||
4064.90 1.86850
|
||||
4078.00 1.88436
|
||||
4091.15 1.90036
|
||||
4104.34 1.91650
|
||||
4117.57 1.93280
|
||||
4130.85 1.94923
|
||||
4144.17 1.96581
|
||||
4157.53 1.98253
|
||||
4170.93 1.99939
|
||||
4184.38 2.01642
|
||||
4197.87 2.03360
|
||||
4211.41 2.05093
|
||||
4224.98 2.06840
|
||||
4238.60 2.08602
|
||||
4252.27 2.10383
|
||||
4265.98 2.12178
|
||||
4279.73 2.13989
|
||||
4293.53 2.15815
|
||||
4307.37 2.17657
|
||||
4321.26 2.19517
|
||||
4335.19 2.21393
|
||||
4349.17 2.23286
|
||||
4363.19 2.25194
|
||||
4377.26 2.27119
|
||||
4391.37 2.29064
|
||||
4405.53 2.31025
|
||||
4419.73 2.33003
|
||||
4433.98 2.34998
|
||||
4448.28 2.37011
|
||||
4462.62 2.39043
|
||||
4477.01 2.41092
|
||||
4491.44 2.43159
|
||||
4505.92 2.45244
|
||||
4520.45 2.47347
|
||||
4535.02 2.49471
|
||||
4549.65 2.51612
|
||||
4564.31 2.53773
|
||||
4579.03 2.55951
|
||||
4593.79 2.58150
|
||||
4608.60 2.60369
|
||||
4623.46 2.62608
|
||||
4638.37 2.64865
|
||||
4653.32 2.67143
|
||||
4668.33 2.69441
|
||||
4683.38 2.71761
|
||||
4698.48 2.74101
|
||||
4713.62 2.76461
|
||||
4728.82 2.78842
|
||||
4744.07 2.81244
|
||||
4759.36 2.83669
|
||||
4774.71 2.86115
|
||||
4790.10 2.88582
|
||||
4805.54 2.91070
|
||||
4821.04 2.93581
|
||||
4836.58 2.96115
|
||||
4852.17 2.98672
|
||||
4867.82 3.01250
|
||||
4883.51 3.03851
|
||||
4899.26 3.06475
|
||||
4915.05 3.09123
|
||||
4930.90 3.11795
|
||||
4946.80 3.14490
|
||||
4962.75 3.17208
|
||||
4978.75 3.19950
|
||||
4994.80 3.22719
|
||||
5010.90 3.25511
|
||||
5027.06 3.28328
|
||||
5043.26 3.31169
|
||||
5059.52 3.34036
|
||||
5075.84 3.36930
|
||||
5092.20 3.39849
|
||||
5108.62 3.42794
|
||||
5125.09 3.45764
|
||||
5141.61 3.48761
|
||||
5158.19 3.51787
|
||||
5174.82 3.54839
|
||||
5191.50 3.57918
|
||||
5208.24 3.61023
|
||||
5225.03 3.64156
|
||||
5241.88 3.67318
|
||||
5258.78 3.70507
|
||||
5275.73 3.73723
|
||||
5292.74 3.76968
|
||||
5309.81 3.80242
|
||||
5326.93 3.83547
|
||||
5344.10 3.86881
|
||||
5361.33 3.90244
|
||||
5378.62 3.93635
|
||||
5395.96 3.97058
|
||||
5413.35 4.00513
|
||||
5430.81 4.03998
|
||||
5448.32 4.07513
|
||||
5465.88 4.11059
|
||||
5483.50 4.14637
|
||||
5501.18 4.18249
|
||||
5518.92 4.21891
|
||||
5536.71 4.25566
|
||||
5554.56 4.29272
|
||||
5572.47 4.33013
|
||||
5590.44 4.36787
|
||||
5608.46 4.40593
|
||||
5626.54 4.44433
|
||||
5644.68 4.48307
|
||||
5662.88 4.52218
|
||||
5681.14 4.56165
|
||||
5699.46 4.60148
|
||||
5717.83 4.64165
|
||||
5736.27 4.68217
|
||||
5754.76 4.72305
|
||||
5773.31 4.76428
|
||||
5791.93 4.80589
|
||||
5810.60 4.84784
|
||||
5829.33 4.89016
|
||||
5848.13 4.93287
|
||||
5866.98 4.97599
|
||||
5885.90 5.01947
|
||||
5904.88 5.06333
|
||||
5923.91 5.10757
|
||||
5943.01 5.15223
|
||||
5962.17 5.19730
|
||||
5981.40 5.24277
|
||||
6000.68 5.28863
|
||||
6020.03 5.33489
|
||||
6039.44 5.38159
|
||||
6058.91 5.42870
|
||||
6078.44 5.47622
|
||||
6098.04 5.52416
|
||||
6117.70 5.57253
|
||||
6137.42 5.62133
|
||||
6157.21 5.67057
|
||||
6177.06 5.72025
|
||||
6196.98 5.77036
|
||||
6216.96 5.82091
|
||||
6237.00 5.87193
|
||||
6257.11 5.92342
|
||||
6277.28 5.97537
|
||||
6297.52 6.02778
|
||||
6317.82 6.08064
|
||||
6338.19 6.13398
|
||||
6358.63 6.18781
|
||||
6379.13 6.24212
|
||||
6399.69 6.29691
|
||||
6420.33 6.35217
|
||||
6441.03 6.40791
|
||||
6461.79 6.46416
|
||||
6482.63 6.52088
|
||||
6503.53 6.57811
|
||||
6524.49 6.63584
|
||||
6545.53 6.69413
|
||||
6566.63 6.75299
|
||||
6587.80 6.81235
|
||||
6609.04 6.87223
|
||||
6630.35 6.93264
|
||||
6651.73 6.99358
|
||||
6673.17 7.05504
|
||||
6694.69 7.11704
|
||||
6716.27 7.17959
|
||||
6737.93 7.24269
|
||||
6759.65 7.30638
|
||||
6781.44 7.37065
|
||||
6803.31 7.43548
|
||||
6825.24 7.50090
|
||||
6847.25 7.56688
|
||||
6869.32 7.63346
|
||||
6891.47 7.70065
|
||||
6913.69 7.76843
|
||||
6935.98 7.83682
|
||||
6958.34 7.90580
|
||||
6980.77 7.97541
|
||||
7003.28 8.04564
|
||||
7025.86 8.11651
|
||||
7048.51 8.18798
|
||||
7071.24 8.26009
|
||||
7094.03 8.33285
|
||||
7116.91 8.40627
|
||||
7139.85 8.48033
|
||||
7162.87 8.55504
|
||||
7185.96 8.63041
|
||||
7209.13 8.70650
|
||||
7232.38 8.78327
|
||||
7255.69 8.86073
|
||||
7279.09 8.93886
|
||||
7302.55 9.01770
|
||||
7326.10 9.09719
|
||||
7349.72 9.17737
|
||||
7373.41 9.25825
|
||||
7397.19 9.33986
|
||||
7421.03 9.42219
|
||||
7444.96 9.50534
|
||||
7468.96 9.58928
|
||||
7493.04 9.67395
|
||||
7517.20 9.75939
|
||||
7541.44 9.84557
|
||||
7565.75 9.93250
|
||||
7590.14 10.0202
|
||||
7614.62 10.1087
|
||||
7639.17 10.1979
|
||||
7663.79 10.2880
|
||||
7688.50 10.3788
|
||||
7713.29 10.4705
|
||||
7738.16 10.5630
|
||||
7763.11 10.6563
|
||||
7788.14 10.7505
|
||||
7813.25 10.8454
|
||||
7838.44 10.9412
|
||||
7863.71 11.0378
|
||||
7889.06 11.1352
|
||||
7914.50 11.2336
|
||||
7940.01 11.3329
|
||||
7965.61 11.4331
|
||||
7991.29 11.5342
|
||||
8017.06 11.6362
|
||||
8042.91 11.7391
|
||||
8068.84 11.8430
|
||||
8094.85 11.9478
|
||||
8120.95 12.0536
|
||||
8147.13 12.1603
|
||||
8173.40 12.2679
|
||||
8199.75 12.3765
|
||||
8226.19 12.4860
|
||||
8252.71 12.5964
|
||||
8279.32 12.7079
|
||||
8306.01 12.8204
|
||||
8332.79 12.9337
|
||||
8359.65 13.0481
|
||||
8386.60 13.1635
|
||||
8413.64 13.2799
|
||||
8440.77 13.3973
|
||||
8467.98 13.5160
|
||||
8495.29 13.6358
|
||||
8522.67 13.7566
|
||||
8550.15 13.8785
|
||||
8577.72 14.0015
|
||||
8605.37 14.1256
|
||||
8633.12 14.2508
|
||||
8660.95 14.3771
|
||||
8688.87 14.5045
|
||||
8716.89 14.6331
|
||||
8744.99 14.7628
|
||||
8773.19 14.8936
|
||||
8801.47 15.0255
|
||||
8829.85 15.1586
|
||||
8858.32 15.2930
|
||||
8886.88 15.4285
|
||||
8915.53 15.5652
|
||||
8944.27 15.7032
|
||||
8973.11 15.8424
|
||||
9002.04 15.9828
|
||||
9031.06 16.1245
|
||||
9060.18 16.2675
|
||||
9089.39 16.4118
|
||||
9118.69 16.5574
|
||||
9148.09 16.7043
|
||||
9177.59 16.8524
|
||||
9207.18 17.0019
|
||||
9236.86 17.1527
|
||||
9266.64 17.3049
|
||||
9296.52 17.4583
|
||||
9326.49 17.6133
|
||||
9356.56 17.7696
|
||||
9386.72 17.9273
|
||||
9416.99 18.0864
|
||||
9447.35 18.2469
|
||||
9477.81 18.4089
|
||||
9508.37 18.5722
|
||||
9539.02 18.7371
|
||||
9569.78 18.9033
|
||||
9600.63 19.0711
|
||||
9631.58 19.2404
|
||||
9662.63 19.4113
|
||||
9693.79 19.5836
|
||||
9725.04 19.7575
|
||||
9756.39 19.9329
|
||||
9787.85 20.1100
|
||||
9819.41 20.2886
|
||||
9851.07 20.4689
|
||||
9882.83 20.6507
|
||||
9914.69 20.8342
|
||||
9946.65 21.0193
|
||||
9978.72 21.2060
|
||||
10010.9 21.3945
|
||||
10043.2 21.5845
|
||||
10075.5 21.7763
|
||||
10108.0 21.9698
|
||||
10140.6 22.1651
|
||||
10173.3 22.3620
|
||||
10206.1 22.5607
|
||||
10239.0 22.7612
|
||||
10272.0 22.9635
|
||||
10305.2 23.1677
|
||||
10338.4 23.3736
|
||||
10371.7 23.5814
|
||||
10405.1 23.7910
|
||||
10438.7 24.0026
|
||||
10472.3 24.2160
|
||||
10506.1 24.4312
|
||||
10540.0 24.6484
|
||||
10574.0 24.8676
|
||||
10608.1 25.0887
|
||||
10642.3 25.3119
|
||||
10676.6 25.5370
|
||||
10711.0 25.7642
|
||||
10745.5 25.9933
|
||||
10780.2 26.2246
|
||||
10814.9 26.4579
|
||||
10849.8 26.6933
|
||||
10884.8 26.9308
|
||||
10919.9 27.1703
|
||||
10955.1 27.4121
|
||||
10990.4 27.6560
|
||||
11025.8 27.9021
|
||||
11061.4 28.1503
|
||||
11097.0 28.4008
|
||||
11132.8 28.6537
|
||||
11168.7 28.9088
|
||||
11204.7 29.1662
|
||||
11240.8 29.4259
|
||||
11277.1 29.6879
|
||||
11313.4 29.9523
|
||||
11349.9 30.2190
|
||||
11386.5 30.4880
|
||||
11423.2 30.7595
|
||||
11460.0 31.0334
|
||||
11497.0 31.3098
|
||||
11534.1 31.5887
|
||||
11571.2 31.8700
|
||||
11608.6 32.1539
|
||||
11646.0 32.4403
|
||||
11683.5 32.7293
|
||||
11721.2 33.0208
|
||||
11759.0 33.3149
|
||||
11796.9 33.6117
|
||||
11834.9 33.9111
|
||||
11873.1 34.2133
|
||||
11911.4 34.5182
|
||||
11949.8 34.8259
|
||||
11988.3 35.1362
|
||||
12026.9 35.4493
|
||||
12065.7 35.7652
|
||||
12104.6 36.0840
|
||||
12143.7 36.4055
|
||||
12182.8 36.7300
|
||||
12222.1 37.0573
|
||||
12261.5 37.3877
|
||||
12301.0 37.7211
|
||||
12340.7 38.0574
|
||||
12380.5 38.3967
|
||||
12420.4 38.7391
|
||||
12460.4 39.0846
|
||||
12500.6 39.4331
|
||||
12540.9 39.7847
|
||||
12581.3 40.1394
|
||||
12621.9 40.4974
|
||||
12662.6 40.8587
|
||||
12703.4 41.2232
|
||||
12744.4 41.5910
|
||||
12785.5 41.9621
|
||||
12826.7 42.3364
|
||||
12868.0 42.7141
|
||||
12909.5 43.0951
|
||||
12951.1 43.4795
|
||||
12992.9 43.8674
|
||||
13034.8 44.2587
|
||||
13076.8 44.6538
|
||||
13119.0 45.0524
|
||||
13161.3 45.4547
|
||||
13203.7 45.8604
|
||||
13246.3 46.2698
|
||||
13289.0 46.6829
|
||||
13331.8 47.0997
|
||||
13374.8 47.5201
|
||||
13417.9 47.9443
|
||||
13461.2 48.3724
|
||||
13504.6 48.8045
|
||||
13548.1 49.2404
|
||||
13591.8 49.6802
|
||||
13635.6 50.1239
|
||||
13679.6 50.5715
|
||||
13723.7 51.0233
|
||||
13767.9 51.4790
|
||||
13812.3 51.9388
|
||||
13856.9 52.4027
|
||||
13901.5 52.8708
|
||||
13946.4 53.3433
|
||||
13991.3 53.8201
|
||||
14036.4 54.3010
|
||||
14081.7 54.7863
|
||||
14127.1 55.2759
|
||||
14172.6 55.7700
|
||||
14218.3 56.2685
|
||||
14264.2 56.7715
|
||||
14310.2 57.2788
|
||||
14356.3 57.7909
|
||||
14402.6 58.3077
|
||||
14449.0 58.8292
|
||||
14495.6 59.3554
|
||||
14542.3 59.8861
|
||||
14589.2 60.4216
|
||||
14636.2 60.9620
|
||||
14683.4 61.5072
|
||||
14730.8 62.0572
|
||||
14778.3 62.6121
|
||||
14825.9 63.1721
|
||||
14873.7 63.7375
|
||||
14921.7 64.3078
|
||||
14969.8 64.8832
|
||||
15018.0 65.4638
|
||||
15066.5 66.0497
|
||||
15115.0 66.6410
|
||||
15163.8 67.2375
|
||||
15212.7 67.8394
|
||||
15261.7 68.4467
|
||||
15310.9 69.0595
|
||||
15360.3 69.6780
|
||||
15409.8 70.3020
|
||||
15459.5 70.9316
|
||||
15509.3 71.5669
|
||||
15559.3 72.2079
|
||||
15609.5 72.8549
|
||||
15659.8 73.5076
|
||||
15710.3 74.1663
|
||||
15761.0 74.8307
|
||||
15811.8 75.5011
|
||||
15862.7 76.1778
|
||||
15913.9 76.8606
|
||||
15965.2 77.5494
|
||||
16016.7 78.2443
|
||||
16068.3 78.9456
|
||||
16120.1 79.6534
|
||||
16172.1 80.3674
|
||||
16224.2 81.0878
|
||||
16276.5 81.8145
|
||||
16329.0 82.5481
|
||||
16381.7 83.2888
|
||||
16434.5 84.0359
|
||||
16487.5 84.7897
|
||||
16540.6 85.5502
|
||||
16593.9 86.3179
|
||||
16647.4 87.0925
|
||||
16701.1 87.8740
|
||||
16755.0 88.6625
|
||||
16809.0 89.4582
|
||||
16863.2 90.2611
|
||||
16917.5 91.0715
|
||||
16972.1 91.8892
|
||||
17026.8 92.7141
|
||||
17081.7 93.5466
|
||||
17136.8 94.3866
|
||||
17192.0 95.2345
|
||||
17247.4 96.0899
|
||||
17303.1 96.9532
|
||||
17358.8 97.8239
|
||||
17414.8 98.7027
|
||||
17470.9 99.5896
|
||||
17527.3 100.485
|
||||
17583.8 101.387
|
||||
17640.5 102.298
|
||||
17697.4 103.218
|
||||
17754.4 104.146
|
||||
17811.6 105.082
|
||||
17869.1 106.027
|
||||
17926.7 106.980
|
||||
17984.0 107.934
|
||||
17984.1 107.936
|
||||
17984.2 107.938
|
||||
17984.3 107.939
|
||||
17984.4 107.941
|
||||
17984.5 107.943
|
||||
17984.6 107.944
|
||||
17984.7 107.946
|
||||
17984.8 107.948
|
||||
17984.9 107.949
|
||||
17985.0 107.951
|
||||
17985.1 107.953
|
||||
17985.2 107.954
|
||||
17985.3 107.956
|
||||
17985.4 107.958
|
||||
17985.5 107.959
|
||||
17985.6 107.961
|
||||
17985.7 107.963
|
||||
17985.8 107.964
|
||||
17985.9 107.966
|
||||
17986.0 107.968
|
||||
17986.1 107.969
|
||||
17986.2 107.971
|
||||
17986.3 107.973
|
||||
17986.4 107.974
|
||||
17986.5 107.976
|
||||
17986.6 107.978
|
||||
17986.7 107.979
|
||||
17986.8 107.981
|
||||
17986.9 107.983
|
||||
17987.0 107.984
|
||||
17987.1 107.986
|
||||
17987.2 107.988
|
||||
17987.3 107.989
|
||||
17987.4 107.991
|
||||
17987.5 107.993
|
||||
17987.6 107.994
|
||||
17987.7 107.996
|
||||
17987.8 107.998
|
||||
17987.9 107.999
|
||||
17988.0 108.001
|
||||
17988.1 108.003
|
||||
17988.2 108.004
|
||||
17988.3 108.006
|
||||
17988.4 108.008
|
||||
17988.5 108.009
|
||||
17988.6 108.011
|
||||
17988.7 108.013
|
||||
17988.8 108.014
|
||||
17988.9 108.016
|
||||
17989.0 108.018
|
||||
17989.1 108.019
|
||||
17989.2 108.021
|
||||
17989.3 108.023
|
||||
17989.4 108.024
|
||||
17989.5 108.026
|
||||
17989.6 108.028
|
||||
17989.7 108.029
|
||||
17989.8 108.031
|
||||
17989.9 108.033
|
||||
17990.0 108.034
|
||||
17990.1 108.036
|
||||
17990.2 108.038
|
||||
17990.3 108.039
|
||||
17990.4 108.041
|
||||
17990.5 108.043
|
||||
17990.6 108.044
|
||||
17990.7 108.046
|
||||
17990.8 108.048
|
||||
17990.9 108.049
|
||||
17991.0 108.051
|
||||
17991.1 108.053
|
||||
17991.2 108.054
|
||||
17991.3 108.056
|
||||
17991.4 108.058
|
||||
17991.5 108.059
|
||||
17991.6 108.061
|
||||
17991.7 108.063
|
||||
17991.8 108.064
|
||||
17991.9 108.066
|
||||
17992.0 108.068
|
||||
17992.1 108.069
|
||||
17992.2 108.071
|
||||
17992.3 108.073
|
||||
17992.4 108.074
|
||||
17992.5 108.076
|
||||
17992.6 108.078
|
||||
17992.7 108.079
|
||||
17992.8 108.081
|
||||
17992.9 108.083
|
||||
17993.0 108.084
|
||||
17993.1 108.086
|
||||
17993.2 108.088
|
||||
17993.3 108.089
|
||||
17993.4 108.091
|
||||
17993.5 108.093
|
||||
17993.6 108.094
|
||||
17993.7 108.096
|
||||
17993.8 108.098
|
||||
17993.9 108.099
|
||||
17994.0 108.101
|
||||
17994.1 108.103
|
||||
17994.2 108.105
|
||||
17994.3 108.106
|
||||
17994.4 108.108
|
||||
17994.5 108.109
|
||||
17994.6 108.111
|
||||
17994.7 108.113
|
||||
17994.8 108.115
|
||||
17994.9 108.116
|
||||
17995.0 108.118
|
||||
17995.1 108.119
|
||||
17995.2 108.121
|
||||
17995.3 108.123
|
||||
17995.4 108.125
|
||||
17995.5 108.126
|
||||
17995.6 108.128
|
||||
17995.7 108.130
|
||||
17995.8 108.131
|
||||
17995.9 108.133
|
||||
17996.0 108.134
|
||||
17996.1 108.136
|
||||
17996.2 108.138
|
||||
17996.3 108.140
|
||||
17996.4 108.141
|
||||
17996.5 108.143
|
||||
17996.6 108.144
|
||||
17996.7 108.146
|
||||
17996.8 108.148
|
||||
17996.9 108.150
|
||||
17997.0 108.151
|
||||
17997.1 108.153
|
||||
17997.2 108.155
|
||||
17997.3 108.156
|
||||
17997.4 108.158
|
||||
17997.5 108.160
|
||||
17997.6 41.5713
|
||||
17997.7 15.9385
|
||||
17997.8 15.9387
|
||||
17997.9 15.9389
|
||||
17998.0 15.9391
|
||||
17998.1 15.9394
|
||||
17998.2 15.9396
|
||||
17998.3 15.9398
|
||||
17998.4 15.9400
|
||||
17998.5 15.9403
|
||||
17998.6 15.9405
|
||||
17998.7 15.9407
|
||||
17998.8 15.9410
|
||||
17998.9 15.9412
|
||||
17999.0 15.9414
|
||||
17999.1 15.9416
|
||||
17999.2 15.9419
|
||||
17999.3 15.9421
|
||||
17999.4 15.9423
|
||||
17999.5 15.9425
|
||||
17999.6 15.9427
|
||||
17999.7 15.9430
|
||||
17999.8 15.9432
|
||||
17999.9 15.9434
|
||||
18000.0 15.9437
|
||||
18000.1 15.9439
|
||||
18000.2 15.9441
|
||||
18000.3 15.9443
|
||||
18000.4 15.9446
|
||||
18000.5 15.9448
|
||||
18000.6 15.9450
|
||||
18000.7 15.9452
|
||||
18000.8 15.9455
|
||||
18000.9 15.9457
|
||||
18001.0 15.9459
|
||||
18001.1 15.9461
|
||||
18001.2 15.9463
|
||||
18001.3 15.9466
|
||||
18001.4 15.9468
|
||||
18001.5 15.9470
|
||||
18001.6 15.9473
|
||||
18001.7 15.9475
|
||||
18001.8 15.9477
|
||||
18001.9 15.9479
|
||||
18002.0 15.9482
|
||||
18002.1 15.9484
|
||||
18002.2 15.9486
|
||||
18002.3 15.9489
|
||||
18002.4 15.9491
|
||||
18002.5 15.9493
|
||||
18002.6 15.9495
|
||||
18002.7 15.9497
|
||||
18002.8 15.9500
|
||||
18002.9 15.9502
|
||||
18003.0 15.9504
|
||||
18003.1 15.9506
|
||||
18003.2 15.9509
|
||||
18003.3 15.9511
|
||||
18003.4 15.9513
|
||||
18003.5 15.9515
|
||||
18003.6 15.9518
|
||||
18003.7 15.9520
|
||||
18003.8 15.9522
|
||||
18003.9 15.9525
|
||||
18004.0 15.9527
|
||||
18004.1 15.9529
|
||||
18004.2 15.9531
|
||||
18004.3 15.9534
|
||||
18004.4 15.9536
|
||||
18004.5 15.9538
|
||||
18004.6 15.9540
|
||||
18004.7 15.9542
|
||||
18004.8 15.9545
|
||||
18004.9 15.9547
|
||||
18005.0 15.9549
|
||||
18005.1 15.9552
|
||||
18005.2 15.9554
|
||||
18005.3 15.9556
|
||||
18005.4 15.9558
|
||||
18005.5 15.9561
|
||||
18005.6 15.9563
|
||||
18005.7 15.9565
|
||||
18005.8 15.9567
|
||||
18005.9 15.9570
|
||||
18006.0 15.9572
|
||||
18006.1 15.9574
|
||||
18006.2 15.9576
|
||||
18006.3 15.9579
|
||||
18006.4 15.9581
|
||||
18006.5 15.9583
|
||||
18006.6 15.9585
|
||||
18006.7 15.9588
|
||||
18006.8 15.9590
|
||||
18006.9 15.9592
|
||||
18007.0 15.9594
|
||||
18007.1 15.9597
|
||||
18007.2 15.9599
|
||||
18007.3 15.9601
|
||||
18007.4 15.9604
|
||||
18007.5 15.9606
|
||||
18007.6 15.9608
|
||||
18007.7 15.9610
|
||||
18007.8 15.9613
|
||||
18007.9 15.9615
|
||||
18008.0 15.9617
|
||||
18008.1 15.9619
|
||||
18008.2 15.9621
|
||||
18008.3 15.9624
|
||||
18008.4 15.9626
|
||||
18008.5 15.9628
|
||||
18008.6 15.9631
|
||||
18008.7 15.9633
|
||||
18008.8 15.9635
|
||||
18008.9 15.9637
|
||||
18009.0 15.9640
|
||||
18009.1 15.9642
|
||||
18009.2 15.9644
|
||||
18009.3 15.9646
|
||||
18009.4 15.9649
|
||||
18009.5 15.9651
|
||||
18009.6 15.9653
|
||||
18009.7 15.9655
|
||||
18009.8 15.9658
|
||||
18009.9 15.9660
|
||||
18010.0 15.9662
|
||||
18010.1 15.9664
|
||||
18010.2 15.9667
|
||||
18010.3 15.9669
|
||||
18010.4 15.9671
|
||||
18010.5 15.9673
|
||||
18010.6 15.9676
|
||||
18010.7 15.9678
|
||||
18010.8 15.9680
|
||||
18010.9 15.9683
|
||||
18011.0 15.9685
|
||||
18011.1 15.9687
|
||||
18011.2 15.9689
|
||||
18011.3 15.9692
|
||||
18011.4 15.9694
|
||||
18011.5 15.9696
|
||||
18011.6 15.9698
|
||||
18011.7 15.9700
|
||||
18011.8 15.9703
|
||||
18011.9 15.9705
|
||||
18012.0 15.9707
|
||||
18012.1 15.9709
|
||||
18012.2 15.9712
|
||||
18012.3 15.9714
|
||||
18012.4 15.9716
|
||||
18012.5 15.9719
|
||||
18012.6 15.9721
|
||||
18012.7 15.9723
|
||||
18012.8 15.9725
|
||||
18012.9 15.9728
|
||||
18013.0 15.9730
|
||||
18013.1 15.9732
|
||||
18013.2 15.9735
|
||||
18013.3 15.9737
|
||||
18013.4 15.9739
|
||||
18013.5 15.9741
|
||||
18013.6 15.9743
|
||||
18013.7 15.9746
|
||||
18013.8 15.9748
|
||||
18013.9 15.9750
|
||||
18014.0 15.9752
|
||||
18042.5 16.0396
|
||||
18100.6 16.1715
|
||||
18159.0 16.3045
|
||||
18217.5 16.4386
|
||||
18276.3 16.5738
|
||||
18335.2 16.7101
|
||||
18394.3 16.8475
|
||||
18453.6 16.9861
|
||||
18513.1 17.1258
|
||||
18572.8 17.2670
|
||||
18632.7 17.4095
|
||||
18692.8 17.5533
|
||||
18753.0 17.6983
|
||||
18813.5 17.8444
|
||||
18874.1 17.9921
|
||||
18935.0 18.1412
|
||||
18996.0 18.2916
|
||||
19057.3 18.4432
|
||||
19118.7 18.5961
|
||||
19180.4 18.7506
|
||||
19242.2 18.9066
|
||||
19304.2 19.0639
|
||||
19366.5 19.2225
|
||||
19428.9 19.3824
|
||||
19491.6 19.5440
|
||||
19554.4 19.7072
|
||||
19617.4 19.8717
|
||||
19680.7 20.0376
|
||||
19744.1 20.2048
|
||||
19807.8 20.3739
|
||||
19871.7 20.5446
|
||||
19935.7 20.7167
|
||||
20000.0 20.8903
|
||||
20081.3 21.1110
|
||||
20162.8 21.3347
|
||||
20244.8 21.5609
|
||||
20327.0 21.7894
|
||||
20409.6 22.0204
|
||||
20492.5 22.2546
|
||||
20575.8 22.4913
|
||||
20659.4 22.7305
|
||||
20743.3 22.9722
|
||||
20827.6 23.2173
|
||||
20912.2 23.4650
|
||||
20997.2 23.7153
|
||||
21082.5 23.9683
|
||||
21168.1 24.2248
|
||||
21254.1 24.4840
|
||||
21340.5 24.7460
|
||||
21427.2 25.0109
|
||||
21514.3 25.2792
|
||||
21601.7 25.5505
|
||||
21689.4 25.8246
|
||||
21777.6 26.1018
|
||||
21866.0 26.3827
|
||||
21954.9 26.6666
|
||||
22044.1 26.9536
|
||||
22133.6 27.2438
|
||||
22223.6 27.5378
|
||||
22313.9 27.8350
|
||||
22404.5 28.1354
|
||||
22495.5 28.4392
|
||||
22586.9 28.7469
|
||||
22678.7 29.0579
|
||||
22770.8 29.3723
|
||||
22863.4 29.6904
|
||||
22956.3 30.0124
|
||||
23049.5 30.3380
|
||||
23143.2 30.6670
|
||||
23237.2 30.9999
|
||||
23331.6 31.3370
|
||||
23426.4 31.6777
|
||||
23521.6 32.0221
|
||||
23617.1 32.3705
|
||||
23713.1 32.7234
|
||||
23809.4 33.0801
|
||||
23906.2 33.4407
|
||||
24003.3 33.8055
|
||||
24100.8 34.1749
|
||||
24198.7 34.5483
|
||||
24297.1 34.9258
|
||||
24395.8 35.3077
|
||||
24494.9 35.6943
|
||||
24594.4 36.0851
|
||||
24694.3 36.4802
|
||||
24794.7 36.8800
|
||||
24895.4 37.2846
|
||||
24996.6 37.6937
|
||||
25098.1 38.1073
|
||||
25200.1 38.5259
|
||||
25302.5 38.9496
|
||||
25405.3 39.3779
|
||||
25508.5 39.8109
|
||||
25612.1 40.2493
|
||||
25716.2 40.6927
|
||||
25820.7 41.1411
|
||||
25925.6 41.5944
|
||||
26030.9 42.0533
|
||||
26136.7 42.5177
|
||||
26242.9 42.9871
|
||||
26349.5 43.4618
|
||||
26456.5 43.9422
|
||||
26564.0 44.4283
|
||||
26672.0 44.9197
|
||||
26780.3 45.4165
|
||||
26889.1 45.9195
|
||||
26998.4 46.4284
|
||||
27108.1 46.9428
|
||||
27218.2 47.4630
|
||||
27328.8 47.9896
|
||||
27439.8 48.5223
|
||||
27551.3 49.0609
|
||||
27663.2 49.6054
|
||||
27775.6 50.1569
|
||||
27888.5 50.7146
|
||||
28001.8 51.2787
|
||||
28115.6 51.8489
|
||||
28229.8 52.4262
|
||||
28344.5 53.0102
|
||||
28459.6 53.6005
|
||||
28575.3 54.1975
|
||||
28691.4 54.8021
|
||||
28807.9 55.4134
|
||||
28925.0 56.0316
|
||||
29042.5 56.6567
|
||||
29160.5 57.2896
|
||||
29279.0 57.9297
|
||||
29397.9 58.5769
|
||||
29517.4 59.2313
|
||||
29637.3 59.8941
|
||||
29757.7 60.5643
|
||||
29878.6 61.2421
|
||||
30000.0 61.9272
|
||||
@@ -1,672 +0,0 @@
|
||||
|
||||
"""
|
||||
cSAXS exposure-box filter transmission utilities.
|
||||
|
||||
This method has been created based on previous spec implementations
|
||||
The translation was mainly done by copilot AI.
|
||||
|
||||
Implements fil_trans physics:
|
||||
- Per-material attenuation-length tables loaded from package 'filter_data/'.
|
||||
- Linear interpolation of attenuation length vs. energy (eV).
|
||||
- Transmission T = exp(-t / lambda), t in micrometers.
|
||||
- Enumeration of all enabled combinations across 4 units x 6 positions.
|
||||
- Selection of the combination with transmission closest to a target.
|
||||
|
||||
Motion is executed using provided position tables for each filter_array_*_x stage.
|
||||
"""
|
||||
|
||||
|
||||
#todo
|
||||
#check dmm is off
|
||||
#X12SA-OP-DMM-EMLS-3010:THRU translation THROUGH
|
||||
#X12SA-OP-DMM-EMLS-3030:THRU bragg through
|
||||
#X12SA-OP-CCM1:ENERGY-GET > 1
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from importlib import resources
|
||||
# Resolve the filter_data/ folder via importlib.resources
|
||||
import csaxs_bec.bec_ipython_client.plugins.cSAXS.filter_transmission as ft_pkg
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get
|
||||
|
||||
from bec_lib import bec_logger
|
||||
|
||||
import builtins
|
||||
|
||||
|
||||
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 cSAXSFilterTransmission:
|
||||
"""
|
||||
Mixin providing the fil_trans command.
|
||||
Assumes self.client and self.OMNYTools exist.
|
||||
|
||||
Example:
|
||||
csaxs.fil_trans(0.10, energy_kev=6.2) # dry-run first, then asks to execute
|
||||
"""
|
||||
|
||||
# -----------------------------
|
||||
# Material naming & file mapping
|
||||
# -----------------------------
|
||||
_MATERIAL_FILES: Dict[str, Optional[str]] = {
|
||||
"none": None,
|
||||
"diam": "filter_attenuation-length_diamond.txt",
|
||||
"al": "filter_attenuation-length_al.txt",
|
||||
"si": "filter_attenuation-length_si.txt",
|
||||
"ti": "filter_attenuation-length_ti.txt",
|
||||
"cu": "filter_attenuation-length_cu.txt",
|
||||
"ge": "filter_attenuation-length_ge.txt",
|
||||
"zr": "filter_attenuation-length_zr.txt",
|
||||
# optional; provide file if you enable Fe5
|
||||
"fe": "filter_attenuation-length_fe.txt",
|
||||
}
|
||||
|
||||
# -----------------------------------------
|
||||
# Exposure-box filter configuration (4 x 6)
|
||||
#
|
||||
# Current hardware (per your message):
|
||||
# Unit 1 (filter_array_1_x): out, Si400, Ge300, Ti800, Zr20
|
||||
# Unit 2 (filter_array_2_x): out, Si200, Si3200, Ti400, Cu20
|
||||
# Unit 3 (filter_array_3_x): out, Si100, Si1600, Ti200, Ti3200, Fe5
|
||||
# Unit 4 (filter_array_4_x): out, Si50, Si800, Ti100, Ti1600, Ti20
|
||||
#
|
||||
# Positions 1..6 = [out, m1, m2, m3, m4, m5]
|
||||
# Each entry: ((mat1, th1_um), (mat2, th2_um), enabled_bool)
|
||||
# -----------------------------------------
|
||||
_FILTERS: List[Tuple[Tuple[str, float], Tuple[str, float], bool]] = [
|
||||
# Unit 1
|
||||
(("none", 0.0), ("none", 0.0), True), # out
|
||||
(("si", 400.0), ("none", 0.0), True), # Si400
|
||||
(("ge", 300.0), ("none", 0.0), True), # Ge300
|
||||
(("ti", 800.0), ("none", 0.0), True), # Ti800
|
||||
(("zr", 20.0), ("none", 0.0), True), # Zr20
|
||||
(("none", 0.0), ("none", 0.0), False), # unused
|
||||
|
||||
# Unit 2
|
||||
(("none", 0.0), ("none", 0.0), True), # out
|
||||
(("si", 200.0), ("none", 0.0), True), # Si200
|
||||
(("si", 3200.0), ("none", 0.0), True), # Si3200
|
||||
(("ti", 400.0), ("none", 0.0), True), # Ti400
|
||||
(("cu", 20.0), ("none", 0.0), True), # Cu20
|
||||
(("none", 0.0), ("none", 0.0), False), # unused
|
||||
|
||||
# Unit 3
|
||||
(("none", 0.0), ("none", 0.0), True), # out
|
||||
(("si", 100.0), ("none", 0.0), True), # Si100
|
||||
(("si", 1600.0), ("none", 0.0), True), # Si1600
|
||||
(("ti", 200.0), ("none", 0.0), True), # Ti200
|
||||
(("ti", 3200.0), ("none", 0.0), True), # Ti3200
|
||||
(("fe", 5.0), ("none", 0.0), False), # Fe5 (disabled unless data file provided)
|
||||
|
||||
# Unit 4
|
||||
(("none", 0.0), ("none", 0.0), True), # out
|
||||
(("si", 50.0), ("none", 0.0), True), # Si50
|
||||
(("si", 800.0), ("none", 0.0), True), # Si800
|
||||
(("ti", 100.0), ("none", 0.0), True), # Ti100
|
||||
(("ti", 1600.0), ("none", 0.0), True), # Ti1600
|
||||
(("ti", 20.0), ("none", 0.0), True), # Ti20
|
||||
]
|
||||
|
||||
_UNITS = 4
|
||||
_PER_UNIT = 6
|
||||
|
||||
# -----------------------------------------
|
||||
# Motion mapping: user-scale coordinates
|
||||
# [out, m1, m2, m3, m4, m5]
|
||||
# -----------------------------------------
|
||||
_POSITIONS_USER: List[List[Optional[float]]] = [
|
||||
# Unit 1 (filter_array_1_x)
|
||||
[25.0, 17.9, 7.9, -2.3, -12.1, None],
|
||||
# Unit 2 (filter_array_2_x)
|
||||
[25.5, 17.6, 7.8, -2.3, -12.3, None],
|
||||
# Unit 3 (filter_array_3_x)
|
||||
[25.8, 17.6, 7.8, -2.2, -12.3, -22.3], # Fe5 at -22.3
|
||||
# Unit 4 (filter_array_4_x)
|
||||
[25.0, 17.5, 7.5, -2.2, -12.4, -22.2],
|
||||
]
|
||||
|
||||
# Device axis names (adjust if different)
|
||||
_AXES: List[str] = [
|
||||
"filter_array_1_x",
|
||||
"filter_array_2_x",
|
||||
"filter_array_3_x",
|
||||
"filter_array_4_x",
|
||||
]
|
||||
|
||||
# -----------------------------
|
||||
# Construction / Internals
|
||||
# -----------------------------
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
# In multiple-inheritance setups our __init__ might be skipped; guard lazily too.
|
||||
self._attlen_cache: Dict[str, Tuple[List[float], List[float]]] = {}
|
||||
|
||||
def _ensure_internal_state(self):
|
||||
"""Lazy guard for robustness if __init__ wasn’t called."""
|
||||
if not hasattr(self, "_attlen_cache"):
|
||||
self._attlen_cache = {}
|
||||
|
||||
# -----------------------------
|
||||
# Public API
|
||||
# -----------------------------
|
||||
def fil_trans(
|
||||
self,
|
||||
transmission: Optional[float] = None,
|
||||
energy_kev: Optional[float] = None,
|
||||
print_only: bool = True,
|
||||
) -> Optional[None]:
|
||||
"""
|
||||
Set exposure-box filters to achieve a target transmission.
|
||||
|
||||
If called without 'transmission', prints usage and current status.
|
||||
|
||||
Safety:
|
||||
- fil_trans(1) is always allowed.
|
||||
- fil_trans(<1) is only allowed if:
|
||||
- epics_get("X12SA-OP-DMM-EMLS-3010:THRU") == 1 (DMM translation THROUGH)
|
||||
- epics_get("X12SA-OP-DMM-EMLS-3030:THRU") == 1 (DMM rotation THROUGH)
|
||||
- epics_get("X12SA-OP-CCM1:ENERGY-GET") > 1 (CCM active, energy in keV)
|
||||
Otherwise, prompt with default NO.
|
||||
"""
|
||||
|
||||
# --- No-arg usage helper ---
|
||||
if transmission is None:
|
||||
print("\nUsage example:")
|
||||
print(" csaxs.fil_trans(0.10, energy_kev=6.2)")
|
||||
print(" First parameter is the transmission factor requested.")
|
||||
print(" If energy is not specified it will be read from the CCM energy PV.")
|
||||
print("\nCurrent filter transmission:")
|
||||
self._fil_trans_report(energy_kev=energy_kev)
|
||||
return None
|
||||
|
||||
# --- Validation of transmission ---
|
||||
try:
|
||||
transmission = float(transmission)
|
||||
except Exception:
|
||||
raise ValueError("Transmission must be numeric.")
|
||||
|
||||
if not (0.0 < transmission <= 1.0):
|
||||
raise ValueError("Transmission must be between 0 and 1.")
|
||||
|
||||
# -------------------------------------------------------
|
||||
# SAFETY CHECK (before any calculation/motion):
|
||||
# Only allow fil_trans < 1 when DMM is in THROUGH (both)
|
||||
# and CCM energy > 1 keV. fil_trans(1) is always allowed.
|
||||
# -------------------------------------------------------
|
||||
if transmission < 1.0:
|
||||
try:
|
||||
dmm_trans = float(epics_get("X12SA-OP-DMM-EMLS-3010:THRU"))
|
||||
except Exception:
|
||||
dmm_trans = -1
|
||||
try:
|
||||
dmm_rot = float(epics_get("X12SA-OP-DMM-EMLS-3030:THRU"))
|
||||
except Exception:
|
||||
dmm_rot = -1
|
||||
try:
|
||||
ccm_energy = float(epics_get("X12SA-OP-CCM1:ENERGY-GET"))
|
||||
except Exception:
|
||||
ccm_energy = -1
|
||||
|
||||
allowed = (dmm_trans == 1) and (dmm_rot == 1) and (ccm_energy > 1)
|
||||
|
||||
if not allowed:
|
||||
print("\n⚠️ SAFETY WARNING: Reducing transmission (< 1) typically requires:")
|
||||
print(" - DMM translation in THROUGH (THRU == 1)")
|
||||
print(" - DMM rotation in THROUGH (THRU == 1)")
|
||||
print(" - CCM energy > 1 keV")
|
||||
print("\nCurrent state:")
|
||||
print(f" DMM translation THRU : {dmm_trans}")
|
||||
print(f" DMM rotation THRU : {dmm_rot}")
|
||||
print(f" CCM energy (keV) : {ccm_energy}")
|
||||
|
||||
# Ask user (default = NO)
|
||||
if hasattr(self, "OMNYTools") and hasattr(self.OMNYTools, "yesno"):
|
||||
proceed = self.OMNYTools.yesno(
|
||||
"Conditions not satisfied. Proceed anyway?",
|
||||
default="n",
|
||||
)
|
||||
else:
|
||||
# Safe fallback
|
||||
proceed = False
|
||||
|
||||
if not proceed:
|
||||
print("Aborted. Transmission unchanged.")
|
||||
return None
|
||||
|
||||
# --- Energy handling (EPICS only) ---
|
||||
if energy_kev is None:
|
||||
try:
|
||||
energy_kev = float(epics_get("X12SA-OP-CCM1:ENERGY-GET"))
|
||||
except Exception as exc:
|
||||
raise RuntimeError(
|
||||
"Energy not specified and could not read EPICS PV "
|
||||
"'X12SA-OP-CCM1:ENERGY-GET'."
|
||||
) from exc
|
||||
else:
|
||||
energy_kev = float(energy_kev)
|
||||
|
||||
|
||||
# --- Summary header ---
|
||||
print("\nExposure-box filter transmission request")
|
||||
print("-" * 60)
|
||||
print(f"Target transmission : {transmission:.6e}")
|
||||
print(f"Photon energy : {energy_kev:.3f} keV")
|
||||
print(f"Mode : {'PRINT ONLY' if print_only else 'EXECUTE'}")
|
||||
print("-" * 60)
|
||||
|
||||
# --- Compute best combination ---
|
||||
best = self._find_best_combination(transmission, energy_kev)
|
||||
|
||||
# --- Report selected combination ---
|
||||
self._print_combination(best, energy_kev, header="Selected combination")
|
||||
|
||||
# Nearby: print only code + transmission
|
||||
neighbors = self._neighbors_around_best(transmission, energy_kev, span=5)
|
||||
if neighbors:
|
||||
print("\nNearby combinations (by transmission proximity):")
|
||||
for row in neighbors:
|
||||
print(f"{row['transmission']:9.3e}")
|
||||
|
||||
# --- Dry run prompt ---
|
||||
if print_only:
|
||||
print("\n[DRY RUN] No motion executed yet.")
|
||||
if hasattr(self, "OMNYTools") and hasattr(self.OMNYTools, "yesno"):
|
||||
if self.OMNYTools.yesno(
|
||||
"Execute motion to the selected filter combination now?",
|
||||
"y", # default YES
|
||||
):
|
||||
self._execute_combination(best, energy_kev)
|
||||
else:
|
||||
print("Execution skipped.")
|
||||
else:
|
||||
# If yesno not available, default to 'skip' on print_only
|
||||
print("No interactive prompt available. Execution skipped (print_only=True).")
|
||||
return None
|
||||
|
||||
# --- Execute motion directly ---
|
||||
self._execute_combination(best, energy_kev)
|
||||
return None
|
||||
|
||||
# -----------------------------
|
||||
# Physics helpers
|
||||
# -----------------------------
|
||||
def _load_attlen(self, material: str) -> Tuple[List[float], List[float]]:
|
||||
"""
|
||||
Load and cache attenuation-length table for a material from package resources.
|
||||
|
||||
Returns:
|
||||
energies_eV (list), attlen_um (list)
|
||||
"""
|
||||
self._ensure_internal_state()
|
||||
|
||||
material = material.lower()
|
||||
if material in self._attlen_cache:
|
||||
return self._attlen_cache[material]
|
||||
|
||||
fname = self._MATERIAL_FILES.get(material)
|
||||
if not fname:
|
||||
# 'none' or unsupported mapped to empty
|
||||
self._attlen_cache[material] = ([], [])
|
||||
return ([], [])
|
||||
|
||||
energies_eV: List[float] = []
|
||||
attlen_um: List[float] = []
|
||||
|
||||
# Load from installed package: <this_module>/filter_data/<fname>
|
||||
res = resources.files(ft_pkg) / "filter_data" / fname
|
||||
try:
|
||||
# as_file yields a concrete filesystem path even if package is zipped
|
||||
with resources.as_file(res) as p:
|
||||
with p.open("r") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
parts = line.split()
|
||||
if len(parts) < 2:
|
||||
continue
|
||||
energies_eV.append(float(parts[0]))
|
||||
attlen_um.append(float(parts[1]))
|
||||
except FileNotFoundError as e:
|
||||
raise FileNotFoundError(
|
||||
f"Attenuation data file not found for '{material}': {fname} "
|
||||
f"(looked in package filter_data)"
|
||||
) from e
|
||||
|
||||
if not energies_eV:
|
||||
raise ValueError(
|
||||
f"Attenuation data for material '{material}' is empty or invalid: {fname}"
|
||||
)
|
||||
|
||||
self._attlen_cache[material] = (energies_eV, attlen_um)
|
||||
return energies_eV, attlen_um
|
||||
|
||||
def _attenuation_length_um(self, energy_kev: float, material: str) -> float:
|
||||
"""
|
||||
Linear interpolation of attenuation length λ(energy) in µm.
|
||||
Input energy in keV; tables are in eV.
|
||||
"""
|
||||
material = material.lower()
|
||||
if material == "none":
|
||||
return float("inf") # No attenuation
|
||||
|
||||
energies_eV, attlen_um = self._load_attlen(material)
|
||||
if not energies_eV:
|
||||
# unsupported mapped above
|
||||
raise ValueError(f"Unsupported material or missing data: '{material}'")
|
||||
|
||||
e_ev = energy_kev * 1000.0
|
||||
|
||||
# Clip to the nearest edge for practicality
|
||||
if e_ev <= energies_eV[0]:
|
||||
bec_logger.logger.warning(
|
||||
f"[cSAXS] energy {energy_kev:.3f} keV below table range for {material}; "
|
||||
f"clipping to {energies_eV[0]/1000.0:.3f} keV."
|
||||
)
|
||||
return attlen_um[0]
|
||||
if e_ev >= energies_eV[-1]:
|
||||
bec_logger.logger.warning(
|
||||
f"[cSAXS] energy {energy_kev:.3f} keV above table range for {material}; "
|
||||
f"clipping to {energies_eV[-1]/1000.0:.3f} keV."
|
||||
)
|
||||
return attlen_um[-1]
|
||||
|
||||
# Binary search for interval
|
||||
lo, hi = 0, len(energies_eV) - 1
|
||||
while hi - lo > 1:
|
||||
mid = (lo + hi) // 2
|
||||
if energies_eV[mid] >= e_ev:
|
||||
hi = mid
|
||||
else:
|
||||
lo = mid
|
||||
|
||||
e_lo, e_hi = energies_eV[lo], energies_eV[hi]
|
||||
lam_lo, lam_hi = attlen_um[lo], attlen_um[hi]
|
||||
lam = (e_ev - e_lo) / (e_hi - e_lo) * (lam_hi - lam_lo) + lam_lo
|
||||
return lam
|
||||
|
||||
def _position_transmission(
|
||||
self,
|
||||
pos_entry: Tuple[Tuple[str, float], Tuple[str, float], bool],
|
||||
energy_kev: float,
|
||||
) -> Optional[float]:
|
||||
"""Transmission for a single position (possibly two layers)."""
|
||||
(mat1, th1), (mat2, th2), enabled = pos_entry
|
||||
if not enabled:
|
||||
return None
|
||||
T1 = 1.0
|
||||
T2 = 1.0
|
||||
if mat1 != "none" and th1 > 0.0:
|
||||
lam1 = self._attenuation_length_um(energy_kev, mat1)
|
||||
T1 = math.exp(-th1 / lam1)
|
||||
if mat2 != "none" and th2 > 0.0:
|
||||
lam2 = self._attenuation_length_um(energy_kev, mat2)
|
||||
T2 = math.exp(-th2 / lam2)
|
||||
return T1 * T2
|
||||
|
||||
def _all_combinations(self, energy_kev: float) -> List[dict]:
|
||||
"""
|
||||
Enumerate all enabled combinations across 4 units.
|
||||
Returns a list of dicts sorted by transmission ascending:
|
||||
{
|
||||
'code': 'abcd' # positions 1..6 per unit
|
||||
'indices': [i0, i1, i2, i3], # 0..5
|
||||
'materials': [ ((m1,t1), (m2,t2)|None ), ... for 4 units ]
|
||||
'transmission': float
|
||||
}
|
||||
"""
|
||||
# Slice filters per unit
|
||||
units = [
|
||||
self._FILTERS[u * self._PER_UNIT : (u + 1) * self._PER_UNIT]
|
||||
for u in range(self._UNITS)
|
||||
]
|
||||
|
||||
# Precompute per-position transmissions
|
||||
per_pos_T: List[List[Optional[float]]] = [
|
||||
[self._position_transmission(pos_entry, energy_kev) for pos_entry in unit]
|
||||
for unit in units
|
||||
]
|
||||
|
||||
combos: List[dict] = []
|
||||
for i0 in range(self._PER_UNIT):
|
||||
T0 = per_pos_T[0][i0]
|
||||
if T0 is None:
|
||||
continue
|
||||
for i1 in range(self._PER_UNIT):
|
||||
T1 = per_pos_T[1][i1]
|
||||
if T1 is None:
|
||||
continue
|
||||
for i2 in range(self._PER_UNIT):
|
||||
T2 = per_pos_T[2][i2]
|
||||
if T2 is None:
|
||||
continue
|
||||
for i3 in range(self._PER_UNIT):
|
||||
T3 = per_pos_T[3][i3]
|
||||
if T3 is None:
|
||||
continue
|
||||
|
||||
T = T0 * T1 * T2 * T3
|
||||
indices = [i0, i1, i2, i3]
|
||||
code = "".join(str(i + 1) for i in indices)
|
||||
|
||||
# Collect materials/thickness for reporting
|
||||
mats = []
|
||||
for u, idx in enumerate(indices):
|
||||
(m1, t1), (m2, t2), _ = units[u][idx]
|
||||
mats.append(((m1, t1), (m2, t2) if (m2 != "none" and t2 > 0.0) else None))
|
||||
|
||||
combos.append(
|
||||
{
|
||||
"code": code,
|
||||
"indices": indices,
|
||||
"materials": mats,
|
||||
"transmission": T,
|
||||
}
|
||||
)
|
||||
|
||||
combos.sort(key=lambda c: c["transmission"]) # ascending
|
||||
return combos
|
||||
|
||||
def _find_best_combination(self, target_T: float, energy_kev: float) -> dict:
|
||||
"""Pick combination with transmission closest to target."""
|
||||
combos = self._all_combinations(energy_kev)
|
||||
best = min(combos, key=lambda c: abs(c["transmission"] - target_T))
|
||||
return best
|
||||
|
||||
def _neighbors_around_best(
|
||||
self, target_T: float, energy_kev: float, span: int = 5
|
||||
) -> List[dict]:
|
||||
"""Return a few combinations around the best, by proximity in transmission."""
|
||||
combos = self._all_combinations(energy_kev)
|
||||
ranked = sorted(combos, key=lambda c: abs(c["transmission"] - target_T))
|
||||
return ranked[1 : 1 + span] # exclude best itself
|
||||
|
||||
# -----------------------------
|
||||
# Formatting & motion
|
||||
# -----------------------------
|
||||
def _print_combination(self, comb: dict, energy_kev: float, header: Optional[str] = None):
|
||||
if header:
|
||||
print(f"\n{header}:")
|
||||
code = comb["code"]
|
||||
T = comb["transmission"]
|
||||
print(f" Filters {code} transmission at {energy_kev:.3f} keV = {T:9.3e}")
|
||||
# Per-unit detail for the selected combination only
|
||||
for u, matinfo in enumerate(comb["materials"], start=1):
|
||||
first, second = matinfo
|
||||
(m1, t1) = first
|
||||
pos = int(code[u - 1])
|
||||
if second is not None:
|
||||
(m2, t2) = second
|
||||
print(
|
||||
f" unit {u}: #{pos} "
|
||||
f"{t1:4.0f} mu {m1:<4} + {t2:4.0f} mu {m2:<4}"
|
||||
)
|
||||
else:
|
||||
if m1 != "none" and t1 > 0.0:
|
||||
print(f" unit {u}: #{pos} {t1:4.0f} mu {m1:<4}")
|
||||
else:
|
||||
print(f" unit {u}: #{pos} ----- out")
|
||||
|
||||
|
||||
|
||||
def _execute_combination(self, comb: dict, energy_kev: float):
|
||||
"""
|
||||
Execute motion to the indices encoded in 'comb["code"]'.
|
||||
|
||||
Mapping:
|
||||
- code 'abcd' → per-unit index (a,b,c,d) ∈ {1..6}
|
||||
- positions are looked up from _POSITIONS_USER
|
||||
- axes are defined in _AXES
|
||||
|
||||
Motion uses: umv(dev.axis, position, dev.axis2, position2, ...)
|
||||
"""
|
||||
|
||||
indices = comb["indices"] # 0-based per unit
|
||||
move_args = [] # Collect (device, position) pairs
|
||||
|
||||
print("\nExecuting combined motion:")
|
||||
for unit_idx, pos_idx in enumerate(indices):
|
||||
pos_list = self._POSITIONS_USER[unit_idx]
|
||||
target_pos = pos_list[pos_idx]
|
||||
if target_pos is None:
|
||||
raise RuntimeError(
|
||||
f"Unit {unit_idx+1} position {pos_idx+1} has no defined coordinate."
|
||||
)
|
||||
|
||||
axis_name = self._AXES[unit_idx]
|
||||
axis_obj = getattr(dev, axis_name)
|
||||
print(f" {axis_name} → {target_pos:.3f}")
|
||||
move_args.extend([axis_obj, target_pos])
|
||||
|
||||
umv(*move_args)
|
||||
|
||||
print("\nVerifying final positions:")
|
||||
for unit_idx in range(self._UNITS):
|
||||
axis_name = self._AXES[unit_idx]
|
||||
axis_obj = getattr(dev, axis_name)
|
||||
try:
|
||||
actual = float(axis_obj.readback.get())
|
||||
print(f" {axis_name} = {actual:.3f}")
|
||||
except Exception:
|
||||
print(f" {axis_name}: readback unavailable")
|
||||
|
||||
achieved_T = comb["transmission"]
|
||||
print(f"\nAchieved transmission (approx.): {achieved_T:9.3e} at {energy_kev:.3f} keV")
|
||||
|
||||
|
||||
|
||||
def _fil_trans_report(self, tol: float = 0.1, energy_kev: Optional[float] = None) -> None:
|
||||
"""
|
||||
Report the currently active exposure‑box filter combination.
|
||||
Determines stage positions via dev.<axis>.readback.get()
|
||||
with a tolerance window of ±tol relative to nominal positions.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tol : float
|
||||
Tolerance for matching positions.
|
||||
energy_kev : float, optional
|
||||
Photon energy in keV. If None, tries to read from dev.mokev or defaults to 6.2 keV.
|
||||
"""
|
||||
|
||||
# Ensure global dev is available
|
||||
if dev is None:
|
||||
print("ERROR: Global 'dev' object not found.")
|
||||
return
|
||||
|
||||
# --- Energy handling (EPICS only) ---
|
||||
if energy_kev is None:
|
||||
try:
|
||||
energy_kev = float(epics_get("X12SA-OP-CCM1:ENERGY-GET"))
|
||||
except Exception as exc:
|
||||
raise RuntimeError(
|
||||
"Energy not specified and could not read EPICS PV "
|
||||
"'X12SA-OP-CCM1:ENERGY-GET'."
|
||||
) from exc
|
||||
else:
|
||||
energy_kev = float(energy_kev)
|
||||
|
||||
|
||||
print("\nCurrent filter transmission report")
|
||||
print("-" * 60)
|
||||
print(f"Photon energy : {energy_kev:.3f} keV")
|
||||
|
||||
indices = [] # 0–5 per unit
|
||||
|
||||
for unit_idx, axis_name in enumerate(self._AXES):
|
||||
axis_obj = getattr(dev, axis_name, None)
|
||||
if axis_obj is None:
|
||||
print(f"ERROR: Device axis '{axis_name}' not found.")
|
||||
return
|
||||
|
||||
try:
|
||||
rb = float(axis_obj.readback.get())
|
||||
except Exception:
|
||||
print(f"ERROR: readback unavailable for axis {axis_name}")
|
||||
return
|
||||
|
||||
# Match readback to nearest nominal
|
||||
pos_list = self._POSITIONS_USER[unit_idx]
|
||||
best_idx = None
|
||||
for i, nominal in enumerate(pos_list):
|
||||
if nominal is None:
|
||||
continue
|
||||
if abs(rb - nominal) <= tol:
|
||||
best_idx = i
|
||||
break
|
||||
|
||||
if best_idx is None:
|
||||
print(f"Unit {unit_idx+1}: readback {rb:.3f} does not match any known position.")
|
||||
return
|
||||
|
||||
indices.append(best_idx)
|
||||
|
||||
# Build combination code
|
||||
code = "".join(str(i + 1) for i in indices)
|
||||
print(f"Matched filter code: {code}")
|
||||
|
||||
# Compute transmission and materials
|
||||
units = [
|
||||
self._FILTERS[u * self._PER_UNIT : (u + 1) * self._PER_UNIT]
|
||||
for u in range(self._UNITS)
|
||||
]
|
||||
|
||||
materials = []
|
||||
total_T = 1.0
|
||||
|
||||
for u, pos_idx in enumerate(indices):
|
||||
(m1, t1), (m2, t2), enabled = units[u][pos_idx]
|
||||
T = self._position_transmission(units[u][pos_idx], energy_kev)
|
||||
if T is None:
|
||||
print(f"Unit {u+1}: position disabled")
|
||||
T = 1.0
|
||||
total_T *= T
|
||||
|
||||
if m2 != "none" and t2 > 0:
|
||||
materials.append(((m1, t1), (m2, t2)))
|
||||
else:
|
||||
materials.append(((m1, t1), None))
|
||||
|
||||
# Print detailed report
|
||||
self.OMNYTools.printgreenbold(f"Total transmission: {total_T:.6e}")
|
||||
print("-" * 60)
|
||||
|
||||
for u, matinfo in enumerate(materials, start=1):
|
||||
(m1, t1), second = matinfo
|
||||
pos = indices[u - 1] + 1
|
||||
if second:
|
||||
m2, t2 = second
|
||||
print(f" unit {u}: #{pos} {t1:4.0f} µm {m1:<4} + {t2:4.0f} µm {m2:<4}")
|
||||
else:
|
||||
if m1 != "none" and t1 > 0:
|
||||
print(f" unit {u}: #{pos} {t1:4.0f} µm {m1:<4}")
|
||||
else:
|
||||
print(f" unit {u}: #{pos} ----- out")
|
||||
@@ -1,447 +0,0 @@
|
||||
|
||||
import builtins
|
||||
import time
|
||||
|
||||
from bec_lib import bec_logger
|
||||
|
||||
# Logger initialization
|
||||
logger = bec_logger.logger
|
||||
|
||||
# Pull BEC globals if present
|
||||
bec = builtins.__dict__.get("bec")
|
||||
dev = builtins.__dict__.get("dev")
|
||||
umv = builtins.__dict__.get("umv")
|
||||
umvr = builtins.__dict__.get("umvr")
|
||||
|
||||
|
||||
class cSAXSInitSmaractStagesError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class cSAXSInitSmaractStages:
|
||||
"""
|
||||
Runtime SmarAct utilities for referencing and moving to initial positions.
|
||||
|
||||
This class no longer relies on static mappings. Instead, it:
|
||||
- discovers available devices from `list(dev.keys())`
|
||||
- reads the numeric channel/axis from each device's `user_parameter['bl_smar_stage']`
|
||||
- reads `init_position` from `user_parameter['init_position']`
|
||||
"""
|
||||
|
||||
def __init__(self, client) -> None:
|
||||
self.client = client
|
||||
|
||||
# ------------------------------
|
||||
# Internal helpers (runtime-based)
|
||||
# ------------------------------
|
||||
def _yesno(self, question: str, default: str = "y") -> bool:
|
||||
"""
|
||||
Use OMNYTools.yesno if available; otherwise default to 'yes' (or fallback to input()).
|
||||
"""
|
||||
try:
|
||||
if hasattr(self, "OMNYTools") and hasattr(self.OMNYTools, "yesno"):
|
||||
return self.OMNYTools.yesno(question, default)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Fallback: default answer without interaction
|
||||
# (Safe default: 'y' proceeds; adjust if you want interactive input)
|
||||
logger.info(f"[cSAXS] (yesno fallback) {question} -> default '{default}'")
|
||||
return (default or "y").lower().startswith("y")
|
||||
|
||||
def _get_user_param_safe(self, device_name: str, key: str):
|
||||
"""
|
||||
Safe access to device user parameters from current BEC session.
|
||||
"""
|
||||
try:
|
||||
return dev[device_name].user_parameter.get(key)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _iter_session_devices(self):
|
||||
"""
|
||||
Yield device names available in current BEC session.
|
||||
"""
|
||||
if dev is None:
|
||||
return
|
||||
for name in list(dev.keys()):
|
||||
yield name
|
||||
|
||||
def _build_session_axis_map(self, selection: set | None = None) -> dict:
|
||||
"""
|
||||
Build runtime axis map {device_name: channel} for devices that define 'bl_smar_stage'.
|
||||
If 'selection' is provided, restrict to names in selection.
|
||||
"""
|
||||
axis_map = {}
|
||||
missing = []
|
||||
for name in self._iter_session_devices() or []:
|
||||
if selection is not None and name not in selection:
|
||||
continue
|
||||
ch = self._get_user_param_safe(name, "bl_smar_stage")
|
||||
if ch is None:
|
||||
missing.append(name)
|
||||
continue
|
||||
try:
|
||||
axis_map[name] = int(ch)
|
||||
except Exception:
|
||||
missing.append(name)
|
||||
|
||||
if missing and selection is None:
|
||||
logger.info(
|
||||
"[cSAXS] Devices without 'bl_smar_stage' (ignored): " + ", ".join(sorted(missing))
|
||||
)
|
||||
return axis_map
|
||||
|
||||
def _get_device_object(self, device_name: str):
|
||||
"""
|
||||
Return the live device object from BEC 'dev'.
|
||||
"""
|
||||
try:
|
||||
return getattr(dev, device_name)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
# ------------------------------
|
||||
# Public API
|
||||
# ------------------------------
|
||||
def smaract_reference_stages(self, force: bool = False, devices_to_reference=None):
|
||||
"""
|
||||
Reference SmarAct stages using runtime discovery.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
force : bool, optional
|
||||
If True, re-reference ALL selected stages.
|
||||
If False (default), only reference stages that are currently NOT referenced.
|
||||
|
||||
devices_to_reference : iterable of str or str, optional
|
||||
If provided, only these devices will be considered for referencing.
|
||||
If None, all devices in the current session that define 'bl_smar_stage' are considered.
|
||||
|
||||
Behavior
|
||||
--------
|
||||
- Runtime-based: reads axis channel from user_parameter['bl_smar_stage'].
|
||||
- If devices_to_reference is given → restrict referencing to those.
|
||||
- If force=False → skip devices already referenced.
|
||||
- If force=True → re-reference selected devices always.
|
||||
- Only newly referenced devices are passed to
|
||||
smaract_components_to_initial_position(devices_to_move=[...]) afterwards.
|
||||
|
||||
Examples
|
||||
--------
|
||||
Reference only stages that are NOT referenced yet (default)
|
||||
csaxs.smaract_reference_stages()
|
||||
|
||||
Force re-reference of all stages
|
||||
csaxs.smaract_reference_stages(force=True)
|
||||
|
||||
Reference only specific stages
|
||||
csaxs.smaract_reference_stages(
|
||||
devices_to_reference=["sl3trxi", "sl3trxo", "xbpm3x"]
|
||||
)
|
||||
|
||||
Reference selected stages and force re-referencing
|
||||
csaxs.smaract_reference_stages(
|
||||
devices_to_reference=["sl4trxi", "sl4trxo"],
|
||||
force=True
|
||||
)
|
||||
|
||||
Reference a single device
|
||||
csaxs.smaract_reference_stages(
|
||||
devices_to_reference="xbimtrx"
|
||||
)
|
||||
|
||||
Reference only the selected devices (skip already-referenced ones)
|
||||
csaxs.smaract_reference_stages(
|
||||
devices_to_reference=["sl3trxi", "sl4trxo", "sl5trxt"]
|
||||
)
|
||||
|
||||
Check referencing status of all stages
|
||||
csaxs.smaract_check_all_referenced()
|
||||
"""
|
||||
# Normalize selection
|
||||
if isinstance(devices_to_reference, str):
|
||||
devices_to_reference = [devices_to_reference]
|
||||
selection = set(devices_to_reference) if devices_to_reference else None
|
||||
|
||||
# Build axis map for selected devices (or all devices present)
|
||||
axis_map = self._build_session_axis_map(selection=selection)
|
||||
if selection:
|
||||
unknown = sorted(list(selection - set(axis_map.keys())))
|
||||
if unknown:
|
||||
print(f"Unknown devices requested or missing 'bl_smar_stage' (ignored): {unknown}")
|
||||
|
||||
|
||||
newly_referenced = []
|
||||
already_referenced = []
|
||||
failed = []
|
||||
to_verify = [] # devices that need a final verification
|
||||
|
||||
print("\nStarting SmarAct referencing...\n")
|
||||
|
||||
for dev_name in sorted(axis_map.keys()):
|
||||
ch = axis_map[dev_name]
|
||||
d = self._get_device_object(dev_name)
|
||||
|
||||
if d is None:
|
||||
print(f"{dev_name}: device not accessible, skipping.")
|
||||
failed.append(dev_name)
|
||||
continue
|
||||
|
||||
try:
|
||||
is_ref = d.controller.axis_is_referenced(ch)
|
||||
|
||||
# Skip if already referenced and not forcing
|
||||
if is_ref and not force:
|
||||
print(f"{dev_name}: already referenced, skipping.")
|
||||
already_referenced.append(dev_name)
|
||||
continue
|
||||
|
||||
# Start referencing
|
||||
print(f"{dev_name}: referencing axis...")
|
||||
d.controller.set_closed_loop_move_speed(ch, 1)
|
||||
d.controller.find_reference_mark(ch, 0, 1000, 1)
|
||||
time.sleep(0.1)
|
||||
|
||||
# Add to list for final verification
|
||||
to_verify.append((dev_name, ch, d))
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error referencing {dev_name} (axis {ch}): {e}")
|
||||
failed.append(dev_name)
|
||||
|
||||
time.sleep(1.0)
|
||||
|
||||
print("\nVerifying referencing state...\n")
|
||||
|
||||
for dev_name, ch, d in to_verify:
|
||||
try:
|
||||
if d.controller.axis_is_referenced(ch):
|
||||
print(f"{dev_name}: successfully referenced.")
|
||||
newly_referenced.append(dev_name)
|
||||
else:
|
||||
print(f"{dev_name}: referencing FAILED.")
|
||||
failed.append(dev_name)
|
||||
except Exception as e:
|
||||
print(f"{dev_name}: verification error: {e}")
|
||||
failed.append(dev_name)
|
||||
|
||||
# --- Summary ---
|
||||
print("\n--- Referencing summary ---")
|
||||
print(f"Newly referenced: {newly_referenced}")
|
||||
print(f"Already referenced (kept): {already_referenced}")
|
||||
print(f"Failed: {failed}")
|
||||
print("-----------------------------------------\n")
|
||||
|
||||
# --- Move newly referenced only ---
|
||||
if newly_referenced:
|
||||
print("Moving newly referenced stages to initial positions...")
|
||||
self.smaract_components_to_initial_position(devices_to_move=newly_referenced)
|
||||
else:
|
||||
print("No newly referenced stages.")
|
||||
|
||||
def smaract_check_all_referenced(self):
|
||||
"""
|
||||
Check reference state for all SmarAct devices that define 'bl_smar_stage'.
|
||||
"""
|
||||
axis_map = self._build_session_axis_map(selection=None)
|
||||
for dev_name in sorted(axis_map.keys()):
|
||||
ch = axis_map[dev_name]
|
||||
d = self._get_device_object(dev_name)
|
||||
if d is None:
|
||||
print(f"{dev_name}: device not accessible or unsupported.")
|
||||
continue
|
||||
try:
|
||||
if d.controller.axis_is_referenced(ch):
|
||||
print(f"{dev_name} (axis {ch}) is referenced.")
|
||||
else:
|
||||
print(f"{dev_name} (axis {ch}) is NOT referenced.")
|
||||
except Exception as e:
|
||||
print(f"Error checking {dev_name} (axis {ch}): {e}")
|
||||
|
||||
def smaract_components_to_initial_position(self, devices_to_move=None):
|
||||
"""
|
||||
Move selected (or all) SmarAct-based components to their configured init_position.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
devices_to_move : iterable of str or str, optional
|
||||
Specific device names to move (e.g. ["xbpm3x", "sl3trxi"]).
|
||||
If None, all devices in the current session that define 'bl_smar_stage' are considered.
|
||||
|
||||
Behavior
|
||||
--------
|
||||
- Runtime-based: uses user_parameter['bl_smar_stage'] (numeric channel) and 'init_position'.
|
||||
- Only axes that are referenced will be moved.
|
||||
- Unreferenced axes are skipped with a WARNING; the operation continues.
|
||||
- Devices missing `init_position` are skipped and listed.
|
||||
- At the end, a summary warns if some stages could not be moved because they were not referenced.
|
||||
"""
|
||||
# Normalize selection
|
||||
if isinstance(devices_to_move, str):
|
||||
devices_to_move = [devices_to_move]
|
||||
selection = set(devices_to_move) if devices_to_move else None
|
||||
|
||||
# Resolve axis map based on selection
|
||||
axis_map = self._build_session_axis_map(selection=selection)
|
||||
unknown_requested = []
|
||||
if selection:
|
||||
unknown_requested = sorted(list(selection - set(axis_map.keys())))
|
||||
if unknown_requested:
|
||||
logger.warning(
|
||||
"[cSAXS] Requested devices unknown or missing 'bl_smar_stage': "
|
||||
+ ", ".join(unknown_requested)
|
||||
)
|
||||
|
||||
# First confirmation: intent
|
||||
scope_desc = "all SmarAct-based components" if selection is None else "the selected SmarAct-based components"
|
||||
if not self._yesno(
|
||||
f"Do you want to move {scope_desc} to the init position as defined in the config file?",
|
||||
"y",
|
||||
):
|
||||
return
|
||||
|
||||
planned_moves = []
|
||||
not_referenced = []
|
||||
missing_params = []
|
||||
inaccessible_devices = []
|
||||
|
||||
# --- Pre-check phase ---
|
||||
for dev_name in sorted(axis_map.keys()):
|
||||
d = self._get_device_object(dev_name)
|
||||
if d is None:
|
||||
logger.warning(f"[cSAXS] Device {dev_name} not accessible, skipping.")
|
||||
inaccessible_devices.append(dev_name)
|
||||
continue
|
||||
|
||||
ch = axis_map[dev_name]
|
||||
try:
|
||||
# Reference check
|
||||
if not d.controller.axis_is_referenced(ch):
|
||||
not_referenced.append(dev_name)
|
||||
continue
|
||||
|
||||
# Fetch init_position (from user parameters)
|
||||
init_pos = self._get_user_param_safe(dev_name, "init_position")
|
||||
if init_pos is None:
|
||||
missing_params.append(dev_name)
|
||||
continue
|
||||
|
||||
planned_moves.append((dev_name, float(init_pos)))
|
||||
|
||||
except Exception as exc:
|
||||
logger.error(f"[cSAXS] Error during pre-check for {dev_name}: {exc}")
|
||||
|
||||
if not planned_moves:
|
||||
# Nothing to move—still summarize why.
|
||||
header = "\nNo motions planned. Summary of issues:"
|
||||
lines = []
|
||||
if not_referenced:
|
||||
lines.append(" - Not referenced: " + ", ".join(sorted(not_referenced)))
|
||||
if missing_params:
|
||||
lines.append(" - Missing init_position: " + ", ".join(sorted(missing_params)))
|
||||
if inaccessible_devices:
|
||||
lines.append(" - Not accessible: " + ", ".join(sorted(inaccessible_devices)))
|
||||
if unknown_requested:
|
||||
lines.append(" - Unknown requested: " + ", ".join(sorted(unknown_requested)))
|
||||
if not lines:
|
||||
lines.append(" - (No eligible devices or nothing to do.)")
|
||||
|
||||
print(header)
|
||||
for line in lines:
|
||||
print(line)
|
||||
logger.warning("[cSAXS] Nothing to do.")
|
||||
return
|
||||
|
||||
# --- Summary table ---
|
||||
print("\nPlanned SmarAct motions to initial position:")
|
||||
print("-" * 60)
|
||||
print(f"{'Device':<35} {'Init position':>20}")
|
||||
print("-" * 60)
|
||||
for dev_name, init_pos in planned_moves:
|
||||
print(f"{dev_name:<35} {init_pos:>20.6g}")
|
||||
print("-" * 60)
|
||||
|
||||
# Notes / diagnostics
|
||||
if selection is not None:
|
||||
print("\nNote: Only the following devices were requested to move:")
|
||||
print(", ".join(sorted(selection)))
|
||||
if unknown_requested:
|
||||
print("\nNote: The following requested devices are unknown and were ignored:")
|
||||
print(", ".join(unknown_requested))
|
||||
if not_referenced:
|
||||
print("\nNote: The following devices are NOT referenced and will be skipped:")
|
||||
print(", ".join(sorted(not_referenced)))
|
||||
if missing_params:
|
||||
print("\nNote: The following devices have no init_position defined and will be skipped:")
|
||||
print(", ".join(sorted(missing_params)))
|
||||
if inaccessible_devices:
|
||||
print("\nNote: The following devices were not accessible and will be skipped:")
|
||||
print(", ".join(sorted(inaccessible_devices)))
|
||||
|
||||
# Second confirmation: execution
|
||||
if not self._yesno("Proceed with the motions listed above?", "y"):
|
||||
logger.info("[cSAXS] Motion to initial position aborted by user.")
|
||||
return
|
||||
|
||||
# --- Execution phase (SIMULTANEOUS MOTION) ---
|
||||
if umv is None:
|
||||
logger.error("[cSAXS] 'umv' is not available in this session.")
|
||||
return
|
||||
|
||||
# Build a flat argument list: [dev1, pos1, dev2, pos2, ...]
|
||||
move_args = []
|
||||
for dev_name, init_pos in planned_moves:
|
||||
d = self._get_device_object(dev_name)
|
||||
if d is None:
|
||||
logger.error(f"[cSAXS] Could not access {dev_name}, skipping.")
|
||||
continue
|
||||
move_args.append(d)
|
||||
move_args.append(init_pos)
|
||||
logger.info(f"[cSAXS] Preparing move: {dev_name} -> {init_pos}")
|
||||
|
||||
if not move_args:
|
||||
logger.warning("[cSAXS] No valid devices left for simultaneous motion.")
|
||||
return
|
||||
|
||||
# Trigger simultaneous move
|
||||
try:
|
||||
logger.info(f"[cSAXS] Starting simultaneous motion of {len(planned_moves)} devices.")
|
||||
umv(*move_args) # simultaneous move
|
||||
except Exception as exc:
|
||||
logger.error(f"[cSAXS] Simultaneous motion failed: {exc}")
|
||||
return
|
||||
|
||||
logger.info("[cSAXS] Simultaneous SmarAct motion to initial positions completed.")
|
||||
|
||||
# Final warning summary about unreferenced devices
|
||||
if not_referenced:
|
||||
logger.warning(
|
||||
"[cSAXS] Some stages were NOT moved because they are not referenced:\n"
|
||||
+ ", ".join(sorted(not_referenced))
|
||||
+ "\nPlease reference these axes and re-run if needed."
|
||||
)
|
||||
|
||||
|
||||
class cSAXSSmaract:
|
||||
def __init__(self, client) -> None:
|
||||
self.client = client
|
||||
|
||||
def _get_user_param_safe(self, device_name: str, key: str):
|
||||
try:
|
||||
return dev[device_name].user_parameter.get(key)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def fshn1in(self):
|
||||
"""
|
||||
Move fast shutter n1 to its 'in' position defined in user parameters.
|
||||
"""
|
||||
in_pos = self._get_user_param_safe("fast_shutter_n1_x", "in")
|
||||
if in_pos is None:
|
||||
logger.error("[cSAXS] No 'in' position defined for fast_shutter_n1_x.")
|
||||
return
|
||||
if umv is None:
|
||||
logger.error("[cSAXS] 'umv' is not available in this session.")
|
||||
return
|
||||
umv(dev.fast_shutter_n1_x, in_pos)
|
||||
@@ -1 +0,0 @@
|
||||
from .flomni import Flomni
|
||||
@@ -1,351 +0,0 @@
|
||||
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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,177 +0,0 @@
|
||||
import time
|
||||
|
||||
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 FlomniOpticsMixin:
|
||||
@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 feye_out(self):
|
||||
fshclose()
|
||||
self.foptics_in()
|
||||
feyex_out = self._get_user_param_safe("feyex", "out")
|
||||
umv(dev.feyex, feyex_out)
|
||||
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 2)
|
||||
# move rotation stage to zero to avoid problems with wires
|
||||
umv(dev.fsamroy, 0)
|
||||
# umv(dev.fttrx1, 9.2)
|
||||
|
||||
def feye_in(self):
|
||||
bec.queue.next_dataset_number += 1
|
||||
# umv(dev.fttrx1, -17)
|
||||
|
||||
feyex_in = self._get_user_param_safe("feyex", "in")
|
||||
feyey_in = self._get_user_param_safe("feyey", "in")
|
||||
umv(dev.feyex, feyex_in, dev.feyey, feyey_in)
|
||||
#self.align.update_frame()
|
||||
|
||||
def _ffzp_in(self):
|
||||
foptx_in = self._get_user_param_safe("foptx", "in")
|
||||
fopty_in = self._get_user_param_safe("fopty", "in")
|
||||
umv(dev.foptx, foptx_in)
|
||||
umv(
|
||||
dev.fopty, fopty_in
|
||||
) # for 7.2567 keV and 150 mu, 60 nm fzp, loptz 83.6000 for propagation 1.4 mm
|
||||
|
||||
def ffzp_in(self):
|
||||
"""
|
||||
move in the flomni zone plate.
|
||||
This will disable rt feedback, move the FZP and re-enabled the feedback.
|
||||
"""
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
|
||||
self._ffzp_in()
|
||||
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def foptics_in(self):
|
||||
"""
|
||||
Move in the flomni optics, including the FZP and the OSA.
|
||||
"""
|
||||
self.ffzp_in()
|
||||
self.fosa_in()
|
||||
|
||||
def foptics_out(self):
|
||||
"""Move out the flomni optics"""
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
dev.rtx.controller.feedback_disable()
|
||||
|
||||
self.fosa_out()
|
||||
fopty_out = self._get_user_param_safe("fopty", "out")
|
||||
umv(dev.fopty, fopty_out)
|
||||
|
||||
if "rtx" in dev and dev.rtx.enabled:
|
||||
time.sleep(1)
|
||||
dev.rtx.controller.feedback_enable_with_reset()
|
||||
|
||||
def fosa_in(self):
|
||||
# 6.2 keV, 170 um FZP
|
||||
# umv(dev.losax, -1.4450000, dev.losay, -0.1800)
|
||||
# umv(dev.losaz, -1)
|
||||
# 6.7, 170
|
||||
# umv(dev.losax, -1.4850, dev.losay, -0.1930)
|
||||
# umv(dev.losaz, 1.0000)
|
||||
# 7.2, 150
|
||||
fosax_in = self._get_user_param_safe("fosax", "in")
|
||||
fosay_in = self._get_user_param_safe("fosay", "in")
|
||||
fosaz_in = self._get_user_param_safe("fosaz", "in")
|
||||
dev.fosax.limits = [fosax_in - 0.1, fosax_in + 0.1]
|
||||
dev.fosay.limits = [fosay_in - 0.1, fosay_in + 0.1]
|
||||
dev.fosaz.limits = [fosaz_in - 0.1, fosaz_in + 0.1]
|
||||
umv(dev.fosax, fosax_in, dev.fosay, fosay_in)
|
||||
umv(dev.fosaz, fosaz_in)
|
||||
|
||||
# 11 kev
|
||||
# umv(dev.losax, -1.161000, dev.losay, -0.196)
|
||||
# umv(dev.losaz, 1.0000)
|
||||
|
||||
def fosa_out(self):
|
||||
self.ensure_fheater_up()
|
||||
curtain_is_triggered = dev.foptz.controller.fosaz_light_curtain_is_triggered()
|
||||
if not curtain_is_triggered:
|
||||
fosaz_out = self._get_user_param_safe("fosaz", "out")
|
||||
dev.fosaz.limits = [fosaz_out - 0.1, fosaz_out + 0.1]
|
||||
umv(dev.fosaz, fosaz_out)
|
||||
fosax_out = self._get_user_param_safe("fosax", "out")
|
||||
dev.fosax.limits = [fosax_out - 0.1, fosax_out + 0.1]
|
||||
umv(dev.fosax, fosax_out)
|
||||
|
||||
def ffzp_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
|
||||
foptz_val = dev.foptz.readback.get()
|
||||
distance = -foptz_val + 43.15 + 36.7
|
||||
print(f"\nThe sample is in a distance of \033[1m{distance:.1f} mm\033[0m from the 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)
|
||||
|
||||
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)
|
||||
|
||||
fosaz_val = dev.fosaz.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")
|
||||
@@ -1,225 +0,0 @@
|
||||
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 flomniGuiToolsError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class flomniGuiTools:
|
||||
|
||||
def __init__(self):
|
||||
self.text_box = None
|
||||
self.progressbar = None
|
||||
|
||||
def set_client(self, client):
|
||||
self.client = client
|
||||
self.gui = self.client.gui
|
||||
|
||||
def flomnigui_show_gui(self):
|
||||
if "flomni" in self.gui.windows:
|
||||
self.gui.flomni.show()
|
||||
else:
|
||||
self.gui.new("flomni")
|
||||
|
||||
def flomnigui_stop_gui(self):
|
||||
self.gui.flomni.hide()
|
||||
|
||||
def flomnigui_raise(self):
|
||||
self.gui.flomni.raise_window()
|
||||
|
||||
# def flomnigui_show_xeyealign(self):
|
||||
# self.flomnigui_show_gui()
|
||||
# if self.xeyegui is None:
|
||||
# self.flomnigui_remove_all_docks()
|
||||
# self.xeyegui = self.gui.flomni.new("xeyegui").new("XRayEye")
|
||||
# # start live
|
||||
# if not dev.cam_xeye.live_mode:
|
||||
# dev.cam_xeye.live_mode = True
|
||||
|
||||
def flomnigui_show_xeyealign(self):
|
||||
self.flomnigui_show_gui()
|
||||
if self._flomnigui_check_attribute_not_exists("xeyegui"):
|
||||
self.flomnigui_remove_all_docks()
|
||||
self.xeyegui = self.gui.flomni.new("xeyegui").new("XRayEye")
|
||||
# start live
|
||||
if not dev.cam_xeye.live_mode:
|
||||
dev.cam_xeye.live_mode = True
|
||||
|
||||
|
||||
def _flomnigui_check_attribute_not_exists(self, attribute_name):
|
||||
if hasattr(self.gui,"flomni"):
|
||||
if hasattr(self.gui.flomni,attribute_name):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def flomnigui_show_cameras(self):
|
||||
self.flomnigui_show_gui()
|
||||
if self._flomnigui_check_attribute_not_exists("camera_gripper") or self._flomnigui_check_attribute_not_exists("camera_overview"):
|
||||
self.flomnigui_remove_all_docks()
|
||||
camera_gripper_image = self.gui.flomni.new("camera_gripper").new("Image")
|
||||
if self._flomnicam_check_device_exists(dev.cam_flomni_gripper):
|
||||
camera_gripper_image.image(("cam_flomni_gripper", "preview"))
|
||||
camera_gripper_image.lock_aspect_ratio = True
|
||||
camera_gripper_image.enable_fps_monitor = True
|
||||
camera_gripper_image.enable_toolbar = False
|
||||
camera_gripper_image.outer_axes = False
|
||||
camera_gripper_image.inner_axes = False
|
||||
dev.cam_flomni_gripper.start_live_mode()
|
||||
else:
|
||||
print("Cannot open camera_gripper. Device does not exist.")
|
||||
camera_overview_image = self.gui.flomni.new("camera_overview").new("Image")
|
||||
if self._flomnicam_check_device_exists(dev.cam_flomni_overview):
|
||||
camera_overview_image.image(("cam_flomni_overview", "preview"))
|
||||
camera_overview_image.lock_aspect_ratio = True
|
||||
camera_overview_image.enable_fps_monitor = True
|
||||
camera_overview_image.enable_toolbar = False
|
||||
camera_overview_image.outer_axes = False
|
||||
camera_overview_image.inner_axes = False
|
||||
dev.cam_flomni_overview.start_live_mode()
|
||||
else:
|
||||
print("Cannot open camera_overview. Device does not exist.")
|
||||
|
||||
def flomnigui_remove_all_docks(self):
|
||||
#dev.cam_flomni_overview.stop_live_mode()
|
||||
#dev.cam_flomni_gripper.stop_live_mode()
|
||||
#dev.cam_xeye.live_mode = False
|
||||
self.gui.flomni.delete_all()
|
||||
self.progressbar = None
|
||||
self.text_box = None
|
||||
|
||||
def flomnigui_idle(self):
|
||||
self.flomnigui_show_gui()
|
||||
if self._flomnigui_check_attribute_not_exists("idle_text_box"):
|
||||
self.flomnigui_remove_all_docks()
|
||||
idle_text_box = self.gui.flomni.new("idle_textbox").new("TextBox")
|
||||
text = (
|
||||
"<pre>"
|
||||
+ " ,---.,--. ,-----. ,--. ,--.,--. ,--.,--. \n"
|
||||
+ "/ .-'| |' .-. '| `.' || ,'.| || | \n"
|
||||
+ "| `-,| || | | || |'.'| || |' ' || | \n"
|
||||
+ "| .-'| |' '-' '| | | || | ` || | \n"
|
||||
+ "`--' `--' `-----' `--' `--'`--' `--'`--' \n"
|
||||
+ "</pre>"
|
||||
)
|
||||
idle_text_box.set_html_text(text)
|
||||
|
||||
def flomnigui_docs(self, filename: str | None = None):
|
||||
import csaxs_bec
|
||||
from pathlib import Path
|
||||
|
||||
print("The general flOMNI documentation is at \nhttps://sls-csaxs.readthedocs.io/en/latest/user/ptychography/flomni.html#user-ptychography-flomni")
|
||||
|
||||
csaxs_bec_basepath = Path(csaxs_bec.__file__).parent
|
||||
docs_folder = (
|
||||
csaxs_bec_basepath /
|
||||
"bec_ipython_client" / "plugins" / "flomni" / "docs"
|
||||
)
|
||||
|
||||
if not docs_folder.is_dir():
|
||||
raise NotADirectoryError(f"Docs folder not found: {docs_folder}")
|
||||
|
||||
pdfs = sorted(docs_folder.glob("*.pdf"))
|
||||
if not pdfs:
|
||||
raise FileNotFoundError(f"No PDF files found in {docs_folder}")
|
||||
|
||||
# --- Resolve PDF ------------------------------------------------------
|
||||
if filename is not None:
|
||||
pdf_file = docs_folder / filename
|
||||
if not pdf_file.exists():
|
||||
raise FileNotFoundError(f"Requested file not found: {filename}")
|
||||
else:
|
||||
print("\nAvailable flOMNI documentation PDFs:\n")
|
||||
for i, pdf in enumerate(pdfs, start=1):
|
||||
print(f" {i:2d}) {pdf.name}")
|
||||
print()
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = int(input(f"Select a file (1–{len(pdfs)}): "))
|
||||
if 1 <= choice <= len(pdfs):
|
||||
pdf_file = pdfs[choice - 1]
|
||||
break
|
||||
print(f"Enter a number between 1 and {len(pdfs)}.")
|
||||
except ValueError:
|
||||
print("Invalid input. Please enter a number.")
|
||||
|
||||
# --- GUI handling (active existence check) ----------------------------
|
||||
self.flomnigui_show_gui()
|
||||
|
||||
if self._flomnigui_check_attribute_not_exists("PdfViewerWidget"):
|
||||
self.flomnigui_remove_all_docks()
|
||||
self.pdf_viewer = self.gui.flomni.new(widget="PdfViewerWidget")
|
||||
|
||||
# --- Load PDF ---------------------------------------------------------
|
||||
self.pdf_viewer.PdfViewerWidget.load_pdf(str(pdf_file.resolve()))
|
||||
print(f"\nLoaded: {pdf_file.name}\n")
|
||||
|
||||
|
||||
def _flomnicam_check_device_exists(self, device):
|
||||
try:
|
||||
device
|
||||
except:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def flomnigui_show_progress(self):
|
||||
self.flomnigui_show_gui()
|
||||
if self._flomnigui_check_attribute_not_exists("progressbar"):
|
||||
self.flomnigui_remove_all_docks()
|
||||
# Add a new dock with a RingProgressBar widget
|
||||
self.progressbar = self.gui.flomni.new("progressbar").new("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[0].set_update("manual")
|
||||
self.progressbar.rings[1].set_update("manual")
|
||||
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.flomni.new(name="progress_text").new("TextBox")
|
||||
|
||||
self._flomnigui_update_progress()
|
||||
|
||||
def _flomnigui_update_progress(self):
|
||||
if self.progressbar is not None:
|
||||
progress = self.progress["projection"] / self.progress["total_projections"] * 100
|
||||
subtomo_progress = (
|
||||
self.progress["subtomo_projection"]
|
||||
/ self.progress["subtomo_total_projections"]
|
||||
* 100
|
||||
)
|
||||
self.progressbar.set_value([progress, subtomo_progress, 0])
|
||||
if self.text_box is not None:
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from bec_lib.client import BECClient
|
||||
from bec_widgets.cli.client_utils import BECGuiClient
|
||||
|
||||
client = BECClient()
|
||||
client.start()
|
||||
client.gui = BECGuiClient()
|
||||
|
||||
flomni_gui = flomniGuiTools(client)
|
||||
flomni_gui.flomnigui_show_gui()
|
||||
flomni_gui.flomnigui_show_progress()
|
||||
@@ -1,277 +0,0 @@
|
||||
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, fshclose
|
||||
|
||||
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.flomni import Flomni
|
||||
|
||||
|
||||
class XrayEyeAlign:
|
||||
# pixel calibration, multiply to get mm
|
||||
labview=False
|
||||
PIXEL_CALIBRATION = 0.1 / 113 # .2 with binning
|
||||
|
||||
def __init__(self, client, flomni: Flomni) -> None:
|
||||
self.client = client
|
||||
self.flomni = flomni
|
||||
self.device_manager = client.device_manager
|
||||
self.scans = client.scans
|
||||
self.alignment_values = {}
|
||||
self.flomni.reset_correction()
|
||||
self.flomni.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,keep_shutter_open=False):
|
||||
if self.labview:
|
||||
epics_put("XOMNYI-XEYE-ACQDONE:0", 0)
|
||||
|
||||
if not self.labview:
|
||||
self.flomni.flomnigui_show_xeyealign()
|
||||
if not dev.cam_xeye.live_mode:
|
||||
dev.cam_xeye.live_mode = True
|
||||
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 1)
|
||||
if self.labview:
|
||||
# wait for start live
|
||||
while epics_get("XOMNYI-XEYE-ACQDONE:0") == 0:
|
||||
time.sleep(0.5)
|
||||
print("waiting for live view to start...")
|
||||
|
||||
fshopen()
|
||||
|
||||
if self.labview:
|
||||
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
|
||||
if not keep_shutter_open:
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 0)
|
||||
time.sleep(0.1)
|
||||
fshclose()
|
||||
print("got new frame")
|
||||
else:
|
||||
print("Staying in live view, shutter is and remains open!")
|
||||
|
||||
def tomo_rotate(self, val: float):
|
||||
# pylint: disable=undefined-variable
|
||||
umv(self.device_manager.devices.fsamroy, val)
|
||||
|
||||
def get_tomo_angle(self):
|
||||
return self.device_manager.devices.fsamroy.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,keep_shutter_open=False):
|
||||
if not keep_shutter_open:
|
||||
print("This routine can be called with paramter keep_shutter_open=True to keep the shutter always open")
|
||||
self.send_message("Getting things ready. Please wait...")
|
||||
|
||||
#potential unresolved movement requests to zero
|
||||
epics_put("XOMNYI-XEYE-MVX:0", 0)
|
||||
epics_put("XOMNYI-XEYE-MVY:0", 0)
|
||||
|
||||
# reset shift xy and fov params
|
||||
self._reset_init_values()
|
||||
|
||||
self.flomni.lights_off()
|
||||
|
||||
self.flomni.flomnigui_show_xeyealign()
|
||||
self.flomni.flomnigui_raise()
|
||||
|
||||
self.tomo_rotate(0)
|
||||
epics_put("XOMNYI-XEYE-ANGLE:0", 0)
|
||||
|
||||
self.flomni.feye_in()
|
||||
|
||||
self.flomni.laser_tracker_on()
|
||||
|
||||
self.flomni.feedback_enable_with_reset()
|
||||
|
||||
# disable movement buttons
|
||||
self.movement_buttons_enabled = False
|
||||
|
||||
sample_name = self.flomni.sample_get_name(0)
|
||||
epics_put("XOMNYI-XEYE-SAMPLENAME:0.DESC", sample_name)
|
||||
|
||||
# this makes sure we are in a defined state
|
||||
self.flomni.feedback_disable()
|
||||
|
||||
epics_put("XOMNYI-XEYE-PIXELSIZE:0", self.PIXEL_CALIBRATION)
|
||||
|
||||
self.flomni.fosa_out()
|
||||
|
||||
fsamx_in = self.flomni._get_user_param_safe("fsamx", "in")
|
||||
umv(dev.fsamx, fsamx_in - 0.25)
|
||||
|
||||
self.flomni.ffzp_in()
|
||||
self.update_frame(keep_shutter_open)
|
||||
|
||||
# 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.flomni.feedback_disable()
|
||||
fsamx_in = self.flomni._get_user_param_safe("fsamx", "in")
|
||||
umv(dev.fsamx, fsamx_in)
|
||||
|
||||
self.flomni.foptics_out()
|
||||
|
||||
self.flomni.feedback_disable()
|
||||
umv(dev.fsamx, fsamx_in - 0.25)
|
||||
|
||||
if self.labview:
|
||||
self.update_frame(keep_shutter_open)
|
||||
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.fsamx, fsamx_in)
|
||||
time.sleep(0.5)
|
||||
self.flomni.feedback_enable_with_reset()
|
||||
|
||||
self.update_frame(keep_shutter_open)
|
||||
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(keep_shutter_open)
|
||||
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(keep_shutter_open)
|
||||
|
||||
if k < 2:
|
||||
# allow movements, store movements to calculate center
|
||||
_xrayeyalignmvy = epics_get("XOMNYI-XEYE-MVY:0")
|
||||
if _xrayeyalignmvy != 0:
|
||||
self.flomni.feedback_disable()
|
||||
umvr(dev.fsamy, _xrayeyalignmvy / 1000)
|
||||
time.sleep(2)
|
||||
epics_put("XOMNYI-XEYE-MVY:0", 0)
|
||||
self.flomni.feedback_enable_with_reset()
|
||||
self.update_frame(keep_shutter_open)
|
||||
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
|
||||
if self.labview:
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 2)
|
||||
if keep_shutter_open and not self.labview:
|
||||
if self.flomni.OMNYTools.yesno("Close the shutter now?","y"):
|
||||
fshclose()
|
||||
epics_put("XOMNYI-XEYE-ACQ:0", 0)
|
||||
if not self.labview:
|
||||
self.flomni.flomnigui_idle()
|
||||
|
||||
|
||||
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 flomni.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")
|
||||
@@ -1 +0,0 @@
|
||||
from .omny import OMNY
|
||||
@@ -1,715 +0,0 @@
|
||||
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
@@ -1,171 +0,0 @@
|
||||
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)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,246 +0,0 @@
|
||||
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
|
||||
@@ -1,153 +0,0 @@
|
||||
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)
|
||||
@@ -1,384 +0,0 @@
|
||||
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")
|
||||
@@ -1,241 +0,0 @@
|
||||
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
@@ -1,235 +0,0 @@
|
||||
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")
|
||||
@@ -1,250 +0,0 @@
|
||||
"""Module providing debugging tools for the BEC IPython client at cSAXS."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from functools import partial
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
import numpy as np
|
||||
from pydantic import BaseModel
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.table import Table
|
||||
from rich.text import Text
|
||||
from slugify import slugify
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bec_ipython_client.main import BECIPythonClient
|
||||
from bec_lib.devicemanager import DeviceManagerBase
|
||||
from bec_lib.scans import Scans
|
||||
from bec_widgets.cli.client_utils import BECGuiClient
|
||||
|
||||
scans: Scans # type: ignore[no-redef]
|
||||
|
||||
bec: BECIPythonClient # type: ignore[no-redef]
|
||||
|
||||
dev: DeviceManagerBase # type: ignore[no-redef]
|
||||
|
||||
|
||||
class Detector(BaseModel):
|
||||
"""Model representing a detector configuration."""
|
||||
|
||||
name: str
|
||||
hostnames: list[str]
|
||||
cfg: dict
|
||||
|
||||
|
||||
def to_identifier(text: str) -> str:
|
||||
"""
|
||||
Convert an unsafe string into a valid Python identifier.
|
||||
"""
|
||||
name = slugify(text.strip(), separator="_")
|
||||
name = re.sub(r"[^a-zA-Z0-9_]", "", name)
|
||||
|
||||
if not name:
|
||||
raise ValueError(f"Cannot convert '{text}' to a valid identifier.")
|
||||
|
||||
if name[0].isdigit():
|
||||
name = f"_{name}"
|
||||
|
||||
return name
|
||||
|
||||
|
||||
class DebugTools:
|
||||
"""A collection of debugging tools for the BEC IPython client at cSAXS."""
|
||||
|
||||
_PURPOSE = (
|
||||
"Debugging helpers for the cSAXS BEC IPython client. These tools are intended for advanced users "
|
||||
"and developers to diagnose and troubleshoot issues within the BEC environment. "
|
||||
"Below are the available methods together with a brief description of their functionality."
|
||||
)
|
||||
|
||||
######################
|
||||
## Internal Methods ##
|
||||
######################
|
||||
|
||||
def _describe(self) -> None:
|
||||
"""Pretty-print a description of this debugging tool."""
|
||||
console = Console()
|
||||
|
||||
# Offset for IPython prompt misplacement
|
||||
console.print("\n\n", end="")
|
||||
|
||||
header = Text("DebugTools", style="bold cyan")
|
||||
purpose = Text(self._PURPOSE, style="dim")
|
||||
|
||||
console.print(Panel(purpose, title=header, expand=False))
|
||||
|
||||
table = Table(show_header=True, header_style="bold magenta")
|
||||
table.add_column("Method", style="bold", no_wrap=True)
|
||||
table.add_column("Description")
|
||||
|
||||
for name, member in inspect.getmembers(self, predicate=inspect.ismethod):
|
||||
if name.startswith("_"):
|
||||
continue
|
||||
|
||||
doc = inspect.getdoc(member)
|
||||
short_doc = doc.splitlines()[0] if doc else ""
|
||||
table.add_row(name, short_doc)
|
||||
|
||||
console.print(table)
|
||||
|
||||
def _repr_pretty_(self, p, cycle: bool) -> None:
|
||||
if cycle:
|
||||
p.text("DebugTools(...)")
|
||||
else:
|
||||
self._describe()
|
||||
|
||||
#####################
|
||||
### MCS Card Check ###
|
||||
#####################
|
||||
|
||||
def _check_if_device_is_loaded(self, device_name: str):
|
||||
"""Check if a device is loaded in the current BEC session."""
|
||||
if device_name not in dev:
|
||||
raise RuntimeError(
|
||||
f"Device {device_name} was not loaded in the current active BEC session."
|
||||
)
|
||||
|
||||
def mcs_test_acquire(
|
||||
self, mode: Literal["high_frame", "medium_frame", "low_frame"] = "high_frame"
|
||||
):
|
||||
"""
|
||||
Method to perform a test acquisition with randomized exposure time, burst frames, and cycles
|
||||
on the MCS card using the DDG trigger setup.
|
||||
|
||||
Args:
|
||||
mode (Literal["high_frame", "medium_frame", "low_frame"]): The mode of the test.
|
||||
- 'high_frame': Tests high frame rates with short exposure times.
|
||||
- 'medium_frame': Tests medium frame rates with moderate exposure times.
|
||||
- 'low_frame': Tests low frame rates with longer exposure times.
|
||||
"""
|
||||
self._check_if_device_is_loaded("mcs")
|
||||
self._check_if_device_is_loaded("ddg1")
|
||||
self._check_if_device_is_loaded("ddg2")
|
||||
|
||||
if mode == "high_frame":
|
||||
burst_frames = np.random.randint(10_000, 100_000) # between 10000 and 100000
|
||||
cycles = np.random.randint(5, 20) # between 5 and 20
|
||||
exp_time = (
|
||||
np.random.rand() * (0.001 - 0.201e-3) + 0.201e-3
|
||||
) # between 0.000201 ms and 0.001 s
|
||||
elif mode == "medium_frame":
|
||||
burst_frames = np.random.randint(50, 500) # between 50 and 500
|
||||
cycles = np.random.randint(1, 10) # between 1 and 10
|
||||
exp_time = np.random.rand() * (0.01 - 0.001) + 0.001 # between 0.001 ms and 0.01 s
|
||||
elif mode == "low_frame":
|
||||
burst_frames = np.random.randint(5, 20) # between 5 and 20
|
||||
cycles = np.random.randint(1, 5) # between 1 and 5
|
||||
exp_time = np.random.rand() * (2 - 0.1) + 0.1 # between 0.1 ms and 2 s
|
||||
else:
|
||||
raise ValueError(f"Invalid mode '{mode}' specified for acquire scan test.")
|
||||
print(
|
||||
f"Starting acquire measurement with exp_time={exp_time:.6f}, burst_frames={burst_frames}, cycles={cycles}"
|
||||
)
|
||||
s = scans.acquire(
|
||||
exp_time=exp_time, frames_per_trigger=burst_frames, burst_at_each_point=cycles
|
||||
)
|
||||
s.wait(file_written=True)
|
||||
print("Acquire measurement finished.")
|
||||
print("Checking MCS data...")
|
||||
scan_data = bec.history.get_by_scan_id(s.scan.scan_id)
|
||||
mcs_data = scan_data.devices.mcs
|
||||
print(mcs_data)
|
||||
|
||||
shape = mcs_data._info["mcs_mca_mca1"]["value"]["shape"]
|
||||
expected_shape = (cycles * burst_frames,)
|
||||
# Assert will raise an error if the shapes do not match
|
||||
assert (
|
||||
shape == expected_shape
|
||||
), f"MCS data shape {shape} does not match expected shape {expected_shape}."
|
||||
|
||||
########################
|
||||
### JFJ/Eiger Checks ###
|
||||
########################
|
||||
|
||||
def _get_jfj_eiger_config(self) -> dict[str, Detector]:
|
||||
"""Retrieve the current JFJ/Eiger detector configuration from the BEC client."""
|
||||
# FIXME: Implement REST API call once ready for use from Leo Sala's team.
|
||||
ret = {}
|
||||
base_path = os.path.dirname(__file__)
|
||||
config_path = os.path.join(base_path, "jfj_config.json")
|
||||
with open(config_path, "r", encoding="utf-8") as fh:
|
||||
cfg = json.load(fh)
|
||||
|
||||
for entry in cfg["detector"]:
|
||||
det = Detector(
|
||||
name=to_identifier(entry["description"]), hostnames=entry["hostname"], cfg=cfg
|
||||
)
|
||||
ret[det.name] = det
|
||||
return ret
|
||||
|
||||
def list_detectors(self) -> list[str]:
|
||||
"""
|
||||
List the names of all JFJ/Eiger detectors configured in the BEC client.
|
||||
|
||||
Returns:
|
||||
list[str]: A list of detector names.
|
||||
"""
|
||||
detectors = self._get_jfj_eiger_config()
|
||||
return list(detectors.keys())
|
||||
|
||||
def ping_detector(self, detector_name: str) -> bool:
|
||||
"""
|
||||
Ping a JFJ/Eiger detector to check if it is reachable.
|
||||
|
||||
Args:
|
||||
detector_name (str): The name of the detector to ping.
|
||||
|
||||
Returns:
|
||||
bool: True if the detector is reachable, False otherwise.
|
||||
"""
|
||||
detectors = self._get_jfj_eiger_config()
|
||||
if detector_name not in detectors:
|
||||
raise ValueError(f"Detector '{detector_name}' not found in configuration.")
|
||||
|
||||
det = detectors[detector_name]
|
||||
results = self._ping_many(det.hostnames)
|
||||
|
||||
table = Table(title=f"Ping results for detector '{detector_name}'")
|
||||
table.add_column("Hostname", style="cyan", no_wrap=True)
|
||||
table.add_column("Status", style="magenta")
|
||||
|
||||
for host, alive in results.items():
|
||||
status = "[green]OK[/green]" if alive else "[red]DOWN[/red]"
|
||||
table.add_row(host, status)
|
||||
|
||||
console = Console()
|
||||
console.print(table)
|
||||
|
||||
def _ping_many(self, hosts: list[str], port=22, timeout=2, max_workers=None):
|
||||
max_workers = max_workers or len(hosts)
|
||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
primed_ping = partial(self._ping, port=port, timeout=timeout)
|
||||
pings = executor.map(primed_ping, hosts)
|
||||
return dict(zip(hosts, pings))
|
||||
|
||||
def _ping(self, host: str, port=23, timeout=2): # telnet is port 23
|
||||
address = (host, port)
|
||||
try:
|
||||
with socket.create_connection(address, timeout):
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
def open_it_service_page(self):
|
||||
"""Open the overview of IT services hosted by Science IT Infrastructure and Services for cSAXS."""
|
||||
gui: BECGuiClient = bec.gui
|
||||
dock_area = gui.new()
|
||||
print("Opening IT service page in new dock...")
|
||||
url = "https://metrics.psi.ch/d/saf8mxv/x12sa?orgId=1&from=now-24h&to=now&timezone=browser&var-receiver_hosts=sls-jfjoch-001.psi.ch&var-writer_hosts=xbl-daq-34.psi.ch&var-beamline=X12SA&var-slurm_partitions=csaxs&var-receiver_services=broker&var-writer_services=writer&refresh=15m"
|
||||
# FIXME BEC WIDGETS v3
|
||||
dock = dock_area.new()
|
||||
wb = dock.new(widget=gui.available_widgets.WebsiteWidget)
|
||||
wb.set_url(url)
|
||||
@@ -1,162 +0,0 @@
|
||||
{
|
||||
"zeromq" : {
|
||||
"image_socket": ["tcp://0.0.0.0:5500"]
|
||||
},
|
||||
"zeromq_preview": {
|
||||
"socket_address": "tcp://0.0.0.0:5400",
|
||||
"enabled": true,
|
||||
"period_ms": 1000
|
||||
},
|
||||
"zeromq_metadata" : {
|
||||
"socket_address": "tcp://0.0.0.0:5600",
|
||||
"enabled": true,
|
||||
"period_ms": 100
|
||||
},
|
||||
"instrument" : {
|
||||
"source_name": "Swiss Light Source",
|
||||
"instrument_name": "cSAXS",
|
||||
"source_type": "Synchrotron X-ray Source"
|
||||
},
|
||||
"detector": [
|
||||
{
|
||||
"description": "EIGER 9M",
|
||||
"serial_number": "E1",
|
||||
"type": "EIGER",
|
||||
"mirror_y": true,
|
||||
"base_data_ipv4_address": "10.10.10.10",
|
||||
"calibration_file":["/opt/jfjoch/calibration/"],
|
||||
"standard_geometry" : {
|
||||
"nmodules": 18,
|
||||
"modules_in_row": 3,
|
||||
"gap_x": 8,
|
||||
"gap_y": 36
|
||||
},
|
||||
"hostname": [
|
||||
"beb101",
|
||||
"beb103",
|
||||
"beb014",
|
||||
"beb078",
|
||||
"beb060",
|
||||
"beb030",
|
||||
"beb092",
|
||||
"beb178",
|
||||
"beb009",
|
||||
"beb038",
|
||||
"beb056",
|
||||
"beb058",
|
||||
"beb033",
|
||||
"beb113",
|
||||
"beb005",
|
||||
"beb017",
|
||||
"beb119",
|
||||
"beb095",
|
||||
"beb186",
|
||||
"beb042",
|
||||
"beb106",
|
||||
"beb059",
|
||||
"beb111",
|
||||
"beb203",
|
||||
"beb100",
|
||||
"beb093",
|
||||
"beb123",
|
||||
"beb061",
|
||||
"beb121",
|
||||
"beb055",
|
||||
"beb004",
|
||||
"beb190",
|
||||
"beb054",
|
||||
"beb189",
|
||||
"beb107",
|
||||
"beb115"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "EIGER 8.5M (tmp)",
|
||||
"serial_number": "E1-tmp",
|
||||
"type": "EIGER",
|
||||
"mirror_y": true,
|
||||
"base_data_ipv4_address": "10.10.10.10",
|
||||
"calibration_file":["/opt/jfjoch/calibration/"],
|
||||
"standard_geometry" : {
|
||||
"nmodules": 17,
|
||||
"modules_in_row": 3,
|
||||
"gap_x": 8,
|
||||
"gap_y": 36
|
||||
},
|
||||
"hostname": [
|
||||
"beb101",
|
||||
"beb103",
|
||||
"beb014",
|
||||
"beb078",
|
||||
"beb060",
|
||||
"beb030",
|
||||
"beb092",
|
||||
"beb178",
|
||||
"beb009",
|
||||
"beb038",
|
||||
"beb056",
|
||||
"beb058",
|
||||
"beb033",
|
||||
"beb113",
|
||||
"beb005",
|
||||
"beb017",
|
||||
"beb119",
|
||||
"beb095",
|
||||
"beb186",
|
||||
"beb042",
|
||||
"beb106",
|
||||
"beb059",
|
||||
"beb100",
|
||||
"beb093",
|
||||
"beb123",
|
||||
"beb061",
|
||||
"beb121",
|
||||
"beb055",
|
||||
"beb004",
|
||||
"beb190",
|
||||
"beb054",
|
||||
"beb189",
|
||||
"beb107",
|
||||
"beb115"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "EIGER 1.5M",
|
||||
"serial_number": "E2",
|
||||
"type": "EIGER",
|
||||
"mirror_y": true,
|
||||
"base_data_ipv4_address": "10.10.11.10",
|
||||
"calibration_file":["/opt/jfjoch/calibration_e1p5m/"],
|
||||
"standard_geometry" : {
|
||||
"nmodules": 3,
|
||||
"modules_in_row": 1,
|
||||
"gap_x": 8,
|
||||
"gap_y": 36
|
||||
},
|
||||
"hostname": ["beb062", "beb026", "beb099", "beb084", "beb120", "beb108"]
|
||||
}
|
||||
],
|
||||
"frontend_directory": "/usr/share/jfjoch/frontend/",
|
||||
"image_pusher": "ZeroMQ",
|
||||
"numa_policy": "n2g2",
|
||||
"receiver_threads": 64,
|
||||
"image_buffer_MiB": 96000,
|
||||
"pcie": [
|
||||
{
|
||||
"blk": "/dev/jfjoch0",
|
||||
"ipv4": "10.10.10.1"
|
||||
},
|
||||
{
|
||||
"blk": "/dev/jfjoch1",
|
||||
"ipv4": "10.10.10.2"
|
||||
},
|
||||
{
|
||||
"blk": "/dev/jfjoch2",
|
||||
"ipv4": "10.10.10.3"
|
||||
},
|
||||
{
|
||||
"blk": "/dev/jfjoch3",
|
||||
"ipv4": "10.10.10.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
"""
|
||||
Pre-startup script for BEC client. This script is executed before the BEC client
|
||||
is started. It can be used to add additional command line arguments.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from bec_lib.service_config import ServiceConfig
|
||||
|
||||
import csaxs_bec
|
||||
|
||||
|
||||
def extend_command_line_args(parser):
|
||||
"""
|
||||
Extend the command line arguments of the BEC client.
|
||||
"""
|
||||
|
||||
parser.add_argument("--session", help="Session name", type=str, default="cSAXS")
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
# def get_config() -> ServiceConfig:
|
||||
# """
|
||||
# Create and return the ServiceConfig for the plugin repository
|
||||
# """
|
||||
# deployment_path = os.path.dirname(os.path.dirname(os.path.dirname(csaxs_bec.__file__)))
|
||||
# files = os.listdir(deployment_path)
|
||||
# if "bec_config.yaml" in files:
|
||||
# return ServiceConfig(config_path=os.path.join(deployment_path, "bec_config.yaml"))
|
||||
# else:
|
||||
# return ServiceConfig(redis={"host": "localhost", "port": 6379})
|
||||
@@ -1,63 +0,0 @@
|
||||
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): ...
|
||||
@@ -1,148 +0,0 @@
|
||||
# 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, rpc_timeout
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
# pylint: skip-file
|
||||
|
||||
|
||||
_Widgets = {
|
||||
"OmnyAlignment": "OmnyAlignment",
|
||||
"XRayEye": "XRayEye",
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
class XRayEye(RPCBase):
|
||||
@rpc_call
|
||||
def active_roi(self) -> "BaseROI | None":
|
||||
"""
|
||||
Return the currently active ROI, or None if no ROI is active.
|
||||
"""
|
||||
|
||||
@property
|
||||
@rpc_call
|
||||
def enable_live_view(self):
|
||||
"""
|
||||
Get or set the live view enabled state.
|
||||
"""
|
||||
|
||||
@enable_live_view.setter
|
||||
@rpc_call
|
||||
def enable_live_view(self):
|
||||
"""
|
||||
Get or set the live view enabled state.
|
||||
"""
|
||||
|
||||
@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
|
||||
"""
|
||||
|
||||
|
||||
class XRayEye2DControl(RPCBase):
|
||||
@rpc_call
|
||||
def remove(self):
|
||||
"""
|
||||
Cleanup the BECConnector
|
||||
"""
|
||||
@@ -1,140 +0,0 @@
|
||||
|
||||
|
||||
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)
|
||||
|
||||
# self.ui.moveUpButton.clicked.connect(self.on_move_up)
|
||||
|
||||
|
||||
@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("cam_xeye")
|
||||
return
|
||||
|
||||
image.disconnect_monitor("cam_xeye")
|
||||
|
||||
|
||||
@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_())
|
||||
@@ -1 +0,0 @@
|
||||
{'files': ['omny_alignment.py']}
|
||||
@@ -1,125 +0,0 @@
|
||||
<?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>cam_xeye</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>
|
||||
@@ -1,54 +0,0 @@
|
||||
# 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()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user