16#include <boost/algorithm/string.hpp>
17#include <boost/format.hpp>
33 :
CoordTransform(inD, outD), m_affineMatrix(outD + 1, inD + 1), m_rawMatrix(nullptr), m_rawMemory(nullptr) {
43 for (
size_t i = 0; i < nx; i++)
105 throw std::runtime_error(
"setMatrix(): Number of rows must match!");
107 throw std::runtime_error(
"setMatrix(): Number of columns must match!");
132 for (
size_t i = 0; i <
outD; i++)
133 translationMatrix[i][
inD] = translationVector[i];
174 const std::vector<Mantid::Kernel::VMD> &axes,
177 throw std::runtime_error(
"CoordTransformAffine::buildOrthogonal(): the "
178 "origin must be in the dimensions of the input "
179 "workspace (length inD).");
180 if (axes.size() !=
outD)
181 throw std::runtime_error(
"CoordTransformAffine::buildOrthogonal(): you "
182 "must give as many basis vectors as there are "
183 "dimensions in the output workspace.");
185 throw std::runtime_error(
"CoordTransformAffine::buildOrthogonal(): the "
186 "size of the scaling vector must be the same as "
187 "the number of dimensions in the output "
193 for (
size_t i = 0; i < axes.size(); i++) {
194 if (axes[i].length() == 0.0)
195 throw std::runtime_error(
"CoordTransformAffine::buildOrthogonal(): one "
196 "of the basis vector was of zero length.");
197 if (axes[i].size() !=
inD)
198 throw std::runtime_error(
"CoordTransformAffine::buildOrthogonal(): one "
199 "of the basis vectors had the wrong number of "
200 "dimensions (must be inD).");
205 for (
size_t j = 0; j < basis.
size(); j++)
210 for (
size_t j = 0; j < basis.
size(); j++)
211 transl +=
static_cast<coord_t>(origin[j] * basis[j]);
221 const std::vector<Mantid::Kernel::VMD> &axes,
224 throw std::runtime_error(
"CoordTransformAffine::buildNonOrthogonal(): the "
225 "origin must be in the dimensions of the input "
226 "workspace (length inD).");
227 if (axes.size() !=
outD)
228 throw std::runtime_error(
"CoordTransformAffine::buildNonOrthogonal(): you "
229 "must give as many basis vectors as there are "
230 "dimensions in the output workspace.");
232 throw std::runtime_error(
"CoordTransformAffine::buildNonOrthogonal(): the "
233 "size of the scaling vector must be the same as "
234 "the number of dimensions in the output "
241 for (
size_t i = 0; i <
outD; i++) {
242 for (
size_t j = 0; j <
inD; j++) {
243 A[j][i] = axes[i][j];
252 for (
size_t j = 0; j <
inD; j++) {
253 offset[j][0] = origin[j];
257 for (
size_t i = 0; i <
outD; i++) {
258 for (
size_t j = 0; j <
inD; j++) {
275 for (
size_t out = 0; out <
outD; ++out) {
280 for (in = 0; in <
inD; ++in)
281 outVal += rawMatrixRow[in] * inputVector[in];
285 outVal += rawMatrixRow[in];
287 outVector[out] = outVal;
299 AutoPtr<Document> pDoc =
new Document;
300 AutoPtr<Element> coordTransformElement = pDoc->createElement(
"CoordTransform");
301 pDoc->appendChild(coordTransformElement);
303 AutoPtr<Element> coordTransformTypeElement = pDoc->createElement(
"Type");
304 coordTransformTypeElement->appendChild(AutoPtr<Node>(pDoc->createTextNode(
"CoordTransformAffine")));
305 coordTransformElement->appendChild(coordTransformTypeElement);
307 AutoPtr<Element> paramListElement = pDoc->createElement(
"ParameterList");
309 AutoPtr<Text> formatText = pDoc->createTextNode(
"%s%s%s");
310 paramListElement->appendChild(formatText);
312 coordTransformElement->appendChild(paramListElement);
314 std::stringstream xmlstream;
317 writer.writeNode(xmlstream, pDoc);
322 Mantid::API::InDimParameter inD_param(
inD);
323 Mantid::API::OutDimParameter outD_param(
outD);
325 std::string formattedXMLString =
326 boost::str(boost::format(xmlstream.str().c_str()) % inD_param.toXMLString().c_str() %
327 outD_param.toXMLString().c_str() % affineMatrixParameter.
toXMLString().c_str());
328 return formattedXMLString;
347 if (!first || !second)
348 throw std::runtime_error(
"CoordTransformAffine::combineTransformations(): Null input provided.");
350 throw std::runtime_error(
"CoordTransformAffine::combineTransformations(): "
351 "The # of output dimensions of first must be the "
352 "same as the # of input dimensions of second.");
355 bool ownFirstAff(
false);
359 throw std::runtime_error(
"CoordTransformAffine::combineTransformations(): first transform "
360 "must be either CoordTransformAffine or CoordTransformAligned.");
362 firstAff->setMatrix(firstAl->makeAffineMatrix());
366 bool ownSecondAff(
false);
370 throw std::runtime_error(
"CoordTransformAffine::combineTransformations(): second transform "
371 "must be either CoordTransformAffine or CoordTransformAligned.");
373 secondAff->setMatrix(secondAl->makeAffineMatrix());
379 Matrix<coord_t> outMat = secondAff->getMatrix() * firstAff->getMatrix();
381 out->setMatrix(outMat);
Type to wrap an affine matrix and allow serialization via xml.
std::string toXMLString() const override
Serialize the Affine Matrix Parameter.
void setMatrix(const AffineMatrixType &newMatrix)
Setter for the internal affine matrix.
T Invert()
LU inversion routine.
void identityMatrix()
Makes the matrix an idenity matrix.
size_t numRows() const
Return the number of rows in the matrix.
size_t numCols() const
Return the number of columns in the matrix.
Matrix< T > & Transpose()
Transpose the matrix.
TYPE normalize()
Normalize this vector to unity length.
void swap(MDLeanEvent< nd > &first, MDLeanEvent< nd > &second)
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...