def _getPositions(self, target): if self.opmode == '4blades': if len(target) != 4: raise InvalidValueError(self, 'arguments required for 4-blades ' 'mode: [left, right, bottom, top]') positions = list(target) elif self.opmode == '4blades_opposite': if len(target) != 4: raise InvalidValueError(self, 'arguments required for 4-blades ' 'mode: [left, right, bottom, top]') positions = [-target[0], target[1], -target[2], target[3]] elif self.opmode == 'centered': if len(target) != 2: raise InvalidValueError(self, 'arguments required for centered ' 'mode: [width, height]') positions = [-target[0]/2., target[0]/2., -target[1]/2., target[1]/2.] else: if len(target) != 4: raise InvalidValueError(self, 'arguments required for ' 'offcentered mode: [xcenter, ycenter, ' 'width, height]') positions = [target[0] - target[2]/2., target[0] + target[2]/2., target[1] - target[3]/2., target[1] + target[3]/2.] return positions
def __start_tube_stick(self, tubetarget, sticktarget): ok, why = self._attached_tube.isAllowed(tubetarget) if not ok: raise InvalidValueError(self, why) ok, why = self._attached_stick.isAllowed(sticktarget) if not ok: raise InvalidValueError(self, why) self.log.debug('Moving %s to %r and %s to %r', self._attached_tube.name, tubetarget, self._attached_stick, sticktarget) try: self._attached_tube.start(tubetarget) finally: self._attached_stick.start(sticktarget)
def doWriteStopdelay(self, value): if self._hwtype == 'single': self._attached_bus.send(self.addr, 58, int(value * 10), 3) else: raise InvalidValueError(self, 'stopdelay not supported by card') self.log.info('parameter change not permanent, use _store() ' 'method to write to EEPROM')
def _mapTargetValue(self, target): if target not in self.mapping: positions = ', '.join(repr(pos) for pos in self.mapping) raise InvalidValueError(self, '%r is an invalid position for ' 'this device; valid positions are %s' % (target, positions)) return self.mapping.get(target)[0]
def doWriteConfbyte(self, value): if self._hwtype == 'single': self._attached_bus.send(self.addr, 49, value, 3) else: raise InvalidValueError(self, 'confbyte not supported by card') self.log.info('parameter change not permanent, use _store() ' 'method to write to EEPROM')
def doWriteDivider(self, value): try: self._attached_bus.send(self.addr, 60, value, 3) except InvalidCommandError as err: raise InvalidValueError(self, 'divider not supported by card') from err self.log.info('parameter change not permanent, use _store() ' 'method to write to EEPROM')
def doWriteEnergytransferunit(self, val): if val not in ENERGYTRANSFERUNITS: raise InvalidValueError(self, 'invalid energy transfer unit: %r' % val) if self._cache: self._cache.invalidate(self, 'value') self.unit = 'rlu rlu rlu %s' % val self.E.unit = val
def doEnable(self, on): if not on: if self.curstatus[0] != status.OK: raise InvalidValueError(self, 'cannot disable busy device') self.curstatus = (status.DISABLED, 'disabled') else: if self.curstatus[0] == status.DISABLED: self.curstatus = (status.OK, 'idle')
def doIsAllowed(self, target): if len(target) != 2: raise InvalidValueError(self, 'arguments required for centered ' 'mode: [width, height]') for slit, slitname, pos in zip(self._slits, self._slitnames, target): ok, why = slit.isAllowed(pos) if not ok: return ok, '[%s slit] %s' % (slitname, why) return True, ''
def _startRaw(self, target): """target is the raw value, i.e. a list of positions""" moveables = self._attached_moveables if not isinstance(target, (tuple, list)) or \ len(target) < len(moveables): raise InvalidValueError(self, 'doStart needs a tuple of %d ' 'positions for this device!' % len(moveables)) # only check and move the moveables, which are first in self.devices for d, t in zip(moveables, target): if not d.isAllowed(t): raise InvalidValueError(self, 'target value %r not accepted ' 'by device %s' % (t, d.name)) for d, t in zip(moveables, target): self.log.debug('moving %r to %r', d, t) d.start(t) if self.blockingmove: multiWait(moveables)
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 set(self, number, parameters): """Set sample information for sample no. *number*.""" if number is None: raise InvalidValueError(self, 'cannot use None as sample number') info = self.samples.copy() if number in info: self.log.warning('overwriting parameters for sample %s (%s)', number, info[number]['name']) info[number] = parameters self.samples = info
def select(self, number_or_name): """Select sample with given number or name.""" number = self._findIdent(number_or_name) try: parameters = self.samples[number] except KeyError: raise InvalidValueError( self, 'cannot find sample with number or name %r' % number_or_name) from None self._applyParams(number, parameters) session.experiment.newSample(parameters) self.poll()
def doIsAllowed(self, value): if len(value) != 11: raise InvalidValueError(self, 'list must have 11 entries') # map everything to 0 or 1 value = [bool(v) for v in value] # check allowed positions if value == [True] * 11: # open everything is allowed return True, '' if sum(value) > 2: return False, 'cannot open more than 2 chevrons' if value[0] or value[10]: return False, 'cannot open first or last chevron' return True, ''
def doWriteMicrostep(self, value): if self._hwtype == 'single': if value == 1: self._attached_bus.send(self.addr, 36) elif value == 2: self._attached_bus.send(self.addr, 37) else: raise InvalidValueError( self, 'microsteps > 2 not supported by card') else: self._attached_bus.send(self.addr, 57, [1, 2, 4, 8, 16].index(value), 3) self.log.info('parameter change not permanent, use _store() ' 'method to write to EEPROM')
def queryUser(user): """Query the FRM II proposal database for the user ID and password hash.""" with ProposalDB() as cur: count = cur.execute( ''' SELECT user_id, user_password FROM nuke_users WHERE username=%s ''', (user, )) if count == 0: raise InvalidValueError('user %s does not exist in the user ' 'office database' % (user, )) row = cur.fetchone() uid = int(row[0]) password = row[1] return uid, password
def _mapTargetValue(self, target): """Hook for integration of mapping/switcher devices. This method is called to get a value to pass to `._startRaw()` and should map the high-level value to a raw value. By default, it maps values according to the `nicos.core.mixins.HasMapping.mapping` parameter. """ if not self.relax_mapping: # be strict... if target not in self.mapping: positions = ', '.join(repr(pos) for pos in self.mapping) raise InvalidValueError( self, '%r is an invalid position for ' 'this device; valid positions are %s' % (target, positions)) return self.mapping.get(target, target)
def _findIdent(self, number_or_name): """Find sample number. Can be overridden in subclasses.""" # look by number if number_or_name in self.samples: return number_or_name # look by name found = None for (number, parameters) in self.samples.items(): if parameters['name'] == number_or_name: if found is not None: # two samples with same name found... raise InvalidValueError( self, 'two samples with name %r ' 'were found, please use the ' 'sample number (%s or %s)' % (number_or_name, found, number)) found = number return found
def test_slit_reference(session, log): slit = session.getDevice('slit') slit.opmode = '4blades' slit.maw([10, 10, 10, 10]) with log.assert_warns('m_top cannot be referenced'): slit.reference() # left and right should be referenced assert slit.read(0) == [0, 0, 10, 10] # this one references in parallel slit3 = session.getDevice('slit3') slit3.opmode = '4blades' slit3.maw([10, 10, 10, 10]) slit3.reference() assert slit3.read(0) == [0, 0, 10, 10] slit3.left._ref_error = InvalidValueError('invalid') with log.assert_errors('invalid'): assert raises(MoveError, slit3.reference)
def doStart(self, rpos): if rpos > sum(self.blades): raise InvalidValueError(self, 'Value %d too big!, maximum is %d' % (rpos, sum(self.blades))) which = 0 pos = rpos # start with biggest blade and work downwards, ignoring disabled blades for bladewidth in reversed(self.blades): if bladewidth and pos >= bladewidth: which |= 1 << self.blades.index(bladewidth) pos -= bladewidth if pos != 0: self.log.warning('Value %d impossible, trying %d instead!', rpos, rpos + 1) return self.start(rpos + 1) self._attached_output.move(which) if self.readout == 'output': # if we have no readback, give blades time to react session.delay(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')
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 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 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 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 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 doStart(self, value): # filter unsupported echotimes # find best match from table for entry in self.currenttable: if abs(entry - value) < 1e-12: value = entry break else: raise InvalidValueError( 'Given echo time not supported by current ' 'tunewave table (%s/%s) within %s' % (getattr(session.experiment, 'measurementmode', 'mieze'), self._attached_wavelength.read(), self.wavelengthtolerance)) # stop stopfirst devices for devname in self.stopfirst: dev = session.getDevice(devname) self.log.debug('stopping %s', str(dev)) dev.stop() # move zerofirst devices to configured value self.log.debug('zeroing devices') wait_on = set() for devname, val in self.zerofirst.items(): dev = session.getDevice(devname) self.log.debug('moving %s to zero', str(dev)) dev.start(val) wait_on.add(dev) self.log.debug('waiting for devices to reach zero') multiWait(wait_on) self.log.debug('devices now at zero') # move all tuning devices at once without blocking wait_on = set() for tunedev, val in sorted(iteritems(self.currenttable[value])): if tunedev in self.stopfirst: self.log.debug('skipping %s (will be set later)', tunedev) continue if tunedev in self._tunedevs: self.log.debug('setting %s to %s', tunedev, val) dev = self._tunedevs[tunedev] dev.start(val) wait_on.add(dev) else: self.log.warning('tune device %r from table not in tunedevs! ' 'movement to %r ignored !' % (tunedev, val)) self.log.debug('waiting for devices...') multiWait(wait_on) self.log.debug('devices now at configured values') # activate stopfirst devices wait_on = set() for devname in self.stopfirst: dev = session.getDevice(devname) val = self.currenttable[value][devname] self.log.debug('moving %s to %s', devname, val) dev.move(val) wait_on.add(dev) self.log.debug('devices now at configured values') multiWait(wait_on) self.log.debug('all done. good luck!')
def queryProposal(pnumber, instrument=None): """Query the FRM II proposal database for information about the given proposal number. """ if not isinstance(pnumber, integer_types): raise InvalidValueError('proposal number must be an integer') # check still needed? if session.instrument is None: raise InvalidValueError('cannot query proposals, no instrument ' 'configured') with ProposalDB() as cur: # get proposal title and properties cur.execute( ''' SELECT xname, mname, value FROM Proposal, Proposal_members, Proposal_values WHERE xid = %s AND xid = _xid AND mid = _mid ORDER BY abs(mid-4.8) ASC''', (pnumber, )) rows = cur.fetchall() # get real instrument name cur.execute( ''' SELECT instruments.name FROM frm2_tita_instruments, instruments WHERE instruments.id = iid and proposal_id = %s ORDER BY start ASC''', (pnumber, )) instrumentnames = ','.join(instr[0] for instr in cur.fetchall()).lower() # get user info cur.execute( ''' SELECT name, user_email, institute1 FROM nuke_users, Proposal WHERE user_id = _uid AND xid = %s''', (pnumber, )) userrow = cur.fetchone() # get security and radiation permissions cur.execute( ''' SELECT sec_ok, rad_ok FROM frm2_survey_comments WHERE _pid = %s''', (pnumber, )) permissions = cur.fetchone() if not rows or len(rows) < 3: raise InvalidValueError('proposal %s does not exist in database' % pnumber) if not userrow: raise InvalidValueError('user does not exist in database') if not permissions: raise InvalidValueError('no permissions entry in database') instrumentnames = instrumentnames.replace('poli-heidi', 'poli') instrumentnames = instrumentnames.replace('kws ', 'kws-') instruments = set(instrumentnames.split(',')) if instrument is not None and (instrument.lower() not in instruments): session.log.error( 'proposal %s is not a proposal for ' '%s, but for %s, cannot use proposal information', pnumber, instrument, '/'.join(instruments)) # avoid data leakage return instrument, {'wrong_instrument': instruments} # structure of returned data: (title, user, prop_name, prop_value) info = { 'instrument': instrument, 'instruments': instruments, 'title': rows[0][0], 'user': userrow[0], 'user_email': userrow[1], 'affiliation': userrow[2], 'permission_security': ['no', 'yes'][permissions[0]], 'permission_radiation_protection': ['no', 'yes'][permissions[1]], } for row in rows: # extract the property name in a form usable as dictionary key key = row[1][4:].lower().replace('-', '_') value = row[2] if value and key not in info: info[key] = value # convert all values to utf-8 for k in info: info[k] = text_type(info[k]).encode('utf-8') return info.pop('instrument', 'None'), info