예제 #1
0
class Spectrum(VirtualImage):

    parameters = {
        'preselection': Param('Preset value for this channel', type=float,
                              settable=True),
    }

    parameter_overrides = {
        'sizes': Override(type=tupleof(intrange(1, 1), intrange(1, 16384)),
                          default=(1, 16384)),
        'ismaster': Override(settable=True),
    }

    # set to True to get a simplified doEstimateTime
    is_timer = False

    def doEstimateTime(self, elapsed):
        if not self.ismaster or self.doStatus()[0] != status.BUSY:
            return None
        if self.is_timer:
            return self.preselection - elapsed
        else:
            counted = float(self.doRead()[0])
            # only estimated if we have more than 3% or at least 100 counts
            if counted > 100 or counted > 0.03 * self.preselection:
                if 0 <= counted <= self.preselection:
                    return (self.preselection - counted) * elapsed / counted

    def doReadArray(self, _quality):
        return self._buf[0]
예제 #2
0
class Input(Readable):
    """IPC I/O card digital input class."""

    parameters = {
        'addr':
        Param('Bus address of the card',
              type=intrange(32, 255),
              mandatory=True),
        'first':
        Param('First bit to read', type=intrange(0, 15), mandatory=True),
        'last':
        Param('Last bit to read', type=intrange(0, 15), mandatory=True),
    }

    parameter_overrides = {
        'unit': Override(mandatory=False, default=''),
        'fmtstr': Override(default='%d'),
    }

    attached_devices = {
        'bus': Attach('The communication bus', IPCModBus),
    }

    def doInit(self, mode):
        self._mask = ((1 << (self.last - self.first + 1)) - 1) << self.first

    def doRead(self, maxage=0):
        high = self._attached_bus.get(self.addr, 181) << 8
        low = self._attached_bus.get(self.addr, 180)
        return ((high + low) & self._mask) >> self.first

    def doStatus(self, maxage=0):
        return status.OK, ''
예제 #3
0
class TriangleAngle(HasOffset, TriangleMaster):

    parameters = {
        'index':
        Param('index of return',
              type=intrange(0, 1),
              settable=False,
              volatile=False,
              userparam=False),
        'scale':
        Param('direction definition (-1, 1)',
              type=oneof(-1, 1),
              settable=False,
              mandatory=True),
    }

    parameter_overrides = {
        'offset': Override(type=floatrange(-2, 2)),
    }

    def doRead(self, maxage=0):
        try:
            self.log.debug('index: %d' % self.index)
            res = self.offset + self.scale * self._read_controller(self.index)
            self.log.debug('pos: %f' % res)
        except IndexError:
            res = 0
        return res
예제 #4
0
파일: toni.py 프로젝트: umithardal/nicos
class LVPower(Moveable):
    """Toni TOFTOF-type low-voltage power supplies."""

    attached_devices = {
        'bus': Attach('Toni communication bus', ToniBus),
    }

    parameters = {
        'addr':
        Param('Bus address of the supply controller',
              type=intrange(0xF0, 0xFF),
              mandatory=True),
    }

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

    valuetype = oneofdict({1: 'on', 0: 'off'})

    def doRead(self, maxage=0):
        sval = self._attached_bus.communicate('S?', self.addr, expect_hex=2)
        return 'on' if sval >> 7 else 'off'

    def doStatus(self, maxage=0):
        sval = self._attached_bus.communicate('S?', self.addr, expect_hex=2)
        tval = self._attached_bus.communicate('T?', self.addr, expect_hex=2)
        return status.OK, 'status=%d, temperature=%d' % (sval, tval)

    @requires(level=ADMIN)
    def doStart(self, target):
        self._attached_bus.communicate('P%d' % (target == 'on'),
                                       self.addr,
                                       expect_ok=True)
예제 #5
0
class TemperatureSensor(PyTangoDevice, Readable):
    """The temperature readout device of the IMPAC pyrometer."""

    parameters = {
        'address':
        Param(
            'Device address',
            type=intrange(0, 97),
            default=0,
            settable=False,
        ),
    }

    parameter_overrides = {
        'comtries': Override(default=5),
    }

    def doInit(self, mode):
        pass

    def doRead(self, maxage=0):
        # return current temperature
        what = '%02dms' % self.address
        temp = float(self._dev.Communicate(what))
        if temp > 77769:
            temp = -0
        else:
            temp /= 10.0
        return temp

    def doStatus(self, maxage=0):
        return status.OK, 'idle'
예제 #6
0
class ChopperDisc2(ChopperDisc2Base, ChopperDisc):
    """Chopper disc 2 device."""

    # Due to a limitation of the hardware the position of the chopper disc2
    # position can be 0 but it is not a valid position. It indicates that the
    # hardware is not referenced. The parameter read raises always an error, so
    #  the device can't be initialised.

    # To overcome the problem the parameter type for the hardware is extended
    # to the 0 position, but the writing of 0 raises an error.

    parameter_overrides = {
        'pos':
        Override(type=intrange(0, 5),
                 volatile=True,
                 settable=True,
                 fmtstr='%d',
                 unit=''),
    }

    def doWritePos(self, target):
        if target == 0:
            raise ConfigurationError(
                self, "'%d' is an invalid value for "
                "parameter 'pos'" % target)
        self._attached_translation.move(target)
예제 #7
0
class FPGARate(PyTangoDevice, Readable):
    """Determines the instantaneous count rate of a counter card channel."""

    parameters = {
        'channel':
        Param('Channel number',
              type=intrange(0, 4),
              settable=False,
              mandatory=True)
    }

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

    _last = None

    def doRead(self, maxage=0):
        cur = (self._dev.DevFPGACountReadCount(self.channel),
               self._dev.DevFPGACountReadTime() / 1000.)
        if cur[1] == 0:
            res = 0.0
        elif self._last is None or self._last[1] > cur[1]:
            res = cur[0] / cur[1]
        elif self._last[1] == cur[1]:
            res = 0.0
        else:
            res = (cur[0] - self._last[0]) / (cur[1] - self._last[1])

        self._last = cur
        return res
예제 #8
0
class ChopperDisc2(DeviceMixinBase):
    """Chopper disc device with translation."""

    parameter_overrides = {
        'pos': Override(settable=True, type=intrange(1, 5), fmtstr='%d',
                        volatile=True, default=intrange(1, 5)(), unit=''),
    }

    attached_devices = {
        'translation': Attach('Chopper disc device', Moveable),
    }

    def doWritePos(self, target):
        self._attached_translation.move(target)

    def doReadPos(self):
        return self._attached_translation.read(0)
예제 #9
0
class LVPower(Moveable):
    """Toni TOFTOF-type low-voltage power supplies."""

    attached_devices = {
        'bus': Attach('Toni communication bus', ToniBus),
    }

    parameters = {
        'addr':
        Param('Bus address of the supply controller',
              type=intrange(0xF0, 0xFF),
              mandatory=True),
        'temperature':
        Param('Temperature of the module',
              type=int,
              settable=False,
              volatile=True,
              unit='degC',
              fmtstr='%d'),
    }

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

    valuetype = oneofdict({1: 'on', 0: 'off'})

    def doRead(self, maxage=0):
        sval = self._attached_bus.communicate('S?', self.addr, expect_hex=2)
        return 'on' if sval >> 7 else 'off'

    def doReadTemperature(self):
        return self._attached_bus.communicate('T?', self.addr, expect_hex=2)

    def doStatus(self, maxage=0):
        sval = self._attached_bus.communicate('S?', self.addr, expect_hex=2)
        if sval in (0x0, 0x80):
            return status.OK, ''
        msg = []
        if sval & 0x1:
            msg.append('undervoltage +5V')
        if sval & 0x2:
            msg.append('overvoltage +5V')
        if sval & 0x4:
            msg.append('undervoltage -5V')
        if sval & 0x8:
            msg.append('overvoltage -5V')
        if sval & 0x10:
            msg.append('undervoltage +12V')
        if sval & 0x20:
            msg.append('overvoltage +12V')
        return status.ERROR, ', '.join(msg)

    @requires(level=ADMIN)
    def doStart(self, target):
        self._attached_bus.communicate('P%d' % (target == 'on'),
                                       self.addr,
                                       expect_ok=True)
예제 #10
0
class CPTReadout(HasOffset, JsonBase):

    parameters = {
        'phasesign':
        Param('Phase sign',
              type=oneof('unsigned', 'signed'),
              settable=False,
              default='unsigned'),
        'channel':
        Param(
            'Index of value',
            type=intrange(-1, 99),
        ),
    }

    def _read_ctrl(self, channel):
        data = self._read_controller([self.valuekey, 'start_act'])
        self.log.debug('res: %r', data)
        self.log.debug('channel %d', channel)
        if channel == 0:
            self.log.debug('calc speed')
            res = 3e9 / data['start_act']  # speed
            res -= self.offset  # should be Zero
        elif channel == -1:
            self.log.debug('calc phase in respect to Disk 1 of Disc 1')
            self.log.debug('offset %.2f', self.offset)
            res = -360.0 * data[self.valuekey][0] / data['start_act']
            res -= self.offset
            res = self._kreis(res)
        else:
            self.log.debug('calc phase in respect to Disk 1')
            self.log.debug('offset %.2f', self.offset)
            res = -360.0 * data[self.valuekey][channel] / data['start_act']
            res -= self.offset
            res = self._kreis(res)
        return res

    def _kreis(self, phase, kreis=360.0):
        line = 'kreis phase %.2f' % phase
        if self.phasesign == 'signed':
            while phase > kreis / 2:
                phase -= kreis
            while phase < -kreis / 2:
                phase += kreis
        else:
            phase = -phase
            while phase > kreis:
                phase -= kreis
            while phase < 0:
                phase += kreis
        self.log.debug('%s %.2f', line, phase)
        return phase

    def doRead(self, maxage=0):
        return self._read_ctrl(self.channel)
예제 #11
0
class Shs(PyTangoDevice, Readable):
    """
    Basic IO Device object for devices in refsans'
    contains common things for all devices.
    """
    _buffer_old = None

    hardware_access = True

    parameters = {
        'address': Param('Starting offset (words) of IO area',
                         # type=intrange(0x3000, 0x47ff),
                         type=oneof(1026), mandatory=False, settable=False,
                         userparam=False, default=1026),
        'banks': Param('Banks to be read',
                       type=listof(intrange(0, 0xffff)), settable=False,
                       userparam=False, default=[0x300, 0x400])
    }

    def doInit(self, mode):
        # switch off watchdog, important before doing any write access
        # if mode != SIMULATION:
        #    self._taco_guard(self._dev.writeSingleRegister, (0, 0x1120, 0))
        pass

    def _readBuffer(self):
        buf = ()
        for bank in self.banks:
            Notausgang = 1
            while True:
                self.log.debug('bank: 0x%04X', bank)
                for _ in range(2):
                    session.delay(0.1)
                    self._dev.WriteOutputWords((self.address, bank))
                bu = tuple(self._dev.ReadOutputWords((0, 10)))
                if bu[2] == bank:
                    self.log.debug('Bank ok %d == %d', bu[2], bank)
                    buf += bu
                    break
                self.log.debug('Data from wrong bank %d != %d', bu[2], bank)
                Notausgang += 1
                if Notausgang > 6:
                    self.log.info('NOTAUSGANG<')  # raise error ???
                    break
                session.delay(0.5 * Notausgang)

        self.log.debug('buffer: %s', buf)
        self._buffer_old = buf
        return buf

    def doRead(self, maxage=0):
        return self._readBuffer()

    def doStatus(self, maxage=0):
        return status.OK, 'DEBUG'
예제 #12
0
파일: mcc2.py 프로젝트: umithardal/nicos
class MCC2Coder(MCC2core, NicosCoder):
    """Class for the readout of a MCC2-coder"""

    codertypes = ('none', 'incremental', 'ssi-binary', 'ssi-gray')

    parameters = {
        'slope':
        Param('Coder units per degree of rotation',
              type=float,
              default=1,
              settable=True,
              unit='1/main',
              prefercache=False),
        'zerosteps':
        Param('Coder steps at physical zero',
              type=int,
              default=0,
              settable=True,
              prefercache=False),
        'codertype':
        Param('Type of encoder',
              type=oneof(*codertypes),
              default='none',
              settable=True,
              prefercache=False),
        'coderbits':
        Param('Number of bits of ssi-encoder',
              default=0,
              type=intrange(0, 31),
              settable=True,
              prefercache=False),
    }

    def doReset(self):
        self.comm('XP39S1')  # encoder conversion factor set to 1

    def doReadCoderbits(self):
        return int(self.comm('XP35R'))

    def doWriteCoderbits(self, value):
        return self.comm('XP35S%d' % int(value))

    def doReadCodertype(self):
        return self.codertypes[int(self.comm('XP34R'))]

    def doWriteCodertype(self, value):
        return self.comm('XP34S%d' % self.codertypes.index(value))

    def doRead(self, maxage=0):
        return (float(self.comm('XP22R')) - self.zerosteps) / self.slope

    def doSetPosition(self, pos):
        self.comm('XP22S%d' % int(float(pos) * self.slope + self.zerosteps))
        return self.doRead()
예제 #13
0
class PNGLiveFileSink(ImageSink):
    """Writes (live) data to a PNG file, possibly with a log-10 color scale.

    Data is normalized to the highest-value pixel, and the used color map is
    the commonly used "Jet" colormap.

    This is not intended for data result storage, but to create images of the
    live measurement for quick view, e.g. in status monitors.
    """

    parameter_overrides = {
        'filenametemplate':
        Override(mandatory=False, userparam=False, default=['']),
    }

    parameters = {
        'interval':
        Param('Interval to write file to disk', unit='s', default=5),
        'filename':
        Param('File name for .png image', type=str, mandatory=True),
        'log10':
        Param('Use logarithmic counts for image', type=bool, default=False),
        'size':
        Param('Size of the generated image',
              unit='pixels',
              default=256,
              settable=True),
        'rgb':
        Param('Create RBG image', type=bool, default=True, mandatory=False),
        'histrange':
        Param('Range of histogram for scaling greyscale image',
              type=limits,
              default=(0.05, 0.95),
              settable=True,
              mandatory=False),
        'sumaxis':
        Param('Axis over which should be summed if data are 3D',
              type=intrange(1, 3),
              default=1,
              settable=False),
    }

    handlerclass = PNGLiveFileSinkHandler

    def doPreinit(self, mode):
        if PIL is None:
            self.log.error(_import_error)
            raise NicosError(
                self, 'Python Image Library (PIL) is not '
                'available. Please check whether it is installed '
                'and in your PYTHONPATH')

    def isActiveForArray(self, arraydesc):
        return len(arraydesc.shape) in (2, 3)
예제 #14
0
파일: virtual.py 프로젝트: umithardal/nicos
class VirtualReferenceMotor(CanReference, VirtualMotor):
    """Virtual motor device with reference capability."""

    parameters = {
        'refpos':
        Param('Reference position if given',
              type=none_or(float),
              settable=False,
              default=None,
              unit='main'),
        'addr':
        Param('Bus address of the motor', type=intrange(32, 255), default=71),
        'refswitch':
        Param('Type of the reference switch',
              type=oneof('high', 'low', 'ref'),
              default='high',
              settable=False),
    }

    def doReference(self, *args):
        refswitch = args[0] if args and isinstance(args[0], string_types) \
            else None
        self.log.debug('reference: %s', refswitch)
        self._setrefcounter()
        if self.refpos is not None:
            ret = self.read(0)
            self.log.debug('%s %r', self.name, self.isAtReference())
            return ret
        return self.refpos

    def _setrefcounter(self):
        self.log.debug('in setrefcounter')
        if self.refpos is not None:
            self.setPosition(self.refpos)
            self._setROParam('target', self.refpos)
            self.log.debug('%r %r', self.refpos, self.target)
            session.delay(0.1)
        if not self.isAtReference():
            raise UsageError('cannot set reference counter, not at reference '
                             'point')

    def isAtReference(self, refswitch=None):
        if self.refpos is None:
            return False
        pos = self.read(0)
        is_at_refpos = abs(self.refpos - self.read(0)) <= self.precision
        if refswitch == 'low':
            return is_at_refpos and (abs(self.abslimits[0] - pos) <
                                     abs(self.abslimits[1] - pos))
        elif refswitch == 'high':
            return is_at_refpos and (abs(self.abslimits[0] - pos) >
                                     abs(self.abslimits[1] - pos))
        return is_at_refpos
예제 #15
0
class MeanTemp(PyTangoDevice, Readable):
    """Returns mean temperature of some channels of a MawiTherm VectorInput."""

    parameters = {
        'first':
        Param('First channel to include',
              type=intrange(1, 8),
              default=1,
              settable=True),
        'last':
        Param('Last channel to include',
              type=intrange(1, 8),
              default=8,
              settable=True),
    }

    def doRead(self, maxage=0):
        if self.first > self.last:
            return 0
        allchannels = self._dev.value[self.first - 1:self.last]
        return float(sum(allchannels) / len(allchannels))
예제 #16
0
class Valve(Moveable):
    """Control element for 8 valves."""

    attached_devices = {
        'bus': Attach('Toni communication bus', ModBus),
    }

    parameters = {
        'addr':
        Param('Bus address of the valve control', type=int, mandatory=True),
        'channel':
        Param('Channel of the valve', type=intrange(0, 7), mandatory=True),
        'states':
        Param('Names for the closed/open states',
              type=listof(str),
              default=['off', 'on']),
        'waittime':
        Param('Time to wait after switching', type=float, unit='s', default=4),
    }

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

    _started = 0

    def doInit(self, mode):
        if len(self.states) != 2:
            raise ConfigurationError(
                self, 'Valve states must be a list of '
                'two strings for closed/open state')
        self.valuetype = oneof(*self.states)

    def doStart(self, value):
        value = self.states.index(value)
        self._hw_wait()
        msg = '%s=%02x' % (value and 'O' or 'C', 1 << self.channel)
        self._attached_bus.communicate(msg, self.addr, expect_ok=True)
        self._started = currenttime()

    def doRead(self, maxage=0):
        ret = self._attached_bus.communicate('R?', self.addr, expect_hex=2)
        return self.states[bool(ret & (1 << self.channel))]

    def doStatus(self, maxage=0):
        ret = self._attached_bus.communicate('I?', self.addr, expect_hex=2)
        if ret != 0:
            return status.BUSY, 'busy'
        if self._started and self._started + self.waittime < currenttime():
            return status.BUSY, 'waiting'
        else:
            return status.OK, 'idle'
예제 #17
0
class ChopperDisc(HasLimits, HasPrecision, DeviceMixinBase):

    parameters = {
        'phase': Param('Phase of chopper disc',
                       type=floatrange(0, 360), settable=True, userparam=True,
                       fmtstr='%.2f', unit='deg', category='status'),
        'current': Param('motor current',
                         type=float, settable=False, volatile=True,
                         userparam=True, fmtstr='%.2f', unit='A'),
        'mode': Param('Internal mode',
                      type=int, settable=False, userparam=True),
        'chopper': Param('chopper number inside controller',
                         type=intrange(1, 6), settable=False, userparam=True),
        'reference': Param('reference to Disc one',
                           type=floatrange(-360, 360), settable=False,
                           userparam=True),
        'edge': Param('Chopper edge of neutron window',
                      type=oneof('open', 'close'), settable=False,
                      userparam=True),
        'gear': Param('Chopper ratio',
                      type=intrange(-6, 6), settable=False, userparam=True,
                      default=0),
        'pos': Param('Distance to the disc 1',
                     type=floatrange(0), settable=False, userparam=True,
                     default=0., fmtstr='%.2f', unit='m', category='status'),
    }

    parameter_overrides = {
        'unit': Override(default='rpm', mandatory=False,),
        'precision': Override(default=2),
        'abslimits': Override(default=(0, 6000), mandatory=False),
        'fmtstr': Override(default='%.f'),
    }

    def doPoll(self, n, maxage):
        self._pollParam('current')

    def _isStopped(self):
        return abs(self.read(0)) <= self.precision
예제 #18
0
class DigitalInput(Moveable):
    """A test DigitalInput."""

    parameters = {
        '_value':
        Param('Simulated value',
              type=intrange(0, 0xFFFFFFFF),
              default=0,
              settable=False,
              internal=True),
    }

    parameter_overrides = {
        'unit': Override(mandatory=False, settable=False, default=''),
        'fmtstr': Override(default='%d'),
    }

    valuetype = intrange(0, 0xFFFFFFFF)

    def doRead(self, maxage=0):
        return self._value

    def doStatus(self, maxage=0):
        return status.OK, 'idle'
예제 #19
0
class RTE1104(Readable):

    parameters = {
        'channel':
        Param('calculation channel',
              type=intrange(1, 8),
              settable=False,
              default=1),
        'timescale':
        Param('Time scale setting',
              type=float,
              settable=True,
              userparam=True,
              volatile=True,
              category='general'),
        'yscale':
        Param('Y axis scaling',
              type=float,
              settable=True,
              userparam=True,
              volatile=True,
              category='general'),
    }

    attached_devices = {
        'io': Attach('Communication device', StringIO),
    }

    def doRead(self, maxage=0):
        return float(
            self._attached_io.communicate('MEAS%d:ARES?' % self.channel))

    def doStatus(self, maxage=0):
        return status.OK, ''

    def doReadTimescale(self):
        return float(self._attached_io.communicate('TIM:SCAL?'))

    def doWriteTimescale(self, value):
        self._attached_io.writeLine('TIM:SCAL %g' % value)

    def doReadYscale(self):
        return float(
            self._attached_io.communicate('CHAN%d:SCAL?' % self.channel))

    def doWriteYscale(self, value):
        self._attached_io.writeLine('CHAN%d:SCAL %g' % (self.channel, value))
예제 #20
0
class RTE1104YScaleSetting(Moveable):

    parameters = {
        'channel':
        Param('Input channel', type=intrange(1, 4), settable=False, default=1),
    }

    attached_devices = {
        'io':
        Attach('Communication device', StringIO),
        'regulator':
        Attach('regulator for the amplitude', Moveable, optional=True),
    }

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

    valuetype = float

    def doReadUnit(self):
        if self._attached_regulator:
            return self._attached_regulator.unit
        return 'V'

    def doRead(self, maxage=0):
        # main value is target amplitude
        if self._attached_regulator:
            return self._attached_regulator.read(maxage)
        setting = float(
            self._attached_io.communicate('CHAN%d:SCAL?' % self.channel))
        return setting * 10. / (2.2 * math.sqrt(2))

    def doStart(self, value):
        setting = math.ceil(value * math.sqrt(2.) * 2.2) / 10.
        self._attached_io.writeLine('CHAN%d:SCAL %g' % (self.channel, setting))
        if self._attached_regulator:
            self._attached_regulator.start(value)

    def doStatus(self, maxage=0):
        if self._attached_regulator:
            return self._attached_regulator.status(maxage)
        return status.OK, ''

    def doStop(self):
        if self._attached_regulator:
            self._attached_regulator.stop()
예제 #21
0
파일: servo.py 프로젝트: ess-dmsc/nicos
class MicroPythonServo(HasOffset, Motor):
    attached_devices = {
        'io': Attach('Comm device', SerComIO),
    }
    parameters = {
        'channel': Param('Channel (1..4)', type=intrange(1, 4), default=1),
    }
    parameter_overrides = {
        'precision': Override(default=1),
        'fmtstr': Override(default='%d'),
    }

    _busytime = 0

    def doInit(self, mode):
        if mode != SIMULATION:
            io = self._attached_io
            io.communicate('import pyb')
            io.communicate('s%d=pyb.Servo(%d)' % (self.channel, self.channel))
            io.communicate('s%d.calibration(600,2400,1500,2400,2400)' %
                           self.channel)
            io.communicate('s%d.angle(%f)' % (self.channel, self.target or 0.))
            io.addPollDev(self)

    def doRead(self, maxage=None):
        return float(
            self._attached_io.communicate(
                's%d.angle()' % self.channel)) - self.offset

    def doStart(self, target):
        duration = abs(self.read(0) - target) / self.speed
        target = target + self.offset
        cmd = ("s%d.angle(%f,%d)" %
               (self.channel, target, int(duration * 1000)))
        self.log.debug(cmd)
        self._attached_io.communicate(cmd)
        self._busytime = time.time() + duration

    def doStatus(self, maxage=None):
        if time.time() < self._busytime:
            return status.BUSY, ''
        return status.OK, ''

    def doShutdown(self):
        self._attached_io.delPollDev(self)
예제 #22
0
파일: lens.py 프로젝트: umithardal/nicos
class LensControl(HasTimeout, Moveable):
    """Control the 3 lenses."""

    valuetype = intrange(0, 7)

    attached_devices = {
        'output': Attach('output setter', Moveable),
        'input_in': Attach('input for limit switch "in" position', Readable),
        'input_out': Attach('input for limit switch "out" position', Readable),
        'sync_bit': Attach('sync bit output', Moveable),
    }

    parameter_overrides = {
        'fmtstr': Override(default='%d'),
        'timeout': Override(default=10),
        'unit': Override(mandatory=False, default=''),
    }

    def doStatus(self, maxage=0):
        is_in = self._attached_input_in.read(maxage)
        is_out = self._attached_input_out.read(maxage)
        # check individual bits
        for i in range(3):
            mask = 1 << i
            if is_in & mask == is_out & mask:
                # inconsistent state, check switches
                if is_in & mask:
                    # both switches on?
                    return status.ERROR, 'both switches on for lens ' \
                        '%d' % (i + 1)
                return status.BUSY, 'lenses moving'
        # HasTimeout will check for target reached
        return status.OK, 'idle'

    def doRead(self, maxage=0):
        return self._attached_input_in.read(maxage)

    def doStart(self, target):
        self._attached_output.start(target)
        # without this bit, no outputs will be changed
        self._attached_sync_bit.start(1)
예제 #23
0
파일: base.py 프로젝트: umithardal/nicos
class ChopperDiscTranslation(CanReference, IsController, DeviceMixinBase):
    """Position of chopper disc along the x axis.

    Since the chopper disc can be translated, the chopper speed must be low
    enough (around 0, defined by its precision).

    The change of speed must be blocked if the translation device is not at
    a defined position.
    """

    valuetype = intrange(1, 5)

    attached_devices = {
        'disc': Attach('Chopper disc device', Moveable),
    }

    parameter_overrides = {
        'unit': Override(default='', mandatory=False),
        'abslimits': Override(mandatory=False, default=limits((1, 5))),
        'fmtstr': Override(default='%d'),
    }

    def doReference(self, *args):
        self.move(1)

    def doIsAllowed(self, target):
        if self._attached_disc._isStopped():
            return True, ''
        return False, 'Disc (%s) speed is too high, %.0f!' % (
            self._attached_disc, self.read(0))

    def isAdevTargetAllowed(self, dev, target):
        state = self.status(0)
        if state[0] == status.OK:
            return True, ''
        return False, 'translation is: %s' % state[1]

    def _getWaiters(self):
        return []
예제 #24
0
class FPGACounterChannel(CounterChannelMixin, FPGAChannelBase):
    """FPGACounterChannel implements one monitor channel for ZEA-2 counter
    card.
    """

    parameters = {
        'channel':
        Param('Channel number',
              type=intrange(0, 4),
              settable=False,
              mandatory=True)
    }

    def _setPreselection(self):
        self._dev.DevFPGACountSetMinTime(0)
        self._dev.DevFPGACountSetTimeLimit(3600 * 24 * 1000)
        # Clamped to 1 for the same reason as the timer channel.
        self._dev.DevFPGACountSetCountLimit(
            [self.channel, int(self.preselection) or 1])

    def doRead(self, maxage=0):
        return self._dev.DevFPGACountReadCount(self.channel)
예제 #25
0
파일: toni.py 프로젝트: umithardal/nicos
class DelayBox(Moveable):
    """Toni TOFTOF-type programmable delay box."""

    attached_devices = {
        'bus': Attach('Toni communication bus', ToniBus),
    }

    parameters = {
        'addr':
        Param('Bus address of the supply controller',
              type=intrange(0xF0, 0xFF),
              mandatory=True),
    }

    parameter_overrides = {
        'fmtstr': Override(default='%d'),
    }

    valuetype = int

    def doRead(self, maxage=0):
        return self._attached_bus.communicate('D?', self.addr, expect_hex=4)

    def doStart(self, target):
        self._attached_bus.communicate('D=%04X' % target,
                                       self.addr,
                                       expect_ok=True)

    def doIsAllowed(self, target):
        if 0 <= target <= 65535:
            return True, ''
        else:
            return False, '%r is not in the allowed range [0, 65535], please '\
                          'check your delay calculation' % (target,)

    def doStatus(self, maxage=0):
        return status.OK, ''
예제 #26
0
class Ratemeter(Readable):
    """Toni ratemeter inside a "crate"."""

    attached_devices = {
        'bus': Attach('Toni communication bus', ModBus),
    }

    parameters = {
        'addr':
        Param('Bus address of crate',
              type=intrange(0xF0, 0xFF),
              mandatory=True),
    }

    def doRead(self, maxage=0):
        bus = self._attached_bus
        self._cachelock_acquire()
        try:
            # ratemeter is on channel 2
            bus.communicate('C2', self.addr, expect_ok=True)
            # send command (T = transmit, X = anything for input buffer update
            bus.communicate('TX', self.addr, expect_ok=True)
            # wait until response is ready
            rlen = -1
            t = 0
            while 1:
                sleep(0.05)
                ret = bus.communicate('R?', self.addr)
                if rlen == -1 or len(ret) == rlen:
                    return ret
                t += 1
                if t == 10:
                    raise CommunicationError('timeout while waiting for '
                                             'response')
        finally:
            self._cachelock_release()
예제 #27
0
class McStasImage(ImageChannelMixin, PassiveChannel):
    """Image channel based on McStas simulation."""

    _mythread = None

    _process = None

    parameters = {
        'size':
        Param(
            'Detector size in pixels (x, y)',
            settable=False,
            type=tupleof(intrange(1, 8192), intrange(1, 8192)),
            default=(1, 1),
        ),
        'mcstasprog':
        Param('Name of the McStas simulation executable',
              type=str,
              settable=False),
        'mcstasdir':
        Param('Directory where McStas stores results',
              type=str,
              default='singlecount',
              settable=False),
        'mcstasfile':
        Param('Name of the McStas data file', type=str, settable=False),
        'mcsiminfo':
        Param('Name for the McStas Siminfo file',
              settable=False,
              type=str,
              default='mccode.sim'),
        'ci':
        Param('Constant ci applied to simulated intensity I',
              settable=False,
              type=floatrange(0.),
              default=1e3)
    }

    def doInit(self, mode):
        self.arraydesc = ArrayDesc(self.name, self.size, '<u4')
        self._workdir = os.getcwd()

    def doReadArray(self, quality):
        self.log.debug('quality: %s', quality)
        if quality == LIVE:
            self._send_signal(SIGUSR2)
        elif quality == FINAL:
            if self._mythread and self._mythread.is_alive():
                self._mythread.join(1.)
                if self._mythread.is_alive():
                    self.log.exception("Couldn't join readout thread.")
                else:
                    self._mythread = None
        self._readpsd(quality == LIVE)
        return self._buf

    def _prepare_params(self):
        """Return a list of key=value strings.

        Each entry defines a parameter setting for the mcstas simulation call.

        examples:
            param=10
        """
        raise NotImplementedError('Please implement _prepare_params method')

    def doPrepare(self):
        self._mcstas_params = ' '.join(self._prepare_params())
        self.log.debug('McStas parameters: %s', self._mcstas_params)
        self._buf = np.zeros(self.size[::-1])
        self.readresult = [0]

    def valueInfo(self):
        return (Value(self.name + '.sum',
                      unit='cts',
                      type='counter',
                      errors='sqrt',
                      fmtstr='%d'), )

    def doStart(self):
        self._mythread = createThread('detector %s' % self, self._run)

    def doStatus(self, maxage=0):
        if self._mythread and self._mythread.is_alive():
            return status.BUSY, 'busy'
        return status.OK, 'idle'

    def doFinish(self):
        self.log.debug('finish')
        self._send_signal(SIGTERM)

    def _send_signal(self, sig):
        if self._process and self._process.is_running():
            self._process.send_signal(sig)
            # wait for mcstas releasing fds
            datafile = path.join(self._workdir, self.mcstasdir,
                                 self.mcstasfile)
            siminfo = path.join(self._workdir, self.mcstasdir, self.mcsiminfo)
            try:
                while self._process and self._process.is_running():
                    fnames = [f.path for f in self._process.open_files()]
                    if siminfo not in fnames and datafile not in fnames:
                        break
                    session.delay(.01)
            except (AccessDenied, NoSuchProcess):
                self.log.debug(
                    'McStas process already terminated in _send_signal(%r)',
                    sig)
            self.log.debug('McStas process has written file on signal (%r)',
                           sig)

    def _run(self):
        """Run McStas simulation executable.

        The current settings of the instrument parameters will be transferred
        to it.
        """
        try:
            shutil.rmtree(self.mcstasdir)
        except (IOError, OSError):
            self.log.info('could not remove old data')
        command = '%s -n 1e8 -d %s %s' % (self.mcstasprog, self.mcstasdir,
                                          self._mcstas_params)
        self.log.debug('run %s', command)
        try:
            self._process = Popen(command.split(),
                                  stdout=PIPE,
                                  stderr=PIPE,
                                  cwd=self._workdir)
            out, err = self._process.communicate()
            if out:
                self.log.debug('McStas output:')
                for line in out.splitlines():
                    self.log.debug('[McStas] %s', line)
            if err:
                self.log.warning('McStas found some problems:')
                for line in err.splitlines():
                    self.log.warning('[McStas] %s', line)
        except OSError as e:
            self.log.error('Execution failed: %s', e)
        self._process.wait()
        self._process = None

    def _readpsd(self, ignore_error=False):
        try:
            with open(
                    path.join(self._workdir, self.mcstasdir, self.mcstasfile),
                    'r') as f:
                lines = f.readlines()[-3 * (self.size[0] + 1):]
            if lines[0].startswith('# Data') and self.mcstasfile in lines[0]:
                self._buf = (
                    np.loadtxt(lines[1:self.size[0] + 1], dtype=np.float32) *
                    self.ci).astype(np.uint32)
                self.readresult = [self._buf.sum()]
            elif not ignore_error:
                raise IOError('Did not find start line: %s' % lines[0])
        except IOError:
            if not ignore_error:
                self.log.exception('Could not read result file')
예제 #28
0
class Sans1ColliMotorAllParams(Sans1ColliMotor):
    """
    Device object for a digital output device via a Beckhoff modbus interface.
    Maximum Parameter Implementation.
    All Relevant Parameters are accessible and can be configured.
    """

    _paridx = dict(
        refpos=2,
        vmax=3,
        v_max=3,
        vmin=4,
        v_min=4,
        vref=5,
        v_ref=5,
        acc=6,
        a_acc=6,
        ae=7,
        a_e=7,
        microsteps=8,
        backlash=9,
        fullsteps_u=10,
        fullsteps=10,
        imax=11,
        i_max=11,
        iv=12,
        i_v=12,
        iv0=12,
        i_v0=12,
        imin=12,
        i_min=12,
        encodersteps_u=20,
        features=30,
        t=40,
        temp=40,
        temperature=40,
        type=250,
        hw=251,
        fw=252,
        reset=255,
    )

    parameters = {
        # provided by parent class: speed, unit, fmtstr, warnlimits, userlimits,
        # abslimits, precision and others
        'power':
        Param(
            'Power on/off for the motordriver and '
            'enable/disable for the logic',
            type=oneof('off', 'on'),
            default='off',
            settable=True),
        'backlash':
        Param('Backlash correction in physical units',
              type=float,
              default=0.0,
              settable=True,
              mandatory=False,
              volatile=True),
        'maxcurrent':
        Param('Max Motor current in A',
              type=floatrange(0.05, 5),
              settable=True,
              volatile=True),
        'idlecurrent':
        Param('Idle Motor current in A',
              type=floatrange(0.05, 5),
              settable=True,
              volatile=True),
        'temperature':
        Param('Temperature of the motor driver',
              type=float,
              settable=False,
              volatile=True),
        'minspeed':
        Param('The minimum motor speed',
              unit='main/s',
              settable=True,
              volatile=True),
        'refspeed':
        Param('The referencing speed',
              unit='main/s',
              settable=True,
              volatile=True),
        'accel':
        Param('Acceleration/Decceleration',
              unit='main/s**2',
              settable=True,
              volatile=True),
        'stopaccel':
        Param('Emergency Decceleration',
              unit='main/s**2',
              settable=True,
              volatile=True),

        # needed ? Ask the Sans1 people...
        'hw_vmax':
        Param('Maximum Velocity in HW-units',
              type=intrange(1, 2047),
              settable=True,
              volatile=True),
        'hw_vmin':
        Param('Minimum Velocity in HW-units',
              type=intrange(1, 2047),
              settable=True,
              volatile=True),
        'hw_vref':
        Param('Referencing Velocity in HW-units',
              type=intrange(1, 2047),
              settable=True,
              volatile=True),
        'hw_accel':
        Param('Acceleration in HW-units',
              type=intrange(16, 2047),
              settable=True,
              volatile=True),
        'hw_accel_e':
        Param('Acceleration when hitting a limit switch in '
              'HW-units',
              type=intrange(16, 2047),
              settable=True,
              volatile=True),
        'hw_backlash':
        Param(
            'Backlash in HW-units',  # don't use
            type=intrange(-32768, 32767),
            settable=True,
            volatile=True),
        'hw_fullsteps':
        Param('Motor steps per turn in HW-units',
              type=intrange(1, 65535),
              settable=True,
              volatile=True),
        'hw_enc_steps':
        Param('Encoder steps per turn in HW-units',
              type=intrange(1, 65535),
              settable=True,
              volatile=True),
        'hw_features':
        Param('Value of features register (16 Bit, see docu)',
              type=intrange(0, 65535),
              settable=True,
              volatile=True),
        'hw_type':
        Param('Value of features register (16 Bit, see docu)',
              type=int,
              settable=True,
              volatile=True),
        'hw_revision':
        Param('Value of HW-revision register '
              '(16 Bit, see docu)',
              type=int,
              settable=True,
              volatile=True),
        'hw_firmware':
        Param('Value of HW-Firmware register '
              '(16 Bit, see docu)',
              type=int,
              settable=True,
              volatile=True),
        'hw_coderflt':
        Param('Input filter for Encoder signals',
              type=oneofdict({
                  1: 'disabled',
                  0: 'enabled'
              }),
              default='enabled',
              settable=True,
              volatile=True),
        'hw_feedback':
        Param('Feedback signal for positioning',
              type=oneofdict({
                  0: 'encoder',
                  1: 'motor'
              }),
              default='motor',
              settable=True,
              volatile=True),
        'hw_invposfb':
        Param('Turning direction of encoder',
              type=oneofdict({
                  1: 'opposite',
                  0: 'concordant'
              }),
              default='concordant',
              settable=True,
              volatile=True),
        'hw_ramptype':
        Param('Shape of accel/deccel ramp',
              type=oneofdict({
                  1: 'exponential',
                  0: 'linear'
              }),
              default='linear',
              settable=True,
              volatile=True),
        'hw_revin1':
        Param('Type of input 1',
              type=oneofdict({
                  1: 'nc',
                  0: 'no'
              }),
              default='no',
              settable=True,
              volatile=True),
        'hw_revin2':
        Param('Type of input 2',
              type=oneofdict({
                  1: 'nc',
                  0: 'no'
              }),
              default='no',
              settable=True,
              volatile=True),
        'hw_disin1rev':
        Param('Use Input 1 as reference input',
              type=oneofdict({
                  1: 'off',
                  0: 'on'
              }),
              default='on',
              settable=True,
              volatile=True),
        'hw_disin2rev':
        Param('Use Input 2 as reference input',
              type=oneofdict({
                  1: 'off',
                  0: 'on'
              }),
              default='on',
              settable=True,
              volatile=True),
        'hw_invrev':
        Param('Direction of reference drive',
              type=oneofdict({
                  1: 'pos',
                  0: 'neg'
              }),
              default='neg',
              settable=True,
              volatile=True),
    }

    parameter_overrides = {
        'microsteps': Override(mandatory=False, settable=True, volatile=True),
        'refpos': Override(settable=True),
    }

    # more advanced stuff: setting/getting parameters
    # only to be used manually at the moment
    @usermethod
    @requires(level='user')
    def readParameter(self, index):
        self.log.debug('readParameter %d', index)
        try:
            index = int(self._paridx.get(index, index))
        except ValueError:
            raise UsageError(
                self, 'Unknown parameter %r, try one of %s' %
                (index, ', '.join(self._paridx))) from None
        if self._readStatusWord() & (1 << 7):
            raise UsageError(
                self, 'Can not access Parameters while Motor is '
                'moving, please stop it first!')
        if self.power == 'on':
            self.power = 'off'

        # wait for inactive ACK/NACK
        self.log.debug('Wait for idle ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) == 0:
                break
        else:
            raise CommunicationError(
                self, 'HW still busy, can not read '
                'Parameter, please retry later.')

        self._writeUpperControlWord((index << 8) | 4)

        self.log.debug('Wait for ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) != 0:
                break
        else:
            raise CommunicationError(
                self, 'ReadPar command not recognized by '
                'HW, please retry later.')

        if self._readStatusWord() & (1 << 14):
            raise CommunicationError(
                self, 'Reading of Parameter %r failed, '
                'got a NACK' % index)
        return self._readReturn()

    @usermethod
    @requires(level='admin')
    def writeParameter(self, index, value, store2eeprom=False):
        self.log.debug('writeParameter %d:0x%04x', index, value)
        if store2eeprom:
            self.log.warning('writeParameter stores to eeprom !')
        try:
            index = int(self._paridx.get(index, index))
        except ValueError:
            UsageError(self, 'Unknown parameter %r' % index)
        if self._readStatusWord() & (1 << 7):
            raise UsageError(
                self, 'Can not access Parameters while Motor is '
                'moving, please stop it first!')
        if self.power == 'on':
            self.power = 'off'

        # wait for inactive ACK/NACK
        self.log.debug('Wait for idle ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) == 0:
                break
        else:
            raise CommunicationError(
                self, 'HW still busy, can not write '
                'Parameter, please retry later.')

        self._writeDestination(value)
        if store2eeprom:
            # store to eeprom
            self._writeUpperControlWord((index << 8) | 3)
        else:
            # store to volatile memory
            self._writeUpperControlWord((index << 8) | 1)

        self.log.debug('Wait for ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) != 0:
                break
        else:
            raise CommunicationError(
                self, 'WritePar command not recognized '
                'by HW, please retry later.')

        if self._readStatusWord() & (1 << 14):
            raise CommunicationError(
                self, 'Writing of Parameter %r failed, '
                'got a NACK' % index)
        return self._readReturn()

    #
    # Parameter access methods
    #
    def doWritePower(self, value):
        if self._readStatusWord() & (1 << 7):
            raise UsageError(
                self, 'Never switch off Power while Motor is '
                'moving !')
        value = ['off', 'on'].index(value)
        # docu: bit0 = enable/disable
        self._writeControlBit(0, value)

    def doReadPower(self):
        # docu: bit0 = enable/disable
        return ['off', 'on'][self._readControlBit(0)]

    # Parameter 1 : CurrentPosition
    def doSetPosition(self, value):
        self.writeParameter(1, self._phys2steps(value))

    # Parameter 2 : Refpos
    def doReadRefpos(self):
        return self._steps2phys(self.readParameter(2))

    def doWriteRefpos(self, value):
        self.writeParameter(2, self._phys2steps(value), store2eeprom=True)

    # Parameter 3 : hw_vmax -> speed
    def doReadHw_Vmax(self):
        return self.readParameter(3)

    def doReadSpeed(self):
        return self._speed2phys(self.hw_vmax)  # units per second

    def doWriteHw_Vmax(self, value):
        self.writeParameter(3, value)

    def doWriteSpeed(self, speed):
        self.hw_vmax = self._phys2speed(speed)

    # Parameter 4 : hw_vmin -> minspeed
    def doReadHw_Vmin(self):
        return self.readParameter(4)

    def doReadMinspeed(self):
        return self._speed2phys(self.hw_vmin)  # units per second

    def doWriteHw_Vmin(self, value):
        self.writeParameter(4, value)

    def doWriteMinspeed(self, speed):
        self.hw_vmin = self._phys2speed(speed)

    # Parameter 5 : hw_vref -> refspeed
    def doReadHw_Vref(self):
        return self.readParameter(5)  # µSteps per second

    def doReadRefspeed(self):
        return self._speed2phys(self.hw_vref)  # units per second

    def doWriteHw_Vref(self, value):
        self.writeParameter(5, value)

    def doWriteRefspeed(self, speed):
        self.hw_vref = self._phys2speed(speed)

    # Parameter 6 : hw_accel -> accel
    def doReadHw_Accel(self):
        return self.readParameter(6)  # µSteps per second

    def doReadAccel(self):
        return self._speed2phys(self.hw_accel)  # units per second

    def doWriteHw_Accel(self, value):
        self.writeParameter(6, value)

    def doWriteAccel(self, accel):
        self.hw_accel = self._phys2speed(accel)

    # Parameter 7 : hw_accel_e -> stopaccel
    def doReadHw_Accel_E(self):
        return self.readParameter(7)  # µSteps per second

    def doReadStopaccel(self):
        return self._speed2phys(self.hw_accel_e)  # units per second

    def doWriteHw_Accel_E(self, value):
        self.writeParameter(7, value)

    def doWriteStopaccel(self, accel):
        self.hw_accel_e = self._phys2speed(accel)

    # Parameter 8 : microsteps
    def doWriteMicrosteps(self, value):
        for i in range(7):
            if value == 2**i:
                self.writeParameter(8, i)
                break
        else:
            raise InvalidValueError(
                self, 'This should never happen! value should be one of: '
                '1, 2, 4, 8, 16, 32, 64 !')

    def doReadMicrosteps(self):
        return 2**self.readParameter(8)

    # Parameter 9 : hw_backlash -> backlash
    def doReadHw_Backlash(self):
        return self.readParameter(9)  # µSteps per second

    def doReadBacklash(self):
        return self._steps2phys(self.hw_backlash)

    def doWriteHw_Backlash(self, value):
        self.writeParameter(9, value)

    def doWriteBacklash(self, value):
        self.hw_backlash = self._phys2steps(value)

    # Parameter 10 : Fullsteps per turn
    def doReadHw_Fullsteps(self):
        return self.readParameter(10)

    def doWriteHw_Fullsteps(self, value):
        self.writeParameter(10, value)

    # Parameter 11 : MaxCurrent
    def doReadMaxcurrent(self):
        return self.readParameter(11) * 0.05

    def doWriteMaxcurrent(self, value):
        self.writeParameter(11, int(0.5 + value / 0.05))

    # Parameter 12 : IdleCurrent
    def doReadIdlecurrent(self):
        return self.readParameter(12) * 0.05

    def doWriteIdlecurrent(self, value):
        self.writeParameter(12, int(0.5 + value / 0.05))

    # Parameter 20 : Encodersteps per turn
    def doReadHw_Enc_Steps(self):
        return self.readParameter(20)

    def doWriteHw_Enc_Steps(self, value):
        self.writeParameter(20, value)

    # Parameter 30 : Features
    def doReadHw_Features(self):
        value = self.readParameter(30)
        self.log.debug('Feature0: Inputfilter for encodersignals: %d',
                       value & 1)
        self.log.debug(
            'Feature1: Positionsrueckfuehrung (0=Encoder, '
            '1=Zaehler): %d', (value >> 1) & 1)
        self.log.debug(
            'Feature2: Zaehlrichtung encoder (0=mitlaufend, '
            '1=gegenlaufend): %d', (value >> 2) & 1)
        self.log.debug('Feature3: Bremsrampe (0=linear, 1=exponentiell): %d',
                       (value >> 3) & 1)
        self.log.debug('Feature4: Eingang1 (0=Schliesser, 1=oeffner): %d',
                       (value >> 4) & 1)
        self.log.debug('Feature5: Eingang2 (0=Schliesser, 1=oeffner): %d',
                       (value >> 5) & 1)
        self.log.debug('Feature6: Eingang1 (0=referenz, 1=normal): %d',
                       (value >> 6) & 1)
        self.log.debug('Feature7: Eingang2 (0=referenz, 1=normal): %d',
                       (value >> 7) & 1)
        self.log.debug(
            'Feature8: Richtung der Referenzfahrt (0=negativ, '
            '1=positiv): %d', (value >> 8) & 1)
        return value

    def doWriteHw_Features(self, value):
        self.writeParameter(30, value)

    # bitwise access
    def doReadHw_Coderflt(self):
        return (self.hw_features >> 0) & 1

    def doWriteHw_Coderflt(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 0)) | (value << 0)
        else:
            raise InvalidValueError(self, 'hw_disencfltr can only be 0 or 1')

    def doReadHw_Feedback(self):
        return (self.hw_features >> 1) & 1

    def doWriteHw_Feedback(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 1)) | (value << 1)
        else:
            raise InvalidValueError(self, 'hw_feedback can only be 0 or 1')

    def doReadHw_Invposfb(self):
        return (self.hw_features >> 2) & 1

    def doWriteHw_Invposfb(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 2)) | (value << 2)
        else:
            raise InvalidValueError(self, 'hw_invposfb can only be 0 or 1')

    def doReadHw_Ramptype(self):
        return (self.hw_features >> 3) & 1

    def doWriteHw_Ramptype(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 3)) | (value << 3)
        else:
            raise InvalidValueError(self, 'hw_ramptype can only be 0 or 1')

    def doReadHw_Revin1(self):
        return (self.hw_features >> 4) & 1

    def doWriteHw_Revin1(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 4)) | (value << 4)
        else:
            raise InvalidValueError(self, 'hw_revin1 can only be 0 or 1')

    def doReadHw_Revin2(self):
        return (self.hw_features >> 5) & 1

    def doWriteHw_Revin2(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 5)) | (value << 5)
        else:
            raise InvalidValueError(self, 'hw_revin2 can only be 0 or 1')

    def doReadHw_Disin1Rev(self):
        return (self.hw_features >> 6) & 1

    def doWriteHw_Disin1Rev(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 6)) | (value << 6)
        else:
            raise InvalidValueError(self, 'hw_disin1rev can only be 0 or 1')

    def doReadHw_Disin2Rev(self):
        return (self.hw_features >> 7) & 1

    def doWriteHw_Disin2Rev(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 7)) | (value << 7)
        else:
            raise InvalidValueError(self, 'hw_disin2rev can only be 0 or 1')

    def doReadHw_Invrev(self):
        return (self.hw_features >> 8) & 1

    def doWriteHw_Invrev(self, value):
        if value in [0, 1]:
            self.hw_features = (self.hw_features & ~(1 << 8)) | (value << 8)
        else:
            raise InvalidValueError(self, 'hw_invrev can only be 0 or 1')

    # Parameter 40 : Temperature
    def doReadTemperature(self):
        return self.readParameter(40)

    # Parameter 250 : Klemmentyp
    def doReadHw_Type(self):
        return self.readParameter(250)

    # Parameter 251 : Hardwarestand
    def doReadHw_Revision(self):
        return self.readParameter(251)

    # Parameter 252 : Firmwarestand
    def doReadHw_Firmware(self):
        return self.readParameter(252)

    # Parameter 255 : Factory Reset
    @usermethod
    def FactoryReset(self, password):
        """resets the motorcontroller to factory default values
        for the right password see docu"""
        # 0x544B4531
        self.writeParameter(255, password)
예제 #29
0
from numpy import int32, uint16, uint32

from nicos import session
from nicos.core import SIMULATION, Attach, CommunicationError, \
    ConfigurationError, HasTimeout, InvalidValueError, Moveable, MoveError, \
    Override, Param, PositionError, UsageError, floatrange, intrange, \
    none_or, oneof, oneofdict, requires, status, usermethod
from nicos.core.utils import multiStatus
from nicos.devices.abstract import CanReference, Coder, Motor
from nicos.devices.generic import Switcher
from nicos.devices.generic.sequence import SeqMethod, SequencerMixin
from nicos.devices.tango import PyTangoDevice

WATCHDOG_REGISTER = 0x1120
WATCHDOG_DISABLE = 0
CODER_VALIDATOR = intrange(0x4000, 0x4800)
MOTOR_VALIDATOR = oneof(*range(0x4020, 0x4800, 10))


class Sans1ColliSlit(Switcher):
    """class for slit mounted onto something moving

    and thus beeing only effective if the underlying
    device is in a certain position.
    """
    attached_devices = {
        'table': Attach('Guide table this slit is mounted on', Moveable),
    }

    parameters = {
        'activeposition':
예제 #30
0
class SXTalBase(Instrument, Moveable):
    """An instrument class that can move in q space.

    When setting up a single xtal configuration, use a subclass that reflects
    the instrument geometry as your instrument device.
    """

    attached_devices = {
        'mono': Attach('Monochromator device', Monochromator),
    }

    parameters = {
        'wavelength':
        Param('Wavelength', type=float, volatile=True, settable=False),
        'scanmode':
        Param('Scanmode',
              type=oneof('omega', 't2t'),
              userparam=True,
              settable=True,
              default='omega'),
        'scansteps':
        Param('Scan steps',
              type=intrange(10, 999),
              userparam=True,
              settable=True,
              default=40),
        'scan_uvw':
        Param('U,V,W Param',
              type=vec3,
              userparam=True,
              settable=True,
              default=[1.0, 1.0, 1.0]),
    }

    parameter_overrides = {
        'fmtstr': Override(default='[%6.4f, %6.4f, %6.4f]'),
        'unit': Override(default='rlu', mandatory=False, settable=True),
    }

    valuetype = tupleof(float, float, float)
    hardware_access = False
    _last_calpos = None

    def doInit(self, mode):
        self.__dict__['h'] = SXTalIndex('h',
                                        unit='rlu',
                                        fmtstr='%.3f',
                                        index=0,
                                        lowlevel=True,
                                        sxtal=self)
        self.__dict__['k'] = SXTalIndex('k',
                                        unit='rlu',
                                        fmtstr='%.3f',
                                        index=1,
                                        lowlevel=True,
                                        sxtal=self)
        self.__dict__['l'] = SXTalIndex('l',
                                        unit='rlu',
                                        fmtstr='%.3f',
                                        index=2,
                                        lowlevel=True,
                                        sxtal=self)
        self._last_calpos = None

    def doShutdown(self):
        for name in ['h', 'k', 'l']:
            if name in self.__dict__:
                self.__dict__[name].shutdown()

    def _calcPos(self, hkl, wavelength=None):
        """Calculate instrument position object for given HKL position."""
        cell = session.experiment.sample.cell
        cpos = PositionFactory('c', c=cell.CVector(hkl))
        return self._convertPos(cpos, wavelength)

    def _extractPos(self, pos):
        """Extract values for the attached devices from a position object.
        Must be implemented in subclasses.
        """
        raise NotImplementedError

    def _convertPos(self, pos, wavelength=None):
        """Convert given position to the type usable by this geometry.
        Must be implemented in subclasses.
        """
        raise NotImplementedError

    def _readPos(self, maxage=0):
        """Create a position object with the current values of the attached
        devices.  Must be implemented in subclasses.
        """
        raise NotImplementedError

    def _createPos(self, **kwds):
        """Create a position object with the values of the given devices.
        Must be implemented in subclasses.
        """
        raise NotImplementedError

    def _calpos(self, hkl, printout=True, checkonly=True):
        """Implements the calpos() command."""
        try:
            poslist = self._extractPos(self._calcPos(hkl))
        except Exception as err:
            return False, str(err)
        ok, why = True, ''
        for devname, value in poslist:
            dev = self._adevs[devname]
            if dev is None:
                continue
            devok, devwhy = dev.isAllowed(value)
            if not devok:
                ok = False
                why += 'target position %s outside limits for %s: %s -- ' % \
                    (dev.format(value, unit=True), dev, devwhy)
            self.log.info('%-14s %8.3f %s', dev.name + ':', value, dev.unit)
        if ok:
            self._last_calpos = hkl
            if checkonly:
                self.log.info('position allowed')
        else:
            if checkonly:
                self.log.warning('position not allowed: %s', why[:-4])
            else:
                raise LimitError(self, 'position not allowed: ' + why[:-4])

    def _reverse_calpos(self, **kwds):
        """Implements the pos2hkl() command."""
        pos = self._createPos(**kwds).asC()
        hkl = session.experiment.sample.cell.hkl(pos.c)
        self.log.info('pos: [%.4f, %.4f, %.4f]', *hkl)

    def doIsAllowed(self, hkl):
        try:
            poslist = self._extractPos(self._calcPos(hkl))
        except Exception as err:
            return False, str(err)
        # check limits for the individual axes
        for (devname, devvalue) in poslist:
            dev = self._adevs[devname]
            if dev is None:
                continue
            else:
                ok, why = dev.isAllowed(devvalue)
            if not ok:
                return ok, 'target position %s outside limits for %s: %s' % \
                    (dev.format(devvalue, unit=True), dev, why)
        return True, ''

    def _sim_getMinMax(self):
        ret = []
        if self._sim_min is not None:
            for i, name in enumerate(['h', 'k', 'l']):
                ret.append(
                    (name, '%.4f' % self._sim_value[i],
                     '%.4f' % self._sim_min[i], '%.4f' % self._sim_max[i]))
        return ret

    def _sim_setValue(self, pos):
        self._sim_old_value = self._sim_value
        self._sim_value = pos
        self._sim_min = tuple(map(min, pos, self._sim_min or pos))
        self._sim_max = tuple(map(max, pos, self._sim_max or pos))

    def doStart(self, hkl):
        poslist = self._extractPos(self._calcPos(hkl))
        for (devname, devvalue) in poslist:
            dev = self._adevs[devname]
            dev.start(devvalue)
        # store the min and max values of h,k,l, and E for simulation
        self._sim_setValue(hkl)

    def doFinish(self):
        # make sure index members read the latest value
        for index in (self.h, self.k, self.l):
            if index._cache:
                index._cache.invalidate(index, 'value')

    def valueInfo(self):
        return Value('h', unit='rlu', fmtstr='%.4f'), \
            Value('k', unit='rlu', fmtstr='%.4f'), \
            Value('l', unit='rlu', fmtstr='%.4f')

    def doRead(self, maxage=0):
        pos = self._readPos(maxage).asC()
        hkl = session.experiment.sample.cell.hkl(pos.c)
        return list(hkl)

    def doReadWavelength(self, maxage=0):
        # ensure using correct unit
        oldunit = None
        if self._attached_mono.unit != 'A':
            oldunit = self._attached_mono.unit
            self._attached_mono.unit = 'A'
        result = self._attached_mono.read(0)
        if oldunit:
            self._attached_mono.unit = oldunit
        return result

    def getScanWidthFor(self, hkl):
        """Get scan width for a certain HKL."""
        raise NotImplementedError