From c1b8bb4a344dd7d5e1f7ddb1076e9c81a435955a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20BRON=C3=88S?= <romain.brones@synchrotron-soleil.fr> Date: Thu, 25 Jan 2024 16:48:21 +0100 Subject: [PATCH] Keep working * Have configuration of blocks working * Have basic deals with deviceserver working --- FofbTool/CommandLineInterface.py | 46 ++-- FofbTool/Configuration.py | 362 ++++++++++++++++++------------- FofbTool/Utils.py | 112 +++++++++- 3 files changed, 343 insertions(+), 177 deletions(-) diff --git a/FofbTool/CommandLineInterface.py b/FofbTool/CommandLineInterface.py index a15663d..9e448bf 100755 --- a/FofbTool/CommandLineInterface.py +++ b/FofbTool/CommandLineInterface.py @@ -16,6 +16,7 @@ if __name__ == '__main__': # Safer import: add the parent dir in path sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import FofbTool.Utils + import FofbTool.Configuration # Get the module logger @@ -30,27 +31,17 @@ if __name__ == '__main__': parser = argparse.ArgumentParser("FofbTool") parser.add_argument("--log", default="info", help="Log level (error, warning, info, debug)") - parser.add_argument("--init-opcua", action="store_true", + + parser.add_argument("--DS-init-opcua", action="store_true", help="Run init on opcua devices.") - parser.add_argument("--init-watcher", action="store_true", + parser.add_argument("--DS-init-watcher", action="store_true", help="Run init on the Fofb-Watcher device, and then the Fofb-Command.") - parser.add_argument("--conf-DS", action="store_true", + parser.add_argument("--DS-conf", action="store_true", help="Applying attribute configuration on Tango Device Servers. This is required after restart of devices.") - parser.add_argument("--stop", action="store_true", - ) - parser.add_argument("--conf", action="store_true", - ) - parser.add_argument("--start", action="store_true", - ) - parser.add_argument("--disable-corr", action="store_true", - help="Disable cellnode corrector output frames." - ) - parser.add_argument("--respmat", default=None, - help="Configure response matrix from file" - ) - parser.add_argument("node", default="allnodes", nargs='*', - choices=('c01', 'c06', 'c09', 'c14', 'central', 'allcells', 'allnodes'), - help="Node to apply the selected actions. Default is all.") + + parser.add_argument("--configure", choices=["combpm", "ccn", "comcorr", "corr", "all", "every"], nargs="+", + help="Configuration commands for the Fofb applications blocs."+ + " 'all' is for all com, not configuring corrector. 'every' configure everything.") args = parser.parse_args() @@ -59,15 +50,28 @@ if __name__ == '__main__': logger.debug(args) - if args.init_opcua: + ## Device Server related commands + if args.DS_init_opcua: FofbTool.Utils.init_opcua() - if args.init_watcher: + if args.DS_init_watcher: FofbTool.Utils.init_watcher() - if args.conf_DS: + if args.DS_conf: FofbTool.Utils.confds_opcua() + for conf in args.configure: + if conf in ("combpm", "all", "every"): + FofbTool.Utils.conf_all_combpm() + if conf in ("comcorr", "all", "every"): + FofbTool.Utils.conf_all_comcorr() + if conf in ("ccn", "all", "every"): + FofbTool.Utils.conf_all_ccn() + if conf in ("corr", "every"): + FofbTool.Configuration.centralnode_configure_corr() + + exit(0) + if args.stop: for cnp in cellnode_subscribers: cellnode_stop_ccn(cnp) diff --git a/FofbTool/Configuration.py b/FofbTool/Configuration.py index 359d5f5..1b1f2b3 100755 --- a/FofbTool/Configuration.py +++ b/FofbTool/Configuration.py @@ -1,108 +1,148 @@ -#!/usr/bin/env python +################################################################################################### +# CONFIGURATION FUNCTIONS +################################################################################################### +# +# Contains functions to configure blocks of the FOFB application. +# +################################################################################################### import tango import logging import argparse import numpy as np import time +import FofbTool.Utils # Get the module logger logger = logging.getLogger("FofbTool") + ################################################################################################### -# TANGO DEVICE PROXIES +# CONFIGURE COM BPM ################################################################################################### -cellnode_subscribers = [ tango.DeviceProxy("ans/dg/fofb-cellnode-{}".format(cell)) for cell in ("C01", "C06", "C09", "C14") ] +# Filter list depends on the cellnode. These are the default values. +bpmfilterlist = { + "cellnode-c01":np.array(list(range(1,23))+list(range(115,123))), + "cellnode-c06":np.array(range(23,53)), + "cellnode-c09":np.array(range(53,83)), + "cellnode-c14":np.array(range(83,115)), + } + +def cellnode_configure_combpm(cellnodename, bpmallowed=None): + """ + Configure the combpm block of a CellNode. + The BPM data allowed through are either taken in the argument, or default to nominal values. + + + PARAMETERS + ---------- + cellnodename: str + The target cellnode, ie 'cellnode-c09' + bpmallowed: [int], None + List of BPMID allowed through the block. If None, default to nominal values. + + RETURN + ------ + success: boolean + True if configuration is a success + """ + + # Get device proxy + try: + p = FofbTool.Utils.tangopath_cellnodes[cellnodename.lower()] + except KeyError: + logger.error("Wrong cellnodename. Possibilities are {}".format(FofbTool.Utils.tangopath_cellnodes.keys())) + return False + + try: + prx= tango.DeviceProxy(p) + except tango.DevFailed as e: + logger.error("Failed to get the Device proxy to '{}'".format(p)) + logger.debug(str(e)) + return False + + # Select BPM id allowed to pass through + if bpmallowed is None: + logger.debug("Default to nominal values for BPM filter") + bpmallowed = bpmfilterlist[cellnodename.lower()] -centralnode_subscriber = tango.DeviceProxy("ans/dg/fofb-centralnode") -bpmmanager = tango.DeviceProxy("ans/dg/bpm-manager") + logger.debug("Activate BPMs {} in the filter for {}".format(bpmallowed, p)) + f = prx["combpm_filter_table"].value + f[:] = 0 + f[np.array(bpmallowed)] = 0x80 + prx["combpm_filter_table"] = f -fofbcommand = tango.DeviceProxy("ans/dg/fofb-command") + logger.info("Configuration of ComBpm done on {}.".format(p)) + return True ################################################################################################### -# OPERATION FUNCTIONS +# CONFIGURE CCN: COM CELLNODES ################################################################################################### -def cellnode_stop_ccn(cnp): - logger.info("Stopping CCN on {}".format(cnp.name())) - cnp["ccnpack0_control"] = False - cnp["ccnunpack0_control"] = False - -def cellnode_start_ccn(cnp): - logger.info("Starting CCN on {}".format(cnp.name())) - cnp["ccneth0_reset"] = 0x60000001 # impossible to write 0xE0000001 - cnp["ccneth0_gt_reset"] = 1 - cnp["ccneth0_gt_reset"] = 0 - cnp["ccneth0_reset"] = 0 - cnp["ccnpack0_control"] = True - cnp["ccnunpack0_control"] = True - -def cellnode_ack_ccn(snp): - logger.info("Ack CCN error on {}".format(cnp.name())) - cnp["ccnpack0_reset_error"] = True - cnp["ccnunpack0_reset_error"] = True - cnp["ccnpack0_reset_error"] = False - cnp["ccnunpack0_reset_error"] = False - -def centralnode_stop_ccn(cnp): - logger.info("Stopping CCN on {}".format(cnp.name())) - for n in range(4): - cnp["ccnpack{}_control".format(n)] = False - cnp["ccnunpack{}_control".format(n)] = False -def centralnode_start_ccn(cnp): - logger.info("Starting CCN on {}".format(cnp.name())) - for n in range(4): - cnp["ccneth{}_reset".format(n)] = 0x60000001 # impossible to write 0xE0000001 - cnp["ccneth{}_gt_reset".format(n)] = 1 - cnp["ccneth{}_gt_reset".format(n)] = 0 - cnp["ccneth{}_reset".format(n)] = 0 - cnp["ccnpack{}_control".format(n)] = True - cnp["ccnunpack{}_control".format(n)] = True - cnp["ccnpack{}_reset_error".format(n)] = True - cnp["ccnunpack{}_reset_error".format(n)] = True - cnp["ccnpack{}_reset_error".format(n)] = False - cnp["ccnunpack{}_reset_error".format(n)] = False - -def cellnode_configure_ccn(cnp, nbpm=None, npsc=100): +def cellnode_configure_ccn(cellnodename, nbpm=None, npsc=100): """ - Configure the ComCellNode block. + Configure the ComCellNode block on a cellnode. + Automatically set the number of bpm/psc packets and MAC length. PARAMETERS ---------- + cellnodename: str + The target cellnode, ie 'cellnode-c09' nbpm: Number of BPM allowed by the filter, hence the number of expected BPM packets. If None, auto detect the number from the combpm_filter_table attribute. npsc: Number of total PSC, hence the number of expected PSC packets. + Default to 100. + RETURN + ------ + success: boolean + True if configuration is a success """ + # Get device proxy + try: + p = FofbTool.Utils.tangopath_cellnodes[cellnodename.lower()] + except KeyError: + logger.error("Wrong cellnodename. Possibilities are {}".format(FofbTool.Utils.tangopath_cellnodes.keys())) + return False + + try: + prx= tango.DeviceProxy(p) + except tango.DevFailed as e: + logger.error("Failed to get the Device proxy to '{}'".format(p)) + logger.debug(str(e)) + return False + if nbpm is None: # Get number of BPM activated in the filter - nbpm = int((cnp["combpm_filter_table"].value == 0x80).sum()) - logger.debug("{} bpm allowed in the filter on {}".format(nbpm, cnp.name())) + nbpm = int((prx["combpm_filter_table"].value == 0x80).sum()) + logger.debug("{} bpm allowed in the filter on {}".format(nbpm, p)) maclen = 10*nbpm+10 logger.debug("Configure packeter framesize (mac length) to {}".format(maclen)) - cnp["ccnpack0_framesize"] = maclen + prx["ccnpack0_framesize"] = maclen logger.debug("Configure packeter npackets to {}".format(nbpm-1)) - cnp["ccnpack0_npackets"] = nbpm-1 + prx["ccnpack0_npackets"] = nbpm-1 maclen = npsc*6+10 logger.debug("Configure unpacketer framesize (mac length) to {}".format(maclen)) - cnp["ccnunpack0_framesize"] = maclen + prx["ccnunpack0_framesize"] = maclen - logger.info("Configuration of CCN done on {}.".format(cnp.name())) + logger.info("Configuration of CCN done on {}.".format(p)) + return True -def centralnode_configure_ccn(cnp, nbpm=[30,30,30,32], npsc=100): +def centralnode_configure_ccn(nbpm=[30,30,30,32], npsc=100): """ - Configure the ComCellNode block. + Configure the ComCellNode block on the centralnode. + Automatically set the number of bpm/psc packets and MAC length. PARAMETERS ---------- @@ -111,120 +151,142 @@ def centralnode_configure_ccn(cnp, nbpm=[30,30,30,32], npsc=100): npsc: Number of total PSC, hence the number of expected PSC packets. + RETURN + ------ + success: boolean + True if configuration is a success """ + p = FofbTool.Utils.tangopath_nodes["centralnode"] + try: + prx= tango.DeviceProxy(p) + except tango.DevFailed as e: + logger.error("Failed to get the Device proxy to '{}'".format(p)) + logger.debug(str(e)) + return False for n in range(4): - maclen = npsc*6+10 logger.debug("Configure packeter {} framesize (mac length) to {}".format(n, maclen)) - cnp["ccnpack{}_framesize".format(n)] = maclen + prx["ccnpack{}_framesize".format(n)] = maclen logger.debug("Configure packeter {} npackets to {}".format(n, npsc-1)) - cnp["ccnpack{}_npackets".format(n)] = npsc-1 + prx["ccnpack{}_npackets".format(n)] = npsc-1 maclen = 10*nbpm[n]+10 logger.debug("Configure unpacketer {} framesize (mac length) to {}".format(n, maclen)) - cnp["ccnunpack{}_framesize".format(n)] = maclen - - logger.info("Configuration of CCN done on {}.".format(cnp.name())) - - -def cellnode_stop_combpm(cnp): - logger.info("Stopping ComBpm on {}".format(cnp.name())) - cnp["combpm_reset"] = 1 - cnp["combpm_gt_control"] = 0x5 - -def cellnode_start_combpm(cnp): - logger.info("Starting ComBpm on {}".format(cnp.name())) - cnp["combpm_reset"] = 0 - cnp["combpm_gt_control"] = 0x1 - cnp["combpm_reset_error"] = True - cnp["combpm_reset_error"] = False - -def cellnode_configure_combpm(cnp): - - # Filter list depends on the cellnode - filterlist = { - "C01":np.array(list(range(1,23))+list(range(115,123))), - "C06":np.array(range(23,53)), - "C09":np.array(range(53,83)), - "C14":np.array(range(83,115)), - } - - for k in filterlist.keys(): - if k in cnp.name(): - logger.debug("Activate BPMs {} in the filter for {}".format(filterlist[k], cnp.name())) - f = cnp["combpm_filter_table"].value - f[:] = 0 - f[np.array(filterlist[k])] = 0x80 - cnp["combpm_filter_table"] = f - - logger.info("Configuration of ComBpm done on {}.".format(cnp.name())) - -def cellnode_configure_comcorr(cnp, enable=True): - - pscidlist = { - 'C01':[50,100,49,99,255,255,255,255,2,52,1,51,255,255,255,255,56,6,3,53,4,54,5,55,10,60,7,57,8,58,9,59], - 'C06':[12,62,11,61,255,255,255,255,14,64,13,63,255,255,255,255,68,18,15,65,16,66,17,67,22,72,19,69,20,70,21,71], - 'C09':[24,74,23,73,255,255,255,255,26,76,25,75,255,255,255,255,80,30,27,77,28,78,29,79,34,84,31,81,32,82,33,83], - 'C14':[36,86,35,85,37,87,38,88,40,90,39,89,255,255,255,255,94,44,41,91,42,92,43,93,48,98,45,95,46,96,47,97] - } + prx["ccnunpack{}_framesize".format(n)] = maclen - for k in pscidlist.keys(): - if k in cnp.name(): - logger.debug("Set PSCIDs {} in the filter for {}".format(pscidlist[k], cnp.name())) - f= cnp["comcorr_line_id"].value - f[:] = pscidlist[k] - f[:] = f+ 0x10000*bool(enable) - logger.debug("Set comcorr_line_id {} for {}".format(f, cnp.name())) - cnp["comcorr_line_id"] = f + logger.info("Configuration of CCN done on {}.".format(p)) + return True - logger.info("Configuration of ComCorr done on {}.".format(cnp.name())) +################################################################################################### +# CONFIGURE COM CORR +################################################################################################### -def centralnode_configure_corr(cnp): +pscidlist = { + 'cellnode-c01':[50,100,49,99,255,255,255,255,2,52,1,51,255,255,255,255,56,6,3,53,4,54,5,55,10,60,7,57,8,58,9,59], + 'cellnode-c06':[12,62,11,61,255,255,255,255,14,64,13,63,255,255,255,255,68,18,15,65,16,66,17,67,22,72,19,69,20,70,21,71], + 'cellnode-c09':[24,74,23,73,255,255,255,255,26,76,25,75,255,255,255,255,80,30,27,77,28,78,29,79,34,84,31,81,32,82,33,83], + 'cellnode-c14':[36,86,35,85,37,87,38,88,40,90,39,89,255,255,255,255,94,44,41,91,42,92,43,93,48,98,45,95,46,96,47,97] + } - # Legacy - cnp["corr_k1a_x"]=256 - cnp["corr_k1b_x"]=0 - cnp["corr_k1ic_x"]=64 - cnp["corr_k1d_x"]=16300 +def cellnode_configure_comcorr(cellnodename, pscid=None, enable=True): + """ + Configure the comcorr block of a CellNode. + The PSC ID either taken in the argument, or default to nominal values. - cnp["corr_k1a_y"]=256 - cnp["corr_k1b_y"]=0 - cnp["corr_k1ic_y"]=64 - cnp["corr_k1d_y"]=16300 - # Unitary - cnp["corr_k2a_x"]=128 - cnp["corr_k2b_x"]=0 - cnp["corr_k2ic_x"]=8192 - cnp["corr_k2d_x"]=0 + PARAMETERS + ---------- + cellnodename: str + The target cellnode, ie 'cellnode-c09' + pscid: [int], None + List of 32 PSCID to program on the output board. If None, default to nominal values. + + enable: boolean + Enable or not the hardware outputs. + + RETURN + ------ + success: boolean + True if configuration is a success + """ - cnp["corr_k2a_y"]=128 - cnp["corr_k2b_y"]=0 - cnp["corr_k2ic_y"]=8192 - cnp["corr_k2d_y"]=0 + # Get device proxy + try: + p = FofbTool.Utils.tangopath_cellnodes[cellnodename.lower()] + except KeyError: + logger.error("Wrong cellnodename. Possibilities are {}".format(FofbTool.Utils.tangopath_cellnodes.keys())) + return False + + try: + prx= tango.DeviceProxy(p) + except tango.DevFailed as e: + logger.error("Failed to get the Device proxy to '{}'".format(p)) + logger.debug(str(e)) + return False + + if pscid is None: + logger.debug("Default to nominal values for PSCID") + pscid = pscidlist[cellnodename.lower()] + else: + if len(pscid) != 32: + logger.error("pscid shall have length 32") + return False + + + logger.debug("Set PSCIDs {} in the filter for {}".format(pscid, p)) + f= prx["comcorr_line_id"].value + f[:] = pscid + f[:] = f+ 0x10000*bool(enable) + logger.debug("Set comcorr_line_id {} for {}".format(f, p)) + prx["comcorr_line_id"] = f + + logger.info("Configuration of ComCorr done on {}.".format(p)) + return True - f= cnp["corr_pscid"].value - f[0:100] = range(1,101) - cnp["corr_pscid"] = f +################################################################################################### +# CONFIGURE MATRIX CORRECTOR +################################################################################################### - logger.info("Configuration of Corr done on {}.".format(cnp.name())) +def centralnode_configure_corr(): + """ + Configure the correction algorithm on the centralnode. + """ + p = FofbTool.Utils.tangopath_nodes["centralnode"] + try: + prx= tango.DeviceProxy(p) + except tango.DevFailed as e: + logger.error("Failed to get the Device proxy to '{}'. Configuration of corrector algorithm failed.".format(p)) + logger.debug(str(e)) + return False -def fofbcommand_writeref(what='current'): - if what=="current": - fofbcommand["x_ref_orbit"] = (bpmmanager.xmeanorbit*1e6).astype(int) - fofbcommand["y_ref_orbit"] = (bpmmanager.zmeanorbit*1e6).astype(int) + # Legacy + prx["corr_k1a_x"]=256 + prx["corr_k1b_x"]=0 + prx["corr_k1ic_x"]=64 + prx["corr_k1d_x"]=16300 - if what=="oldref": - fofbcommand["x_ref_orbit"] = (bpmmanager.xreforbit*1e6).astype(int) - fofbcommand["y_ref_orbit"] = (bpmmanager.zreforbit*1e6).astype(int) + prx["corr_k1a_y"]=256 + prx["corr_k1b_y"]=0 + prx["corr_k1ic_y"]=64 + prx["corr_k1d_y"]=16300 - if what=="zeros": - fofbcommand["x_ref_orbit"] = np.zeros(122, dtype=int) - fofbcommand["y_ref_orbit"] = np.zeros(122, dtype=int) + # Unitary + prx["corr_k2a_x"]=128 + prx["corr_k2b_x"]=0 + prx["corr_k2ic_x"]=8192 + prx["corr_k2d_x"]=0 + + prx["corr_k2a_y"]=128 + prx["corr_k2b_y"]=0 + prx["corr_k2ic_y"]=8192 + prx["corr_k2d_y"]=0 + + f= prx["corr_pscid"].value + f[0:100] = range(1,101) + prx["corr_pscid"] = f -def fofbcommand_writemat(filename='respmat.npy'): + logger.info("Configuration of Corr done on {}.".format(p)) + return True - fofbcommand["x_inv_resp_mat"] = np.hstack([np.zeros((50, 1)), np.load(filename)[50:], np.zeros((50,5))]).astype(int) - fofbcommand["y_inv_resp_mat"] = np.hstack([np.zeros((50, 1)), np.load(filename)[:50], np.zeros((50,5))]).astype(int) diff --git a/FofbTool/Utils.py b/FofbTool/Utils.py index 15da6a9..02237b8 100644 --- a/FofbTool/Utils.py +++ b/FofbTool/Utils.py @@ -8,25 +8,30 @@ import tango import logging -import DeviceAttributeConfiguration +import FofbTool.DeviceAttributeConfiguration # Get the module logger logger = logging.getLogger("FofbTool") -tangopath_nodes = { - "centralnode":"ans/dg/fofb-centralnode", +tangopath_cellnodes = { "cellnode-c01":"ans/dg/fofb-cellnode-c01", "cellnode-c06":"ans/dg/fofb-cellnode-c06", "cellnode-c09":"ans/dg/fofb-cellnode-c09", "cellnode-c14":"ans/dg/fofb-cellnode-c14", } +tangopath_nodes = { + "centralnode":"ans/dg/fofb-centralnode", + } +tangopath_nodes.update(tangopath_cellnodes) + tangopath = { "fofb-watcher":"ans/dg/fofb-watcher", "fofb-command":"ans/dg/fofb-command", "fofb-manager":"ans/dg/fofb-manager", "bpm-manager":"ans/dg/bpm-manager", - }.update(tangopath_nodes) + } +tangopath.update(tangopath_nodes) def init_opcua(): """ @@ -72,12 +77,107 @@ def confds_opcua(): try: if 'central' in n: - DeviceAttributeConfiguration.set_attr_config_centralnode(prx) + FofbTool.DeviceAttributeConfiguration.set_attr_config_centralnode(prx) else: - DeviceAttributeConfiguration.set_attr_config_cellnode(prx) + FofbTool.DeviceAttributeConfiguration.set_attr_config_cellnode(prx) except tango.DevFailed as e: logger.error("Could not set attribute configuration for '{}', got DevFailed.".format(p)) logger.debug(str(e)) +def check_fofbnotrunning(): + """ + Check if the FOFB is not running. + If it fails to know, return False and log error. + + RETURN + ------ + running: Boolean + True if FOFB is not running + """ + + try: + prx = tango.DeviceProxy(tangopath["fofb-watcher"]) + except tango.DevFailed as e: + logger.error("Failed to get the Device proxy to '{}'".format(tangopath["fofb-watcher"])) + logger.debug(str(e)) + return False + + try: + return not (prx.fofbrunning_x or prx.fofbrunning_y) + except tango.DevFailed as e: + logger.error("Failed to read the FOFB status on device Fofb-Watcher") + logger.debug(str(e)) + return False + +def conf_all_combpm(): + """ + Run default configuration of all combpm blocks. + Check beforehand that the FOFB is not running. + + RETURN + ------ + running: Boolean + True if FOFB is not running + """ + + if not check_fofbnotrunning(): + logger.warning("Not running configuration of combpm because FOFB seems to be running.") + return False + + success=True + for i,(n,p) in enumerate(tangopath_cellnodes.items()): + s=FofbTool.Configuration.cellnode_configure_combpm(n) + success = success and s + + return success + + +def conf_all_comcorr(): + """ + Run default configuration of all comcorr blocks. + Check beforehand that the FOFB is not running. + + RETURN + ------ + running: Boolean + True if FOFB is not running + """ + + if not check_fofbnotrunning(): + logger.warning("Not running configuration of comcorr because FOFB seems to be running.") + return False + + success=True + for i,(n,p) in enumerate(tangopath_cellnodes.items()): + s=FofbTool.Configuration.cellnode_configure_comcorr(n) + success = success and s + + return success + + +def conf_all_ccn(): + """ + Run default configuration of all comcellnode blocks. + Check beforehand that the FOFB is not running. + + RETURN + ------ + running: Boolean + True if FOFB is not running + """ + + if not check_fofbnotrunning(): + logger.warning("Not running configuration of comcorr because FOFB seems to be running.") + return False + + success=True + for i,(n,p) in enumerate(tangopath_cellnodes.items()): + s=FofbTool.Configuration.cellnode_configure_ccn(n) + success = success and s + + s=FofbTool.Configuration.centralnode_configure_ccn() + success = success and s + + return success -- GitLab