Add comments to trigger.py, add option to add devices to existing devices in phoenix.py. Method connecting different config files via cat into a tmp file which is then loaded

This commit is contained in:
gac-x07mb
2024-08-29 17:58:41 +02:00
committed by wakonig_k
parent 16b49fe670
commit 08a63c54ce
4 changed files with 191 additions and 90 deletions

View File

@ -54,13 +54,12 @@ bec._ip.prompts.status = 1
# make sure that edited modules are reloaded when changed
print('phoenix_bec/bec_iphyon_client/startup/post_startup.py')
print('... set autoreload of modules')
print("phoenix_bec/bec_iphyon_client/startup/post_startup.py")
print("... set autoreload of modules")
bec._ip.run_line_magic("reload_ext", "autoreload")
bec._ip.run_line_magic("autoreload", "2")
print('autoreload loaded ')
print("autoreload loaded ")
#############################################################################
@ -70,7 +69,6 @@ print('autoreload loaded ')
##############################################################################
@register_line_magic
def ph_reload(line):
@ -85,22 +83,24 @@ def ph_reload(line):
###################################################################W#####
from phoenix_bec.scripts import phoenix as PH
print('reload phoenix_bec.scripts.phoenix to iphyhton console')
print('to update version server restart server ')
print("reload phoenix_bec.scripts.phoenix to iphyhton console")
print("to update version server restart server ")
# need to use global statement here, as I like to reload into space on
# iphyton consoel
global PH, phoenix
print('from phoenix_bec.scripts import phoenix as PH')
print('phoenix = PH.PhoenixBL()')
print("from phoenix_bec.scripts import phoenix as PH")
print("phoenix = PH.PhoenixBL()")
phoenix = PH.PhoenixBL()
# ph_config=PH.PhoenixConfighelper()
# enddef
print('##################################################################')
print('register magic')
print('...... %ph_load_xmap ... to reload xmap configuration')
print("##################################################################")
print("register magic")
print("...... %ph_load_xmap ... to reload xmap configuration")
@register_line_magic
@ -112,10 +112,14 @@ def ph_load_xmap(line):
t0 = tt.time()
phoenix_server.add_xmap()
print('elapsed time:', tt.time()-t0)
print("elapsed time:", tt.time() - t0)
# enddef
print('...... %ph_load_falcon ... to reload falcon configuration')
print("...... %ph_load_falcon ... to reload falcon configuration")
@register_line_magic
def ph_load_falcon(line):
@ -123,22 +127,30 @@ def ph_load_falcon(line):
t0 = tt.time()
phoenix_server.add_falcon()
print('elapsed time:', tt.time()-t0)
print("elapsed time:", tt.time() - t0)
# enddef
print('...... %ph_load_config ... to reload phoenix default configuration')
print("...... %ph_load_config ... to reload phoenix default configuration")
@register_line_magic
def ph_load_config(line):
t0 = tt.time()
phoenix_server.add_phoenix_config()
print('elapsed time:', tt.time()-t0)
print("elapsed time:", tt.time() - t0)
# enddef
@register_line_magic
def ph_restart_bec_server(line):
os.system('bec-server restart')
os.system("bec-server restart")
os.system('gnome-terminal --geometry 120X50 -- bash -c "bec-server attach; exec bash"')
##@register_line_magic
# def ph_post_startup(line):
# print('import phoenix_bec.bec_ipython_client.startup.post_startup does not work caused loop ')
@ -154,21 +166,20 @@ def ph_restart_bec_server(line):
##
#####################################################################################
print('###############################################################')
print('init phoenix_bec/scripts/phoenix.py in two different ways')
print(' 1) phoenix_server = PhoenixBL() ... takes code from server version ')
print('SERBVR VERSION DOES NOT WORK ANYMORE ')
print('FOLDER SCRUIPT SEEMS TO BE NON_STANDARD!!!!!!! ')
print("###############################################################")
print("init phoenix_bec/scripts/phoenix.py in two different ways")
print(" 1) phoenix_server = PhoenixBL() ... takes code from server version ")
print("SERBVR VERSION DOES NOT WORK ANYMORE ")
print("FOLDER SCRUIPT SEEMS TO BE NON_STANDARD!!!!!!! ")
phoenix_server = PhoenixBL()
print(' 2) phoenix=PH.PhoenixBL() ... on inpython shell only! (for debugging)')
print(" 2) phoenix=PH.PhoenixBL() ... on inpython shell only! (for debugging)")
from phoenix_bec.scripts import phoenix as PH
phoenix = PH.PhoenixBL()
phoenix = PH.PhoenixBL()
# from phoenix_bec.bec_ipython_client.plugins.phoenix import Phoenix
# from phoenix_bec.devices.falcon_phoenix_no_hdf5 import FalconHDF5Plugins

View File

@ -1,26 +1,4 @@
falcon_nohdf5:
description: Falcon detector x-ray fluoresence II
deviceClass: phoenix_bec.devices.falcon_phoenix_no_hdf5.FalconPhoenix
deviceConfig:
prefix: 'X07MB-SITORO:'
deviceTags:
- phoenix
- falcon
- no hdf5
- phoenix_devices.yaml
onFailure: buffer
enabled: true
readoutPriority: async
softwareTrigger: false
###################################################
#
# phoenix standard devices (motors)
#
#
####################################################:
PH_TTL:
description: PHOENIX TTL trigger
deviceClass: phoenix_bec.devices.phoenix_trigger.PhoenixTrigger
@ -36,6 +14,13 @@ PH_TTL:
softwareTrigger: true
###################################################
#
# phoenix standard devices (motors)
#
#
####################################################:
PH_Dummy:
description: PHOENIX DUMMY DET
deviceClass: phoenix_bec.devices.dummy_devices.Dummy_PSIDetector

View File

@ -1,5 +1,17 @@
""" Module for the PhoenixTrigger class to connect to the ADC card
that creates TTL signals to trigger cameras and detectors at Phoenix. """
"""
Module for the PhoenixTrigger class to connect to the ADC card
that creates TTL signals to trigger cameras and detectors at Phoenix.
TO Do
-- allow for variable dwell times
-- add erase/Start for XMAP and FALCON
-- check values for time.sleep()
-- check in on_triggerthe status check for Falcon
-- rework togther with Xiaoquiang the functionality of involved EPICS channels
(Callbacks etc.) to minimize the need of sleeping times.
"""
import enum
import time
@ -23,10 +35,16 @@ class PhoenixTriggerError(Exception):
class SAMPLING(int, enum.Enum):
"""Sampling Done PV"""
"""Sampling Done PV
RUNNING = 0
DONE = 1
This class serves redabilty of missinx class and ensure correct setting of
certain conditions.
defiend preset values for certain states to be called in the
mixing class, where we for example check whether the sampling is done of not
by comparing with SAMPLING.DONE
xxx==SAMPLING.DONE
"""
class PhoenixTriggerSetup(CustomDetectorMixin):
@ -35,13 +53,26 @@ class PhoenixTriggerSetup(CustomDetectorMixin):
"""
def on_stage(self) -> None:
"""On stage actions which are executed upon staging the device"""
if self.parent.scaninfo.scan_type == "step":
"""
On stage actions which are executed upon staging the device
"""
if self.parent.scaninfo.scan_type == "step": # check whether we use step scanning
###############
# next lines ensure that TTL trigger is on single sampling mode (posible )
##############
self.parent.start_csmpl.set(0)
time.sleep(0.1)
self.parent.total_cycles.set(1)
self.parent.smpl.put(1)
time.sleep(0.5)
#####
# set sampling to dwell time of scan
######
self.parent.total_cycles.set(np.ceil(self.parent.scaninfo.exp_time * 5))
logger.info(f"Device {self.parent.name} was staged for step scan")
def on_unstage(self) -> None:
@ -50,21 +81,26 @@ class PhoenixTriggerSetup(CustomDetectorMixin):
def on_trigger(self) -> DeviceStatus:
"""On trigger actions which are executed upon triggering the device"""
# TODO Test the proper check for the falcon state
# Check first that falcon is set to acquiring
falcon = self.parent.device_manager.devices.get("falcon_nohdf5", None)
falcon = self.parent.device_manager.devices.get("falcon_nohdf5", None) # get device
timeout = 1
if falcon is not None:
# TODO Check that falcon.state.get() == 1 is the correct check. --> When is the falcon acquiring, this assumes 1?
if not self.wait_for_signals([(falcon.state.get, 1)], timeout=timeout):
raise PhoenixTriggerError(
f"Device {self.parent.name} is not ready to take trigger, timeout due to waiting for Falcon to get ready. Timeout after {timeout}s"
)
if self.parent.scaninfo.scan_type == "step":
time.sleep(0.2)
self.parent.smpl.put(1)
# Minimum of 1 cycle has to be waited. Cycle == 0.2s
time.sleep(0.2)
# Trigger function from ophyd.Device returns a DeviceStatus. This function
# starts a process that creates a DeviceStatus, and waits for the signal_conditions
# self.parent.smpl_done.get to change to the value SAMPLING.DONE
@ -74,18 +110,30 @@ class PhoenixTriggerSetup(CustomDetectorMixin):
# In ScanBase, the _at_each_point function calls
# self.stubs.wait(wait_type="trigger", group="trigger", wait_time=self.exp_time)
# which ensures that the DeviceStatus object resolves before continuing, i.e. DeviceStatus.done = True
status = self.wait_with_status(
signal_conditions=[(self.parent.smpl_done.get, SAMPLING.DONE)],
timeout=5 * self.parent.scaninfo.exp_time, # Check if timeout is appropriate
check_stopped=True,
)
return status
# explanation of last line (self.parent.smpl_done.get, SAMPLINGDONE.DONE) creates a tuple which defines a
# condition, which is tested in self.wait_with_status, here it tests for :
# (self.parent.smpl_done.get() == SAMPLINGDONE.DONE), where SAMPLINGDONE.DONE =1, as set in code above
# As this is in mixing class (PhoenixtriggerSetup), parent.sample_done is defined in
# main class as smpl_done = Cpt(EpicsSignalRO, "SMPL-DONE", kind=Kind.config)
return status # should this be in if clause level or outside?
# endif
def on_stop(self) -> None:
"""Actions to stop the Device"""
# Put the Device again in continous acquisition mode
self.parent.total_cycles.set(5)
"""
Actions to stop the Device
Here the device is switched back to continuous sampling.
"""
self.parent.start_csmpl.set(1)
time.sleep(0.5)
self.parent.smpl.put(1)
time.sleep(0.5)
self.parent.smpl.put(1)
@ -102,8 +150,51 @@ class PhoenixTrigger(PSIDetectorBase):
This device is used to trigger communicate with an ADC card that creates TTL signals to trigger cameras and detectors at Phoenix.
"""
##################################################################
#
# The Variable USER_ACCESS contains an ascii list of functions which will be
# visible in dev.TTL. Here, this list is empty.
# note that components are alway public
#
##################################################################
USER_ACCESS = []
#####################################################################
# specify Setup class into variable custom_prepare_cls
# in __init__ of PSIDetectorBase will the initialzed by
# self.custom_prepare = self.custom_prepare_cls(parent=self, **kwargs)
# making the instance of PSIDetectorBase availble to functions
# in PhoenixTriggerSetup.
######################################################################
custom_prepare_cls = PhoenixTriggerSetup
#############################################################
#
# Now use Component=Cpt to provide channel access
# when PhoenixTrigger is initialized, the parameters of the base class are
# inherited, most notable prefix, which is here 'X07MB-OP2:'
#
# The input of Component=Cpt is Cpt(deviceClass,suffix)
# if Cpt is used in a class, which has interited Device, here via:
#
# (Here PhoenixTrigger <-- PSIDetectorBase <- Device
#
# then Cpt will construct - magically- the
# Epics channel name = prefix+suffix,
#
# for example
# 'X07MB-OP2:' + 'START-CSMPL' -> 'X07MB-OP2:' + 'START-CSMPL'
#
# to construct names, for now we keep the convention to derive
# them from the EPICS NAMES (such as ) X07MB-OP2:SMPL-DONE --> smpl_done
#
# this mean access to channel using dev.PH_TTL.smpl_done.get()
#
#
###################################################################
start_csmpl = Cpt(
EpicsSignal, "START-CSMPL", kind=Kind.config, put_complete=True
) # cont on / off

View File

@ -55,21 +55,29 @@ class PhoenixBL:
self.path_scripts_local = (
"/data/test/x07mb-test-bec/bec_deployment/phoenix_bec/phoenix_bec/local_scripts/"
)
self.path_config_local = (
self.path_scripts_local + "TEST_ConfigPhoenix/"
) # base dir for local configurations
self.path_devices_local = (
self.path_config_local + "Local_device_config/"
) # local yamal file
self.file_devices_file_local = self.path_devices_local + "phoenix_devices.yaml"
self.path_phoenix_bec = "/data/test/x07mb-test-bec/bec_deployment/phoenix_bec/"
self.path_devices = (
self.path_phoenix_bec + "phoenix_bec/device_configs/"
) # local yamal file
self.path_devices = self.path_phoenix_bec + "phoenix_bec/device_configs/"
# yamal file for default configuration
self.file_devices_file = (
self.path_phoenix_bec + "phoenix_bec/device_configs/phoenix_devices.yaml"
) # local yamal file
self.file_devices_tmp = (
self.path_phoenix_bec + "phoenix_bec/device_configs/current_devices_tmp.yaml"
) # tmp configuration file. Will be electronicall created and appended if needed
self.t0 = time.time()
def read_local_phoenix_config(self):
@ -77,24 +85,30 @@ class PhoenixBL:
print(self.file_phoenix_devices_file)
bec.config.update_session_with_file(self.file_devices_file_local)
def create_base_config(self):
# create a yaml file from standard configuration
os.system("cat " + self.file_devices_file + " > " + self.file_devices_tmp)
# os.system("ls -altr" + self.path_phoenix_bec + "phoenix_bec/devices")
bec.config.update_session_with_file(self.file_devices_tmp)
def add_phoenix_config(self):
print("add_phoenix_config ")
print("self.file_devices_file")
bec.config.update_session_with_file(self.file_devices_file)
bec.config.update_session_with_file(self.tmp.file_devices_file)
def add_xmap(self):
print("add xmap ")
print(self.path_devices + "phoenix_xmap.yaml")
bec.config.update_session_with_file(
self.path_devices + "phoenix_xmap.yaml"
) # ,timeout=100)
os.system("cat " + self.path_devices + "phoenix_xmap.yaml" + " >> " + self.file_devices_tmp)
bec.config.update_session_with_file(self.file_devices_tmp)
def add_falcon(self):
print("add_xmap")
print(self.path_devices + "/phoenix_falcon.yaml")
# bec.config.wait_for_config_reply()
bec.config.update_session_with_file(self.path_devices + "/phoenix_falcon.yaml")
print("add_falcon")
os.system(
"cat " + self.path_devices + "phoenix_falcon.yaml" + " >> " + self.file_devices_tmp
)
bec.config.update_session_with_file(self.file_devices_tmp)
def show_phoenix_setup(self):
print(self.path_phoenix_bec)