Mantid
Loading...
Searching...
No Matches
MDWSDescription.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 +
8
12#include "MantidAPI/Run.h"
13#include "MantidAPI/Sample.h"
14
17
21
22#include <boost/lexical_cast.hpp>
23#include <utility>
24
25namespace Mantid::MDAlgorithms {
26
31void MDWSDescription::setDimName(unsigned int nDim, const std::string &Name) {
32 if (nDim >= m_NDims) {
33 std::string ERR = "setDimName::Dimension index: " + std::to_string(nDim) +
34 " out of total dimensions range: " + std::to_string(m_NDims);
35 throw(std::invalid_argument(ERR));
36 }
37 m_DimNames[nDim] = Name;
38}
43void MDWSDescription::setDimUnit(unsigned int nDim, const std::string &Unit) {
44 if (nDim >= m_NDims) {
45 std::string ERR = "setDimUnit::Dimension index: " + std::to_string(nDim) +
46 " out of total dimensions range: " + std::to_string(m_NDims);
47 throw(std::invalid_argument(ERR));
48 }
49 m_DimUnits[nDim] = Unit;
50}
51
66void MDWSDescription::buildFromMatrixWS(const API::MatrixWorkspace_sptr &pWS, const std::string &QMode,
67 const std::string &dEMode, const std::vector<std::string> &dimPropertyNames) {
68 m_InWS = pWS;
69 // fill additional dimensions values, defined by workspace properties;
70 this->fillAddProperties(m_InWS, dimPropertyNames, m_AddCoord);
71
72 this->AlgID = QMode;
73
74 // check and get energy conversion mode;
75
77
78 // get raw pointer to Q-transformation (do not delete this pointer, its held
79 // by MDTransfFactory!)
80 MDTransfInterface *pQtransf = MDTransfFactory::Instance().create(QMode).get();
81
82 // get number of dimensions this Q transformation generates from the
83 // workspace.
84 unsigned int nMatrixDim = pQtransf->getNMatrixDimensions(m_Emode, m_InWS);
85
86 // number of MD ws dimensions is the sum of n-matrix dimensions and dimensions
87 // coming from additional coordinates
88 m_NDims = nMatrixDim + static_cast<unsigned int>(m_AddCoord.size());
90 // check if all MD dimensions descriptors are set properly
91 if (m_NDims != m_DimNames.size() || m_NDims != m_DimMin.size()) {
93 throw(std::invalid_argument(" dimension limits vectors and dimension "
94 "description vectors inconsistent as have "
95 "different length"));
96 } else {
97 throw(std::invalid_argument(" dimension limits vectors and dimension description vectors "
98 "inconsistent as have different length\n"
99 " Are you trying to add to existing workspace with convertToMD, "
100 "which generates workspace with different number of dimensions?"));
101 }
102 }
103
104 //*********** fill in dimension id-s, dimension units and dimension names
105 // get default dim ID-s. TODO: it should be possibility to override it later;
106 std::vector<std::string> MatrDimID = pQtransf->getDefaultDimID(m_Emode, m_InWS);
107 std::vector<std::string> MatrUnitID = pQtransf->outputUnitID(m_Emode, m_InWS);
108 for (unsigned int i = 0; i < m_NDims; i++) {
109 if (i < nMatrixDim) {
110 m_DimIDs[i] = MatrDimID[i];
111 m_DimNames[i] = MatrDimID[i];
112 m_DimUnits[i] = MatrUnitID[i];
113 } else {
114 m_DimIDs[i] = dimPropertyNames[i - nMatrixDim];
115 m_DimNames[i] = dimPropertyNames[i - nMatrixDim];
116 m_DimUnits[i] = dimPropertyNames[i - nMatrixDim];
117 }
118 }
119}
120
121void MDWSDescription::setWS(API::MatrixWorkspace_sptr otherMatrixWS) { m_InWS = std::move(otherMatrixWS); }
124 if ((m_InWS != nullptr) && (m_InWS->run().getNumGoniometers() > 0))
125 return m_InWS->run().getGoniometer().isDefined();
126 else
127 return false;
128}
132 if (m_InWS)
133 return m_InWS->run().getGoniometer().getR();
134 else
135 return Kernel::Matrix<double>(3, 3, true);
136}
137
143 m_NDims = static_cast<unsigned int>(pWS->getNumDims());
144 // prepare all arrays:
145 m_DimNames.resize(m_NDims);
146 m_DimIDs.resize(m_NDims);
147 m_DimUnits.resize(m_NDims);
148
149 m_NBins.resize(m_NDims);
150 m_DimMin.resize(m_NDims);
151 m_DimMax.resize(m_NDims);
152 for (size_t i = 0; i < m_NDims; i++) {
153 const Geometry::IMDDimension *pDim = pWS->getDimension(i).get();
154 m_DimNames[i] = pDim->getName();
155 m_DimIDs[i] = pDim->getDimensionId();
156 m_DimUnits[i] = pDim->getUnits();
157
158 m_NBins[i] = pDim->getNBins();
159 m_DimMin[i] = pDim->getMinimum();
160 m_DimMax[i] = pDim->getMaximum();
161 }
162 m_Wtransf = Kernel::DblMatrix(pWS->getWTransf());
163}
178 m_InWS = SourceMatrWS.m_InWS;
179 m_Emode = SourceMatrWS.m_Emode;
180 m_LorentzCorr = SourceMatrWS.m_LorentzCorr;
181 m_AbsMin = SourceMatrWS.m_AbsMin;
182 this->AlgID = SourceMatrWS.AlgID;
183
184 m_AddCoord.assign(SourceMatrWS.m_AddCoord.begin(), SourceMatrWS.m_AddCoord.end());
185}
186
201 if (m_NDims != NewMDWorkspaceD.m_NDims) {
202 std::string ERR = "Dimension numbers are inconsistent: this workspace has " + std::to_string(m_NDims) +
203 " dimensions and target one: " + std::to_string(NewMDWorkspaceD.m_NDims);
204 throw(std::invalid_argument(ERR));
205 }
206
208 throw(std::invalid_argument("Workspace description has not been correctly "
209 "defined, as emode has not been defined"));
210
211 // TODO: !!! Dim Unit currently have decorative name and is not used in real
212 // conversion. It is just a name. This is why this check does not work
213 // properly
214 /* for(size_t i=0;i<m_NDims;i++)
215 {
216 if(m_DimUnits[i] != NewMDWorkspaceD.m_DimUnits[i])
217 {
218 throw std::runtime_error("The target MDEventWorkspace dimension N:
219 "+boost::lexical_cast<std::string>(i)+" has units: "+m_DimUnits[i]+
220 " different from the requested: "+NewMDWorkspaceD.m_DimUnits[i]+
221 "\n Either give a different workspace as the output, or change the
222 OutputDimensions parameter.");
223 }
224 }*/
225
226 // TODO: More thorough checks may be necessary to prevent adding different
227 // kind of workspaces e.g 4D |Q|-dE-T-P workspace to Q3d+dE ws
228}
229
231MDWSDescription::MDWSDescription(unsigned int nDimensions)
232 : m_Wtransf(3, 3, true), m_RotMatrix(9, 0), m_buildingNewWorkspace(true), m_Emode(Kernel::DeltaEMode::Undefined),
233 m_LorentzCorr(false), m_AbsMin(0.), m_coordinateSystem(Mantid::Kernel::None) {
234
235 this->resizeDimDescriptions(nDimensions);
236 m_DimMin.assign(m_NDims, std::numeric_limits<double>::quiet_NaN());
237 m_DimMax.assign(m_NDims, std::numeric_limits<double>::quiet_NaN());
238
239 // set transformation matrix to identity - aka do nothing
240 m_RotMatrix[0] = 1.;
241 m_RotMatrix[4] = 1.;
242 m_RotMatrix[8] = 1.;
243}
244void MDWSDescription::resizeDimDescriptions(unsigned int nDimensions, size_t nBins) {
246
247 m_DimNames.assign(m_NDims, "mdn");
248 m_DimIDs.assign(m_NDims, "mdn_");
249 m_DimUnits.assign(m_NDims, "Momentum");
250 m_NBins.assign(m_NDims, nBins);
251
252 for (size_t i = 0; i < m_NDims; i++) {
253 m_DimIDs[i] = m_DimIDs[i] + std::to_string(i);
255 }
256}
263void MDWSDescription::setNumBins(const std::vector<int> &nBins_toSplit) {
264
265 if (!(nBins_toSplit.size() == 1 || nBins_toSplit.size() == this->m_NDims))
266 throw std::invalid_argument(" Number of dimensions: " + std::to_string(nBins_toSplit.size()) +
267 " defining number of bins to split into is not equal to total number "
268 "of dimensions: " +
269 std::to_string(this->m_NDims));
270
271 this->m_NBins.resize(this->m_NDims);
272
273 bool propagateOneNum = true;
274 if (nBins_toSplit.size() == this->m_NDims)
275 propagateOneNum = false;
276
277 for (size_t i = 0; i < this->m_NDims; i++) {
278 if (propagateOneNum)
279 this->m_NBins[i] = nBins_toSplit[0];
280 else
281 this->m_NBins[i] = nBins_toSplit[i];
282 }
283}
284
290void MDWSDescription::setMinMax(const std::vector<double> &minVal, const std::vector<double> &maxVal) {
291 m_DimMin.assign(minVal.begin(), minVal.end());
292 m_DimMax.assign(maxVal.begin(), maxVal.end());
293
295}
296
298void MDWSDescription::getMinMax(std::vector<double> &min, std::vector<double> &max) const {
299 min.assign(m_DimMin.begin(), m_DimMin.end());
300 max.assign(m_DimMax.begin(), m_DimMax.end());
301}
302//******************************************************************************************************************************************
303//************* HELPER FUNCTIONS
304//******************************************************************************************************************************************
307 return (this->AlgID == "|Q|") || (this->AlgID.empty() && !m_InWS->sample().hasOrientedLattice());
308}
309
312
324 const std::vector<std::string> &dimPropertyNames,
325 std::vector<coord_t> &AddCoord) {
326 size_t nDimPropNames = dimPropertyNames.size();
327 if (AddCoord.size() != nDimPropNames)
328 AddCoord.resize(nDimPropNames);
329 const auto &runObj = inWS2D->run();
330
331 for (size_t i = 0; i < nDimPropNames; i++) {
332 try {
333 const double value = runObj.getLogAsSingleValue(dimPropertyNames[i], Mantid::Kernel::Math::TimeAveragedMean);
334 AddCoord[i] = static_cast<coord_t>(value);
335 } catch (std::invalid_argument &) {
336 std::string ERR = " Can not interpret property, used as dimension.\n Property: " + dimPropertyNames[i] +
337 " cannot be converted into a double.";
338 throw(std::invalid_argument(ERR));
339 }
340 }
341}
342
346void MDWSDescription::checkMinMaxNdimConsistent(const std::vector<double> &minVal, const std::vector<double> &maxVal) {
347 if (minVal.size() != maxVal.size()) {
348 std::string ERR = " number of specified min dimension values: " + std::to_string(minVal.size()) +
349 " and number of max values: " + std::to_string(maxVal.size()) + " are not consistent\n";
350 throw(std::invalid_argument(ERR));
351 }
352
353 for (size_t i = 0; i < minVal.size(); i++) {
354 if (maxVal[i] <= minVal[i]) {
355 std::string ERR = " min value " + boost::lexical_cast<std::string>(minVal[i]) + " not less then max value" +
356 boost::lexical_cast<std::string>(maxVal[i]) + " in direction: " + std::to_string(i) + "\n";
357 throw(std::invalid_argument(ERR));
358 }
359 }
360}
361
363std::shared_ptr<Geometry::OrientedLattice>
365 // try to get the WS oriented lattice
366 std::shared_ptr<Geometry::OrientedLattice> orl;
367 if (inWS2D->sample().hasOrientedLattice())
368 orl = std::shared_ptr<Geometry::OrientedLattice>(
369 new Geometry::OrientedLattice(inWS2D->sample().getOrientedLattice()));
370
371 return orl;
372}
373
380
390
395void MDWSDescription::setFrame(const std::string &frameKey) { m_frameKey = frameKey; }
396
399
404bool MDWSDescription::isQ3DMode() const { return this->AlgID == "Q3D"; }
405
406bool MDWSDescription::hasLattice() const { return m_InWS->sample().hasOrientedLattice(); }
407
408} // namespace Mantid::MDAlgorithms
double value
The value of the point.
Definition FitMW.cpp:51
The class describes one dimension of multidimensional dataset representing an orthogonal dimension an...
virtual coord_t getMaximum() const =0
virtual coord_t getMinimum() const =0
virtual std::string getName() const =0
virtual const Kernel::UnitLabel getUnits() const =0
virtual const std::string & getDimensionId() const =0
short name which identify the dimension among other dimension.
virtual size_t getNBins() const =0
Input argument type for MDFrameFactory chainable factory.
Class to implement UB matrix.
Numerical Matrix class.
Definition Matrix.h:42
The base units (abstract) class.
Definition Unit.h:41
Interface to set of sub-classes used by ConvertToMD algorithm and responsible for conversion of input...
virtual std::vector< std::string > getDefaultDimID(Kernel::DeltaEMode::Type dEmode, API::MatrixWorkspace_const_sptr inWS) const =0
when one builds MD workspace, he needs a dimension names/ID-s which can be different for different Q-...
virtual std::vector< std::string > outputUnitID(Kernel::DeltaEMode::Type dEmode, API::MatrixWorkspace_const_sptr inWS) const =0
The transformation generates output MD events in particular units.
virtual unsigned int getNMatrixDimensions(Kernel::DeltaEMode::Type mode, API::MatrixWorkspace_const_sptr inWS) const =0
return the number of dimensions, calculated by the transformation from the workspace.
helper class describes the properties of target MD workspace, which should be obtained as the result ...
void setMinMax(const std::vector< double > &minVal, const std::vector< double > &maxVal)
function sets up min-max values to the dimensions, described by the class
void resizeDimDescriptions(unsigned int nDimensions, size_t nBins=10)
helper function to resize all vectors, responsible for MD dimensions in one go
bool isQ3DMode() const
Is the algorithm running in Q3D mode?
double m_AbsMin
hole near origin of Q
std::vector< std::string > m_DimNames
the names for the target workspace dimensions and properties of input MD workspace
Kernel::DeltaEMode::Type m_Emode
energy transfer analysis mode
std::vector< std::string > m_DimUnits
the units of target workspace dimensions and properties of input MD workspace dimensions
void setDimName(unsigned int nDim, const std::string &Name)
set specific (non-default) dimension name
void setUpMissingParameters(const MDWSDescription &SourceMatrWS)
copy some parameters from the input workspace, as target md WS do not have all information about the ...
void setNumBins(const std::vector< int > &nBins_toSplit)
sets number of bins each dimension is split
static std::shared_ptr< Geometry::OrientedLattice > getOrientedLattice(const Mantid::API::MatrixWorkspace_const_sptr &inWS2D)
function retrieves copy of the oriented lattice from the workspace
std::string m_frameKey
Frame key. For frame to use.
void setFrame(const std::string &frameKey)
Set the md frame.
Geometry::MDFrame_uptr getFrame(size_t d) const
Retrieve the md frame.
static void checkMinMaxNdimConsistent(const std::vector< double > &minVal, const std::vector< double > &maxVal)
helper function checks if min values are less them max values and are consistent between each other
Mantid::Kernel::SpecialCoordinateSystem m_coordinateSystem
Coordinate system.
Kernel::Matrix< double > getGoniometerMatr() const
method returns goniometer matrix if one is defined on the workspace or unit matrix if there are no su...
void setDimUnit(unsigned int nDim, const std::string &Unit)
this is rather misleading function, as MD workspace does not currently have dimension units.
bool hasGoniometer() const
Method checks if input workspace has defined goniometer.
void buildFromMDWS(const API::IMDEventWorkspace_const_sptr &pWS)
method builds MD Event description from existing MD event workspace
std::vector< coord_t > m_AddCoord
the vector of MD coordinates, which are obtained from workspace properties.
bool m_LorentzCorr
if one needs to calculate Lorentz corrections
std::string getEModeStr() const
Returns symbolic representation of current Emode.
std::vector< size_t > m_NBins
if defined, specifies number of bins split in each dimension
std::string AlgID
the string which describes ChildAlgorithm, used to convert source ws to target MD ws.
Mantid::Kernel::SpecialCoordinateSystem getCoordinateSystem() const
unsigned int m_NDims
the variable which describes the number of the dimensions, in the target workspace.
void buildFromMatrixWS(const API::MatrixWorkspace_sptr &pWS, const std::string &QMode, const std::string &dEMode, const std::vector< std::string > &dimPropertyNames=std::vector< std::string >())
method builds MD Event ws description from a matrix workspace and the transformations,...
void setWS(API::MatrixWorkspace_sptr otherMatrixWS)
void getMinMax(std::vector< double > &min, std::vector< double > &max) const
get vector of minimal and maximal values from the class
std::vector< double > m_DimMin
minimal and maximal values for the workspace dimensions.
MDWSDescription(unsigned int nDimensions=0)
constructor
bool isPowder() const
Method checks if the workspace is expected to be processed in powder mode.
std::vector< std::string > m_DimIDs
the ID-s for the target workspace, which allow to identify the dimensions according to their ID
static void fillAddProperties(const Mantid::API::MatrixWorkspace_const_sptr &inWS2D, const std::vector< std::string > &dimPropertyNames, std::vector< coord_t > &AddCoord)
function extracts the coordinates from additional workspace properties and places them to AddCoord ve...
void checkWSCorresponsMDWorkspace(const MDWSDescription &NewMDWorkspaceD)
compare two descriptions and select the complimentary result.
void setCoordinateSystem(const Mantid::Kernel::SpecialCoordinateSystem system)
Set the special coordinate system if any.
std::shared_ptr< const IMDEventWorkspace > IMDEventWorkspace_const_sptr
Shared pointer to Mantid::API::IMDEventWorkspace (const version)
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unique_ptr< MDFrame > MDFrame_uptr
Definition MDFrame.h:36
MDFrameFactory_uptr MANTID_GEOMETRY_DLL makeMDFrameFactoryChain()
Make a complete factory chain.
SpecialCoordinateSystem
Special coordinate systems for Q3D.
Mantid::Kernel::Matrix< double > DblMatrix
Definition Matrix.h:206
Helper class which provides the Collimation Length for SANS instruments.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition MDTypes.h:27
std::string to_string(const wide_integer< Bits, Signed > &n)
Defines the possible energy transfer modes:
Definition DeltaEMode.h:23
static std::string asString(const Type mode)
Return a string representation of the given mode.
static Type fromString(const std::string &modeStr)
Returns the emode from the given string.
@ Undefined
this mode should not be displayed among modes availible to select but may have string representation
Definition DeltaEMode.h:33