Differences between revisions 16 and 17
Revision 16 as of 2019-05-14 15:57:02
Size: 10014
Editor: MarkBarton
Comment:
Revision 17 as of 2019-05-14 17:59:33
Size: 9974
Editor: MarkBarton
Comment:
Deletions are marked like this. Additions are marked like this.
Line 125: Line 125:
    'levelorder': ['IP','F0','F1','BF','SF','IM','TM'], # define a standard level ordering - Python dictionaries don't preserve order     'levelorder': ['IP','F0','F1','BF','SF','IM','TM'], # define a default level ordering
Line 154: Line 154:

KAGRA VIS Operations Manual - vistools.py

vistools.py is a Python module and command-line utility for manipulating the suspensions. It lives in /opt/rtcds/userapps/release/vis/k1/scripts (although it may get moved to /opt/rtcds/userapps/release/vis/common/scripts and there is a symlink to it in /opt/rtcds/userapps/release/vis/k1/guardian. Nearby there may be a test version vistoolstest.py.

vistools.py usage modes

vistools.py has three modes of use:

vistools.py as a Python module

vistools.py is primarily an ordinary Python module which provides the class Vis. Each instance of Vis represents a single suspension and can be created with any of the following forms:

BS = vistools.Vis('BS') # an Ezca instance with prefix 'K1:' is created internally
BS = vistools.Vis('VIS-BS') # channel name prefix style
BS = vistools.Vis('VIS_BS') # Guardian file name style
BS = vistools.Vis(('BS',ezca)) # ezca should be an existing ezca.Ezca instance with prefix 'K1:'; 'BS' can be 'VIS-BS' or 'VIS_BS'

A Vis object has a large number of methods which are mostly organized and named by blocks of filters of the same function (e.g., DAMP) at different levels of the suspension:

BS.masterSwitchWrite('ON') # turns the master switch on
BS.dampGainWrite(1.0) # sets all gain values in all DAMP blocks to 1.0. 
BS.dampGainWrite(1.0,levels=['IP']) # sets all gain values in the IP DAMP block to 1.0.  
BS.dampGainWrite(1.0,levels=['IP'],chans=['L','T']) # sets the gain values for the L and T channels of the IP DAMP block to 1.0 

Do dir(vistools.Vis) for a complete listing and help(vistools.Vis.methodName) for more details on individual methods. A typical signature is dampGainWrite([self,] value, levels=[], chans=[], verbose=False, pair='none', withprefix='bare', matlab=False, dorw=2). The arguments are as follows:

  • value: a value or list of values to be written (write methods only)

  • levels: a list of levels to restrict the request or change the default order, e.g, ['IP','F0','F1','BF']

  • chans: a list of channels within a block to restrict the request or change the default order, e.g., ['L','T'] for IP DAMP.

  • verbose: if True, bring debugging information, typically the channel names written to

  • withprefix: can be 'full', 'halffull', 'halfbare' or 'bare'; selects how much of the PV name to return (see next argument)

  • pair: can be 'pv', 'both', 'value' or 'none'; selects whether to return the channel name along with the read/written value

  • matlab: if True, returns lists with Matlab-style syntax (1/0 instead of True/False; {} instead of [] for lists)

  • dorw: 0 -> no live channel access; 1 -> no live write channel access (read only); 2 -> live reading and writing

Not all methods are implemented for every block (feel free to add more based on existing patterns) but DAMP has a complete set which illustrate the naming scheme for filter block commands:

  • dampPvs: Return a list of PVs for DAMP blocks.

  • dampInputSwitchWrite: Write 'ON' or 'OFF' to the INPUT switch in DAMP blocks.

  • dampInputSwitchRead: Read the INPUT switch in DAMP blocks.

  • dampOutputSwitchWrite: Write 'ON' or 'OFF' to the OUTPUT switch in DAMP blocks.

  • dampOutputSwitchRead: Read the OUTPUT switch in DAMP blocks.

  • dampOffsetSwitchWrite: Write 'ON' or 'OFF' to the OFFSET switch in DAMP blocks.

  • dampHoldSwitchWrite: Write 'ON' or 'OFF' to the HOLD switch in DAMP blocks.

  • dampOffsetWrite: Write a value or list of values to the OFFSET field in DAMP blocks.

  • dampGainRead: Read the gain value in DAMP blocks.

  • dampGainWrite: Write a value or list of values to the GAIN field in DAMP blocks.

  • dampFilterModuleEnableWrite: Write 'ON' or 'OFF' to the filter switches in DAMP blocks.

  • dampRampWrite: Write a value or list of values to the RAMP field in DAMP blocks.

  • dampGainRampingRead: Read the gain ramping state (GRAMP) in DAMP blocks.

  • dampOffsetRampingRead: Read the offset ramping state (ORAMP) in DAMP blocks.

  • dampRampingRead: Read the overall ramping state (GRAMP or ORAMP) in DAMP blocks.

  • dampPressButton: Simulate a press of the CLEAR HISTORY ('CLEAR') or LOAD COEFFICIENTS ('LOAD') button in DAMP blocks.

Similarly, OSEM2EUL has a complete set for matrix blocks:

  • o2ePvs: Return PV names for all or selected matrix elements.

  • o2eDefs: Return default values for all or selected matrix elements.

  • o2eRead: Read all or selected matrix elements.

  • o2eWriteValue: Write a common value into all or selected matrix elements.

  • o2eWriteArray: Write an array into all or selected matrix elements

  • lmWriteDefaults: Write default values for all or selected matrix elements

vistools.py from within Guardian

The usage from within Guardian is a bit complicated. According to some versions of the Guardian documentation, there is supposed to be a global Ezca instance called ezca which can be used for channel access. And according to some versions of the documentation, it is supposed to have prefix K1:VIS_BS_ or the like (which gets prepended to channel name fragments passed to it). If you run the Guardian in interactive mode, e.g.,

guardian -i VIS_BS

then there is indeed a global ezca object, but it has prefix just K1:, so the appropriate setup is

vis=vistools.Vis((SYSTEM,ezca))

However the environment seen by an actual Guardian script is different again: the Ezca object is not global but only available within the GuardState classes that define states. Worse, creating a second one at global scope causes channel access errors. Therefore, the initialization of vistools.py has to be done inside a state definition. The solution used by the Type B Guardian extends the decorator watchdog_check to also check whether the Vis object has been initialized and do it if necessary:

visObj = None

def checkvis():
    global visObj
    if visObj == None:
        visObj = vistools.Vis((SYSTEM,ezca))

class watchdog_check(GuardStateDecorator):
    """Decorator to check watchdog"""
    def pre_exec(self):
        global visObj
        checkvis()
        if visObj.trippedWds()!=[] or visObj.trippedBioWds()!=[]:
            return 'TRIPPED'
# ...
class SAFE(GuardState):
    index = 30
    @watchdog_check
    def main(self):
        global visObj
        notify('In SAFE')

vistools.py as a command-line utility

vistools.py Internal Organization

vistools.py uses two large nested dictionary structures, visTypes and visData to define what groups of channels are available. A typical entry in visTypes specifies a particular suspension (e.g., BS) in terms of a generic type (e.g., 'TYPEB') plus watchdog and BIO information:

visTypes = {
...,
    ('K1','BS') : {'type': 'TYPEB', 'watchdogs': typebwd, 'bio' : typebbio},
...
}

where

typebwd = {'IOP':'DACKILL','IP':'IP_WDMON', 'F0':'F0_WDMON','F1':'F1_WDMON','BF':'BF_WDMON', 'IM':'IM_WDMON','TM':'TM_WDMON'}
typebbio = {'GAS':'BIO_GAS_MON','IP':'BIO_IP_MON','GAS':'BIO_GAS_MON','IMV':'BIO_IMV_MON','TM':'BIO_TM_MON'}

Then, a typical entry in visData specifies a generic suspension type, which is further structured by level ('IP', 'F0', 'F1' etc) and optionally by sensor actuator group ('osemConfig', 'olConfig' etc). (The concept of a sensor-actuator group was more important historically when vistools.py was less smart about ignoring missing keys and every level had to have the same set of keys, even though many of them had value None - all the OSEM-related blocks could be declared as non-existent with a single entry 'osemConfig':None.)

visData = {
    'master' : 'MASTERSWITCH', # a switch not associated with any particular level
    'commissioning' : 'COMMISH_STATUS', # another global switch
    'levelorder': ['IP','F0','F1','BF','SF','IM','TM'], # define a default level ordering
    'levels' : { # define the various levels in the suspension
        ... 
        'IM':{ # define the intermediate mass level
            'dofs' : ['L', 'T', 'V', 'R', 'P', 'Y'], # a list of related channels
            'isichans' : ['X', 'Y', 'RZ', 'Z', 'RX', 'RY'], # another list of related channels
            ...
            'cart2eul' : { # a cdsMuxMatrix block
                'blockname':'CART2EUL', # the Simulink block name, used for constructing channel names
                'inames':'isichans', # input channels; reference to the list defined above
                'onames':'dofs', # output channels; reference to the list defined above
                'default':[...] # default values for matrix elements
            }, 
            'osemConfig' : { # a sensor-actuator group
                'chans' : ['V1', 'V2', 'V3', 'H1', 'H2', 'H3'], # a list of input channels
                'dofs' : ['L', 'T', 'V', 'R', 'P', 'Y'], # a list of output channels
                'inf' : {'blockname':'OSEMINF', 'names':'chans'}, # a block with a group of cdsFilt units
                'eul2osem' : { # a cdsMuxMatrix block
                    'blockname':'EUL2OSEM','inames':'dofs', 'onames':'chans', 
                    'default':[[...],[...]],...]) # each sublist represents an _output_!
                },
                ...
            },
            ...
         },
     },
     ....
}

vistools.py Style Guide

vistools.py should have groups of 4 spaces for indentation. To select this in gedit, select Automatic Indentation off, Tab Width 4, Use Spaces on in the Tab Width menu in the lower window frame:<<br>> attachment:Gedit Setup.png

KAGRA/Subgroups/VIS/OpsManual/vistools (last edited 2019-05-15 20:46:07 by MarkBarton)