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 _setfield(self, B=np.array([0, 0, 0])): r"""Set the given field. Field components are: * Bqperp: component perpendicular to q, but within the scattering plane * Bqpar: component parallel to q (within scattering plane) * Bz: component perpendicular to the scattering plane (If TwoTheta==0 & \\hbar\\omega=0 then this coordinate-system is the same as the XYZ of the coils.) """ # subtract offset (The field, which is already there, doesn't need to # be generated....) B = B - np.array(self.background) F = self._B2I(B) # compute currents for requested field # now check limits valueOk = True for i, d in enumerate(self.coils): check = d.isAllowed(F[i]) if not check[0]: self.log.error('Can\'t set %s to %s: %s', d, d.format(F[i], unit=True), check[1]) valueOk = False if not valueOk: raise LimitError(check[1]) # go there for i, d in enumerate(self.coils): d.start(F[i])
def _calc_angles(self, k): try: angle = thetaangle(self.dvalue, self.order, k) except ValueError: raise LimitError( self, 'wavelength not reachable with d=%.3f A ' 'and n=%s' % (self.dvalue, self.order)) tt = 2.0 * angle * self.scatteringsense # twotheta with correct sign th = angle * self.scatteringsense # absolute theta with correct sign th = (angle - 90.0) * self.scatteringsense + 90.0 * self.crystalside # correct for theta axis mounted on top of two-theta table if self.reltheta: th -= tt return th, tt
def _calpos(self, pos, printout=True, checkonly=True): qh, qk, ql, ny, sc, sm = pos ny = self._thz(ny) if sm is None: sm = self.scanmode if sc is None: sc = self.scanconstant try: angles = self._attached_cell.cal_angles([qh, qk, ql], ny, sm, sc, self.scatteringsense[1], self.axiscoupling, self.psi360) except ComputationError as err: if checkonly: self.log.error('cannot calculate position: %s', err) return else: raise if not printout: return angles ok, why = True, '' for devname, value in zip(['mono', 'ana', 'phi', 'psi', 'alpha'], angles): dev = self._adevs[devname] if dev is None: continue if isinstance(dev, Monochromator): devok, devwhy = dev.isAllowed(from_k(value, dev.unit)) else: 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('ki: %8.3f A-1', angles[0]) if self.scanmode != 'DIFF': self.log.info('kf: %8.3f A-1', angles[1]) self.log.info('2theta sample: %8.3f deg', angles[2]) self.log.info('theta sample: %8.3f deg', angles[3]) if self._attached_alpha is not None: self.log.info('alpha: %8.3f deg', angles[4]) if ok: self._last_calpos = pos 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 _calpos(self, hkl, checkonly=True): """Implements the calpos() command.""" try: poslist = self._extractPos(self._calcPos(hkl)) except Exception as err: return False, str(err) ok, why = self._checkPosList(poslist) 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 _field2current(self, field): """Return required current in A for requested field in T. Note: This may be overridden in derived classes. """ # binary search/bisection maxcurr = self._attached_currentsource.abslimits[1] mincurr = -maxcurr maxfield = self._current2field(maxcurr) minfield = self._current2field(mincurr) if not minfield <= field <= maxfield: raise LimitError( self, 'requested field %g %s out of range %g..%g %s' % (field, self.unit, minfield, maxfield, self.unit)) res = fsolve(lambda cur: self._current2field(cur) - field, 0)[0] self.log.debug('current for %g %s is %g', field, self.unit, res) return res
def check(self): res = self.dev.isAllowed(self.target) if not res[0]: raise LimitError(self.dev, res[1])