Further NICOS API

Most API elements described here are used when writing new device classes. They are defined in submodules of nicos.core, but re-exported in nicos.core for easier importing.

Exceptions

The nicos.core.errors module defines several exceptions that are used throughout the system. They are re-exported in nicos.core.

The following exceptions can be used when writing custom devices:

exception nicos.core.errors.NicosError

The basic exception class for exceptions raised by NICOS.

Every NicosError subclass has a “category” attribute, a string that is shown to the user instead of the exception class.

The constructor also accepts a Device instance as its first argument, which is then used to display the error to the user as coming from this device. For example:

def doRead(self):
    if not self._ready:
        raise NicosError(self, 'device is not ready')

The constructor accepts a the keyword wikicode with an integer argument to create a link to a wiki page

where more information can be given. The integer should be the Unix timestamp (e.g from date +%%s, to get a uniqe id) of the first use of this specific error. To create the wiki page, log in to trac and enter ‘wiki:NicosError/<integer>’ in the search box on the upper right.

exception nicos.core.errors.InvalidValueError

Exception to be raised when the user gives an invalid value to a device (as a move target or parameter value).

exception nicos.core.errors.UsageError

Exception to be raised when user commands are used wrongly.

When this exception is caught by the user command handler, the help for the command that was executed is shown.

exception nicos.core.errors.ConfigurationError

Exception to be raised when an error in the setup is detected, or a device is supplied with invalid configuration data.

exception nicos.core.errors.ModeError

Exception to be raised when an action is not allowed in the current execution mode.

exception nicos.core.errors.AccessError

Exception to be raised when an action is forbidden to the current user.

Used by the requires decorator.

exception nicos.core.errors.ProgrammingError

Exception to be raised when an error in the code is detected.

This should not occur during normal operation.

exception nicos.core.errors.PositionError

Exception to be raised when a device detects an undefined position.

For example, this should be raised when several coders do not agree.

exception nicos.core.errors.MoveError

Exception to be raised when errors occur while moving a device.

exception nicos.core.errors.LimitError

Exception to be raised when a requested move target is out of limits.

exception nicos.core.errors.CommunicationError

Exception to be raised when some hardware communication fails.

exception nicos.core.errors.TimeoutError

Exception to be raised when a timeout waiting for hardware occurs.

This is not a communication timeout; for that purpose CommunicationError should be used.

exception nicos.core.errors.HardwareError

Exception to be raised on fatal hardware errors.

exception nicos.core.errors.CacheLockError

Exception to be raised when a cache lock cannot be acquired.

Parameter definition

The nicos.core.params module defines various helpers that are used when writing device classes. They are re-exported in nicos.core.

class nicos.core.params.Param(description, type=float, default=_notset, mandatory=False, settable=False, volatile=False, unit=None, category=None, preinit=False, prefercache=None, userparam=True)

This class defines the properties of a device parameter.

The Device.parameters attribute contains a mapping of parameter names to instances of this class.

Attributes (equivalent to constructor arguments):

  • description: a concise parameter description.
  • type: the parameter type; either a standard Python type (int, float, str) or one of the type converter functions from this module that either return a value of the correct type, or raises TypeError or ValueError.
  • default: a default value, in case the parameter cannot be read from the hardware or the cache.
  • mandatory: true if the parameter must be given in the config file.
  • settable: true if the parameter can be set by NICOS or the user after startup.
  • volatile: true if the parameter should always be read from hardware. For this, a doReadParamname method on the device is needed.
  • unit: unit of the parameter for informational purposes; in there, the substring ‘main’ is replaced by the device unit when presented.
  • category: category of the parameter when returned by Device.info() or None to ignore the parameter. See INFO_CATEGORIES for the list of possible categories.
  • preinit: whether the parameter must be initialized before Device.preinit() is called.
  • prefercache: whether on initialization, a value from the cache is preferred to a value from the config – the default is true for settable parameters and false for non-settable parameters.
  • userparam: whether this parameter should be shown to the user (default is True).
class nicos.core.params.Override(**keywords)

This class defines the overridden properties of a base class parameter.

The Device.parameter_overrides attribute contains a mapping of parameter names to instances of this class.

Overriding parameters allows to share parameters with the base class, but still have slightly different behavior for the parameters. For example, for a general Moveable device the unit parameter is mandatory. However, for some subclasses this will not be necessary, since the unit can either be automatically determined from the device, or the value never has any unit. Instead of redefining the unit parameter in subclasses, you only need to override its mandatory property in the subclass like this:

parameter_overrides = {'unit': Override(mandatory=False)}

The constructor takes all keywords that the Param constructor accepts. These properties of the parameter are then overridden compared to the base class.

class nicos.core.params.Value(name, type='other', errors='none', unit='', fmtstr='%.3f', active=True)

This class defines the properties of the “value” read from Readable and Measurable classes. Their valueInfo method must return a tuple of instances of this class.

  • The name parameter is the name of the value. By convention, if only one value is returned, this is the name of the device. Otherwise, if the values are collected from subdevices, the value names should be the subdevice names. In all other cases, they should be called “devname.valuename” where devname is the device name.
  • The type parameter can be one of:
    • 'counter' – some counter value
    • 'monitor' – some monitor value
    • 'time' – some timing value
    • 'other' – other numeric value
    • 'error' – standard error for previous value
    • 'info' – non-numeric info value
  • The errors parameter can be one of:
    • 'none' – no errors known
    • 'next' – errors are in next value
    • 'sqrt' – counter-like value: errors are square root
  • The unit parameter is the unit of the value, or ‘’ if it has no unit. This will generally be device.unit for Readables.
  • The fmtstr parameter selects how to format the value for display. This will generally be device.fmtstr for Readables.
  • The active parameter is reserved.
nicos.core.params.INFO_CATEGORIES

The categories allowed for Device.info() are:

  • 'experiment' – Experiment information
  • 'sample' – Sample and alignment information
  • 'instrument' – Instrument setup
  • 'offsets' – Offsets
  • 'limits' – Limits
  • 'precisions' – Precisions
  • 'status' – Instrument status (reserved for status() values)
  • 'general' – Instrument state, i.e. everything else of importance

Converter functions

These functions can be used to create parameter types (i.e. the type argument of Param) that not only convert to the correct type (such as int, str etc.), but also do more validation of the parameter.

nicos.core.params.anytype()

Converter that accepts anything. Example:

Param(..., type=anytype)
nicos.core.params.tacodev()

Converter that only accepts valid TACO device names.

nicos.core.params.vec3()

Converter that only accepts 3-vectors (i.e. lists or tuples) of floats.

nicos.core.params.intrange(from, to)

Create a converter that accepts only integers in the range(from, to) (i.e., to is excluded).

nicos.core.params.floatrange(from, to)

Create a converter that accepts only floats between from and to. Examples:

Param(..., type=floatrange(0, 10))
nicos.core.params.none_or(converter)

Create a converter that accepts only None or what the converter accepts. Example:

Param(..., type=none_or(str))
nicos.core.params.oneof(*values)

Create a converter that accepts only one of the given values. Example:

Param(..., type=oneof('up', 'down'))
nicos.core.params.listof(element_converter)

Create a converter that accepts only lists with element types given by the element_converter. Examples:

Param(..., type=listof(int))
Param(..., type=listof(tacodev))
nicos.core.params.nonemptylistof(element_converter)

Like listof, but the list may not be empty.

nicos.core.params.tupleof(*element_converters)

Create a converter that accepts only tuples with element types given by the element_converters. Examples:

Param(..., type=tupleof(int, int))
Param(..., type=tupleof(tacodev, str, str))
nicos.core.params.dictof(key_converter, value_converter)

Create a converter that accepts only dictionaries with key types given by key_converter and value types given by value_converter.

nicos.core.params.oneofdict(values)

Create a converter that accepts only the keys and values of the dictionary given in values. When one of the keys is given, it is converted to the corresponding value. Example:

Param(..., type=oneofdict({'up': 1, 'down': 0}))

Status values

The nicos.core.status module defines the status constants that are used as the first item of the tuple that Device.status returns. The whole status module is re-exported in nicos.core.

nicos.core.status.OK

The device is in a ready or idle state with no errors.

nicos.core.status.BUSY

The device is in a busy state (moving or waiting for completion).

nicos.core.status.PAUSED

The device is a measurable in paused state.

nicos.core.status.NOTREACHED

The device has not reached its setpoint.

nicos.core.status.ERROR

The device is in an error state.

nicos.core.status.UNKNOWN

The state of the device is not known.

nicos.core.status.statuses

A dictionary mapping these status values, which are integers, to their lowercased name (i.e., statuses[ERROR] == 'error').

Utilities

The nicos.core.device module defines some decorators for device methods:

nicos.core.device.usermethod(func)

Decorator that marks a method as a user-visible method.

The method will be shown to the user in the help for a device.

nicos.core.device.requires(**access)

Decorator to implement user access control.

The access is checked based on the keywords given. Currently, the keywords with meaning are:

  • 'level': gives the minimum required user access level and can have the values GUEST, USER or ADMIN as defined in the nicos.core.utils module.
  • 'mode': gives the required exection mode (“master”, “slave”, “maintenance”, “simulation”).
  • 'passcode': only usable in the interactive console: gives a passcode that the user has to type back.

The wrapper function calls Session.checkAccess to verify the requirements. If the check fails, AccessError is raised.

The nicos.core.utils module also defines some utility functions. They are re-exported in nicos.core.

nicos.core.utils.multiStatus(devices, maxage=None)

Combine the status of multiple devices to form a single status value.

This is typically called in the doStatus method of “superdevices” that control several attached devices.

The resulting state value is the highest value of all devices’ values (i.e. if all devices are OK, it will be OK, if one is BUSY, it will be BUSY, but if one is ERROR, it will be ERROR).

The resulting state text is a combination of the status texts of all devices.

nicos.core.utils.waitForStatus(device, delay=0.29999999999999999, timeout=None, busystates=(101, ), errorstates=(104, 103))

Wait for the device status to return exit the busy state.

delay is the delay between status inquiries, and busystates gives the state values that are considered as “busy” states; by default only status.BUSY.

Writing commands

Writing a custom user command is easy: just write a normal function and apply the usercommand decorator. The docstring of the function is the help for the command. A user command should raise UsageError when used improperly: the command help is shown automatically when such an error is raised.

In order to make user commands available in the NICOS namespace, they must be in a module that is mentioned by a modules list in a loaded setup (see Configuring NICOS: Setups).

usercommand(func)

Decorator that marks a function as a user command.

Table Of Contents

Previous topic

Device API reference

Next topic

Project Modules