Skip to content
Snippets Groups Projects
DG_PY_FOFBTool.py 13.7 KiB
Newer Older
BRONES Romain's avatar
BRONES Romain committed
# -*- coding: utf-8 -*-
#
# This file is part of the DG_PY_FOFBTool project
#
#
#
# Distributed under the terms of the GPL license.
# See LICENSE.txt for more info.

""" 

"""

# PyTango imports
import tango
from tango import DebugIt
from tango.server import run
from tango.server import Device
from tango.server import attribute, command
from tango.server import device_property
from tango import AttrQuality, DispLevel, DevState
from tango import AttrWriteType, PipeWriteType
# Additional import
#----- PROTECTED REGION ID(DG_PY_FOFBTool.additionnal_import) ENABLED START -----#
BRONES Romain's avatar
BRONES Romain committed
import FofbTool
BRONES Romain's avatar
BRONES Romain committed
import FofbTool.Operation
import FofbTool.Configuration
import logging
BRONES Romain's avatar
BRONES Romain committed
import multiprocessing
import numpy as np
BRONES Romain's avatar
BRONES Romain committed

#----- PROTECTED REGION END -----#	//	DG_PY_FOFBTool.additionnal_import

__all__ = ["DG_PY_FOFBTool", "main"]


class DG_PY_FOFBTool(Device):
    """

    **Properties:**

    - Device Property
        combpm_bpmfilter
            - Each line gives the BPM id allowed in the combpm engine of the cellnode.\nOne line per cellnode, in the order of the cellnodepath property.
            - Type:'DevVarStringArray'
        tangopath_cellnode
            - Tango path of the cellnodes
            - Type:'DevVarStringArray'
        comcorr_pscid
            - Line by line PSCID to program on cellnode interface.\nOne line by cellnode
            - Type:'DevVarStringArray'
        tangopath_watcher
            - Tango path of FofbWatcher
            - Type:'DevString'
        corr_pscid
            - PSCID of the inv matrix lines
            - Type:'DevString'
        ccn_npsc
            - Number of PSC ID to send in centralnode frames.\nIdentical for all interfaces
            - Type:'DevULong'
        ccn_nbpm
            - Number of BPMID to pack in each cellnode.\nOne valeu per cellnode
            - Type:'DevVarLongArray'
        logfilepath
            - Type:'DevString'
        tangopath_centraltiming
            - Type:'DevString'
        tangopath_centralnode
            - Type:'DevString'
        k1_x
            - Type:'DevVarLongArray'
        k2_x
            - Type:'DevVarLongArray'
        k1_y
            - Type:'DevVarLongArray'
        k2_y
            - Type:'DevVarLongArray'
BRONES Romain's avatar
BRONES Romain committed
        loglevel
            - Type:'DevString'
BRONES Romain's avatar
BRONES Romain committed
    """
    # PROTECTED REGION ID(DG_PY_FOFBTool.class_variable) ENABLED START #

    d_status = {}

    """
    def dev_status(self):
        return my_status()
    """

    def my_status(self):
        try:
            return "\n\n".join([str(v) for v in self.d_status.values()])+"\n"
        except Exception:
            self.debug_stream(str(self.d_status))
            return "Status failure\n"


BRONES Romain's avatar
BRONES Romain committed
    # PROTECTED REGION END #    //  DG_PY_FOFBTool.class_variable

    # -----------------
    # Device Properties
    # -----------------

    combpm_bpmfilter = device_property(
        dtype='DevVarStringArray',
        mandatory=True
    )

    tangopath_cellnode = device_property(
        dtype='DevVarStringArray',
        mandatory=True
    )

    comcorr_pscid = device_property(
        dtype='DevVarStringArray',
        mandatory=True
    )

    tangopath_watcher = device_property(
        dtype='DevString',
        mandatory=True
    )

    corr_pscid = device_property(
        dtype='DevString',
        mandatory=True
    )

    ccn_npsc = device_property(
        dtype='DevULong',
        mandatory=True
    )

    ccn_nbpm = device_property(
        dtype='DevVarLongArray',
        mandatory=True
    )

    logfilepath = device_property(
        dtype='DevString',
        mandatory=True
    )

    tangopath_centraltiming = device_property(
        dtype='DevString',
    )

    tangopath_centralnode = device_property(
        dtype='DevString',
        mandatory=True
    )

    k1_x = device_property(
        dtype='DevVarLongArray',
        mandatory=True
    )

    k2_x = device_property(
        dtype='DevVarLongArray',
        mandatory=True
    )

    k1_y = device_property(
        dtype='DevVarLongArray',
        mandatory=True
    )

    k2_y = device_property(
        dtype='DevVarLongArray',
        mandatory=True
    )

BRONES Romain's avatar
BRONES Romain committed
    loglevel = device_property(
        dtype='DevString',
        mandatory=True
    )

BRONES Romain's avatar
BRONES Romain committed
    # ----------
    # Attributes
    # ----------

    includeLBP = attribute(
        dtype='DevBoolean',
        access=AttrWriteType.READ_WRITE,
    )

BRONES Romain's avatar
BRONES Romain committed
    FofbToolVersion = attribute(
        dtype='DevString',
    )

BRONES Romain's avatar
BRONES Romain committed
    logs = attribute(
        dtype=('DevString',),
        max_dim_x=1024,
    )

BRONES Romain's avatar
BRONES Romain committed
    # ---------------
    # General methods
    # ---------------

    def init_device(self):
        """Initialises the attributes and properties of the DG_PY_FOFBTool."""
        Device.init_device(self)
        #----- PROTECTED REGION ID(DG_PY_FOFBTool.init_device) ENABLED START -----#

BRONES Romain's avatar
BRONES Romain committed
        self.info_stream("FofbTool {}".format(FofbTool.__version__))

        '''logger = logging.getLogger("FofbTool")
BRONES Romain's avatar
BRONES Romain committed
        try:
            fh=logging.FileHandler(self.logfilepath)
        except FileNotFoundError:
            logger.warning("Not logging to file, could not open location {}".format(self.logfilepath))
        else:
            fh.setLevel(logging.DEBUG)
BRONES Romain's avatar
BRONES Romain committed
            fh.setFormatter(logging.Formatter("{asctime} {levelname:8}: {message}", style='{'))
BRONES Romain's avatar
BRONES Romain committed
            logger.addHandler(fh)
BRONES Romain's avatar
BRONES Romain committed

        self.filehandler = fh

        logger.setLevel(getattr(logging, self.loglevel.upper()))'''
        if not hasattr(self, "_include_lbp"):
            self._include_lbp= False

BRONES Romain's avatar
BRONES Romain committed
        self.set_state(tango.DevState.ON)

BRONES Romain's avatar
BRONES Romain committed
        #----- PROTECTED REGION END -----#	//	DG_PY_FOFBTool.init_device

    def always_executed_hook(self):
        """Method always executed before any TANGO command is executed."""
        #----- PROTECTED REGION ID(DG_PY_FOFBTool.always_executed_hook) ENABLED START -----#
        self.set_status(self.my_status())
BRONES Romain's avatar
BRONES Romain committed
        #----- PROTECTED REGION END -----#	//	DG_PY_FOFBTool.always_executed_hook

    def delete_device(self):
        """Hook to delete resources allocated in init_device.

        This method allows for any memory or other resources allocated in the
        init_device method to be released.  This method is called by the device
        destructor and by the device Init command.
        """
        #----- PROTECTED REGION ID(DG_PY_FOFBTool.delete_device) ENABLED START -----#
        #logger = logging.getLogger("FofbTool")
        #logger.removeHandler(self.filehandler)
BRONES Romain's avatar
BRONES Romain committed
        #----- PROTECTED REGION END -----#	//	DG_PY_FOFBTool.delete_device
    # ------------------
    # Attributes methods
    # ------------------

    def read_includeLBP(self):
        # PROTECTED REGION ID(DG_PY_FOFBTool.includeLBP_read) ENABLED START #
        """Return the includeLBP attribute."""
        return self._include_lbp
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.includeLBP_read

    def write_includeLBP(self, value):
        # PROTECTED REGION ID(DG_PY_FOFBTool.includeLBP_write) ENABLED START #
        """Set the includeLBP attribute."""
        self._include_lbp = value
BRONES Romain's avatar
BRONES Romain committed
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.includeLBP_write

BRONES Romain's avatar
BRONES Romain committed
    def read_FofbToolVersion(self):
        # PROTECTED REGION ID(DG_PY_FOFBTool.FofbToolVersion_read) ENABLED START #
        """Return the FofbToolVersion attribute."""
        return FofbTool.__version__
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.FofbToolVersion_read

BRONES Romain's avatar
BRONES Romain committed
    def read_logs(self):
        # PROTECTED REGION ID(DG_PY_FOFBTool.logs_read) ENABLED START #
        """Return the logs attribute."""
        with open(self.logfilepath, 'r') as fp:
            lines = fp.readlines()
        return [l.replace('\n','') for l in lines[:-100:-1]]
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.logs_read

BRONES Romain's avatar
BRONES Romain committed
    # --------
    # Commands
    # --------

    @command(
        dtype_out='DevBoolean',
BRONES Romain's avatar
BRONES Romain committed
    )
    @DebugIt()
    def configure(self):
        # PROTECTED REGION ID(DG_PY_FOFBTool.configure) ENABLED START #
        """

        :return:None
        """
        success=True
        self.d_status["configure"]="Configure: pending"
        self.info_stream("Configure COMBPM")
BRONES Romain's avatar
BRONES Romain committed
        for cn, bpm in zip(self.tangopath_cellnode, self.combpm_bpmfilter):
            bpmid = [int(b) for b in bpm.split()]
            self.debug_stream("Set {} to {}".format(cn, bpmid))
            s=FofbTool.Configuration.cellnode_configure_combpm(cn, bpmid)
            success = success and s
            if not s:
                self.error_stream("Failed to configure COMBPM on {}".format(cn))

        self.info_stream("Configure COMCORR")
        for cn, psc in zip(self.tangopath_cellnode, self.comcorr_pscid):
            pscid = [int(b) for b in psc.split()]
            self.debug_stream("Set {} to {}".format(cn, pscid))
            s=FofbTool.Configuration.cellnode_configure_comcorr(cn, pscid, True)
            success = success and s
            if not s:
                self.error_stream("Failed to configure COMCORR on {}".format(cn))

        self.info_stream("Configure CCN")
        for cn, nbpm in zip(self.tangopath_cellnode, self.ccn_nbpm):
            self.debug_stream("Set {} to {} bpm and {} psc".format(cn, nbpm, self.ccn_npsc))
            FofbTool.Configuration.cellnode_configure_ccn(cn, nbpm, self.ccn_npsc)
            success = success and s
            if not s:
                self.error_stream("Failed to configure CCN on {}".format(cn))

        s=FofbTool.Configuration.centralnode_configure_ccn(self.tangopath_centralnode, self.ccn_nbpm, self.ccn_npsc)
        success = success and s
        if not s:
            self.error_stream("Failed to configure CCN on {}".format(self.tangopath_centralnode))

        numbpm = int(np.sum(self.ccn_nbpm))
        self.debug_stream("Summed {} bpm for corrector".format(numbpm))
        FofbTool.Configuration.centralnode_configure_corr(self.tangopath_centralnode,
                numbpm, [int(p) for p in self.corr_pscid.split()],
                self.k1_x, self.k1_y, self.k2_x, self.k2_y)

        if success:
            self.d_status["configure"]="Configure: success"
        else:
            self.d_status["configure"]="Configure: failed"
        return success
BRONES Romain's avatar
BRONES Romain committed
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.configure

    @command(
    )
    @DebugIt()
    def stop(self):
        # PROTECTED REGION ID(DG_PY_FOFBTool.stop) ENABLED START #
        """

        :return:None
        """

        self.info_stream("Stopping all")
BRONES Romain's avatar
BRONES Romain committed
        self.d_status["nodes"]="FofbNode: stopping"

        self.debug_stream("Stopping combpm and comlbp")
        for cn in self.tangopath_cellnode:
            FofbTool.Operation.stop_combpm(cn)
            FofbTool.Operation.stop_comlbp(cn)

        self.debug_stream("Stopping ccn")
        for cn in self.tangopath_cellnode:
            FofbTool.Operation.stop_ccn(cn)
            FofbTool.Operation.reset_ccn(cn)

BRONES Romain's avatar
BRONES Romain committed
        self.d_status["nodes"]="FofbNode: stopped"
BRONES Romain's avatar
BRONES Romain committed
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.stop

    @command(
    )
    @DebugIt()
    def start(self):
        # PROTECTED REGION ID(DG_PY_FOFBTool.start) ENABLED START #
        """

        :return:None
        """
        self.info_stream("Starting all")
BRONES Romain's avatar
BRONES Romain committed
        self.d_status["nodes"]="FofbNode: starting"

        if self._include_lbp:
            self.debug_stream("Starting comlbp")
            for cn in self.tangopath_cellnode:
                FofbTool.Operation.start_comlbp(cn)
        else:
            self.debug_stream("Skipping comlbp")

        self.debug_stream("Starting combpm")
        for cn in self.tangopath_cellnode:
            FofbTool.Operation.start_combpm(cn)

        self.debug_stream("Starting ccn")
        for cn in self.tangopath_cellnode:
            FofbTool.Operation.start_ccn(cn)
        FofbTool.Operation.start_ccn(self.tangopath_centralnode)

BRONES Romain's avatar
BRONES Romain committed
        self.d_status["nodes"]="FofbNode: started"

BRONES Romain's avatar
BRONES Romain committed
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.start

BRONES Romain's avatar
BRONES Romain committed
    @command(
    )
    @DebugIt()
    def sync(self):
        # PROTECTED REGION ID(DG_PY_FOFBTool.sync) ENABLED START #
        """

        :return:None
        """
        db = tango.Database()
BRONES Romain's avatar
BRONES Romain committed
        self.d_status["synchronize"]="Synchronize: starting"
BRONES Romain's avatar
BRONES Romain committed

        self.debug_stream("Building list form FREE PROPERTIES")
        bpmidlist = [(int(n.split(':')[0]), n.split(':')[2]) for n in db.get_property("FOFB", "bpmlist")['bpmlist'] if 'LIBERA' in n]
        tlocal = [n.split(':')[2] for n in db.get_property("FOFB", 'TimingBoardList')['TimingBoardList'] if "LOCAL" in n]
        lbpevrx = db.get_property("FOFB", 'LBPEVRX')['LBPEVRX']

BRONES Romain's avatar
BRONES Romain committed
        FofbTool.Operation.sync_bpm(bpmidlist, lbpevrx, tlocal, self.tangopath_centraltiming)
        self.d_status["synchronize"]="Synchronize: done"
BRONES Romain's avatar
BRONES Romain committed

        # PROTECTED REGION END #    //  DG_PY_FOFBTool.sync

BRONES Romain's avatar
BRONES Romain committed
    @command(
        dtype_in='DevLong',
        doc_in="cellnode",
    )
    @DebugIt()
    def align_fa(self, argin):
        # PROTECTED REGION ID(DG_PY_FOFBTool.align_fa) ENABLED START #
        """

        :param argin: 'DevLong'
        cellnode

        :return:None
        """

        cn=self.tangopath_cellnode[argin]

        self.debug_stream("Launch align FA on {}".format(cn))

        seqoffset = FofbTool.Operation.align_ccn(cn, 0)
        if (seqoffset is None) or seqoffset in (-1,0,1):
            self.error_stream("Could not align all ccn")
            self.d_status["align"]="FA Align: failed"
            return

        for cn in self.tangopath_cellnode:
            FofbTool.Configuration.cellnode_configure_comlbp(cn, seqoffset)

        self.d_status["align"]="FA Align: OK"
        # PROTECTED REGION END #    //  DG_PY_FOFBTool.align_fa

BRONES Romain's avatar
BRONES Romain committed
# ----------
# Run server
# ----------


def main(args=None, **kwargs):
    """Main function of the DG_PY_FOFBTool module."""
    # PROTECTED REGION ID(DG_PY_FOFBTool.main) ENABLED START #
    return run((DG_PY_FOFBTool,), args=args, **kwargs)
    # PROTECTED REGION END #    //  DG_PY_FOFBTool.main


if __name__ == '__main__':
    main()