start of beamtime p21741
This commit is contained in:
19
exp_temp/acquisition_setup.py
Normal file
19
exp_temp/acquisition_setup.py
Normal file
@ -0,0 +1,19 @@
|
||||
from slic.core.acquisition import SFAcquisition
|
||||
|
||||
from .channels import detectors_with_config, detectors
|
||||
from .channels import bs_channels_jf_direct_beam, bs_channels_pbps_snapshot
|
||||
from .channels import pvs_cristallina, pvs_bernina, bs_channels_DCM_Bernina
|
||||
|
||||
|
||||
instrument = "cristallina"
|
||||
pgroup = "p21569"
|
||||
|
||||
acqui_bill = SFAcquisition(
|
||||
instrument,
|
||||
pgroup,
|
||||
default_channels=bs_channels_pbps_snapshot,
|
||||
default_pvs=pvs_cristallina,
|
||||
default_detectors=detectors,
|
||||
rate_multiplicator=1,
|
||||
)
|
||||
|
319
exp_temp/kb_focusing.py
Normal file
319
exp_temp/kb_focusing.py
Normal file
@ -0,0 +1,319 @@
|
||||
from cam_server import PipelineClient
|
||||
from cam_server.utils import get_host_port_from_stream_address
|
||||
from bsread import source, SUB
|
||||
|
||||
from epics import PV
|
||||
|
||||
import numpy as np
|
||||
import time
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import json
|
||||
|
||||
from loguru import logger
|
||||
|
||||
wait_time_benders = 1.0 # can probably be reduced as we wait for the move to finish
|
||||
wait_time_aperture = 0.5 # can probably be reduced as we wait for the move to finish
|
||||
|
||||
|
||||
def get_position_from_pipeline(pip_instance_id, data_field_name, n_pulses=1):
|
||||
pipeline_client = PipelineClient()
|
||||
|
||||
stream_address = pipeline_client.get_instance_stream(pip_instance_id)
|
||||
stream_host, stream_port = get_host_port_from_stream_address(stream_address)
|
||||
|
||||
with source(host=stream_host, port=stream_port, mode=SUB) as input_stream:
|
||||
sum_pos = 0
|
||||
for i in np.arange(n_pulses):
|
||||
input_stream.connect()
|
||||
message = input_stream.receive()
|
||||
pos = message.data.data[data_field_name].value
|
||||
sum_pos = sum_pos + pos
|
||||
mean_pos = sum_pos / n_pulses
|
||||
|
||||
return mean_pos
|
||||
|
||||
|
||||
def evaluate_bender_scan():
|
||||
""" Evaluation of data is in /sf/cristallina/applications/optic_tools/KBs
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def kbV_focusing_acquire(
|
||||
bender_us=[1.0, 1.2, 1.49, 1.54, 1.59],
|
||||
bender_ds=[1.1, 1.3, 1.5, 1.6, 1.79, 1.84],
|
||||
bender_us_start=1.1,
|
||||
bender_ds_start=1.33,
|
||||
aperture=[-0.3, 0, 0.3],
|
||||
aperture_width=0.15,
|
||||
aperture_height=1.2,
|
||||
n_pulses=1,
|
||||
):
|
||||
""" Vertical KB mirror focusing acquisition with default parameters.
|
||||
"""
|
||||
return kb_focusing_acquire(
|
||||
direction="vertical",
|
||||
bender_us=bender_us,
|
||||
bender_ds=bender_ds,
|
||||
bender_us_start=bender_us_start,
|
||||
bender_ds_start=bender_ds_start,
|
||||
aperture=aperture,
|
||||
aperture_size=aperture_width,
|
||||
aperture_size_pendicular=aperture_height,
|
||||
n_pulses=n_pulses,
|
||||
)
|
||||
|
||||
|
||||
def kbH_focusing_acquire(
|
||||
bender_us=[1.55, 1.6, 1.7],
|
||||
bender_ds=[1.7, 1.8, 1.9],
|
||||
bender_us_start=1.2, # should be 0.3 below the maximum focus
|
||||
bender_ds_start=1.5, # should be 0.3 below the maximum focus
|
||||
aperture=[0.18, 0.48, 0.78],
|
||||
aperture_height=0.15,
|
||||
aperture_width=1.8,
|
||||
n_pulses=1,
|
||||
):
|
||||
""" Horizontal KB mirror focusing acquisition with default parameters.
|
||||
"""
|
||||
return kb_focusing_acquire(
|
||||
direction="horizontal",
|
||||
bender_us=bender_us,
|
||||
bender_ds=bender_ds,
|
||||
bender_us_start=bender_us_start,
|
||||
bender_ds_start=bender_ds_start,
|
||||
aperture=aperture,
|
||||
aperture_size=aperture_height,
|
||||
aperture_size_pendicular=aperture_width,
|
||||
n_pulses=n_pulses,
|
||||
)
|
||||
|
||||
|
||||
def kb_focusing_acquire(
|
||||
direction="vertical",
|
||||
bender_us=[1.49, 1.54, 1.59],
|
||||
bender_ds=[1.79, 1.84, 1.89],
|
||||
bender_us_start=1.29,
|
||||
bender_ds_start=1.59,
|
||||
aperture=[-0.3, 0, 0.3],
|
||||
aperture_size=0.15,
|
||||
aperture_size_pendicular=1.2,
|
||||
n_pulses=1,
|
||||
):
|
||||
""" KB mirror focusing acquisition routine for Cristallina.
|
||||
|
||||
TODO: - split this up into separate routines
|
||||
- Make inner loop a generator, yielding: bender_us_rb, bender_ds_rb, beam_positions
|
||||
Input into live analysis.
|
||||
|
||||
"""
|
||||
# Benders
|
||||
|
||||
if bender_us_start >= np.min(bender_us) - 0.3:
|
||||
bender_us_start = max(0, np.min(bender_us) - 0.3)
|
||||
if bender_ds_start >= np.min(bender_ds) - 0.3:
|
||||
bender_ds_start = max(0, np.min(bender_ds) - 0.3)
|
||||
|
||||
bender_us = np.sort(bender_us)
|
||||
bender_ds = np.sort(bender_ds)
|
||||
|
||||
KBV_NAME = "SAROP31-OKBV153"
|
||||
KBH_NAME = "SAROP31-OKBH154"
|
||||
|
||||
if direction == "vertical":
|
||||
kb_name = KBV_NAME
|
||||
elif direction == "horizontal":
|
||||
kb_name = KBH_NAME
|
||||
|
||||
BU = PV(kb_name + ":BU.VAL")
|
||||
BD = PV(kb_name + ":BD.VAL")
|
||||
# TODO: is the separation necessary?
|
||||
BU_RB = PV(kb_name + ":BU.VAL")
|
||||
BD_RB = PV(kb_name + ":BD.VAL")
|
||||
|
||||
# Aperture
|
||||
|
||||
aperture = np.sort(aperture)
|
||||
|
||||
APU_NAME = "SAROP31-OAPU149"
|
||||
|
||||
if direction == "vertical":
|
||||
APU_CENTER = PV(APU_NAME + ":MOTOR_Y.VAL")
|
||||
APU_CENTER_RB = PV(APU_NAME + ":MOTOR_Y.RBV")
|
||||
|
||||
APU_SIZE = PV(APU_NAME + ":MOTOR_H.VAL")
|
||||
APU_SIZE_RB = PV(APU_NAME + ":MOTOR_H.RBV")
|
||||
|
||||
APU_SIZE_PERPENDICULAR = PV(APU_NAME + ":MOTOR_W.VAL")
|
||||
APU_SIZE_PERPENDICULAR_RB = PV(APU_NAME + ":MOTOR_W.RBV")
|
||||
|
||||
APU_CENTER_PERPENDICULAR = PV(APU_NAME + ":MOTOR_X.VAL")
|
||||
APU_CENTER_PERPENDICULAR_RB = PV(APU_NAME + ":MOTOR_X.RBV")
|
||||
# Camera field name
|
||||
data_field_name = "y_fit_mean"
|
||||
|
||||
elif direction == "horizontal":
|
||||
APU_CENTER = PV(APU_NAME + ":MOTOR_X.VAL")
|
||||
APU_SIZE = PV(APU_NAME + ":MOTOR_W.VAL")
|
||||
APU_CENTER_RB = PV(APU_NAME + ":MOTOR_X.RBV")
|
||||
APU_SIZE_RB = PV(APU_NAME + ":MOTOR_W.RBV")
|
||||
|
||||
APU_SIZE_PERPENDICULAR = PV(APU_NAME + ":MOTOR_H.VAL")
|
||||
APU_SIZE_PERPENDICULAR_RB = PV(APU_NAME + ":MOTOR_H.RBV")
|
||||
|
||||
APU_CENTER_PERPENDICULAR = PV(APU_NAME + ":MOTOR_Y.VAL")
|
||||
APU_CENTER_PERPENDICULAR_RB = PV(APU_NAME + ":MOTOR_Y.RBV")
|
||||
|
||||
# Camera field name
|
||||
data_field_name = "x_fit_mean"
|
||||
|
||||
# Camera
|
||||
|
||||
CAMERA_NAME = "SARES30-CAMS156-XE"
|
||||
pip_instance_id = CAMERA_NAME + "_sp"
|
||||
|
||||
### Acquisition start
|
||||
|
||||
apu_center_ref = APU_CENTER_RB.get()
|
||||
apu_size_ref = APU_SIZE_RB.get()
|
||||
apu_size_perp_ref = APU_SIZE_PERPENDICULAR.get()
|
||||
apu_center_perp_ref = APU_CENTER_PERPENDICULAR.get()
|
||||
|
||||
logger.info("BU/BD sent to start")
|
||||
BU.put(bender_us_start, wait=False)
|
||||
BD.put(bender_ds_start, wait=False)
|
||||
|
||||
APU_SIZE.put(aperture_size, wait=False)
|
||||
APU_SIZE_PERPENDICULAR.put(aperture_size_pendicular, wait=False)
|
||||
APU_CENTER.put(aperture[0], wait=False)
|
||||
|
||||
BU.put(bender_us_start, wait=True)
|
||||
BD.put(bender_ds_start, wait=True)
|
||||
|
||||
time.sleep(wait_time_benders)
|
||||
|
||||
logger.info(f"BU to start: {bender_us_start:6.3f}")
|
||||
logger.info(f"BD to start: {bender_ds_start:6.3f}")
|
||||
|
||||
bender_us_rb = []
|
||||
bender_ds_rb = []
|
||||
beam_positions = []
|
||||
|
||||
bender_scan_data = {}
|
||||
datestr, timestr = generate_date_and_time_str()
|
||||
|
||||
for bu in bender_us:
|
||||
logger.info("")
|
||||
BU.put(bu, wait=False)
|
||||
|
||||
for bd in bender_ds:
|
||||
BU.put(bu, wait=False)
|
||||
BD.put(bd, wait=False)
|
||||
BU.put(bu, wait=True)
|
||||
BD.put(bd, wait=True)
|
||||
time.sleep(wait_time_benders)
|
||||
|
||||
logger.info(f" BU / BD positions = {bu:6.3f} / {bd:6.3f}")
|
||||
|
||||
bender_us_rb.append(BU_RB.get())
|
||||
bender_ds_rb.append(BD_RB.get())
|
||||
|
||||
beam_pos = []
|
||||
|
||||
for apu in aperture:
|
||||
APU_CENTER.put(apu, wait=True)
|
||||
time.sleep(wait_time_aperture)
|
||||
|
||||
beam_pos_apu = get_position_from_pipeline(pip_instance_id, data_field_name, n_pulses=n_pulses)
|
||||
|
||||
logger.info(f" Aperture position = {apu:6.3f}; Beam position = {beam_pos_apu:6.3f}")
|
||||
|
||||
beam_pos.append(beam_pos_apu)
|
||||
|
||||
time.sleep(wait_time_aperture)
|
||||
APU_CENTER.put(aperture[0], wait=False)
|
||||
|
||||
beam_positions.append(beam_pos)
|
||||
|
||||
BD.put(bender_ds_start, wait=True)
|
||||
logger.info("")
|
||||
logger.info(f"BD to start: {bender_ds_start:6.3f}")
|
||||
time.sleep(wait_time_benders)
|
||||
|
||||
# save intermediate data
|
||||
bender_scan_data["bender_us"] = bender_us_rb
|
||||
bender_scan_data["bender_ds"] = bender_ds_rb
|
||||
bender_scan_data["beam_positions"] = beam_positions
|
||||
fpath = save_focusing_data(bender_scan_data, direction=direction, timestr=timestr, datestr=datestr)
|
||||
out_fpath = convert_focusing_to_bender_data(fpath)
|
||||
|
||||
logger.info(f"BU to start: {bender_us_start:6.3f}")
|
||||
|
||||
APU_SIZE.put(apu_size_ref, wait=False)
|
||||
APU_CENTER.put(apu_center_ref, wait=False)
|
||||
APU_SIZE_PERPENDICULAR.put(apu_size_perp_ref, wait=False)
|
||||
APU_CENTER_PERPENDICULAR.put(apu_center_perp_ref, wait=False)
|
||||
|
||||
BU.put(bender_us_start, wait=False)
|
||||
BD.put(bender_ds_start, wait=False)
|
||||
|
||||
logger.info(f"Data saved to: {out_fpath}")
|
||||
logger.info("Done")
|
||||
|
||||
return bender_scan_data
|
||||
|
||||
def generate_date_and_time_str():
|
||||
t = datetime.datetime.now()
|
||||
datestr = t.date().isoformat()
|
||||
|
||||
timestr = t.isoformat(timespec='minutes')
|
||||
return datestr, timestr
|
||||
|
||||
|
||||
def save_focusing_data(bender_scan_data, direction="unknown", timestr=None, datestr=None, beamline_directory="/sf/cristallina/applications/beamline/snapshots/KBs/"):
|
||||
""" Saves bender focusing data to json for analysis in beamline directory.
|
||||
"""
|
||||
bender_scan_data["comment"] = "Cristallina bender focusing data"
|
||||
|
||||
if timestr is None:
|
||||
datestr, timestr = generate_date_and_time_str()
|
||||
|
||||
directory = Path(beamline_directory) / datestr
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
fpath = directory / f"C_{timestr}_{direction}.json"
|
||||
|
||||
with open(fpath, "w") as f:
|
||||
json.dump(bender_scan_data, f)
|
||||
|
||||
return fpath
|
||||
|
||||
|
||||
def convert_focusing_to_bender_data(focusing_json_file):
|
||||
""" Converts focusing data to text array for further processing.
|
||||
"""
|
||||
fpath = Path(focusing_json_file)
|
||||
|
||||
with open(fpath, "r") as f:
|
||||
focusing_data = json.loads(f.read())
|
||||
|
||||
nrows = len(focusing_data['bender_us'])
|
||||
|
||||
arr = np.empty((nrows, 5))
|
||||
arr[:, 0] = focusing_data['bender_us']
|
||||
arr[:, 1] = focusing_data['bender_ds']
|
||||
arr[:, 2:] = focusing_data['beam_positions']
|
||||
|
||||
|
||||
Diff1 = arr[:,2] - arr[:,3]
|
||||
Diff2 = arr[:,4] - arr[:,3]
|
||||
|
||||
# extend array with difference columns
|
||||
arr = np.c_[arr, Diff1]
|
||||
arr = np.c_[arr, Diff2]
|
||||
|
||||
out_fpath = fpath.with_suffix(".dat")
|
||||
np.savetxt(out_fpath, arr)
|
||||
return out_fpath
|
||||
|
13
exp_temp/synchronization.py
Normal file
13
exp_temp/synchronization.py
Normal file
@ -0,0 +1,13 @@
|
||||
import requests
|
||||
import numpy as np
|
||||
|
||||
from loguru import logger
|
||||
|
||||
|
||||
def start_sequence(n: int = 100, pulse_phase: float = np.pi/8):
|
||||
parameters = {"n":n, "pulse_phase":pulse_phase}
|
||||
url = "http://oscillations.psi.ch:8000/pulse"
|
||||
r = requests.get(url, params=parameters)
|
||||
|
||||
d = r.json()
|
||||
return d['pids']
|
Reference in New Issue
Block a user