Mantid
Loading...
Searching...
No Matches
CoordTransformDistance.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include "MantidKernel/System.h"
11
12#include <boost/algorithm/string.hpp>
13#include <boost/format.hpp>
14
15using namespace Mantid::Geometry;
16using namespace Mantid::Kernel;
18
19namespace Mantid::DataObjects {
20
21//----------------------------------------------------------------------------------------------
34CoordTransformDistance::CoordTransformDistance(const size_t inD, const coord_t *center, const bool *dimensionsUsed,
35 const size_t outD, const std::vector<Kernel::V3D> &eigenvects,
36 const std::vector<double> &eigenvals)
37 : CoordTransform(inD, outD) {
38
39 m_center.reserve(inD);
40 m_dimensionsUsed.reserve(inD);
41 m_eigenvals.reserve(inD);
42 m_maxEigenval = 0.0;
43 for (size_t d = 0; d < inD; d++) {
44 m_center.push_back(center[d]);
45 m_dimensionsUsed.push_back(dimensionsUsed[d]);
46 if (eigenvals.size() == inD && eigenvects.size() == inD) {
47 // coord transform for n-ellipsoid specified
48 m_eigenvals.push_back(eigenvals[d]);
49 m_eigenvects.push_back(eigenvects[d]);
50 m_maxEigenval = std::max(m_maxEigenval, eigenvals[d]);
51 }
52 }
53}
54
55//----------------------------------------------------------------------------------------------
59
60//----------------------------------------------------------------------------------------------
70void CoordTransformDistance::apply(const coord_t *inputVector, coord_t *outVector) const {
71 if (outD == 1) {
72 coord_t distanceSquared = 0;
73 if (m_eigenvals.size() == 3) {
74 // ellipsoid transfrom with ratio of axes given by standard deviation
75 // i.e. sqrt(eigenvals)
76 for (size_t d = 0; d < inD; d++) {
77 // do dot prod with eigenvector
78 coord_t dist = 0.0;
79 // calculate the covariance of the delta vector using
80 // the three eigen vector as the new base
81 for (size_t dd = 0; dd < inD; dd++) {
82 dist += static_cast<coord_t>(m_eigenvects[d][dd]) * (inputVector[dd] - m_center[dd]);
83 }
84
85 distanceSquared += (dist * dist) * static_cast<coord_t>(m_maxEigenval / m_eigenvals[d]);
86 }
87 // debug output
88 // std::cout << "[CoordTransFormDistance]\n"
89 // << "eigenvals:" << m_eigenvals[0] << "," << m_eigenvals[1]
90 // << "," << m_eigenvals[2] << "\n"
91 // << "peak_center:" << m_center[0] << "," << m_center[1] << ","
92 // << m_center[2] << "\n"
93 // << "distanceSquared = " << distanceSquared << "\n\n";
94 } else {
95 // nd spherical transform
96 for (size_t d = 0; d < inD; d++) {
97 if (m_dimensionsUsed[d]) {
98 coord_t dist = inputVector[d] - m_center[d];
99 distanceSquared += (dist * dist);
100 }
101 }
102 }
104 outVector[0] = distanceSquared;
105 } else {
106 // Cylinder 2D output radius and length
107 coord_t lenQdata = 0.0;
108 coord_t lenQpeak = 0.0;
109 coord_t cosAng = 0.0;
110 for (size_t d = 0; d < inD; d++) {
111 lenQdata += inputVector[d] * inputVector[d];
112 lenQpeak += m_center[d] * m_center[d];
113 cosAng += m_center[d] * inputVector[d];
114 }
115 lenQdata = std::sqrt(lenQdata);
116 lenQpeak = std::sqrt(lenQpeak);
117 if (lenQpeak * lenQdata != 0.0)
118 cosAng /= (lenQpeak * lenQdata);
119 coord_t angle = std::acos(cosAng);
120 outVector[0] = lenQdata * std::sin(angle);
121 outVector[1] = lenQdata * cosAng - lenQpeak;
122 }
123}
124
125//----------------------------------------------------------------------------------------------
131 using namespace Poco::XML;
132
133 AutoPtr<Document> pDoc = new Document;
134 AutoPtr<Element> coordTransformElement = pDoc->createElement("CoordTransform");
135 pDoc->appendChild(coordTransformElement);
136
137 AutoPtr<Element> coordTransformTypeElement = pDoc->createElement("Type");
138 coordTransformTypeElement->appendChild(AutoPtr<Text>(pDoc->createTextNode("CoordTransformDistance")));
139 coordTransformElement->appendChild(coordTransformTypeElement);
140
141 AutoPtr<Element> paramListElement = pDoc->createElement("ParameterList");
142
143 AutoPtr<Text> formatText = pDoc->createTextNode("%s%s%s%s");
144 paramListElement->appendChild(formatText);
145 coordTransformElement->appendChild(paramListElement);
146
147 std::stringstream xmlstream;
148
149 DOMWriter writer;
150 writer.writeNode(xmlstream, pDoc);
151
152 // Convert the members to parameters
153 Mantid::API::InDimParameter inD_param(inD);
154 Mantid::API::OutDimParameter outD_param(outD);
155 CoordCenterVectorParam m_center_param(inD);
156 DimensionsUsedVectorParam m_dimensionsUsed_param(inD);
157
158 // Create and copy the arrays.
159 for (size_t d = 0; d < inD; d++) {
160 m_center_param.addValue(d, m_center[d]);
161 m_dimensionsUsed_param.addValue(d, m_dimensionsUsed[d]);
162 }
163
164 std::string formattedXMLString = boost::str(boost::format(xmlstream.str().c_str()) % inD_param.toXMLString().c_str() %
165 outD_param.toXMLString().c_str() % m_center_param.toXMLString().c_str() %
166 m_dimensionsUsed_param.toXMLString().c_str());
167
168 return formattedXMLString;
169}
170
175std::string CoordTransformDistance::id() const { return "CoordTransformDistance"; }
176
177} // namespace Mantid::DataObjects
Unique SingleValueParameter Declaration for InputNDimensions.
size_t inD
Input number of dimensions.
size_t outD
Output number of dimensions.
Unique CoordCenterVectorParam type declaration for ndimensional coordinate centers.
std::vector< coord_t > m_center
Coordinates at the center.
void apply(const coord_t *inputVector, coord_t *outVector) const override
Apply the coordinate transformation.
std::vector< bool > m_dimensionsUsed
Parmeter where True is set for those dimensions that are considered when calculating distance.
CoordTransform * clone() const override
Virtual cloner.
CoordTransformDistance(const size_t inD, const coord_t *center, const bool *dimensionsUsed, const size_t outD=1, const std::vector< Kernel::V3D > &eigenvects=std::vector< Kernel::V3D >(0), const std::vector< double > &eigenvals=std::vector< double >(0, 0.0))
Constructor.
std::string id() const override
Coordinate transform id.
std::string toXMLString() const override
Serialize the coordinate transform distance.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27