コード例 #1
0
 def doRead(self, maxage=0):
     res = self._attached_io_status.read(maxage)
     if res == 1:
         return 'in'
     elif res == 2:
         return 'out'
     elif res in [0, 3]:
         raise PositionError(self, 'filter unit in error state, somewhere '
                             'in between in/out')
     else:
         raise PositionError(self, 'invalid value of I/O: %s' % res)
コード例 #2
0
def test_scan_errorhandling(session, log):
    t = session.getDevice('tdev')
    m = session.getDevice('motor')

    dataman = session.experiment.data
    # no errors, works fine
    scan(t, [0, 1, 2])
    dataset = dataman.getLastScans()[-1]
    assert dataset.devvaluelists == [[0], [1], [2]]

    with log.allow_errors():
        # limit error: skips the data points
        scan(t, [-10, 0, 10, 3])
        dataset = dataman.getLastScans()[-1]
        assert dataset.devvaluelists == [[0], [3]]

        # communication error during move: also skips the data points
        t._value = 0
        t._start_exception = CommunicationError()
        scan(t, [0, 1, 2, 3])
        dataset = dataman.getLastScans()[-1]
        assert dataset.devvaluelists == [[
            0
        ]]  # tdev.move only raises when target != 0

        # position error during move: ignored
        t._value = 0
        t._read_exception = None
        t._start_exception = PositionError()
        scan(t, [0, 1, 2, 3])
        dataset = dataman.getLastScans()[-1]
        assert dataset.devvaluelists == [[0], [None], [None], [None]]

        # position error during readout: ignored
        t._read_exception = PositionError()
        t._start_exception = None
        scan(t, [0, 1, 2, 3])
        dataset = dataman.getLastScans()[-1]
        assert dataset.devvaluelists == [[None], [None], [None], [None]]
        # also as an environment device
        scan(m, [0, 1], t)
        dataset = dataman.getLastScans()[-1]
        assert dataset.devvaluelists == [[0.], [1.]]
        assert dataset.envvaluelists == [[None], [None]]

        # other errors: reraised
        t._start_exception = RuntimeError()
        assert raises(RuntimeError, scan, t, [0, 1, 2, 3])
コード例 #3
0
ファイル: axis.py プロジェクト: ess-dmsc/nicos
    def _checkDragerror(self):
        """Check if a "drag error" occurred.

        The values of motor and coder deviate too much.  This indicates that
        the movement is blocked.

        This method sets the error state and returns False if a drag error
        occurs, and returns True otherwise.
        """
        if self._maxdiff <= 0:
            return True
        diff = abs(self._attached_motor.read() - self._attached_coder.read())
        self.log.debug('motor/coder diff: %s', diff)
        if diff > self._maxdiff:
            self._errorstate = MoveError(
                self, 'drag error (primary coder): '
                'difference %.4g, maximum %.4g' % (diff, self._maxdiff))
            return False
        for obs in self._attached_obs:
            diff = abs(self._attached_motor.read() - obs.read())
            if diff > self._maxdiff:
                self._errorstate = PositionError(
                    self, 'drag error (%s): difference %.4g, maximum %.4g' %
                    (obs.name, diff, self._maxdiff))
                return False
        return True
コード例 #4
0
    def _step(self, devicename, pos):
        """Make one step in the changing sequence.

        evaluates the given keyword argument and
        moves the attached_device with the keyname to the value-position.
        Also checks success
        """
        dev = self._adevs[devicename]
        # now log some info
        if pos == 'open':
            self.log.info("Open '%s'", dev.name)
        elif pos == 'closed':
            self.log.info("Close '%s'", dev.name)
        else:
            self.log.info("Move '%s' to '%s' position", dev.name, pos)
        try:
            dev.start(pos)
            if devicename == 'r3':  # R3 does not wait!
                session.delay(2)
            if devicename == 'grip':  # grip does not wait!
                session.delay(2)
            dev.wait()
        except Exception:
            # most probably it is touching the limit switch
            if devicename == 'lift':
                dev._adevs['moveables'][0].motor.stop()
                self.log.info('Limit switch ?')
            else:
                raise
        if dev.read(0) != pos:
            raise PositionError("Device '%s' did not reach its target '%s', "
                                'aborting' % (dev, pos))
コード例 #5
0
    def _mapReadValue(self, pos):
        """Override default inverse mapping to allow a deviation <= precision"""
        prec = self.precision

        def myiter(mapping):
            # use position names beginning with P as last option
            for name, value in mapping.items():
                if name[0] != 'P':
                    yield name, value
            for name, value in mapping.items():
                if name[0] == 'P':
                    yield name, value

        for name, value in myiter(self.mapping):
            if prec:
                if abs(pos - value) <= prec:
                    return name
            elif pos == value:
                return name
        if self.fallback is not None:
            return self.fallback
        if self.relax_mapping:
            return self._attached_moveable.format(pos, True)
        raise PositionError(self,
                            'unknown position of %s' % self._attached_moveable)
コード例 #6
0
 def doRead(self, maxage=0):
     up = self._attached_holdstat.read(maxage)
     down = self._attached_mono_stat.read(maxage)
     if up != 'None':
         if up != down:
             raise PositionError(self, 'unknown position of %s' % self.name)
     return self._attached_holdstat.read(maxage)
コード例 #7
0
ファイル: sr7.py プロジェクト: umithardal/nicos
 def doStart(self, pos):
     if pos == self.read(0):
         return
     self._attached_sr7set.start(self.positions.index(pos))
     if self.wait() != pos:
         raise PositionError(self, 'device returned wrong position')
     self.log.info('SR7: %s', pos)
コード例 #8
0
ファイル: switcher.py プロジェクト: ess-dmsc/nicos
 def _mapReadValue(self, pos):
     """maps a tuple to one of the configured values"""
     hasprec = bool(self.precision)
     if hasprec:
         precisions = self.precision
         if len(precisions) == 1:
             precisions = [precisions[0]] * len(self.devices)
     for name, values in self.mapping.items():
         if hasprec:
             for p, v, prec in zip(pos, values, precisions):
                 if prec:
                     if abs(p - v) > prec:
                         break
                 elif p != v:
                     break
             else:  # if there was no break we end here...
                 return name
         else:
             if tuple(pos) == tuple(values):
                 return name
     if self.fallback is not None:
         return self.fallback
     raise PositionError(self, 'unknown position of %s: %s' % (
         ', '.join(str(d) for d in self.devices),
         ', '.join(d.format(p) for (p, d) in zip(pos, self.devices))))
コード例 #9
0
ファイル: axis.py プロジェクト: ess-dmsc/nicos
    def _checkTargetPosition(self, target, pos, error=True):
        """Check if the axis is at the target position.

        This method returns False if not arrived at target, or True otherwise.
        """
        diff = abs(pos - target)
        prec = self.precision
        if (0 < prec <= diff) or (prec == 0 and diff):
            msg = 'precision error: difference %.4g, precision %.4g' % \
                  (diff, self.precision)
            if error:
                self._errorstate = MoveError(msg)
            else:
                self.log.debug(msg)
            return False
        maxdiff = self.dragerror
        for obs in self._attached_obs:
            diff = abs(target - (obs.read() - self.offset))
            if 0 < maxdiff < diff:
                msg = 'precision error (%s): difference %.4g, maximum %.4g' % \
                      (obs, diff, maxdiff)
                if error:
                    self._errorstate = PositionError(msg)
                else:
                    self.log.debug(msg)
                return False
        return True
コード例 #10
0
ファイル: monochromator.py プロジェクト: umithardal/nicos
    def _to_lambda(self, phi1, phi2, trans):
        """Calculate lambda from phi1, phi2, trans. May raise a PositionError.
        Not necessarily all arguments are used.

        Next iteration could evaluate all 3 args and return an average value...
        """
        try:
            return abs(2 * self.dvalue1 * sin(radians(phi1)))
        except Exception:
            raise PositionError('can not determine lambda!')
コード例 #11
0
 def _mapReadValue(self, pos):
     """maps a tuple to one of the configured values"""
     for name, values in self.mapping.items():
         if tuple(pos) == tuple(values):
             return name
     if self.fallback is not None:
         return self.fallback
     raise PositionError(
         self, 'unknown position of %s: %s' %
         (', '.join(str(d) for d in self._adevs), ', '.join(
             d.format(p) for (p, d) in zip(pos, self._adevs))))
コード例 #12
0
ファイル: switcher.py プロジェクト: ess-dmsc/nicos
 def _mapReadValue(self, pos):
     prec = self.precision
     for name, value in self.mapping.items():
         if prec:
             if abs(pos - value) <= prec:
                 return name
         elif pos == value:
             return name
     if self.fallback is not None:
         return self.fallback
     raise PositionError(self, 'unknown position of %s' %
                         self._attached_readable)
コード例 #13
0
ファイル: sr7.py プロジェクト: umithardal/nicos
 def doRead(self, maxage=0):
     res = self.doStatus()[0]
     if res == status.OK:
         if self._attached_sr7cl.doRead() == 1:
             return 'close'
         elif self._attached_sr7p1.doRead() == 1:
             return 'S1'
         elif self._attached_sr7p2.doRead() == 1:
             return 'S2'
         elif self._attached_sr7p3.doRead() == 1:
             return 'S3'
     else:
         raise PositionError(self, 'SR7 shutter moving or undefined')
コード例 #14
0
ファイル: beamstop.py プロジェクト: umithardal/nicos
 def doRead(self, maxage=0):
     for _ in range(10):
         # try to filter out 'half-broken' values
         value = np.median([Sensor.doRead(self, maxage) for _ in range(3)])
         # avoid fully broken values
         if self.limits[0] <= value <= self.limits[1]:
             return value
         # at least warn (every retry!)
         self.log.warning(
             'Sensor value %s outside sensible range [%s..%s]' %
             (value, self.limits[0], self.limits[1]))
     # 10 times no good value -> error
     raise PositionError('Sensor value %s outside sensible range [%s..%s]' %
                         (value, self.limits[0], self.limits[1]))
コード例 #15
0
 def _mapReadValue(self, pos):
     """Override default inverse mapping to allow a deviation <= precision"""
     for name, values in iteritems(self.mapping):
         value, prec = values
         if pos == value:
             return name
         elif prec:
             if abs(pos - value) <= prec:
                 return name
     if self.fallback is not None:
         return self.fallback
     raise PositionError(self, 'unknown position of %s: %s' %
                         (self._attached_moveable,
                          self._attached_moveable.format(pos, True))
                         )
コード例 #16
0
    def _mapReadValue(self, value):
        """Hook for integration of mapping/switcher devices.

        This method is called with the value returned by `._readRaw()` and
        should map the raw value to a high-level value.  By default, it maps
        values according to the reverse of the
        `nicos.core.mixins.HasMapping.mapping` parameter.
        """
        if value in self._inverse_mapping:
            return self._inverse_mapping[value]
        elif self.relax_mapping:
            if self.fallback is not None:
                return self.fallback
        else:
            raise PositionError(self, 'unknown unmapped position %r' % value)
コード例 #17
0
 def _mapReadValue(self, pos):
     prec = self.precision
     if self._attached_table.read() != self.activeposition:
         return 'N.A.'
     for name, value in self.mapping.items():
         if prec:
             if abs(pos - value) <= prec:
                 return name
         elif pos == value:
             return name
     if self.fallback is not None:
         return self.fallback
     if self.relax_mapping:
         return self._attached_moveable.format(pos, True)
     raise PositionError(self,
                         'unknown position of %s' % self._attached_moveable)
コード例 #18
0
def test_error_handling(session, log, tas):
    # check that if one subdev errors out, we wait for the other subdevs
    mfh = session.getDevice('t_mfh')
    phi = session.getDevice('t_phi')

    tas.maw([1.01, 0, 0, 1])
    phi.speed = 1
    mfh._status_exception = PositionError(mfh, 'wrong position')
    with log.allow_errors():
        try:
            tas.maw([1, 0, 0, 1])
        except MoveError:
            pass
        else:
            assert False, 'PositionError not raised'
        # but we still arrived with phi
        assert phi() == approx(-46.6, abs=0.1)
コード例 #19
0
    def _move2start(self):
        self.log.info('Move %s for monochromator change',
                      ', '.join(sorted(self.changing_positions)))

        for dev, pos in self._changing_values.items():
            dev.start(pos)

        # multiWait(self._changing_values)
        multiWait(self._changing_values.keys())

        for dev, pos in self._changing_values.items():
            if abs(dev.read(0) - pos) > dev.precision:
                raise PositionError(
                    self, "'%s' did not reach target position "
                    "'%s'" % (dev, pos))

        for dev in self._changing_values:
            dev.fix('Monochromator change in progress')
コード例 #20
0
    def doStart(self, position):
        motor = self._attached_motor
        currentpos = self.read(0)
        motorpos = motor.read(0)

        if position == currentpos and motorpos == self.justpos:
            return

        if abs(motorpos - self.justpos) > 0.5:
            motorpos = motor.maw(0)

        self._attached_io_set.start(1 if position == 'in' else 0)
        if self.wait() != position:
            raise PositionError(self, 'device returned wrong position')

        if (self.doStatus()[0] == status.OK) and (motorpos != self.justpos):
            motorpos = motor.maw(self.justpos)
            self.log.info('rotation angle of filter: %s',
                          motor.format(motorpos, unit=True))
コード例 #21
0
ファイル: monochromator.py プロジェクト: umithardal/nicos
    def doRead(self, maxage=0):
        pos = [d.read(maxage) for d in self.devices]

        # Are we in the beam?
        if pos[0] == 'out':
            return None

        # calculate lambda from phi1 and then check the other positions
        # for consistency...
        lam = self._to_lambda(*pos[1:])
        self.log.debug('lambda seems to be %.4f Angstroms', lam)
        compare_pos = self._from_lambda(lam)
        tol = [self.tolphi, self.tolphi, self.toltrans]
        for d, p, t, c in zip(self.devices[1:], pos[1:], tol, compare_pos):
            self.log.debug('%s is at %s and should be at %s for %.4f '
                           'Angstroms', d, d.format(p), d.format(c), lam)
            if abs(p-c) > t:
                raise PositionError('%s is too far away for %.4f Angstroms' %
                                    (d, lam))
        return lam
コード例 #22
0
    def doStart(self, value):
        if value == 'off':
            if self._attached_daq.mode == 'tof':  # don't touch realtime
                self._attached_daq.mode = 'standard'
            self._attached_params.start((0, 0))
            return
        elif value == 'manual':
            if self._attached_daq.mode == 'standard':
                self._attached_daq.mode = 'tof'
            return
        reso = float(value.strip('%')) / 100.0

        sel_target = self._attached_selector.target
        det_target = self._attached_det_pos.target
        try:
            lam = self._attached_selector.presets[sel_target]['lam']
            spread = self._attached_selector.presets[sel_target]['spread']
            det_z = self._attached_det_pos.presets[sel_target][det_target]['z']
            det_offset = self._attached_det_pos.offsets[det_z]
        except KeyError:
            raise PositionError(
                self, 'cannot calculate chopper settings: selector or '
                'detector device not at preset') from None

        self.log.debug('chopper calc inputs: reso=%f, lam=%f, spread=%f, '
                       'det_z=%f', reso, lam, spread, det_z)
        freq, opening = calculate(lam, spread, reso, self.shade,
                                  20.0 + det_z + det_offset,
                                  self.tauoffset, self.nmax)
        self.log.debug('calculated chopper settings: freq=%f, opening=%f',
                       freq, opening)
        interval = int(1000000.0 / (freq * self.channels))
        self.calcresult = freq, opening, interval

        self._attached_params.start((freq, opening))

        self._attached_daq.mode = 'tof'
        self._attached_daq.tofchannels = self.channels
        self._attached_daq.tofinterval = interval
        self._attached_daq.tofprogression = 1.0  # linear channel widths
        self._attached_daq.tofcustom = []  # no custom channels
コード例 #23
0
    def _finalize(self):
        """Will be called after a successful monochromator change."""
        # test this!
        # self.log.debug('Enabling Powerstages for %s',
        #                ', '.join(sorted(self.changing_positions)))
        # for dev in self._changing_values:
        #     dev.power = 'on'

        self.log.info('releasing mono devices')
        # self._attached_monochromator.release()
        for dev in self._changing_values:
            dev.release()
        self.log.info('move mono devices to the nominal positions')
        for dev, pos in self._init_values.items():
            dev.start(pos)

        multiWait(self._init_values.keys())

        for dev, pos in self._init_values.items():
            if abs(dev.read(0) - pos) > dev.precision:
                raise PositionError(
                    self, "'%s' did not reach target position "
                    "'%s'" % (dev, pos))
コード例 #24
0
 def doRead(self, maxage=0):
     if self.target in self.states:
         return self.target
     raise PositionError(self, 'device is in an unknown state')