From c974edede9468a429bc0dd837f289fb1d4f55667 Mon Sep 17 00:00:00 2001 From: tasp Date: Fri, 29 Apr 2022 11:04:58 +0200 Subject: [PATCH] reworked meanings / aliases - add rotation_x to the list - allow to configure items creating an alias without entry in envlist --- commands.py | 51 ++++++++++++++++++++++++++++++------------------ devices.py | 17 +++++++++++++--- setups/frappy.py | 37 +++++++++++++++++++++++++++++++---- 3 files changed, 79 insertions(+), 26 deletions(-) diff --git a/commands.py b/commands.py index 3b141f0..f94b3fc 100644 --- a/commands.py +++ b/commands.py @@ -26,7 +26,7 @@ from glob import glob from configparser import ConfigParser from nicos import session, config -from nicos.core import DeviceAlias +from nicos.core import DeviceAlias, Moveable from nicos.utils import printTable from nicos.commands import helparglist, usercommand from nicos.commands.basic import AddSetup, CreateAllDevices, CreateDevice @@ -92,10 +92,8 @@ def remove_se_aliases(): frappy_config = session.getDevice('frappy_config') configured = {} for meaning in frappy_config.meanings: - try: - aliasname, aliascfg = getattr(frappy_config, meaning) - except TypeError: - continue + info = getattr(frappy_config, meaning) + aliasname = info['alias'] aliasdev = session.devices.get(aliasname) if aliasdev: session.destroyDevice(aliasname) @@ -123,21 +121,34 @@ def set_se_list(): meaning = secnode.modules[secop_module]['properties'].get('meaning') if meaning: meaning_name, importance = meaning - sample_devices.setdefault(meaning_name, []).append((importance * 10 + 5, devname)) + sample_devices.setdefault(meaning_name, []).append((importance, devname)) - newlist = [] - previous = session.experiment.envlist[:] + devset = set() + newenv = {e: None for e in session.experiment.envlist} # use dict instead of set because of order + drivables = {} for meaning in frappy_config.meanings: - try: - aliasname, aliascfg = getattr(frappy_config, meaning) - except TypeError: - continue + info = getattr(frappy_config, meaning) + aliasname = info['alias'] + envlistflag = info.get('envlist', True) + aliascfg = info.get('targets', {}) importance_list = sample_devices.get(meaning, []) importance_list.extend([(nr, nam) for nam, nr in aliascfg.items() if nam in session.devices]) importance_list = sorted(importance_list, reverse=True) session.log.debug('%s: %r', meaning, importance_list) + prefix, _, postfix = meaning.partition('_') + if postfix == 'drivable': + # append the previously collected drivables in the group to the importance_list + group = drivables.get(prefix, {}) + for key in 'regulation', '': + if key in group: + importance_list.append((None, group[key])) for _, devname, in importance_list: dev = session.devices.get(devname) + if isinstance(dev, Moveable): + drivables.setdefault(prefix, {})[postfix] = devname + elif postfix == 'drivable': + # marked as xxx_drivable, but not really drivable: skip + continue if dev: session.log.debug('create alias %r pointing to %r', aliasname, devname) devcfg = ('nicos.core.DeviceAlias', {}) @@ -145,17 +156,19 @@ def set_se_list(): session.dynamic_devices[aliasname] = 'frappy' aliasdev = session.createDevice(aliasname, recreate=True, explicit=True) aliasdev.alias = devname - if aliasname not in previous: - newlist.append(aliasname) + if devname not in devset and envlistflag: + # take only the first one + devset.add(devname) + newenv[aliasname] = None + else: + newenv.pop(aliasname, None) break else: - if aliasname in previous: - previous.remove(aliasname) + newenv.pop(aliasname, None) applyAliasConfig() # for other aliases - newlist = previous + newlist - if set(newlist) != set(session.experiment.envlist): - session.experiment.setEnvironment(newlist) + if set(newenv) != set(session.experiment.envlist): + session.experiment.setEnvironment(list(newenv)) session.log.info('changed environment to: %s', ', '.join(session.experiment.envlist)) diff --git a/devices.py b/devices.py index db0c2fd..dc9b318 100644 --- a/devices.py +++ b/devices.py @@ -47,13 +47,24 @@ def suggest(poi, allowed_keys): class FrappyConfig(Device): + # respect the order: e.g. temperature_regulation must be after temperature + # and temperature_drivable must be the last in the temperature group parameters = { 'temperature': Param( - 'device name for sample temperature', type=anytype, default=['Ts', []]), + 'config for sample temperature', type=anytype, + default={'alias': 'Ts'}), 'temperature_regulation': Param( - 'device name for temperature regulation', type=anytype, default=['Tr', []]), + 'config for temperature regulation', type=anytype, + default={'alias': 'Tr'}), + 'temperature_drivable': Param( + 'config for drivable temperature', type=anytype, + default={'alias': 'T', 'envlist': False}), 'magneticfield': Param( - 'device name for magnetic field', type=anytype, default=['B', []]), + 'config for magnetic field', type=anytype, + default={'alias': 'B'}), + 'rotation_z': Param( + 'config for sample rotation', type=anytype, + default={'alias': 'stickrot', 'envlist': False}), 'nodes': Param( 'list of names of potential SEC nodes', type=listof(str), default=[]), } diff --git a/setups/frappy.py b/setups/frappy.py index 8b034c5..d98ba76 100644 --- a/setups/frappy.py +++ b/setups/frappy.py @@ -6,12 +6,41 @@ modules = ['nicos_sinq.frappy_sinq.commands'] devices = dict( frappy_config = device( 'nicos_sinq.frappy_sinq.devices.FrappyConfig', + # frappy_config does not need to be visible visibility = [], + # the possible SECoP connections nodes = ['se_main', 'se_stick', 'se_addons'], - # T will be either a SECoP module with property meaning=tmperature or one of the keys in the dict - temperature = ['T', {'se_ts': 120, 'se_tt': 100}], - temperature_regulation = ['Tr', {'se_tm': 110, 'se_tv': 100}], - magneticfield = ['B', {'se_mf': 100}], + # + # now follows a list of main SE devices, where an alias is + # generated, if such a device is present, and automatically + # added to the environment list + # remarks: the SECoP meaning should be given from the description + # retrieved from the remote SEC node. if targets is given, + # the devices with the names given by key are added to determine the + # device, using the given importance number, with similar values as + # given by the SECoP standard (10: instrument, 20: cryostat, 30: insert) + temperature = { # the SECoP meaning + 'alias': 'Ts', # the name to be given to the alias + 'targets': # possible devices in addition with importance + {'se_ts': 20, 'se_tt': 19, 'se_tm': 18}, + }, + temperature_regulation = { + 'alias': 'Tr', + 'targets': {'se_tt': 20, 'se_tm': 19}, + }, + temperature_drivable = { + 'alias': 'T', + 'envlist': False, + }, + magneticfield = { + 'alias': 'B', + 'targets': {'se_mf': 20}, + }, + rotation_z = { + 'alias': 'stickrot', + 'envlist': False, + 'targets': {'se_om': 20}, + } ) )