diff --git a/FofbTool/Configuration.py b/FofbTool/Configuration.py index 755e60c07cac9282ac1e977dc82530e04681263b..dca0bf78f15b3cfac0fa530add1e971f2b1f18aa 100644 --- a/FofbTool/Configuration.py +++ b/FofbTool/Configuration.py @@ -8,120 +8,28 @@ import tango import logging -import configparser import numpy as np import FofbTool.Utils -import os # Get the module logger logger = logging.getLogger("FofbTool") -################################################################################################### -# CONFIGURATION PARSER -################################################################################################### - -# Configuration -config = configparser.ConfigParser() - -# Try to load default -defconfpath = os.path.abspath(os.path.join(os.path.dirname(__spec__.origin), "default.cfg")) -if len(config.read(defconfpath)) < 1: - logger.warning("Default configuration file not found: {}".format(defconfpath)) - -def logdebugconf(): - logger.debug("Display config:") - for s in config.sections(): - for o in config.options(s): - logger.debug("{:20} {:10} {}".format(s,o, config[s][o])) - -def loadconfig(filepath): - """ - Load a configuration file for the module. - It supersed the default configuration, if found. - - PARAMETERS - ---------- - filepath: str - Path to the config file - """ - global config - logger.info("Load configuration from file {}".format(filepath)) - if len(config.read(filepath)) < 1: - logger.warning("Configuration file not found: {}".format(filepath)) - - -def getconf(option, section, nodename="", t="", l=False): - """ - Helper method to retrieve an option in the loaded configuration. - It tries to find a section named section.nodename and fall back to section only if fails. - - PARAMETERS - ---------- - option: str - Name of the option to retrieve - section: str - Section in wich to search - nodename: str - Specify a particular nodename. If not found in config, fall back to section default. - t: str ('i', 'f', 'b', '') - Give the type to cast, integer, float, boolean or string. - l: boolean - Cast from a list - - RETURNS - ------- - roption: str, int, float or boolean - Read option - """ - if l: - if t=='b': - raise NotImplemented("List of boolean not implemented") - try: - val= np.asarray(config.get("{}.{}".format(section,nodename), option).split(), dtype=t) - except (configparser.NoSectionError, configparser.NoOptionError): - val= np.asarray(config.get(section, option).split(), dtype=t) - - else: - try: - func = getattr(config, {'i':"getint", 'f':"getfloat", 'b':"getboolean", '':"get"}[t]) - except KeyError as e: - log.debug(str(e)) - raise ValueError("Allowed t argument are 'i', 'f', 'b' or ''") - - try: - val= func("{}.{}".format(section,nodename), option) - except (configparser.NoSectionError, configparser.NoOptionError): - val= func(section, option) - - return val - - - ################################################################################################### # CONFIGURE COM BPM ################################################################################################### -# 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): +def cellnode_configure_combpm(node_tangopath, bpmallowed): """ Configure the combpm block of a CellNode. - The BPM data allowed through are either taken in the argument, or default to configuration. - + The BPM data allowed through are taken in the argument. PARAMETERS ---------- - cellnodename: str - The target cellnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' bpmallowed: [int], None - List of BPMID allowed through the block. If None, default to nominal values. + List of BPMID allowed through the block. RETURN ------ @@ -131,46 +39,37 @@ def cellnode_configure_combpm(cellnodename, bpmallowed=None): # Get device proxy try: - p = config["tangopath.fofbnodes"][cellnodename.lower()] - except KeyError: - logger.error("Wrong cellnodename. Possibilities are {}".format(list(config['tangopath.fofbnodes'].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 + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - # Select BPM id allowed to pass through - if bpmallowed is None: - logger.debug("Default to nominal values for BPM filter") - bpmallowed = getconf("bpmfilter", "combpm", cellnodename.lower(), 'i', True) - - - logger.debug("Activate BPMs {} in the filter for {}".format(bpmallowed, p)) + logger.debug("Activate BPMs {} in the filter for {}".format(bpmallowed, node_tangopath)) f = prx["combpm_filter_table"].value f[:] = 0 f[np.array(bpmallowed)] = 0x80 prx["combpm_filter_table"] = f - logger.info("Configuration of ComBpm done on {}.".format(p)) + logger.info("Configuration of ComBpm done on {}.".format(node_tangopath)) return True ################################################################################################### # CONFIGURE COM LBP ################################################################################################### -def cellnode_configure_comlbp(cellnodename, bpmallowed=None): +def cellnode_configure_comlbp(node_tangopath, seqoffset=0): """ Configure the comlbp block of a CellNode. For now, nothing done PARAMETERS ---------- - cellnodename: str - The target cellnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' + + seqoffset: int + Sequence offset to configure RETURN ------ @@ -178,7 +77,19 @@ def cellnode_configure_comlbp(cellnodename, bpmallowed=None): True if configuration is a success """ - logger.info("Configuration of ComLBP done on {}.".format(p)) + # Get device proxy + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None + + logger.debug("Program sequence offset {} in {}".format(seqoffset, node_tangopath)) + for n in range(4): + prx["comlbp{}_seqoffset".format(n)]=seqoffset + + logger.info("Configuration of ComLBP done on {}.".format(node_tangopath)) return True ################################################################################################### @@ -186,21 +97,19 @@ def cellnode_configure_comlbp(cellnodename, bpmallowed=None): ################################################################################################### -def cellnode_configure_ccn(cellnodename, nbpm=None, npsc=None): +def cellnode_configure_ccn(node_tangopath, nbpm, npsc): """ 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' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-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 ------ @@ -210,28 +119,14 @@ def cellnode_configure_ccn(cellnodename, nbpm=None, npsc=None): # Get device proxy try: - p = config["tangopath.fofbnodes"][cellnodename.lower()] - except KeyError: - logger.error("Wrong cellnodename. Possibilities are {}".format(list(config['tangopath.fofbnodes'].keys()))) - return False + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - 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: - logger.debug("Default to nominal values for number of BPM packets") - # Get number of BPM activated in the filter - nbpm = getconf("nbpm", "ccn", cellnodename, 'i') - logger.debug("{} bpm allowed in the ethernet frame on {}".format(nbpm, p)) - - if npsc is None: - logger.debug("Default to nominal values for number of PSC packets") - npsc = getconf("npsc", "ccn", cellnodename, 'i') - logger.debug("{} psc expected in the ethernet frame on {}".format(nbpm, p)) + logger.debug("{} bpm allowed in the ethernet frame on {}".format(nbpm, node_tangopath)) + logger.debug("{} psc expected in the ethernet frame on {}".format(nbpm, node_tangopath)) maclen = 10*nbpm+10 logger.debug("Configure packeter framesize (mac length) to {}".format(maclen)) @@ -244,16 +139,18 @@ def cellnode_configure_ccn(cellnodename, nbpm=None, npsc=None): logger.debug("Configure unpacketer framesize (mac length) to {}".format(maclen)) prx["ccnunpack0_framesize"] = maclen - logger.info("Configuration of CCN done on {}.".format(p)) + logger.info("Configuration of CCN done on {}.".format(node_tangopath)) return True -def centralnode_configure_ccn(nbpm=None, npsc=None): +def centralnode_configure_ccn(node_tangopath, nbpm, npsc): """ Configure the ComCellNode block on the centralnode. Automatically set the number of bpm/psc packets and MAC length. PARAMETERS ---------- + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-centralnode' nbpm: list(int) Number of BPM packet received on each interface. npsc: @@ -264,24 +161,13 @@ def centralnode_configure_ccn(nbpm=None, npsc=None): success: boolean True if configuration is a success """ - p = config["tangopath.fofbnodes"]["centralnode"] + # Get device proxy 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: - logger.debug("Use default value for nbpm") - nbpm = [getconf("nbpm", "ccn", n, 'i') for n in config['tangopath.fofbnodes'].keys() if 'cellnode' in n] - logger.debug("{} bpm expected in the ethernet frame on {}".format(nbpm, p)) - - if npsc is None: - logger.debug("Default to nominal values for number of BPM packets") - # Get number of BPM activated in the filter - npsc = getconf("npsc", "ccn", 'centralnode', 'i') - logger.debug("{} psc allowed in the ethernet frame on {}".format(nbpm, p)) + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None for n in range(len(nbpm)): maclen = npsc*6+10 @@ -295,14 +181,14 @@ def centralnode_configure_ccn(nbpm=None, npsc=None): logger.debug("Configure unpacketer {} framesize (mac length) to {}".format(n, maclen)) prx["ccnunpack{}_framesize".format(n)] = maclen - logger.info("Configuration of CCN done on {}.".format(p)) + logger.info("Configuration of CCN done on {}.".format(node_tangopath)) return True ################################################################################################### # CONFIGURE COM CORR ################################################################################################### -def cellnode_configure_comcorr(cellnodename, pscid=None, enable=True): +def cellnode_configure_comcorr(node_tangopath, pscid, enable): """ Configure the comcorr block of a CellNode. The PSC ID either taken in the argument, or default to nominal values. @@ -310,8 +196,8 @@ def cellnode_configure_comcorr(cellnodename, pscid=None, enable=True): PARAMETERS ---------- - cellnodename: str - The target cellnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' pscid: [int], None List of 32 PSCID to program on the output board. If None, default to nominal values. @@ -323,84 +209,60 @@ def cellnode_configure_comcorr(cellnodename, pscid=None, enable=True): success: boolean True if configuration is a success """ - # Get device proxy try: - p = config["tangopath.fofbnodes"][cellnodename.lower()] - except KeyError: - logger.error("Wrong cellnodename. Possibilities are {}".format(list(config['tangopath.fofbnodes'].keys()))) - return False + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - 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 = getconf("pscid", "comcorr", cellnodename, 'i', True) - 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)) + logger.debug("Set PSCIDs {} in the filter for {}".format(pscid, node_tangopath)) f= prx["comcorr_line_id"].value f[:] = pscid f[:] = f+ 0x10000*bool(enable) - logger.debug("Set comcorr_line_id {} for {}".format(f, p)) + logger.debug("Set comcorr_line_id {} for {}".format(f, node_tangopath)) prx["comcorr_line_id"] = f - logger.info("Configuration of ComCorr done on {}.".format(p)) + logger.info("Configuration of ComCorr done on {}.".format(node_tangopath)) return True ################################################################################################### # CONFIGURE MATRIX CORRECTOR ################################################################################################### -def centralnode_configure_corr(): +def centralnode_configure_corr(node_tangopath, numbpm, pscid, k1x, k1y, k2x, k2y): """ Configure the correction algorithm on the centralnode. + + PARAMETERS + ---------- + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-centralnode' + k1x, k1y, k2x, k2y: list(int) + List of coefficient for each filter. 4 coefficients : ABCD """ - p = config["tangopath.fofbnodes"]["centralnode"] + + # Get device proxy 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 - - # Legacy - prx["corr_k1a_x"]=getconf( "k1a_x", "corr", t='i') - prx["corr_k1b_x"]=getconf( "k1b_x", "corr", t='i') - prx["corr_k1ic_x"]=getconf( "k1ic_x", "corr", t='i') - prx["corr_k1d_x"]=getconf( "k1d_x", "corr", t='i') - - prx["corr_k1a_y"]=getconf( "k1a_y", "corr", t='i') - prx["corr_k1b_y"]=getconf( "k1b_y", "corr", t='i') - prx["corr_k1ic_y"]=getconf( "k1ic_y", "corr", t='i') - prx["corr_k1d_y"]=getconf( "k1d_y", "corr", t='i') - - # Unitary - prx["corr_k2a_x"]=getconf( "k2a_x", "corr", t='i') - prx["corr_k2b_x"]=getconf( "k2b_x", "corr", t='i') - prx["corr_k2ic_x"]=getconf( "k2ic_x", "corr", t='i') - prx["corr_k2d_x"]=getconf( "k2d_x", "corr", t='i') - - prx["corr_k2a_y"]=getconf( "k2a_y", "corr", t='i') - prx["corr_k2b_y"]=getconf( "k2b_y", "corr", t='i') - prx["corr_k2ic_y"]=getconf( "k2ic_y", "corr", t='i') - prx["corr_k2d_y"]=getconf( "k2d_y", "corr", t='i') + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None + + for i,l in enumerate(["a","b","ic","d"]): + prx["corr_k1{}_x".format(l)]=k1x[i] + prx["corr_k2{}_x".format(l)]=k2x[i] + prx["corr_k1{}_y".format(l)]=k1y[i] + prx["corr_k2{}_y".format(l)]=k2y[i] f= prx["corr_pscid"].value - f[0:100] = getconf('pscid', 'corr', t='i', l=True) + f[0:100] = pscid prx["corr_pscid"] = f - prx["corr_num_bpm"] = getconf('numbpm', 'corr', t='i') + prx["corr_num_bpm"] = numbpm - logger.info("Configuration of Corr done on {}.".format(p)) + logger.info("Configuration of Corr done on {}.".format(node_tangopath)) return True diff --git a/FofbTool/Operation.py b/FofbTool/Operation.py index 33e9a2e371153be2073223e0a30418ba508f760d..3208814f53dcdaf86db2a7949b2bdcb9f1dd095e 100644 --- a/FofbTool/Operation.py +++ b/FofbTool/Operation.py @@ -10,7 +10,6 @@ import tango import logging import numpy as np import time -import FofbTool.Utils # Get the module logger @@ -21,39 +20,62 @@ logger = logging.getLogger("FofbTool") # OPERATIONS ON CCN ################################################################################################### -def align_ccn(nodename): +def align_ccn(node_tangopath, comlbpif=0): """ - Align FA sequence number on a cellnode + Align FA sequence number on a cellnode. Returns the computed offset. + PARAMETERS ---------- - nodename: str - The target fofbnode, ie 'cellnode-c09' or 'centralnode' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' + + comlbpif: int + which comlbp interface to use (0 to 3) + + RETURNS + ------- + seqoffset: int or None + If success, return the found sequece offset. + Return None on failure. """ - prx=FofbTool.Utils.get_prx_from_nodename(nodename) - if prx is None: - logger.error("Failed to align CCN on {}".format(nodename)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None logger.info("Trying to detect and align FA sequences") - logger.debug("Reset offsets on comlbp") - set_comlbp_seqoffset(nodename, 0) + logger.debug("Reset offset on comlbp") + prx["comlbp{}_seqoffset".format(comlbpif)]=0 + + # TODO reset and start comlbp and combpm # Loop until two consecutives identical measures - N=[7,3] + N=[7,3] # random start while N[-2] != N[-1]: if len(N) > 7: logger.error("Could not measure sequence offset.") - return False + return None logger.debug("Latch two sequence numbers without offset") prx.ccnpack0_control=1 # let it roll a bit to collect data time.sleep(2+np.random.uniform()) prx.ccnpack0_control=2 # latch it time.sleep(2) - N.append(prx.ccnpack0_latchedseq1-prx.ccnpack0_latchedseq2) + + _N = prx.ccnpack0_latchedseq1-prx.ccnpack0_latchedseq2 + + # handle diff going from 17 bits to 16bits offset + if _N > 0x7FFF: + _N=_N-0x10000 + if -_N > 0x8000: + _N=_N+0x10000 + + N.append(_N) logger.debug("seq ({}, {}, {})".format(prx.ccnpack0_latchedseq1, prx.ccnpack0_latchedseq2, N[-1])) @@ -63,14 +85,9 @@ def align_ccn(nodename): if N in (-1, 0, 1): logger.warning("Sequence offset measured = {}, something might be wrong".format(N)) - # handle diff going from 17 bits to 16bits offset - if N > 0x7FFF: - N=N-0x10000 - if -N > 0x8000: - N=N+0x10000 - - set_comlbp_seqoffset(nodename, N) + logger.debug("Setting sequence offset to {}".format(N)) + prx["comlbp{}_seqoffset".format(comlbpif)]=N seqoffset=N logger.debug("Perform autocheck") @@ -83,130 +100,145 @@ def align_ccn(nodename): if not N in (-1, 1): logger.warning("Corrected sequence offset measured = {}, something might be wrong. Run it again".format(N)) - return False + return None return seqoffset -def set_comlbp_seqoffset(nodename, N): - """ Set sequence offset for all comlbp interfaces """ - - prx=FofbTool.Utils.get_prx_from_nodename(nodename) - if prx is None: - logger.error("Failed to align CCN on {}".format(nodename)) - return - - logger.info("Program sequence offset {} in {}".format(N, nodename)) - for n in range(4): - prx["comlbp{}_seqoffset".format(n)]=N - - -def stop_ccn(nodename): +def stop_ccn(node_tangopath, ccnif=[]): """ Stop the communication with cellnode on the specified fofbnode. PARAMETERS ---------- - nodename: str - The target fofbnode, ie 'cellnode-c09' or 'centralnode' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' + + ccnif: list(int) + List of the interface to stop. If empty, all the possible interface will be stopped. """ - prx=FofbTool.Utils.get_prx_from_nodename(nodename) - if prx is None: - logger.error("Failed to stop CCN on {}".format(nodename)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None + + if len(ccnif) == 0: + ccnif = [int(a[7]) for a in prx.get_attribute_list() if "ccnpack" in a if "control" in a] - logger.info("Stopping CCN on {}".format(nodename)) - nint=1 - if 'central' in nodename: - nint = 4 - for n in range(nint): - prx["ccnpack{}_control".format(n)] = False - prx["ccnunpack{}_control".format(n)] = False + logger.info("Stopping CCN on {}".format(node_tangopath)) + for n in ccnif: + if 'central' in node_tangopath: + prx["ccnunpack{}_control".format(n)] = False + prx["ccnpack{}_control".format(n)] = False + else: + prx["ccnpack{}_control".format(n)] = False + prx["ccnunpack{}_control".format(n)] = False -def reset_ccn(nodename): +def reset_ccn(node_tangopath, ccnif=[]): """ Reset the communication with cellnode on the specified fofbnode. PARAMETERS ---------- - nodename: str - The target fofbnode, ie 'cellnode-c09' or 'centralnode' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' + + ccnif: list(int) + List of the interface to stop. If empty, all the possible interface will be stopped. """ - prx=FofbTool.Utils.get_prx_from_nodename(nodename) - if prx is None: - logger.error("Failed to reset CCN on {}".format(nodename)) - return - logger.info("Reset CCN on {}".format(nodename)) - nint=1 - if 'central' in nodename: - nint = 4 - for n in range(nint): + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None + + if len(ccnif) == 0: + ccnif = [int(a[6]) for a in prx.get_attribute_list() if "ccneth" in a if "gt_reset" in a] + + logger.info("Reset CCN on {}".format(node_tangopath)) + for n in ccnif: prx["ccneth{}_reset".format(n)] = 0x60000001 # impossible to write 0xE0000001 prx["ccneth{}_gt_reset".format(n)] = 1 time.sleep(2) - for n in range(nint): + for n in ccnif: prx["ccneth{}_gt_reset".format(n)] = 0 prx["ccneth{}_reset".format(n)] = 0 - ack_ccn(nodename) + ack_ccn(node_tangopath, ccnif) -def start_ccn(nodename): +def start_ccn(node_tangopath, ccnif=[]): """ Start the communication with cellnode on the specified fofbnode. PARAMETERS ---------- - nodename: str - The target fofbnode, ie 'cellnode-c09' or 'centralnode' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' + + ccnif: list(int) + List of the interface to stop. If empty, all the possible interface will be stopped. """ - prx=FofbTool.Utils.get_prx_from_nodename(nodename) - if prx is None: - logger.error("Failed to start CCN on {}".format(nodename)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - logger.info("Starting CCN on {}".format(nodename)) + if len(ccnif) == 0: + ccnif = [int(a[7]) for a in prx.get_attribute_list() if "ccnpack" in a if "control" in a] - ack_ccn(nodename) + logger.info("Starting CCN on {}".format(node_tangopath)) - nint=1 - if 'central' in nodename: - nint = 4 - for n in range(nint): - prx["ccnpack{}_control".format(n)] = True - prx["ccnunpack{}_control".format(n)] = True + ack_ccn(node_tangopath, ccnif) -def ack_ccn(nodename): + for n in ccnif: + if 'central' in node_tangopath: + prx["ccnunpack{}_control".format(n)] = 1 + prx["ccnpack{}_control".format(n)] = 1 + else: + prx["ccnpack{}_control".format(n)] = 1 + prx["ccnunpack{}_control".format(n)] = 1 + +def ack_ccn(node_tangopath, ccnif=[]): """ Start the communication with cellnode on the specified fofbnode. PARAMETERS ---------- - nodename: str - The target fofbnode, ie 'cellnode-c09' or 'centralnode' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' + + ccnif: list(int) + List of the interface to stop. If empty, all the possible interface will be stopped. """ - prx=FofbTool.Utils.get_prx_from_nodename(nodename) - if prx is None: - logger.error("Failed to ack CCN on {}".format(nodename)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None + if len(ccnif) == 0: + ccnif = [int(a[7]) for a in prx.get_attribute_list() if "ccnpack" in a if "control" in a] - logger.info("Ack CCN error on {}".format(nodename)) - nint=1 - if 'central' in nodename: - nint = 4 - for n in range(nint): + logger.info("Ack CCN error on {}".format(node_tangopath)) + for n in ccnif: prx["ccnpack{}_reset_error".format(n)] = True prx["ccnunpack{}_reset_error".format(n)] = True time.sleep(1) - for n in range(nint): + for n in ccnif: prx["ccnpack{}_reset_error".format(n)] = False prx["ccnunpack{}_reset_error".format(n)] = False @@ -214,129 +246,142 @@ def ack_ccn(nodename): # OPERATIONS ON COMBPM ################################################################################################### -def stop_combpm(cellnodename): +def stop_combpm(node_tangopath): """ Stop the communication with bpm on the specified cellnode. PARAMETERS ---------- - cellnodename: str - The target fofbnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' """ - prx=FofbTool.Utils.get_prx_from_nodename(cellnodename) - if prx is None: - logger.error("Failed to stop ComBPM on {}".format(p)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - logger.info("Stopping ComBPM on {}".format(cellnodename)) + logger.info("Stopping ComBPM on {}".format(node_tangopath)) prx["combpm_reset"] = 1 prx["combpm_gt_control"] = 0x5 -def start_combpm(cellnodename): +def start_combpm(node_tangopath): """ Start the communication with bpm on the specified cellnode. PARAMETERS ---------- - cellnodename: str - The target fofbnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' """ - prx=FofbTool.Utils.get_prx_from_nodename(cellnodename) - if prx is None: - logger.error("Failed to start ComBPM on {}".format(cellnodename)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - logger.info("Starting ComBpm on {}".format(cellnodename)) + logger.info("Starting ComBpm on {}".format(node_tangopath)) prx["combpm_reset"] = 0 prx["combpm_gt_control"] = 0x1 time.sleep(1) - ack_combpm(cellnodename) + ack_combpm(node_tangopath) -def ack_combpm(cellnodename): +def ack_combpm(node_tangopath): """ Ack errors on the communication with bpm on the specified cellnode. PARAMETERS ---------- - cellnodename: str - The target fofbnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' """ - prx=FofbTool.Utils.get_prx_from_nodename(cellnodename) - if prx is None: - logger.error("Failed to start ComBPM on {}".format(cellnodename)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - logger.info("Ack ComBpm on {}".format(cellnodename)) + logger.info("Ack ComBpm on {}".format(node_tangopath)) prx["combpm_reset_error"] = True time.sleep(1) prx["combpm_reset_error"] = False + ################################################################################################### # OPERATIONS ON COMLBP ################################################################################################### -def stop_comlbp(cellnodename): +def stop_comlbp(node_tangopath): """ Stop the communication with LBP on the specified cellnode. PARAMETERS ---------- - cellnodename: str - The target fofbnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' """ - prx=FofbTool.Utils.get_prx_from_nodename(cellnodename) - if prx is None: - logger.error("Failed to stop ComLBP on {}".format(p)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - logger.info("Stopping ComLBP on {}".format(cellnodename)) + logger.info("Stopping ComLBP on {}".format(node_tangopath)) for n in range(4): prx["comlbp{}_control".format(n)] = 1 time.sleep(1) for n in range(4): prx["comlbp{}_control".format(n)] = 0 -def start_comlbp(cellnodename): +def start_comlbp(node_tangopath): """ Start the communication with LBP on the specified cellnode. PARAMETERS ---------- - cellnodename: str - The target fofbnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' """ - prx=FofbTool.Utils.get_prx_from_nodename(cellnodename) - if prx is None: - logger.error("Failed to start ComLBP on {}".format(p)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - logger.info("Starting ComLBP on {}".format(cellnodename)) + logger.info("Starting ComLBP on {}".format(node_tangopath)) for n in range(4): prx["comlbp{}_control".format(n)] = 0x10 -def reset_comlbp(cellnodename): +def reset_comlbp(node_tangopath): """ Reset the communication with LBP on the specified cellnode. PARAMETERS ---------- - cellnodename: str - The target fofbnode, ie 'cellnode-c09' + node_tangopath: str + The target fofbnode tango path, ie 'ans/dg/fofb-cellnode-c09' """ - prx=FofbTool.Utils.get_prx_from_nodename(cellnodename) - if prx is None: - logger.error("Failed to reset ComLBP on {}".format(p)) - return + try: + prx=tango.DeviceProxy(node_tangopath) + prx.ping() + except tango.DevFailed: + logger.error("Failed to obtain tango proxy or to ping to {}".format(node_tangopath)) + return None - logger.info("Reset ComLBP on {}".format(cellnodename)) + logger.info("Reset ComLBP on {}".format(node_tangopath)) for n in range(4): prx["comlbp{}_control".format(n)] = 0x3 @@ -508,28 +553,27 @@ def electron_stop_com(bpmlist): # OPERATIONS FOR LBP and Electron SYNCHRONIZATION ################################################################################################### -def sync_all_bpm(): +def sync_bpm(bpmlist, bpmidlist, lbpevrx, tlocal, tcentral): """ Synchronize all BPM electronics, Electron and Brillance Plus. This will use the timing system (central and local board). + PARAMETERS: + ----------- + bpmlist: list + list of Libera Electron tango path + bpmidlist: list + list of ID to put on Libera Electron + lbpevrx: list + list of LBP Evrx tanfo path + tlocal: list + list of Timing local board to set event + tcentral: str + Tango path of timing central + """ EVN=240 # Event number - db = tango.Database() - - bpmlist = [n.split(':')[2] for n in db.get_property("FOFB", "bpmlist")['bpmlist'] if ":LIBERA:" in n] - bpmidlist = [(int(n.split(':')[0]), n.split(':')[2]) for n in db.get_property("FOFB", "bpmlist")['bpmlist'] if 'LIBERA' in n] - - tlocal = tango.Group('tlocal') - tlocal.add([n.split(':')[2] for n in db.get_property("FOFB", 'TimingBoardList')['TimingBoardList'] if "LOCAL" in n]) - - # Set a group of Libera Brillance Plus EVRX board, from FofbTool configuration - lbpevrx = tango.Group('lbpevrx') - lbpevrx.add(FofbTool.Configuration.config["tangopath"]["lbpevrx"].split()) - - tcentral = tango.DeviceProxy(FofbTool.Configuration.config["tangopath"]["timing-central"]) - # --------------------------------------------------------------------------------------------------------------- # Init BPMs, stop first and put for each the ID number diff --git a/FofbTool/Utils.py b/FofbTool/Utils.py index b273b14fbcab7c92f54c3a7d336b83b411e2c46f..c43e87d2f7b28d16aea9183f908043adbcacb612 100644 --- a/FofbTool/Utils.py +++ b/FofbTool/Utils.py @@ -11,10 +11,98 @@ import logging import FofbTool.DeviceAttributeConfiguration import FofbTool.Configuration import FofbTool.Operation +import configparser +import os +import numpy as np # Get the module logger logger = logging.getLogger("FofbTool") +################################################################################################### +# CONFIGURATION PARSER +################################################################################################### + +# Configuration +config = configparser.ConfigParser() + +# Try to load default +defconfpath = os.path.abspath(os.path.join(os.path.dirname(__spec__.origin), "default.cfg")) +if len(config.read(defconfpath)) < 1: + logger.warning("Default configuration file not found: {}".format(defconfpath)) + +def logdebugconf(): + logger.debug("Display config:") + for s in config.sections(): + for o in config.options(s): + logger.debug("{:20} {:10} {}".format(s,o, config[s][o])) + +def loadconfig(filepath): + """ + Load a configuration file for the module. + It supersed the default configuration, if found. + + PARAMETERS + ---------- + filepath: str + Path to the config file + """ + global config + logger.info("Load configuration from file {}".format(filepath)) + if len(config.read(filepath)) < 1: + logger.warning("Configuration file not found: {}".format(filepath)) + + +def getconf(option, section, nodename="", t="", l=False): + """ + Helper method to retrieve an option in the loaded configuration. + It tries to find a section named section.nodename and fall back to section only if fails. + + PARAMETERS + ---------- + option: str + Name of the option to retrieve + section: str + Section in wich to search + nodename: str + Specify a particular nodename. If not found in config, fall back to section default. + t: str ('i', 'f', 'b', '') + Give the type to cast, integer, float, boolean or string. + l: boolean + Cast from a list + + RETURNS + ------- + roption: str, int, float or boolean + Read option + """ + if l: + if t=='b': + raise NotImplemented("List of boolean not implemented") + try: + val= np.asarray(config.get("{}.{}".format(section,nodename), option).split(), dtype=t) + except (configparser.NoSectionError, configparser.NoOptionError): + val= np.asarray(config.get(section, option).split(), dtype=t) + + else: + try: + func = getattr(config, {'i':"getint", 'f':"getfloat", 'b':"getboolean", '':"get"}[t]) + except KeyError as e: + log.debug(str(e)) + raise ValueError("Allowed t argument are 'i', 'f', 'b' or ''") + + try: + val= func("{}.{}".format(section,nodename), option) + except (configparser.NoSectionError, configparser.NoOptionError): + val= func(section, option) + + return val + + +################################################################################################### +# INIT FUNCTIONS +################################################################################################### + + def init_opcua(force=False): """ Run init on all OPCUA devices. Catch DevFailed and inform via log. @@ -22,10 +110,10 @@ def init_opcua(force=False): """ if not check_fofbnotrunning(force): - logger.warning("Not running configuration of combpm because FOFB seems to be running.") + logger.warning("Not running because FOFB seems to be running.") return - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): logger.info("Perform init() on {} '{}'".format(n,p)) try: tango.DeviceProxy(p).init() @@ -40,10 +128,10 @@ def init_watcher(force=False): """ if not check_fofbnotrunning(force): - logger.warning("Not running configuration of combpm because FOFB seems to be running.") + logger.warning("Not running because FOFB seems to be running.") return - p=FofbTool.Configuration.config["tangopath"]["fofb-watcher"] + p=config["tangopath"]["fofb-watcher"] try: wprx=tango.DeviceProxy(p) wprx.set_timeout_millis(60000) @@ -60,7 +148,7 @@ def init_watcher(force=False): logger.debug(str(e)) logger.info("Perform init() on Fofb-Command.") - p=FofbTool.Configuration.config["tangopath"]["fofb-command"] + p=config["tangopath"]["fofb-command"] try: tango.DeviceProxy(p).init() except tango.DevFailed as e: @@ -71,7 +159,7 @@ def confds_opcua(): """ Apply attribute configuration on all OPCUA devices. Catch DevFailed and inform via log. """ - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): try: prx = tango.DeviceProxy(p) except tango.DevFailed as e: @@ -89,6 +177,11 @@ def confds_opcua(): logger.debug(str(e)) + +################################################################################################### +# OPERATE FUNCTIONS +################################################################################################### + def check_fofbnotrunning(force=False): """ Check if the FOFB is not running. @@ -104,7 +197,7 @@ def check_fofbnotrunning(force=False): logger.warning("Forced action even if FOFB might be running") return True - p=FofbTool.Configuration.config["tangopath"]["fofb-watcher"] + p=config["tangopath"]["fofb-watcher"] try: prx = tango.DeviceProxy(p) except tango.DevFailed as e: @@ -135,9 +228,10 @@ def conf_all_combpm(force=False): return False success=True - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: - s=FofbTool.Configuration.cellnode_configure_combpm(n) + bpmallowed = getconf("bpmfilter", "combpm", n.lower(), 'i', True) + s=FofbTool.Configuration.cellnode_configure_combpm(p, bpmallowed) success = success and s return success @@ -164,9 +258,10 @@ def conf_all_comcorr(force=False, enable=True): return False success=True - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: - s=FofbTool.Configuration.cellnode_configure_comcorr(n, enable=enable) + pscid = getconf("pscid", "comcorr", n, 'i', True) + s=FofbTool.Configuration.cellnode_configure_comcorr(p, pscid, enable=enable) success = success and s return success @@ -188,12 +283,17 @@ def conf_all_ccn(force=False): return False success=True - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: - s=FofbTool.Configuration.cellnode_configure_ccn(n) + nbpm = getconf("nbpm", "ccn", n, 'i') + npsc = getconf("npsc", "ccn", n, 'i') + s=FofbTool.Configuration.cellnode_configure_ccn(p, nbpm, npsc) success = success and s - s=FofbTool.Configuration.centralnode_configure_ccn() + p = config["tangopath.fofbnodes"]["centralnode"] + nbpm = [getconf("nbpm", "ccn", n, 'i') for n in config['tangopath.fofbnodes'].keys() if 'cellnode' in n] + npsc = getconf("npsc", "ccn", 'centralnode', 'i') + s=FofbTool.Configuration.centralnode_configure_ccn(p, nbpm, npsc) success = success and s return success @@ -214,9 +314,9 @@ def get_prx_from_nodename(nodename): """ # Get device proxy try: - p = FofbTool.Configuration.config["tangopath.fofbnodes"][nodename.lower()] + p = config["tangopath.fofbnodes"][nodename.lower()] except KeyError: - logger.error("Wrong nodename. Possibilities are {}".format(list(FofbTool.Configuration.config["tangopath.fofbnodes"].keys()))) + logger.error("Wrong nodename. Possibilities are {}".format(list(config["tangopath.fofbnodes"].keys()))) return None try: @@ -239,9 +339,9 @@ def stop_all_combpm(force=False): logger.warning("Not running stop combpm because FOFB seems to be running.") return - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: - FofbTool.Operation.stop_combpm(n) + FofbTool.Operation.stop_combpm(p) def stop_all_comlbp(force=False): @@ -252,14 +352,14 @@ def stop_all_comlbp(force=False): """ if not check_fofbnotrunning(force): - logger.warning("Not running stop combpm because FOFB seems to be running.") + logger.warning("Not running stop comlbp because FOFB seems to be running.") return - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: try: - FofbTool.Operation.reset_comlbp(n) - FofbTool.Operation.stop_comlbp(n) + FofbTool.Operation.reset_comlbp(p) + FofbTool.Operation.stop_comlbp(p) except (tango.DevFailed, TypeError): logger.error("Could not stop cpmlbp on {}".format(n)) @@ -272,12 +372,12 @@ def stop_all_ccn(force=False): """ if not check_fofbnotrunning(force): - logger.warning("Not running stop combpm because FOFB seems to be running.") + logger.warning("Not running stop comccn because FOFB seems to be running.") return - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): - FofbTool.Operation.stop_ccn(n) - FofbTool.Operation.reset_ccn(n) + for n,p in config["tangopath.fofbnodes"].items(): + FofbTool.Operation.stop_ccn(p) + FofbTool.Operation.reset_ccn(p) @@ -287,9 +387,9 @@ def start_all_combpm(): """ - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: - FofbTool.Operation.start_combpm(n) + FofbTool.Operation.start_combpm(p) def start_all_comlbp(): """ @@ -297,10 +397,10 @@ def start_all_comlbp(): """ - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: try: - FofbTool.Operation.start_comlbp(n) + FofbTool.Operation.start_comlbp(p) except (tango.DevFailed, TypeError): logger.error("Could not start LBP on {}".format(n)) @@ -312,8 +412,8 @@ def start_all_ccn(): """ - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): - FofbTool.Operation.start_ccn(n) + for n,p in config["tangopath.fofbnodes"].items(): + FofbTool.Operation.start_ccn(p) def align_all_ccn(cellnodename, force=False): """ @@ -325,15 +425,52 @@ def align_all_ccn(cellnodename, force=False): return logger.debug("Use {} for sequence alignement".format(cellnodename)) - seqoffset = FofbTool.Operation.align_ccn(cellnodename) - if not seqoffset: + cellnodepath=FofbTool.Utils.get_prx_from_nodename(cellnodename) + seqoffset = FofbTool.Operation.align_ccn(cellnodepath, 0) + if seqoffset is None: logger.error("Could not align all ccn") return - for n,p in FofbTool.Configuration.config["tangopath.fofbnodes"].items(): + for n,p in config["tangopath.fofbnodes"].items(): if 'cellnode' in n: try: - FofbTool.Operation.set_comlbp_seqoffset(n, seqoffset) + FofbTool.Configuration.cellnode_configure_comlbp(p, seqoffset) except (tango.DevFailed, TypeError): logger.error("Could not set comlbp offset on {}".format(n)) + +def conf_centralnode_corr(): + + p = config["tangopath.fofbnodes"]["centralnode"] + + FofbTool.Configuration.centralnode_configure_corr(p, + getconf('numbpm', 'corr', t='i'), + getconf('pscid', 'corr', t='i', l=True), + [getconf( "k1{}_x".format(l), "corr", t='i') for l in ["a","b","ic","d"]], + [getconf( "k1{}_y".format(l), "corr", t='i') for l in ["a","b","ic","d"]], + [getconf( "k2{}_x".format(l), "corr", t='i') for l in ["a","b","ic","d"]], + [getconf( "k2{}_y".format(l), "corr", t='i') for l in ["a","b","ic","d"]], + ) + +def sync_all_bpm(): + """ + Synchronize all BPM electronics, Electron and Brillance Plus. + This will use the timing system (central and local board). + """ + + db = tango.Database() + + bpmlist = [n.split(':')[2] for n in db.get_property("FOFB", "bpmlist")['bpmlist'] if ":LIBERA:" in n] + bpmidlist = [(int(n.split(':')[0]), n.split(':')[2]) for n in db.get_property("FOFB", "bpmlist")['bpmlist'] if 'LIBERA' in n] + + tlocal = tango.Group('tlocal') + tlocal.add([n.split(':')[2] for n in db.get_property("FOFB", 'TimingBoardList')['TimingBoardList'] if "LOCAL" in n]) + + # Set a group of Libera Brillance Plus EVRX board, from FofbTool configuration + lbpevrx = tango.Group('lbpevrx') + lbpevrx.add(config["tangopath"]["lbpevrx"].split()) + + tcentral = tango.DeviceProxy(config["tangopath"]["timing-central"]) + + FofbTool.Operation.sync_bpm(bpmlist, bpmidlist, lbpevrx, tlocal, tcentral) + diff --git a/FofbTool/__init__.py b/FofbTool/__init__.py index f0545d8b3e912969cfaedcd875d7a030bfd1a5ac..48a75d5699318fe354aa6c03c11df899039efc31 100644 --- a/FofbTool/__init__.py +++ b/FofbTool/__init__.py @@ -14,4 +14,4 @@ This package is cut in several modules: For basic usage, see doc of FofbTool.Utils """ -__version__ = "2.5" +__version__ = "3.0" diff --git a/scripts/FofbTool b/scripts/FofbTool index 3df7a6674e5c854b6afddc78af55c5c53b26e7b2..15449ce191bbf07c576e4f4d5457e0724afde1a2 100755 --- a/scripts/FofbTool +++ b/scripts/FofbTool @@ -17,8 +17,6 @@ if __name__ == '__main__': sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import FofbTool.Utils import FofbTool.Operation - import FofbTool.Configuration # Still needs for one function, TODO - # Get the module logger logger = logging.getLogger("FofbTool") @@ -101,11 +99,11 @@ if __name__ == '__main__': logger.info("FofbTool version {}".format(FofbTool.__version__)) if not args.fileconfig is None: - FofbTool.Configuration.loadconfig(args.fileconfig) - FofbTool.Configuration.logdebugconf() + FofbTool.Utils.loadconfig(args.fileconfig) + FofbTool.Utils.logdebugconf() if not args.dump_configuration is None: - FofbTool.Configuration.config.write(args.dump_configuration) + FofbTool.Utils.config.write(args.dump_configuration) args.dump_configuration.close() @@ -138,10 +136,10 @@ if __name__ == '__main__': if args.configure in ("ccn", "all"): FofbTool.Utils.conf_all_ccn(force=args.force) if args.configure in ("corr", "all"): - FofbTool.Configuration.centralnode_configure_corr() + FofbTool.Utils.conf_centralnode_corr() if args.sync: - FofbTool.Operation.sync_all_bpm() + FofbTool.Utils.sync_all_bpm() if (args.start or args.start_comlbp) and not args.nolbp: FofbTool.Utils.start_all_comlbp()