/** Set goniometer to matrix workspace and get its rotation matrix R (from * Q-sample to Q-lab * and output 1/R * @brief ConvertCWSDExpToMomentum::setupTransferMatrix * @param dataws :: matrix workspace containing sample rotation angles * @param rotationMatrix :: output as matrix 1/R to convert from Q-lab to * Q-sample */ void ConvertCWSDExpToMomentum::setupTransferMatrix( API::MatrixWorkspace_sptr dataws, Kernel::DblMatrix &rotationMatrix) { // Check sample logs if (!dataws->run().hasProperty("_omega") || !dataws->run().hasProperty("_chi") || !dataws->run().hasProperty("_phi")) throw std::runtime_error( "Data workspace does not have sample log _phi, _chi or _omega. " "Unable to set goniometer and calcualte roation matrix R."); // Call algorithm SetGoniometer IAlgorithm_sptr setalg = createChildAlgorithm("SetGoniometer"); setalg->initialize(); setalg->setProperty("Workspace", dataws); setalg->setProperty("Axis0", "_omega,0,1,0,-1"); setalg->setProperty("Axis1", "_chi,0,0,1,-1"); setalg->setProperty("Axis2", "_phi,0,1,0,-1"); setalg->execute(); if (setalg->isExecuted()) { rotationMatrix = dataws->run().getGoniometer().getR(); g_log.debug() << "Ratation matrix: " << rotationMatrix.str() << "\n"; rotationMatrix.Invert(); g_log.debug() << "Ratation matrix: " << rotationMatrix.str() << "\n"; } else throw std::runtime_error("Unable to set Goniometer."); return; }
/** * Fills in a column for each active hermite polynomial, starting at the given * index * @param cmatrix InOut matrix whose columns should be set to the mass profile * for each active hermite polynomial * @param start Index of the column to start on * @param errors Data errors array * @returns The number of columns filled */ size_t GramCharlierComptonProfile::fillConstraintMatrix( Kernel::DblMatrix &cmatrix, const size_t start, const std::vector<double> &errors) const { std::vector<double> profile(NFINE_Y, 0.0); const size_t nData(ySpace().size()); std::vector<double> result(nData, 0.0); // If the FSE term is fixed by user then it's contribution is convoluted with // Voigt and summed with the first column // otherwise it gets a column of it's own at the end. // Either way it needs to be computed, so do this first std::vector<double> fse(NFINE_Y, 0.0); std::vector<double> convolvedFSE(nData, 0.0); addFSETerm(fse); convoluteVoigt(convolvedFSE.data(), nData, fse); size_t col(0); for (unsigned int i = 0; i < m_hermite.size(); ++i) { if (m_hermite[i] == 0) continue; const unsigned int npoly = 2 * i; addMassProfile(profile.data(), npoly); convoluteVoigt(result.data(), nData, profile); if (i == 0 && m_userFixedFSE) { std::transform(result.begin(), result.end(), convolvedFSE.begin(), result.begin(), std::plus<double>()); } std::transform(result.begin(), result.end(), errors.begin(), result.begin(), std::divides<double>()); cmatrix.setColumn(start + col, result); std::fill_n(profile.begin(), NFINE_Y, 0.0); std::fill_n(result.begin(), nData, 0.0); ++col; } if (!m_userFixedFSE) // Extra column for He3 { std::transform(convolvedFSE.begin(), convolvedFSE.end(), errors.begin(), convolvedFSE.begin(), std::divides<double>()); cmatrix.setColumn(start + col, convolvedFSE); ++col; } return col; }
/** * This function takes a square matrix and reduces its dimensionality by * one. * * @param mat : The matrix to strip dimensionality */ void vtkDataSetToNonOrthogonalDataSet::stripMatrix(Kernel::DblMatrix &mat) { std::size_t dim = mat.Ssize() - 1; Kernel::DblMatrix temp(dim, dim); for (std::size_t i = 0; i < dim; i++) { for (std::size_t j = 0; j < dim; j++) { temp[i][j] = mat[i][j]; } } mat = temp; }
/** * Fills in a column of the matrix with this mass profile, starting at the given * index * @param cmatrix InOut matrix whose column should be set to the mass profile * for each active hermite polynomial * @param start Index of the column to start on * @param errors The data errors * @returns The number of columns filled */ size_t MultivariateGaussianComptonProfile::fillConstraintMatrix( Kernel::DblMatrix &cmatrix, const size_t start, const std::vector<double> &errors) const { std::vector<double> result(ySpace().size()); this->massProfile(result.data(), ySpace().size()); std::transform(result.begin(), result.end(), errors.begin(), result.begin(), std::divides<double>()); cmatrix.setColumn(start, result); return 1; }
/** * This function will create the skew matrix and basis for a non-orthogonal * representation. * * @param ol : The oriented lattice containing B matrix and crystal basis *vectors * @param w : The tranform requested when MDworkspace was created * @param aff : The affine matrix taking care of coordinate transformations */ void vtkDataSetToNonOrthogonalDataSet::createSkewInformation( Geometry::OrientedLattice &ol, Kernel::DblMatrix &w, Kernel::Matrix<coord_t> &aff) { // Get the B matrix Kernel::DblMatrix bMat = ol.getB(); // Apply the W tranform matrix bMat *= w; // Create G* Kernel::DblMatrix gStar = bMat.Tprime() * bMat; Geometry::UnitCell uc(ol); uc.recalculateFromGstar(gStar); m_skewMat = uc.getB(); // Calculate the column normalisation std::vector<double> bNorm; for (std::size_t i = 0; i < m_skewMat.numCols(); i++) { double sum = 0.0; for (std::size_t j = 0; j < m_skewMat.numRows(); j++) { sum += m_skewMat[j][i] * m_skewMat[j][i]; } bNorm.push_back(std::sqrt(sum)); } // Apply column normalisation to skew matrix Kernel::DblMatrix scaleMat(3, 3, true); scaleMat[0][0] /= bNorm[0]; scaleMat[1][1] /= bNorm[1]; scaleMat[2][2] /= bNorm[2]; m_skewMat *= scaleMat; // Setup basis normalisation array // Intel and MSBuild can't handle this // m_basisNorm = {ol.astar(), ol.bstar(), ol.cstar()}; m_basisNorm.push_back(ol.astar()); m_basisNorm.push_back(ol.bstar()); m_basisNorm.push_back(ol.cstar()); // Expand matrix to 4 dimensions if necessary if (4 == m_numDims) { m_basisNorm.push_back(1.0); Kernel::DblMatrix temp(4, 4, true); for (std::size_t i = 0; i < 3; i++) { for (std::size_t j = 0; j < 3; j++) { temp[i][j] = m_skewMat[i][j]; } } m_skewMat = temp; } // Convert affine matrix to similar type as others Kernel::DblMatrix affMat(aff.numRows(), aff.numCols()); for (std::size_t i = 0; i < aff.numRows(); i++) { for (std::size_t j = 0; j < aff.numCols(); j++) { affMat[i][j] = aff[i][j]; } } // Strip affine matrix down to correct dimensions this->stripMatrix(affMat); // Perform similarity transform to get coordinate orientation correct m_skewMat = affMat.Tprime() * (m_skewMat * affMat); m_basisNorm = affMat * m_basisNorm; if (4 == m_numDims) { this->stripMatrix(m_skewMat); } this->findSkewBasis(m_basisX, m_basisNorm[0]); this->findSkewBasis(m_basisY, m_basisNorm[1]); this->findSkewBasis(m_basisZ, m_basisNorm[2]); }