/** Method analyzes the state of UB matrix and goniometer attached to the *workspace and decides, which target * coordinate system these variables identify. *Crystal Frame decided in case if there is UB matrix is present and is not *unit matrix *Lab frame -- if goniometer is Unit and UB is unit matrix or not present *Sample frame -- otherwise */ CnvrtToMD::TargetFrame MDWSTransform::findTargetFrame(MDWSDescription &TargWSDescription) const { bool hasGoniometer = TargWSDescription.hasGoniometer(); bool hasLattice = TargWSDescription.hasLattice(); if (!hasGoniometer) { return LabFrame; } else { if (hasLattice) return HKLFrame; else return SampleFrame; } }
/** Method verifies if the information available on the source workspace is *sufficient to build appropriate frame *@param TargWSDescription -- the class which contains the information about the *target workspace *@param CoordFrameID -- the ID of the target frame requested * * method throws invalid argument if the information on the workspace is *insufficient to define the frame requested */ void MDWSTransform::checkTargetFrame( const MDWSDescription &TargWSDescription, const CnvrtToMD::TargetFrame CoordFrameID) const { switch (CoordFrameID) { case (LabFrame): // nothing needed for lab frame return; case (SampleFrame): if (!TargWSDescription.hasGoniometer()) throw std::invalid_argument( " Sample frame needs goniometer to be defined on the workspace "); return; case (HKLFrame): // ubMatrix has to be present if (!TargWSDescription.hasLattice()) throw std::invalid_argument( " HKL frame needs UB matrix defined on the workspace "); if (!TargWSDescription.hasGoniometer()) g_Log.warning() << " HKL frame does not have goniometer defined on the " "workspace. Assuming unit goniometer matrix\n"; return; default: throw std::runtime_error( " Unexpected argument in MDWSTransform::checkTargetFrame"); } }
/** The matrix to convert neutron momentums into the target coordinate system */ std::vector<double> MDWSTransform::getTransfMatrix(MDWSDescription &TargWSDescription, CnvrtToMD::TargetFrame FrameID, CoordScaling &ScaleID) const { Kernel::Matrix<double> mat(3, 3, true); bool powderMode = TargWSDescription.isPowder(); bool has_lattice(true); if (!TargWSDescription.hasLattice()) has_lattice = false; if (!(powderMode || has_lattice)) { std::string inWsName = TargWSDescription.getWSName(); // notice about 3D case without lattice g_Log.notice() << "Can not obtain transformation matrix from the input workspace: " << inWsName << " as no oriented lattice has been defined. \n" "Will use unit transformation matrix.\n"; } // set the frame ID to the values, requested by properties CnvrtToMD::TargetFrame CoordFrameID(FrameID); if (FrameID == AutoSelect || powderMode) // if this value is auto-select, find // appropriate frame from workspace // properties CoordFrameID = findTargetFrame(TargWSDescription); else // if not, and specific target frame requested, verify if everything is // available on the workspace for this frame checkTargetFrame( TargWSDescription, CoordFrameID); // throw, if the information is not available switch (CoordFrameID) { case (CnvrtToMD::LabFrame): { ScaleID = NoScaling; TargWSDescription.m_Wtransf = buildQTrahsf(TargWSDescription, ScaleID, true); // ignore goniometer mat = TargWSDescription.m_Wtransf; break; } case (CnvrtToMD::SampleFrame): { ScaleID = NoScaling; TargWSDescription.m_Wtransf = buildQTrahsf(TargWSDescription, ScaleID, true); // Obtain the transformation matrix to Cartesian related to Crystal mat = TargWSDescription.getGoniometerMatr() * TargWSDescription.m_Wtransf; break; } case (CnvrtToMD::HKLFrame): { TargWSDescription.m_Wtransf = buildQTrahsf(TargWSDescription, ScaleID, false); // Obtain the transformation matrix to Cartesian related to Crystal if (TargWSDescription.hasGoniometer()) mat = TargWSDescription.getGoniometerMatr() * TargWSDescription.m_Wtransf; else mat = TargWSDescription.m_Wtransf; break; } default: throw(std::invalid_argument(" Unknown or undefined Target Frame ID")); } // // and this is the transformation matrix to notional mat.Invert(); std::vector<double> rotMat = mat.getVector(); g_Log.debug() << " *********** Q-transformation matrix ***********************\n"; g_Log.debug() << "*** *qx ! *qy ! *qz !\n"; g_Log.debug() << "q1= " << rotMat[0] << " ! " << rotMat[1] << " ! " << rotMat[2] << " !\n"; g_Log.debug() << "q2= " << rotMat[3] << " ! " << rotMat[4] << " ! " << rotMat[5] << " !\n"; g_Log.debug() << "q3= " << rotMat[6] << " ! " << rotMat[7] << " ! " << rotMat[8] << " !\n"; g_Log.debug() << " *********** *********************** ***********************\n"; return rotMat; }