def doStart(self, position): try: if self.doStatus()[0] != status.OK: raise NicosError(self, 'filter returned wrong position') if position == self.read(0): return if position == 'in': self._attached_io_set.move(1) elif position == 'out': self._attached_io_set.move(0) else: # shouldn't happen... self.log.info('PG filter: illegal input') return session.delay(2) if self.doStatus()[0] == status.ERROR: raise NicosError(self, 'PG filter is not readable, please ' 'check device!') finally: self.log.info('PG filter: %s', self.read(0))
def pos(*args, **kwds): """Move the instrument to a given (Q, E), or the last `calpos()` position. Without arguments, moves to the last position sucessfully calculated with `calpos()`. Examples: >>> pos() # last calpos() position >>> pos(1, 0, 0) # H, K, L >>> pos(1, 0, 0, -4) # H, K, L, E >>> pos(1, 0, 0, -4, 2.662) # H, K, L, E, scanconstant >>> pos(Q(1, 0, 0, -4)) # Q-E vector >>> pos(Q(1, 0, 0, -4), 2.662) # Q-E vector and scanconstant """ instr = session.instrument if not isinstance(instr, TAS): raise NicosError('your instrument device is not a triple axis device') if not args: pos = instr._last_calpos if pos is None: raise NicosError('pos() with no arguments moves to the last ' 'position calculated by calpos(), but no such ' 'position has been stored') else: pos = _convert_qe_args(args, kwds, 'pos') instr._calpos(pos, checkonly=False) if pos[5] and pos[5] != instr.scanmode: instr.scanmode = pos[5] if pos[4] and pos[4] != instr.scanconstant: instr.scanconstant = pos[4] maw(instr, pos[:4])
def doRead(self, maxage=0): img = self._op.open('http://miracam.mira.frm2/IMAGE.JPG').read() open('/tmp/radmon.jpg', 'wb').write(img) p1 = createSubprocess( '/usr/local/bin/ssocr -d 3 -i 1 -t 50 -l maximum ' 'rotate 1 crop 300 157 57 30 ' 'make_mono invert keep_pixels_filter 5 ' '/tmp/radmon.jpg'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) p2 = createSubprocess( '/usr/local/bin/ssocr -d 1 -i 1 -t 50 -l maximum ' 'rotate 1 crop 391 125 20 30 ' 'make_mono invert keep_pixels_filter 5 ' '/tmp/radmon.jpg'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) out1, err1 = p1.communicate() out2, err2 = p2.communicate() out1 = out1.strip() out2 = out2.strip() self.log.warning('out1=%r, out2=%r', out1, out2) if err1: raise NicosError(self, 'ERROR in mantissa') if err2: raise NicosError(self, 'ERROR in exponent') return 0.01 * float(out1 + b'e-' + out2) * 1e6 # convert to uSv/h
def chrun(self, ch, speed=0): ds = round(speed) if ds < -22000 or ds > 22000: raise NicosError(self, 'disc speed out of safety limits') self._discSpeed = ds / 7.0 if ch < 1 or ch > 7: raise NicosError(self, 'invalid chopper number') self._attached_discs[ch].move(ds) self._setROParam('changetime', currenttime())
def doRead(self, maxage=0): if parse is None: raise NicosError(self, 'cannot parse web page, lxml is not ' 'installed on this system') try: tree = parse(URL % self.station) return ', '.join(n.text for n in tree.findall('//td[@class="inMinColumn"]')) except Exception as err: raise NicosError(self, 'MVG site not responding or changed format:' ' %s' % err)
def ScanList(peaklist, preset=1., scanmode=None): instr = session.instrument if not isinstance(instr, SXTalBase): raise NicosError('your instrument device is not a SXTAL device') if scanmode is None: scanmode = instr.scanmode if not isinstance(peaklist, list): lst = session.experiment.sample.peaklists.get(peaklist) if lst is None: raise NicosError('no peak list named %s found' % peaklist) pos = [[v] for v in peaklist] HKLScan([instr], pos, scanmode=scanmode, preset={'t': preset}).run()
def _RunScript(filename, statdevices, debug=False): fn = _scriptfilename(filename) if not path.isfile(fn) and os.access(fn, os.R_OK): raise UsageError('The file %r does not exist or is not readable' % fn) if session.mode == SIMULATION: starttime = session.clock.time for dev in statdevices: if not isinstance(dev, Readable): session.log.warning('unable to collect statistics on %r', dev) continue dev._sim_min = None dev._sim_max = None session.log.info('running user script: %s', fn) try: fp = io.open(fn, 'r', encoding='utf-8') except Exception as e: if session.mode == SIMULATION: session.log.exception('Dry run: error opening script') return raise NicosError('cannot open script %r: %s' % (filename, e)) with fp: code = fp.read() # guard against bare excepts code = fixupScript(code) # quick guard against self-recursion if session.experiment and session.experiment.scripts and \ code.strip() == session.experiment.scripts[-1].strip(): raise NicosError('script %r would call itself, aborting' % filename) def compiler(src): return compile(src + '\n', fn, 'exec', CO_DIVISION) compiled = session.scriptHandler(code, fn, compiler) with _ScriptScope(path.basename(fn), code): try: exec_(compiled, session.namespace) except Exception: if debug: traceback.print_exc() raise session.log.info('finished user script: %s', fn) if session.mode == SIMULATION: session.log.info('simulated minimum runtime: %s', formatDuration(session.clock.time - starttime, precise=False)) for dev in statdevices: if not isinstance(dev, Readable): continue session.log.info('%s: min %s, max %s, last %s %s', dev.name, dev.format(dev._sim_min), dev.format(dev._sim_max), dev.format(dev._sim_value), dev.unit)
def _newCheckHook(self, proptype, proposal): # check if user may start this proposal if self.ghost is None: return # no way to check if proptype == 'user': if not self.ghost.canStartProposal(proposal): raise NicosError(self, 'Current user may not start this ' 'proposal') elif proptype == 'other': if not self.ghost.isLocalContact(): raise NicosError( self, 'Current user may not start a ' 'non-user proposal')
def test_status(self, session, log): """Check status() command.""" motor = session.getDevice('motor') coder = session.getDevice('coder') tdev = session.getDevice('tdev') tdev._status_exception = NicosError('expected failed status') tdev._read_exception = NicosError('expected failed read') status() status(motor, coder, tdev) with log.assert_errors('expected failed read'): tdev._status_exception = None tdev.warnlimits = [-4.99, 4.99] status(tdev) tdev._status_exception = NicosError('expected failed status')
def _findsetting(self, target): if not self.tuning: raise NicosError(self, 'no tuning selected, use %s.usetuning(name)' ' to select a tuning table' % self) if not isinstance(target, int): for idx, setting in enumerate(self.curtable): if setting['_name_'] == target: target = idx break else: raise NicosError(self, 'no such MIEZE setting: %r' % (target,)) if not 0 <= target < len(self.curtable): raise NicosError(self, 'no such MIEZE setting: %r' % target) return target
def _HW_rawCommand(self, cmd, par=0): if cmd not in self._HW_CMDS: raise ValueError('Command code %r not supported, check code and ' 'docu!' % cmd) cmd = int(self._HW_CMDS.get(cmd, cmd)) pswd = 16082008 + ((int(cmd) + int(par)) % 228) self.log.debug('Initiate command %d with par %d and pswd %d', cmd, par, pswd) self._writeU32(16, int(par)) self._writeU32(12, int(pswd)) self._writeU32(14, int(cmd)) self.log.debug('checking reaction') session.delay(0.1) for _ in range(10): ack = bool(self._HW_readACK()) nack = bool(self._HW_readNACK()) self.log.debug('%s %s', ack, nack) if ack and not nack: self.log.debug('Command accepted') return elif nack and not ack: raise NicosError('Command rejected by Beckhoff') raise NicosTimeoutError('Command not recognized by Beckhoff within 1s!')
def doPreinit(self, mode): ''' Constructor ''' # the hardware will use a dummy driver if no hardware is detected if HuberScan is None: raise NicosError( self, 'Nonius scan libraries not found on this ' 'system, cannot use ResiDevice') self._hardware = HuberScan() try: self._hardware.LoadRmat() except RuntimeError as e: print(e) print( 'Setting a default cell (quartz): 4.9287,4.9827,5.3788, 90,90,120' ) self._hardware.SetCellParam(a=4.9287, b=4.9287, c=5.3788, alpha=90.000, beta=90.000, gamma=120.000) self._hardware.cell.conventionalsystem = 'triclinic' self._hardware.cell.standardize = 0 self._hardware.cell.pointgroup = '1' self._hardware.bisect.cell = self._hardware.cell ResiPositionProxy.SetHardware(self._hardware)
def manualscan(*args, **kwargs): """"Manual" scan where no devices are moved automatically. An example usage:: with manualscan(device, otherdevice): for i in range(10): if otherdevice.read() < 15: raise NicosError('cannot continue') maw(device, i+1) count(t=600) This example mimicks a regular `scan()`, with the exception that before every point the value of another device is checked for validity. The arguments to `manualscan()` can be are: * detector devices, to use these for counting * other devices, to read them at every scan point * presets, in the form accepted by the other scan commands Within the ``with manualscan`` block, call `count()` (using the default preset) or ``count(presets...)`` whenever you want to measure a point. """ if getattr(session, '_manualscan', None): raise NicosError('cannot start manual scan within manual scan') return _ManualScan(args, kwargs)
def pos2hkl(phi=None, psi=None, **kwds): """Calculate (Q, E) for a given instrument position. Without arguments, prints the current (Q, E). ``rp()`` is an alias. >>> pos2hkl() >>> rp() The first two arguments are the sample 2-theta and theta angles. The mono and ana values can be left out to use the current values: >>> pos2hkl(41.5, 29.2) # phi and psi at current mono/ana position You can also give a certain energy, which uses the current scan mode and constant to calculate ki and kf: >>> pos2hkl(41.5, 29.2, E=2) Finally, you can give explicit values for ki and kf: >>> pos2hkl(41.5, 29.2, ki=1.83, kf=1.56) """ instr = session.instrument if not isinstance(instr, TAS): raise NicosError('your instrument device is not a triple axis device') if not phi: read(instr) else: instr._reverse_calpos(phi, psi, **kwds)
def calpos(*args, **kwds): """Calculate instrument position for a given (Q, E) position. Can be called with 3 to 5 arguments: >>> calpos(1, 0, 0) # H, K, L >>> calpos(1, 0, 0, -4) # H, K, L, E >>> calpos(1, 0, 0, -4, 2.662) # H, K, L, E, scanconstant or with a Q-E vector: >>> calpos(Q(1, 0, 0, -4)) # Q-E vector >>> calpos(Q(1, 0, 0, -4), 2.662) # Q-E vector and scanconstant Constant ki or kf can be given as keywords: >>> calpos(1, 0, 0, 4, kf=1.5) """ instr = session.instrument if not isinstance(instr, TAS): raise NicosError('your instrument device is not a triple axis device') if not args: raise UsageError('calpos() takes at least one argument') pos = _convert_qe_args(args, kwds, 'calpos') instr._calpos(pos)
def asB(self, wavelength=None): if wavelength is None: wavelength = session.instrument.wavelength or None if not wavelength: raise NicosError( "Cannot perform conversion without knowing wavelength") cosx = np.sqrt(self.c[0]**2 + self.c[1]**2) chi = np.arctan2(self.c[2], cosx) if cosx < 1.0E-6: phi = 0.0 else: try: phi = np.arctan2(-self.c[0], self.c[1]) except ValueError: print("Oops: ", self) phi = 0 sinx = np.sqrt(cosx**2 + self.c[2]**2) * wavelength / 2.0 if sinx >= 1.0: theta = self.signtheta * np.pi / 2.0 else: theta = self.signtheta * np.arcsin(sinx) if self.signtheta < 0: phi = phi + np.deg2rad(180) chi = -chi return PositionFactory(ptype='br', theta=normalangle(theta), phi=normalangle(phi), chi=normalangle(chi), psi=self.psi)
def doStart(self, value): r1, r2 = value for val in self.reflex1, self.reflex2, self.angles1, self.angles2: if all(v == 0 for v in val): raise NicosError(self, 'Please first set the Eulerian cradle ' 'orientation with the reflex1/2 and ' 'angles1/2 parameters') sense = self._attached_tas.scatteringsense[1] self._omat = self.calc_or(sense) ang = self.euler_angles(r1, r2, 2, 2, sense, self._attached_chi.userlimits, self._attached_omega.userlimits) psi, chi, om, _phi = ang self.log.debug('euler angles: %s', ang) self.log.info('moving %s to %12s, %s to %12s', self._attached_chi, self._attached_chi.format(chi, unit=True), self._attached_omega, self._attached_omega.format(om, unit=True)) self._attached_chi.move(chi) self._attached_omega.move(om) self._attached_chi.wait() self._attached_omega.wait() self._attached_cell.orient1 = r1 self._attached_cell.orient2 = r2 wantpsi = self._attached_cell.cal_angles( r1, 0, 'CKF', 2, sense, self._attached_tas.axiscoupling, self._attached_tas.psi360)[3] self._attached_cell.psi0 += wantpsi - psi
def doPreinit(self, _mode): # Stop creation of the FITSImageSink as it would make no sense # without pyfits. if pyfits is None: raise NicosError( self, 'pyfits module is not available. Check' ' if it is installed and in your PYTHONPATH')
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 doPreinit(self, _mode): # Stop creation of the TIFFLaueFileFormat as it would make no sense # without correct PIL version. if Image is None: raise NicosError( self, 'PIL/Pillow module is not available. Check' ' if it\'s installed and in your PYTHONPATH')
def doStart(self, pos): if self.curvalue > pos: # going backwards if self._refswitch(): raise NicosError( self, 'Can\'t go backwards, Limit-switch is ' 'active!') return VirtualMotor.doStart(self, pos)
def doInit(self, mode): phases = [0, 0] self._dev = self._attached_io try: if mode == SIMULATION: raise NicosError('not possible in dry-run/simulation mode') wavelength = self._read(WAVE_LENGTH) / 1000.0 if wavelength == 0.0: wavelength = 4.5 self._setROParam('wavelength', wavelength) self._setROParam('speed', round(self._read(SPEED) / 1118.4735)) self._setROParam('ratio', abs(self._read(RATIO))) slittype = self._read(SLIT_TYPE) if slittype == 2: # XXX this looks strange self._setROParam('slittype', 1) else: self._setROParam('slittype', 0) crc = self._read(CRM) if crc == 1: self._setROParam('crc', 0) else: self._setROParam('crc', 1) for ch in range(2, 8): phases.append( int(round(self._read(PHASE_SET + ch * 100) / 466.0378))) self._setROParam('phases', phases) except NicosError: self._setROParam('wavelength', 4.5) self._setROParam('speed', 0) self._setROParam('ratio', 1) self._setROParam('slittype', 0) self._setROParam('crc', 1) self._setROParam('phases', [0] * 8) self.log.warning('could not read initial data from PMAC chopper ' 'controller', exc=1)
def omscan(hkl, width=None, speed=None, timedelta=None, **kwds): """Perform a continuous omega scan at the specified Q point. The default scan width is calculated from the instrumental resolution. Examples: >>> omscan((1, 0, 0)) # with default with, speed and timedelta >>> omscan((1, 0, 0), 5) # with a width of 5 degrees >>> omscan((1, 0, 0), 5, 0.1, 1) # with width, speed and timedelta """ instr = session.instrument if not isinstance(instr, SXTalBase): raise NicosError('your instrument is not a sxtal diffractometer') if width is None: width = instr.getScanWidthFor(hkl) calc = dict(instr._extractPos(instr._calcPos(hkl))) om1 = calc['omega'] - width / 2. om2 = calc['omega'] + width / 2. cur_om = instr._attached_omega.read() if abs(cur_om - om1) > abs(cur_om - om2): om1, om2 = om2, om1 maw(instr._attached_gamma, calc['gamma'], instr._attached_nu, calc['nu'], instr._attached_omega, om1) contscan(instr._attached_omega, om1, om2, speed, timedelta)
def calc_plane(self, r1, r2=None): """Calculate chi and omega angles to get a scattering plane in which the two given reflexes lie. Example: >>> ec.calc_plane([1, 0, 0], [2, 1, 0]) """ if r2 is None: r1, r2 = r1 for val in self.reflex1, self.reflex2, self.angles1, self.angles2: if all(v == 0 for v in val): raise NicosError(self, 'Please first set the Eulerian cradle ' 'orientation with the reflex1/2 and ' 'angles1/2 parameters') sense = self._attached_tas.scatteringsense[1] self._omat = self.calc_or(sense) ang = self.euler_angles(r1, r2, 2, 2, sense, self._attached_chi.userlimits, self._attached_omega.userlimits) self.log.info('found scattering plane') self.log.info('%s: %20s', self._attached_chi, self._attached_chi.format(ang[1], unit=True)) self.log.info('%s: %20s', self._attached_omega, self._attached_omega.format(ang[2], unit=True))
def _getRaw(self): if parse is None: raise NicosError( self, 'cannot parse web page, lxml is not ' 'installed on this system') url = 'http://%s/web?group=%d' % (self.hostname, self.group) try: tree = parse(url) names = [ name.text.strip() for name in tree.findall('//font[@class="tagname"]') ] values = [ value.text.strip() for value in tree.findall('//font[@class="pv"]') ] info = dict(zip(names, values)) if self.valuename not in info: raise ConfigurationError( self, 'value %r not found on ' 'Memograph page (valid values are %s)' % (self.valuename, ', '.join(map(repr, names)))) return info[self.valuename] except ConfigurationError: # pass through error raised above raise except Exception as err: raise CommunicationError( self, 'Memograph not responding or ' 'changed format: %s' % err)
def _taco_guard_nolog(self, function, *args): """Try running the TACO function, and raise a NicosError on exception. A more specific NicosError subclass is chosen if appropriate. For example, database-related errors are converted to `.CommunicationError`. A TacoDevice subclass can add custom error code to exception class mappings by using the `.taco_errorcodes` class attribute. If the `comtries` parameter is > 1, the call is retried accordingly. """ if not self._dev: raise NicosError(self, 'TACO device not initialised') self._com_lock.acquire() try: return function(*args) except TACOError as err: # for performance reasons, starting the loop and querying # self.comtries only triggers in the error case if self.comtries > 1 or err == DevErr_RPCTimedOut: tries = 2 if err == DevErr_RPCTimedOut and self.comtries == 1 \ else self.comtries - 1 self.log.warning('TACO %s failed, retrying up to %d times', function.__name__, tries) while True: session.delay(self.comdelay) tries -= 1 try: return function(*args) except TACOError as err: if tries == 0: break # and fall through to _raise_taco self._raise_taco(err, '%s%r' % (function.__name__, args)) finally: self._com_lock.release()
def doRead(self, maxage=0): result = self._attached_io_status.doRead(0) if result == 2: return 'in' elif result == 1: return 'out' else: raise NicosError(self, 'PG filter is not readable, check device!')
def doWriteTimeconstant(self, value): if value not in TIMECONSTANTS: raise ConfigurationError(self, 'invalid time constant, valid ones ' 'are ' + ', '.join(map(str, TIMECONSTANTS))) value = TIMECONSTANTS.index(value) self._dev.WriteLine('OFLT %d' % value) if self.doReadTimeconstant() != value: raise NicosError(self, 'setting new time constant failed')
def removetuning(self, name): """Delete a tuning table.""" if name not in self.tunetables: raise NicosError(self, 'tuning %r not found in tables' % name) tables = self.tunetables.copy() del tables[name] self.tunetables = tables self.log.info('tuning %r removed', name)
def doReset(self): speed = sum(self._readspeeds()) if speed > 0.5: raise NicosError( self, 'Attention: It is strictly forbidden to ' 'reset the chopper system if one or more discs ' 'are running!') self._setROParam('changetime', currenttime())