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
205 if (m_NDims != NewMDWorkspaceD.m_NDims) {
206 std::string ERR = "Dimension numbers are inconsistent: this workspace has " + std::to_string(m_NDims) +
207 " dimensions and target one: " + std::to_string(NewMDWorkspaceD.m_NDims);
208 throw(std::invalid_argument(ERR));
209 }
210
212 throw(std::invalid_argument("Workspace description has not been correctly "
213 "defined, as emode has not been defined"));
214
215 // TODO: !!! Dim Unit currently have decorative name and is not used in real
216 // conversion. It is just a name. This is why this check does not work
217 // properly
218 /* for(size_t i=0;i<m_NDims;i++)
219 {
220 if(m_DimUnits[i] != NewMDWorkspaceD.m_DimUnits[i])
221 {
222 throw std::runtime_error("The target MDEventWorkspace dimension N:
223 "+boost::lexical_cast<std::string>(i)+" has units: "+m_DimUnits[i]+
224 " different from the requested: "+NewMDWorkspaceD.m_DimUnits[i]+
225 "\n Either give a different workspace as the output, or change the
226 OutputDimensions parameter.");
227 }
228 }*/
229
230 // TODO: More thorough checks may be necessary to prevent adding different
231 // kind of workspaces e.g 4D |Q|-dE-T-P workspace to Q3d+dE ws
232}
233
235MDWSDescription::MDWSDescription(unsigned int nDimensions)
236 : m_Wtransf(3, 3, true), m_RotMatrix(9, 0), m_buildingNewWorkspace(true), m_Emode(Kernel::DeltaEMode::Undefined),
237 m_LorentzCorr(false), m_AbsMin(0.), m_coordinateSystem(Mantid::Kernel::None) {
238
239 this->resizeDimDescriptions(nDimensions);
240 m_DimMin.assign(m_NDims, std::numeric_limits<double>::quiet_NaN());
241 m_DimMax.assign(m_NDims, std::numeric_limits<double>::quiet_NaN());
242
243 // set transformation matrix to identity - aka do nothing
244 m_RotMatrix[0] = 1.;
245 m_RotMatrix[4] = 1.;
246 m_RotMatrix[8] = 1.;
247}
248void MDWSDescription::resizeDimDescriptions(unsigned int nDimensions, size_t nBins) {
250
251 m_DimNames.assign(m_NDims, "mdn");
252 m_DimIDs.assign(m_NDims, "mdn_");
253 m_DimUnits.assign(m_NDims, "Momentum");
254 m_NBins.assign(m_NDims, nBins);
255
256 for (size_t i = 0; i < m_NDims; i++) {
257 m_DimIDs[i] = m_DimIDs[i] + std::to_string(i);
259 }
260}
267void MDWSDescription::setNumBins(const std::vector<int> &nBins_toSplit) {
268
269 if (!(nBins_toSplit.size() == 1 || nBins_toSplit.size() == this->m_NDims))
270 throw std::invalid_argument(" Number of dimensions: " + std::to_string(nBins_toSplit.size()) +
271 " defining number of bins to split into is not equal to total number "
272 "of dimensions: " +
273 std::to_string(this->m_NDims));
274
275 this->m_NBins.resize(this->m_NDims);
276
277 bool propagateOneNum = true;
278 if (nBins_toSplit.size() == this->m_NDims)
279 propagateOneNum = false;
280
281 for (size_t i = 0; i < this->m_NDims; i++) {
282 if (propagateOneNum)
283 this->m_NBins[i] = nBins_toSplit[0];
284 else
285 this->m_NBins[i] = nBins_toSplit[i];
286 }
287}
288
294void MDWSDescription::setMinMax(const std::vector<double> &minVal, const std::vector<double> &maxVal) {
295 m_DimMin.assign(minVal.begin(), minVal.end());
296 m_DimMax.assign(maxVal.begin(), maxVal.end());
297
299}
300
302void MDWSDescription::getMinMax(std::vector<double> &min, std::vector<double> &max) const {
303 min.assign(m_DimMin.begin(), m_DimMin.end());
304 max.assign(m_DimMax.begin(), m_DimMax.end());
305}
306//******************************************************************************************************************************************
307//************* HELPER FUNCTIONS
308//******************************************************************************************************************************************
311 return (this->AlgID == "|Q|") || (this->AlgID.empty() && !m_InWS->sample().hasOrientedLattice());
312}
313
316
330 const std::vector<std::string> &dimPropertyNames,
331 std::vector<coord_t> &AddCoord) {
332 size_t nDimPropNames = dimPropertyNames.size();
333 if (AddCoord.size() != nDimPropNames)
334 AddCoord.resize(nDimPropNames);
335 const auto &runObj = inWS2D->run();
336
337 for (size_t i = 0; i < nDimPropNames; i++) {
338 try {
339 const double value = runObj.getLogAsSingleValue(dimPropertyNames[i], Mantid::Kernel::Math::TimeAveragedMean);
340 AddCoord[i] = static_cast<coord_t>(value);
341 } catch (std::invalid_argument &) {
342 std::string ERR = " Can not interpret property, used as dimension.\n Property: " + dimPropertyNames[i] +
343 " cannot be converted into a double.";
344 throw(std::invalid_argument(ERR));
345 }
346 }
347}
348
352void MDWSDescription::checkMinMaxNdimConsistent(const std::vector<double> &minVal, const std::vector<double> &maxVal) {
353 if (minVal.size() != maxVal.size()) {
354 std::string ERR = " number of specified min dimension values: " + std::to_string(minVal.size()) +
355 " and number of max values: " + std::to_string(maxVal.size()) + " are not consistent\n";
356 throw(std::invalid_argument(ERR));
357 }
358
359 for (size_t i = 0; i < minVal.size(); i++) {
360 if (maxVal[i] <= minVal[i]) {
361 std::string ERR = " min value " + boost::lexical_cast<std::string>(minVal[i]) + " not less then max value" +
362 boost::lexical_cast<std::string>(maxVal[i]) + " in direction: " + std::to_string(i) + "\n";
363 throw(std::invalid_argument(ERR));
364 }
365 }
366}
367
369std::shared_ptr<Geometry::OrientedLattice>
371 // try to get the WS oriented lattice
372 std::shared_ptr<Geometry::OrientedLattice> orl;
373 if (inWS2D->sample().hasOrientedLattice())
374 orl = std::shared_ptr<Geometry::OrientedLattice>(
375 new Geometry::OrientedLattice(inWS2D->sample().getOrientedLattice()));
376
377 return orl;
378}
379
384 m_coordinateSystem = system;
385}
386
393 auto factory = Geometry::makeMDFrameFactoryChain();
394 return factory->create(Geometry::MDFrameArgument(m_frameKey, m_DimUnits[d]));
395}
396
401void MDWSDescription::setFrame(const std::string &frameKey) { m_frameKey = frameKey; }
402
405
410bool MDWSDescription::isQ3DMode() const { return this->AlgID == "Q3D"; }
411
412bool MDWSDescription::hasLattice() const { return m_InWS->sample().hasOrientedLattice(); }
413
414} // 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...
Definition: IMDDimension.h:39
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
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
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...
API::MatrixWorkspace_sptr m_InWS
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.
Definition: DeltaEMode.cpp:52
static Type fromString(const std::string &modeStr)
Returns the emode from the given string.
Definition: DeltaEMode.cpp:69
@ Undefined
this mode should not be displayed among modes availible to select but may have string representation
Definition: DeltaEMode.h:33