Mantid
Loading...
Searching...
No Matches
MDTransfQ3D.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
11namespace Mantid::MDAlgorithms {
12// register the class, whith conversion factory under Q3D name
13DECLARE_MD_TRANSFID(MDTransfQ3D, Q3D)
14
15
17unsigned int MDTransfQ3D::getNMatrixDimensions(Kernel::DeltaEMode::Type mode,
18 API::MatrixWorkspace_const_sptr inWS) const {
19 UNUSED_ARG(inWS);
20 switch (mode) {
22 return 4;
24 return 4;
26 return 3;
27 default:
28 throw(std::invalid_argument("Unknow or unsupported energy conversion mode"));
29 }
30}
31
47bool MDTransfQ3D::calcMatrixCoord(const double &deltaEOrK0, std::vector<coord_t> &Coord, double &s, double &err) const {
49 return calcMatrixCoord3DElastic(deltaEOrK0, Coord, s, err);
50 } else {
51 return calcMatrixCoord3DInelastic(deltaEOrK0, Coord);
52 }
53}
54
69bool MDTransfQ3D::calcMatrixCoord3DInelastic(const double &deltaE, std::vector<coord_t> &Coord) const {
70 Coord[3] = static_cast<coord_t>(deltaE);
71 if (Coord[3] < m_DimMin[3] || Coord[3] >= m_DimMax[3])
72 return false;
73
74 // x,y,z refer to internal coordinate system where Z is the beam direction
75 double qx{0.0}, qy{0.0}, qz{0.0};
77 const double kFinal = sqrt((m_eFixed - deltaE) / PhysicalConstants::E_mev_toNeutronWavenumberSq);
78 qx = -m_ex * kFinal;
79 qy = -m_ey * kFinal;
80 qz = m_kFixed - m_ez * kFinal;
81 } else {
82 qx = -m_ex * m_kFixed;
83 qy = -m_ey * m_kFixed;
84 const double kInitial = sqrt((m_eFixed + deltaE) / PhysicalConstants::E_mev_toNeutronWavenumberSq);
85 qz = kInitial - m_ez * m_kFixed;
86 }
87
88 if (convention == "Crystallography") {
89 qx = -qx;
90 qy = -qy;
91 qz = -qz;
92 }
93
94 Coord[0] = static_cast<coord_t>(m_RotMat[0] * qx + m_RotMat[1] * qy + m_RotMat[2] * qz);
95
96 if (Coord[0] < m_DimMin[0] || Coord[0] >= m_DimMax[0])
97 return false;
98 Coord[1] = static_cast<coord_t>(m_RotMat[3] * qx + m_RotMat[4] * qy + m_RotMat[5] * qz);
99 if (Coord[1] < m_DimMin[1] || Coord[1] >= m_DimMax[1])
100 return false;
101 Coord[2] = static_cast<coord_t>(m_RotMat[6] * qx + m_RotMat[7] * qy + m_RotMat[8] * qz);
102 if (Coord[2] < m_DimMin[2] || Coord[2] >= m_DimMax[2])
103 return false;
104
105 if (std::sqrt(Coord[0] * Coord[0] + Coord[1] * Coord[1] + Coord[2] * Coord[2]) < m_AbsMin)
106 return false;
107
108 return true;
109}
110
127bool MDTransfQ3D::calcMatrixCoord3DElastic(const double &k0, std::vector<coord_t> &Coord, double &signal,
128 double &errSq) const {
129
130 double qx = -m_ex * k0;
131 double qy = -m_ey * k0;
132 double qz = (1 - m_ez) * k0;
133 if (convention == "Crystallography") {
134 qx = -qx;
135 qy = -qy;
136 qz = -qz;
137 }
138
139 // Dimension limits have to be converted to coord_t, otherwise floating point
140 // error will cause valid events to be discarded.
141 Coord[0] = static_cast<coord_t>(m_RotMat[0] * qx + m_RotMat[1] * qy + m_RotMat[2] * qz);
142 if (Coord[0] < static_cast<coord_t>(m_DimMin[0]) || Coord[0] >= static_cast<coord_t>(m_DimMax[0]))
143 return false;
144
145 Coord[1] = static_cast<coord_t>(m_RotMat[3] * qx + m_RotMat[4] * qy + m_RotMat[5] * qz);
146 if (Coord[1] < static_cast<coord_t>(m_DimMin[1]) || Coord[1] >= static_cast<coord_t>(m_DimMax[1]))
147 return false;
148
149 Coord[2] = static_cast<coord_t>(m_RotMat[6] * qx + m_RotMat[7] * qy + m_RotMat[8] * qz);
150 if (Coord[2] < static_cast<coord_t>(m_DimMin[2]) || Coord[2] >= static_cast<coord_t>(m_DimMax[2]))
151 return false;
152
153 if (std::sqrt(Coord[0] * Coord[0] + Coord[1] * Coord[1] + Coord[2] * Coord[2]) < m_AbsMin)
154 return false;
155
156 /*Apply Lorentz corrections if necessary */
158 double kdash = k0 / (2 * M_PI);
159 double correct = m_SinThetaSq * kdash * kdash * kdash * kdash;
160 signal *= correct;
161 errSq *= (correct * correct);
162 }
163
164 return true;
165}
166
167std::vector<double> MDTransfQ3D::getExtremumPoints(const double xMin, const double xMax, size_t det_num) const {
168 UNUSED_ARG(det_num);
169
170 std::vector<double> rez(2);
171 rez[0] = xMin;
172 rez[1] = xMax;
173
174 return rez;
175}
176
185bool MDTransfQ3D::calcYDepCoordinates(std::vector<coord_t> &Coord, size_t i) {
186 UNUSED_ARG(Coord);
187 m_ex = (m_DetDirecton + i)->X();
188 m_ey = (m_DetDirecton + i)->Y();
189 m_ez = (m_DetDirecton + i)->Z();
190 // if Lorentz-corrected, retrieve the sin(Theta)^2 for the detector;
193 // if input energy changes on each detector (efixed, indirect mode only), then
194 // set up its value
195 if (m_pEfixedArray) {
196 m_eFixed = double(*(m_pEfixedArray + i));
198 }
199 // if masks are defined and detector masked -- no further calculations
200 if (m_pDetMasks) {
201 if (*(m_pDetMasks + i) > 0)
202 return false;
203 }
204
205 return true;
206}
207
211 m_pEfixedArray = nullptr;
212 m_pDetMasks = nullptr;
213 convention = Kernel::ConfigService::Instance().getString("Q.convention");
214 //********** Generic part of initialization, common for elastic and inelastic
215 // modes:
216 // get transformation matrix (needed for CrystalAsPoder mode)
217 m_RotMat = ConvParams.getTransfMatrix();
218
219 if (!ConvParams.m_PreprDetTable)
220 throw(std::runtime_error("The detectors have not been preprocessed but "
221 "they have to before running initialize"));
222 // get pointer to the positions of the preprocessed detectors
223 std::vector<Kernel::V3D> const &DetDir = ConvParams.m_PreprDetTable->getColVector<Kernel::V3D>("DetDirections");
224 m_DetDirecton = &DetDir[0]; //
225
226 // get min and max values defined by the algorithm.
227 ConvParams.getMinMax(m_DimMin, m_DimMax);
228 // get additional coordinates which are
229 m_AddDimCoordinates = ConvParams.getAddCoord();
230
231 //************ specific part of the initialization, dependent on emode:
232 m_Emode = ConvParams.getEMode();
235 // energy needed in inelastic case
236 m_eFixed = ConvParams.m_PreprDetTable->getLogs()->getPropertyValueAsType<double>("Ei");
237 // the wave vector of incident neutrons;
239
240 m_pEfixedArray = nullptr;
241 if (m_Emode == static_cast<int>(Kernel::DeltaEMode::Indirect))
242 m_pEfixedArray = ConvParams.m_PreprDetTable->getColDataArray<float>("eFixed");
243 } else {
245 throw(std::runtime_error("MDTransfQ3D::initialize::Unknown or "
246 "unsupported energy conversion mode"));
247 // check if we need to calculate Lorentz corrections and if we do, prepare
248 // values for their precalculation:
251 auto &TwoTheta = ConvParams.m_PreprDetTable->getColVector<double>("TwoTheta");
252 SinThetaSq.resize(TwoTheta.size());
253 for (size_t i = 0; i < TwoTheta.size(); i++) {
254 double sth = sin(0.5 * TwoTheta[i]);
255 SinThetaSq[i] = sth * sth;
256 }
259 throw(std::runtime_error("MDTransfQ3D::initialize::Uninitilized "
260 "Sin(Theta)^2 array for calculating Lorentz "
261 "corrections"));
262 }
263 }
264 // use detectors masks untill signals are masked by 0 instead of NaN
265 m_pDetMasks = ConvParams.m_PreprDetTable->getColDataArray<int>("detMask");
266 m_AbsMin = ConvParams.absMin();
267}
280 UNUSED_ARG(inWS);
281 std::vector<std::string> default_dim_ID;
282 switch (dEmode) {
284 default_dim_ID.resize(3);
285 break;
286 }
289 default_dim_ID.resize(4);
290 default_dim_ID[3] = "DeltaE";
291 break;
292 }
293 default:
294 throw(std::invalid_argument("MDTransfQ3D::getDefaultDimID::Unknown energy conversion mode"));
295 }
296 default_dim_ID[0] = "Q1";
297 default_dim_ID[1] = "Q2";
298 default_dim_ID[2] = "Q3";
299
300 return default_dim_ID;
301}
302
310 UNUSED_ARG(inWS);
311 std::vector<std::string> UnitID = this->getDefaultDimID(dEmode, inWS);
312
313 // TODO: is it really momentum transfer, as MomentumTransfer units are seems
314 // bound to elastic mode only (at least accorting to Units description on
315 // Wiki)?
316 std::string kUnits("MomentumTransfer");
317 if (dEmode == Kernel::DeltaEMode::Elastic)
318 kUnits = "Momentum";
319
320 UnitID[0] = kUnits;
321 UnitID[1] = kUnits;
322 UnitID[2] = kUnits;
323 return UnitID;
324}
325
328 : m_isLorentzCorrected(false), m_SinThetaSqArray(nullptr), SinThetaSq(), m_SinThetaSq(0.), m_AbsMin(0.) {}
329
330} // namespace Mantid::MDAlgorithms
#define DECLARE_MD_TRANSFID(classname, regID)
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class for 3D vectors.
Definition: V3D.h:34
std::vector< double > m_RotMat
Definition: MDTransfModQ.h:84
Kernel::V3D const * m_DetDirecton
Definition: MDTransfModQ.h:89
std::vector< double > m_DimMin
Definition: MDTransfModQ.h:86
std::vector< double > m_DimMax
Definition: MDTransfModQ.h:86
Kernel::DeltaEMode::Type m_Emode
Definition: MDTransfModQ.h:95
std::vector< coord_t > m_AddDimCoordinates
the vector of the additional coordinates which define additional MD dimensions.
Definition: MDTransfModQ.h:100
Class responsible for conversion of input workspace data into proper number of output dimensions for ...
Definition: MDTransfQ3D.h:31
bool calcMatrixCoord(const double &deltaEOrK0, std::vector< coord_t > &Coord, double &s, double &err) const override
Calculates 3D transformation of the variable coordinates and (if applicable) signal and error dependi...
Definition: MDTransfQ3D.cpp:47
std::vector< double > SinThetaSq
Definition: MDTransfQ3D.h:74
bool calcMatrixCoord3DElastic(const double &k0, std::vector< coord_t > &Coord, double &signal, double &errSq) const
how to transform workspace data in elastic case
std::vector< std::string > getDefaultDimID(Kernel::DeltaEMode::Type dEmode, API::MatrixWorkspace_const_sptr inWS=API::MatrixWorkspace_const_sptr()) const override
the default dimID-s in Q3D mode are Q1,Q2,Q3 and dE if necessary
bool calcMatrixCoord3DInelastic(const double &deltaE, std::vector< coord_t > &Coord) const
how to transform workspace data in inelastic case
Definition: MDTransfQ3D.cpp:69
void initialize(const MDWSDescription &ConvParams) override
function initalizes all variables necessary for converting workspace variables into MD variables in M...
std::vector< double > getExtremumPoints(const double xMin, const double xMax, size_t det_num) const override
method returns the vector of input coordinates values where the transformed coordinates reach its ext...
bool calcYDepCoordinates(std::vector< coord_t > &Coord, size_t i) override
Method updates the value of preprocessed detector coordinates in Q-space, used by other functions.
std::vector< std::string > outputUnitID(Kernel::DeltaEMode::Type dEmode, API::MatrixWorkspace_const_sptr inWS=API::MatrixWorkspace_const_sptr()) const override
function returns units ID-s which this transformation prodiuces its ouptut.
unsigned int getNMatrixDimensions(Kernel::DeltaEMode::Type mode, API::MatrixWorkspace_const_sptr inWS=API::MatrixWorkspace_const_sptr()) const override
return the number of dimensions, calculated by the transformation from the workspace.
Definition: MDTransfQ3D.cpp:17
helper class describes the properties of target MD workspace, which should be obtained as the result ...
bool isLorentsCorrections() const
check if one needs to perform Lorentz corrections
Kernel::DeltaEMode::Type getEMode() const
std::vector< coord_t > getAddCoord() const
void getMinMax(std::vector< double > &min, std::vector< double > &max) const
get vector of minimal and maximal values from the class
DataObjects::TableWorkspace_const_sptr m_PreprDetTable
std::vector< double > getTransfMatrix() const
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
const std::string Q3D("Q3D")
Only convert to Q-vector.
static constexpr double E_mev_toNeutronWavenumberSq
Transformation coefficient to transform neutron energy into neutron wavevector: K-neutron[m^-10] = sq...
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27
Defines the possible energy transfer modes:
Definition: DeltaEMode.h:23
Type
Define the available energy transfer modes It is important to assign enums proper numbers,...
Definition: DeltaEMode.h:29