/** Set the U rotation matrix, to provide the transformation, which translate *an * arbitrary vector V expressed in RLU (hkl) * into another coordinate system defined by vectors u and v, expressed in RLU *(hkl) * Author: Alex Buts * @param u :: first vector of new coordinate system (in hkl units) * @param v :: second vector of the new coordinate system * @return the U matrix calculated * The transformation from old coordinate system to new coordinate system is *performed by * the whole UB matrix **/ const DblMatrix &OrientedLattice::setUFromVectors(const V3D &u, const V3D &v) { const DblMatrix &BMatrix = this->getB(); V3D buVec = BMatrix * u; V3D bvVec = BMatrix * v; // try to make an orthonormal system if (buVec.norm2() < 1e-10) throw std::invalid_argument("|B.u|~0"); if (bvVec.norm2() < 1e-10) throw std::invalid_argument("|B.v|~0"); buVec.normalize(); // 1st unit vector, along Bu V3D bwVec = buVec.cross_prod(bvVec); if (bwVec.normalize() < 1e-5) throw std::invalid_argument( "u and v are parallel"); // 3rd unit vector, perpendicular to Bu,Bv bvVec = bwVec.cross_prod( buVec); // 2nd unit vector, perpendicular to Bu, in the Bu,Bv plane DblMatrix tau(3, 3), lab(3, 3), U(3, 3); /*lab = U tau / 0 1 0 \ /bu[0] bv[0] bw[0]\ | 0 0 1 | = U |bu[1] bv[1] bw[1]| \ 1 0 0 / \bu[2] bv[2] bw[2]/ */ lab[0][1] = 1.; lab[1][2] = 1.; lab[2][0] = 1.; tau[0][0] = buVec[0]; tau[0][1] = bvVec[0]; tau[0][2] = bwVec[0]; tau[1][0] = buVec[1]; tau[1][1] = bvVec[1]; tau[1][2] = bwVec[1]; tau[2][0] = buVec[2]; tau[2][1] = bvVec[2]; tau[2][2] = bwVec[2]; tau.Invert(); U = lab * tau; this->setU(U); return getU(); }
/** @param inname Name of workspace containing peaks @param params optimized cell parameters @param out residuals from optimization */ void OptimizeLatticeForCellType::optLattice(std::string inname, std::vector<double> ¶ms, double *out) { PeaksWorkspace_sptr ws = boost::dynamic_pointer_cast<PeaksWorkspace>( AnalysisDataService::Instance().retrieve(inname)); const std::vector<Peak> &peaks = ws->getPeaks(); size_t n_peaks = ws->getNumberPeaks(); std::vector<V3D> q_vector; std::vector<V3D> hkl_vector; for (size_t i = 0; i < params.size(); i++) params[i] = std::abs(params[i]); for (size_t i = 0; i < n_peaks; i++) { q_vector.push_back(peaks[i].getQSampleFrame()); hkl_vector.push_back(peaks[i].getHKL()); } Mantid::API::IAlgorithm_sptr alg = createChildAlgorithm("CalculateUMatrix"); alg->setPropertyValue("PeaksWorkspace", inname); alg->setProperty("a", params[0]); alg->setProperty("b", params[1]); alg->setProperty("c", params[2]); alg->setProperty("alpha", params[3]); alg->setProperty("beta", params[4]); alg->setProperty("gamma", params[5]); alg->executeAsChildAlg(); ws = alg->getProperty("PeaksWorkspace"); OrientedLattice latt = ws->mutableSample().getOrientedLattice(); DblMatrix UB = latt.getUB(); DblMatrix A = aMatrix(params); DblMatrix Bc = A; Bc.Invert(); DblMatrix U1_B1 = UB * A; OrientedLattice o_lattice; o_lattice.setUB(U1_B1); DblMatrix U1 = o_lattice.getU(); DblMatrix U1_Bc = U1 * Bc; for (size_t i = 0; i < hkl_vector.size(); i++) { V3D error = U1_Bc * hkl_vector[i] - q_vector[i] / (2.0 * M_PI); out[i] = error.norm2(); } return; }
TopoDS_Shape Plane::createShape() { // Get Plane normal and distance. V3D normal = this->getNormal(); double norm2 = normal.norm2(); if (norm2 == 0.0) { throw std::runtime_error("Cannot create a plane with zero normal"); } double distance = this->getDistance(); // Find point closest to origin double t = distance / norm2; // Create Half Space TopoDS_Face P = BRepBuilderAPI_MakeFace( gp_Pln(normal[0], normal[1], normal[2], -distance)) .Face(); TopoDS_Shape Result = BRepPrimAPI_MakeHalfSpace( P, gp_Pnt(normal[0] * (1 + t), normal[1] * (1 + t), normal[2] * (1 + t))) .Solid(); return Result.Complemented(); }
/// Returns the Debye-Waller factor, using an isotropic atomic displacement and /// the stored unit cell. double IsotropicAtomBraggScatterer::getDebyeWallerFactor(const V3D &hkl) const { V3D dstar = getCell().getB() * hkl; return exp(-2.0 * M_PI * M_PI * getU() * dstar.norm2()); }
/// Returns true if lambda of the reflection is within the limits. bool HKLFilterWavelength::isAllowed(const Kernel::V3D &hkl) const { V3D q = m_ub * hkl; double lambda = (2.0 * q.Z()) / (q.norm2()); return lambda >= m_lambdaMin && lambda <= m_lambdaMax; }