def asB(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ sineps = np.sin(self.omega - self.theta) coseps = np.cos(self.omega - self.theta) if coseps < 0: signcb = -1.0 else: signcb = 1.0 coschi = np.cos(self.chi) sinchi = np.sin(self.chi) if self.theta < 0: signth = -1.0 else: signth = 1.0 sinchib = coseps * sinchi coschib = signcb * np.sqrt(coschi**2 + (sinchi * sineps)**2) chib = np.arctan2(sinchib, coschib) if sineps == 0 and coschi == 0: phib = 0 sinpsi = -signcb * np.sin(self.phi) * sinchi cospsi = signth * signcb * np.cos(self.phi) * coseps else: sinphi = -signcb * sineps cosphi = signcb * coseps * coschi phib = self.phi - np.arctan2(sinphi, cosphi) sinpsi = sinchi * sineps cospsi = signth * coschi psi = np.arctan2(sinpsi, cospsi) return PositionFactory(ptype='br', theta=self.theta, phi=normalangle(phib), chi=normalangle(chib), psi=normalangle(psi))
def asK(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ if not hasattr(self, 'alpha'): self.alpha = np.deg2rad(60) # TODO: get from experiment? self.kappamax = np.deg2rad(180) si = np.sin(0.5 * self.chi) co = np.sin(self.alpha)**2 - si**2 con3 = np.cos(self.kappamax / 2.0)**2 * np.sin(self.alpha)**2 if con3 > co: self.log.warning("Chi can not be reached on this hardware") kappa = np.deg2rad(180.0) omega = np.deg2rad(90.0) # raise error("Chi high") co = con3 co = np.sqrt(co) kappa = 2.0 * np.arctan2(si, co) si = si * np.cos(self.alpha) omega = np.arctan2(si, co) else: co = np.sqrt(co) kappa = 2.0 * np.arctan2(si, co) si = si * np.cos(self.alpha) omega = np.arctan2(si, co) phi = self.phi - omega omega = -omega + self.omega return PositionFactory(ptype='kr', theta=self.theta, omega=normalangle(omega), kappa=normalangle(kappa), phi=normalangle(phi))
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 doRead(self, maxage=0): return PositionFactory('k', ttheta=self._adevs['ttheta'].read(maxage), omega=self._adevs['omega'].read(maxage), kappa=self._adevs['kappa'].read(maxage), phi=self._adevs['phi'].read(maxage), )
def Alternate(self): """ The alternate N-position that has the same orientation. """ return PositionFactory(ptype='nr', omega=normalangle(self.omega + np.pi), theta=self.theta, chi=-self.chi, phi=normalangle(self.phi + np.pi))
def With(self, **kw): """ Make clone of this position with some angle(s) changed. """ if not kw.get('_rad', False): if kw.get('theta', None): kw['theta'] = np.deg2rad(kw['theta']) return PositionFactory(ptype='gr', theta=kw.get('theta', self.theta), matrix=kw.get('matrix', self.matrix))
def asG(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ # print >> sys.stderr, self return PositionFactory(ptype='gr', theta=self.theta, matrix=np.dot( Zrot(self.omega), np.dot(Xrot(self.chi), Zrot(self.phi))))
def With(self, **kw): """ Make clone of this position with some angle(s) changed. """ if not kw.get('_rad', False): if kw.get('psi', None): kw['psi'] = np.deg2rad(kw['psi']) return PositionFactory(ptype='cr', c=kw.get('c', self.c), signtheta=kw.get('signtheta', self.signtheta), psi=kw.get('psi', self.psi))
def asE(self, zeromega=0): """ Conversion. Part of Position subclass protocol. """ # The goniometermatrix from the eulerian angles= # Zrot(omega)*Xrot(chi)*Zrot(phi) # So, with a=cos(phi) # b=sin(phi) # c=cos(chi) # d=sin(chi) # e=cos(omega) # f=sin(omega) # The goniometermatrix matrix[0..2][0..2] is: # ( a -b 0 ) ( 1 0 0 ) ( e -f 0 ) # ( b a 0 ) * ( 0 c -d ) * ( f e 0 ) # ( 0 0 1 ) ( 0 d c ) ( 0 0 1 ) # or: # ( a -b 0 ) ( e -f 0 ) # ( b a 0 ) * ( fc ec -d ) # ( 0 0 1 ) ( fd ed c ) # or: # ( ae-bfc -fa-bec bd ) # ( be+afc -fb+aec -ad ) # ( fd ed c ) # or: coschi = self.matrix[2, 2] # Assume chi positive. try: sinchi = np.sqrt(1 - coschi**2) except ValueError: sinchi = 0.0 chi = np.arctan2(sinchi, coschi) if abs(sinchi) < 1.0e-10: # Choose omega to be 180 degrees (easily accessible) sinomega = 0.0 if zeromega: cosomega = 1.0 else: cosomega = -1.0 else: sinomega = self.matrix[0, 2] / sinchi cosomega = self.matrix[1, 2] / sinchi omega = np.arctan2(sinomega, cosomega) if abs(sinchi) < 1.0e-10: # Since f==0 and e==-1, the solution is simple.... sinphi = self.matrix[1, 0] cosphi = -self.matrix[0, 0] else: sinphi = self.matrix[2, 0] / sinchi cosphi = -self.matrix[2, 1] / sinchi phi = np.arctan2(sinphi, cosphi) return PositionFactory(ptype='er', theta=self.theta, omega=omega, phi=phi, chi=chi)
def residuals(varying): p.update(varying) cell = get_new_cell(p) errors = [] for (mpos, hkl, _) in poslist: cpos = PositionFactory('c', c=cell.CVector(hkl)) cpos = getattr(cpos, 'as' + postype)(p.wavelength) errors.append(7.0 * (cpos.omega - mpos.omega)) for axis in axes: errors.append(4.0 * (getattr(cpos, axis) + np.radians( getattr(p, 'delta_' + axis)) - getattr(mpos, axis))) return errors
def With(self, **kw): """ Make clone of this position with some angle(s) changed. """ if not kw.get('_rad', False): for var in ('theta', 'phi', 'kappa', 'omega'): if kw.get(var, None) is not None: kw[var] = np.deg2rad(kw[var]) return PositionFactory(ptype='kr', theta=kw.get('theta', self.theta), omega=kw.get('omega', self.omega), kappa=kw.get('kappa', self.kappa), phi=kw.get('phi', self.phi))
def asG(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ return PositionFactory(ptype='gr', theta=self.theta, matrix=np.dot( Zrot(self.omega), np.dot( Yrot(-self.alpha), np.dot( Zrot(self.kappa), np.dot(Yrot(self.alpha), Zrot(self.phi))))))
def With(self, **kw): """ Make clone of this position with some angle(s) changed. """ if not kw.get('_rad', False): for var in ('gamma', 'omega', 'nu', 'psi'): if kw.get(var, None) is not None: kw[var] = np.deg2rad(kw[var]) return PositionFactory(ptype='lr', gamma=kw.get('gamma', self.gamma), omega=kw.get('omega', self.omega), nu=kw.get('nu', self.nu), signtheta=kw.get('signtheta', self.signtheta), psi=kw.get('psi', self.psi))
def calcEsmeraldaRots(xrot, yrot, zrot): """Move goniometer to new position as specified by orienting angles. *x*,*y*,*z* Orienting angles as determined e.g. by Esmeralda """ try: laue = session.getDevice('kappagon') cpos = laue.read().With(phi=0) except Exception: # enables standalone testing cpos = PositionFactory('k', phi=0, kappa=0, omega=0, theta=0) ma = cpos.asG().matrix # note: internal coordinate system is different from Esmeralda: # X_E = Y_int # Y_E = -X_int # Z_E = Z_int rx = Xrot(np.radians(yrot)) ry = Yrot(np.radians(-xrot)) rz = Zrot(np.radians(zrot)) rotmat = np.dot(rz, np.dot(ry, rx)) newmat = np.dot(ma, rotmat) npos = cpos.asG().With(matrix=newmat) return npos.asK()
def asE(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ if self.kappa is None: print("DBG> Convert incomplete kappa to eulerian!") return PositionFactory(ptype='e', theta=self.theta) halfkappa = 0.5 * self.kappa # Modulo 360 while halfkappa > np.pi / 2: halfkappa -= np.pi while halfkappa < -np.pi / 2: halfkappa += np.pi sinx = np.cos(self.alpha) * np.sin(halfkappa) cosx = np.cos(halfkappa) x = np.arctan2(sinx, cosx) omegae = self.omega + x phie = self.phi + x sinc = np.sin(self.alpha) * np.sin(halfkappa) chie = 2.0 * np.arcsin(sinc) return PositionFactory(ptype='er', theta=self.theta, omega=normalangle(omegae), chi=normalangle(chie), phi=normalangle(phie))
def asC(self, wavelength=None): """ Conversion. Part of Position subclass protocol. """ if wavelength is None: wavelength = session.instrument.wavelength or None if not wavelength: raise NicosError("Cannot perform conversion without knowing wavelength") if self.theta >= 0: signtheta = 1 else: signtheta = -1 d = 2 * np.sin(self.theta) / wavelength c = [-np.sin(self.phi) * np.cos(self.chi) * d, np.cos(self.phi) * np.cos(self.chi) * d, np.sin(self.chi) * d] return PositionFactory(ptype='cr', c=c, psi=self.psi, signtheta=signtheta)
def asC(self, wavelength=None): """ Conversion. Part of Position subclass protocol. """ if wavelength is None: wavelength = session.instrument.wavelength or None if not wavelength: raise NicosError( "Cannot perform conversion without knowing wavelength") cz = np.sin(self.nu) / wavelength theta = 0.5 * np.arccos(np.cos(self.gamma) * np.cos(self.nu)) cabs2 = (2.0 / wavelength * np.sin(theta))**2 cxy = np.sqrt(cabs2 - cz**2) delta = self.signtheta * np.arcsin(cabs2 / cxy * wavelength / 2.0) phi = -np.pi / 2 + delta - self.omega cx = np.cos(phi) * cxy cy = np.sin(phi) * cxy return PositionFactory(ptype='cr', c=(cx, cy, cz), signtheta=self.signtheta, psi=self.psi)
def asE(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ if self.omega is not None: om = np.deg2rad(180) - self.omega else: om = None if self.phi is not None: ph = normalangle(self.phi + np.deg2rad(90)) else: ph = None if self.theta is not None: th = -self.theta else: th = None return PositionFactory(ptype='er', theta=th, chi=self.chi, phi=ph, omega=om)
def asE(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ sinpsi = np.sin(self.psi) cospsi = np.cos(self.psi) signth = sign(np.sin(self.theta)) sinchb = np.sin(self.chi) coschb = np.cos(self.chi) signcb = sign(coschb) sinche = signcb * sign(sinchb) * np.sqrt((cospsi * sinchb) ** 2 + sinpsi ** 2) cosche = signth * signcb * cospsi * coschb try: chi = np.arctan2(sinche, cosche) except ValueError: self.log.warning("B-E Chi problem: %r", self) chi = 0.0 if sinchb == 0 and sinpsi == 0: omega = self.theta - 90.0 * (signcb - 1.0) sinphe = -np.sin(omega - self.theta) * coschb cosphe = signth * signcb * np.cos(omega - self.theta) * cospsi else: signch = sign(np.sin(chi)) sinome = signch * signcb * coschb * sinpsi cosome = signch * sinchb try: omega = np.arctan2(sinome, cosome) + self.theta except ValueError: self.log.warning("B-E Omega problem: %r", self) omega = 0.0 sinphe = -signch * signcb * sinpsi cosphe = signch * signth * signcb * sinchb * cospsi try: phi = np.arctan2(sinphe, cosphe) + self.phi except ValueError: self.log.warning("B-E Phi problem: %r", self) phi = 0.0 return PositionFactory(ptype='er', theta=self.theta, omega=normalangle(omega), chi=normalangle(chi), phi=normalangle(phi))
def asG(self, _wavelength=None): """ Conversion. Part of Position subclass protocol. """ if self.theta > 0: S = 0 else: S = np.pi if np.cos(self.chi) > 0: C = 0 else: C = np.pi return PositionFactory( ptype='gr', theta=self.theta, matrix=np.dot(Zrot(self.theta), np.dot(Xrot(S), np.dot(Yrot(-self.psi), np.dot(Zrot(S + C), np.dot(Xrot(C), np.dot(Xrot(self.chi), Zrot(self.phi))))))))
def asL(self, wavelength=None): """ Conversion. Part of Position subclass protocol. """ if wavelength is None: wavelength = session.instrument.wavelength or None if not wavelength: raise NicosError( "Cannot perform conversion without knowing wavelength") cxy = np.sqrt(self.c[0]**2 + self.c[1]**2) cabs2 = self.c[0]**2 + self.c[1]**2 + self.c[2]**2 theta = np.arcsin(np.sqrt(cabs2) * wavelength / 2.0) nu = np.arcsin(wavelength * self.c[2]) gamma = np.arccos(np.cos(2 * theta) / np.cos(nu)) * self.signtheta omega = -np.arctan2(self.c[1], self.c[0]) + \ self.signtheta * np.arcsin(cabs2/cxy * wavelength / 2.0) - np.pi/2 return PositionFactory(ptype='lr', signtheta=self.signtheta, gamma=normalangle(gamma), omega=normalangle(omega), nu=normalangle(nu), psi=self.psi)
def _createPos(self, ttheta, omega, chi, phi): # pylint: disable=W0221 return PositionFactory('e', theta=ttheta/2., omega=omega, chi=chi, phi=phi)
def _readPos(self, maxage=0): return PositionFactory('l', gamma=self._attached_gamma.read(maxage), omega=self._attached_omega.read(maxage), nu=self._attached_nu.read(maxage))
def _createPos(self, gamma, omega, nu): return PositionFactory('l', gamma=gamma, omega=omega, nu=nu)
def _createPos(self, ttheta, omega, chi, phi): return PositionFactory('e', theta=ttheta / 2., omega=omega, chi=chi, phi=phi)
def _readPos(self, maxage=0): return PositionFactory('e', theta=self._attached_ttheta.read(maxage) / 2., omega=self._attached_omega.read(maxage), chi=self._attached_chi.read(maxage), phi=self._attached_phi.read(maxage))
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 getPositions(): pos = [] p0 = PositionFactory(ptype='n', theta=-7.23, omega=-10.00, chi=54.74, phi=100.00) pos.append(p0) pos.append(p0.With(chi=0)) pos.append(p0.With(omega=0)) pos.append(p0.With(phi=0)) pos.append(p0.With(chi=90)) pos.append(p0.With(theta=0)) p0 = PositionFactory(ptype='k', theta=7.23, omega=-10.00, kappa=73.00, phi=100.00) pos.append(p0) pos.append(p0.With(kappa=0)) pos.append(p0.With(omega=0)) pos.append(p0.With(phi=0)) pos.append(p0.With(theta=0)) return pos
def _createPos(self, gamma, omega, nu): # pylint: disable=W0221 return PositionFactory('l', gamma=gamma, omega=omega, nu=nu)