Mantid
Loading...
Searching...
No Matches
CompareMDWorkspaces.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 +
14#include "MantidKernel/System.h"
15#include <sstream>
16#include <utility>
17
18using namespace Mantid::Kernel;
19using namespace Mantid::API;
20using namespace Mantid::DataObjects;
21using namespace Mantid::Geometry;
22
23//=============================================================================
27class CompareFailsException : public std::runtime_error {
28public:
29 explicit CompareFailsException(const std::string &msg) : std::runtime_error(msg) {}
30 std::string getMessage() const { return this->what(); }
31};
32
33namespace Mantid::MDAlgorithms {
34
36
37private:
38 std::vector<float> mCoordinates;
39 float mSignal;
40 float mError;
41
42public:
44 static float s_tolerance;
45 // static float s_tolerance {static_cast<float>(1E-7)};
46
47 SimpleMDEvent(std::vector<float> coordinates, const float &signal, const float &error)
48 : mCoordinates(std::move(coordinates)), mSignal(signal), mError(error) {}
49
50 SimpleMDEvent(const SimpleMDEvent &other) = default;
51
52 // pretty output
53 std::string str() const {
54 std::stringstream ss;
55 size_t numdirs = mCoordinates.size();
56 for (size_t i = 0; i < numdirs; ++i)
57 ss << mCoordinates[i] << ", ";
58 ss << "signal = " << mSignal << ", error = " << mError;
59
60 return ss.str();
61 }
62
63 float getCenter(size_t dim) const { return mCoordinates[dim]; }
64
65 float getSignal() const { return mSignal; }
66
67 float getError() const { return mError; }
68
69 bool operator()(const SimpleMDEvent &event1, const SimpleMDEvent &event2) const { return event1 < event2; }
70
79 bool operator<(const SimpleMDEvent &event2) const {
80
81 bool less(true);
82 bool equal(false);
83
84 // compare coordinates
85 size_t numdirs = mCoordinates.size();
86 for (size_t i = 0; i < numdirs; ++i) {
87 // equal is hard to tell
88 coord_t diff = mCoordinates[i] - event2.mCoordinates[i];
89
90 if (fabs(mCoordinates[i]) > s_tolerance && fabs(diff / mCoordinates[i]) < s_tolerance * 10.) {
91 // larger than epsilon and relative difference less than epsilon
92 equal = true;
93 less = false;
94 } else if (fabs(mCoordinates[i]) < s_tolerance && fabs(diff) < s_tolerance) {
95 // less than epsilon and absolute difference less than epsilon
96 equal = true;
97 less = false;
98 } else if (diff < 0) {
99 // less
100 less = true;
101 } else {
102 // larger
103 less = false;
104 }
105
106 // no need to continue
107 if (!equal)
108 break;
109 }
110
111 // signal
112 if (equal && mSignal < event2.mSignal) {
113 less = true;
114 equal = false;
115 } else if (equal && mSignal > event2.mSignal) {
116 less = false;
117 equal = false;
118 }
119
120 // error: no need to continue the comparison
121 if (equal && mError >= event2.mError) {
122 less = false;
123 }
124
125 return less;
126 }
127
129 // coordiate
130 size_t numdirs = mCoordinates.size();
131 for (size_t i = 0; i < numdirs; ++i)
132 mCoordinates[i] = event2.mCoordinates[i];
133 // signal and error
134 mSignal = event2.mSignal;
135 mError = event2.mError;
136
137 return *this;
138 }
139};
140
141float SimpleMDEvent::s_tolerance(static_cast<float>(1E-7));
142
143//----------------------------------------------------------------------------------------------
144bool compareSimpleEvents(const SimpleMDEvent &self, const SimpleMDEvent &other) { return self < other; }
145
146// Register the algorithm into the AlgorithmFactory
147DECLARE_ALGORITHM(CompareMDWorkspaces)
148
149//----------------------------------------------------------------------------------------------
151const std::string CompareMDWorkspaces::name() const { return "CompareMDWorkspaces"; }
152
154int CompareMDWorkspaces::version() const { return 1; }
155
157const std::string CompareMDWorkspaces::category() const { return "MDAlgorithms\\Utility\\Workspaces"; }
158
159//----------------------------------------------------------------------------------------------
163 declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("Workspace1", "", Direction::Input),
164 "First MDWorkspace to compare.");
165 declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("Workspace2", "", Direction::Input),
166 "Second MDWorkspace to compare.");
167
168 declareProperty("Tolerance", 0.0, "The maximum amount by which values may differ between the workspaces.");
169 declareProperty("MDEventTolerance", 1E-7,
170 "The maximum amount by which values may differ between 2 MDEvents to compare.");
171 declareProperty("CheckEvents", true,
172 "Whether to compare each MDEvent. If "
173 "False, will only look at the box "
174 "structure.");
175
176 declareProperty(std::make_unique<PropertyWithValue<bool>>("Equals", false, Direction::Output),
177 "Boolean set to true if the workspaces match.");
179 "String describing the difference found between the workspaces");
180 declareProperty("IgnoreBoxID", false,
181 "To ignore box ID-s when comparing MD "
182 "boxes as Multithreaded splitting "
183 "assigns box id-s randomly");
184}
185
186//----------------------------------------------------------------------------------------------
188template <typename T> std::string versus(T a, T b) {
189 return "(" + Strings::toString(a) + " vs " + Strings::toString(b) + ")";
190}
191
192//----------------------------------------------------------------------------------------------
200template <typename T> void CompareMDWorkspaces::compare(T a, T b, const std::string &message) {
201 if (a != b)
202 throw CompareFailsException(message + " " + versus(a, b));
203}
204
205//----------------------------------------------------------------------------------------------
213template <class T> void CompareMDWorkspaces::compareTol(T a, T b, const std::string &message) {
214 double diff = fabs(a - b);
215 if (diff > m_tolerance) {
216 double pa = fabs(a);
217 double pb = fabs(b);
218 if ((pa > 2 * m_tolerance) || (pb > 2 * m_tolerance)) {
219 diff = 0.5 * diff / (pa + pb);
220 if (diff > m_tolerance)
221 throw CompareFailsException(message + " " + versus(a, b));
222 } else
223 throw CompareFailsException(message + " " + versus(a, b));
224 }
225}
226
227//----------------------------------------------------------------------------------------------
232 compare(ws1->getNumDims(), ws2->getNumDims(), "Workspaces have a different number of dimensions");
233 for (size_t d = 0; d < ws1->getNumDims(); d++) {
234 IMDDimension_const_sptr dim1 = ws1->getDimension(d);
235 IMDDimension_const_sptr dim2 = ws2->getDimension(d);
236 compare(dim1->getName(), dim2->getName(), "Dimension #" + Strings::toString(d) + " has a different name");
237 compare(dim1->getUnits(), dim2->getUnits(), "Dimension #" + Strings::toString(d) + " has different units");
238 compare(dim1->getNBins(), dim2->getNBins(),
239 "Dimension #" + Strings::toString(d) + " has a different number of bins");
240 compareTol(dim1->getMinimum(), dim2->getMinimum(),
241 "Dimension #" + Strings::toString(d) + " has a different minimum");
242 compareTol(dim1->getMaximum(), dim2->getMaximum(),
243 "Dimension #" + Strings::toString(d) + " has a different maximum");
244 }
245}
246
247//----------------------------------------------------------------------------------------------
252 compare(ws1->getNumDims(), ws2->getNumDims(), "Workspaces have a different number of dimensions");
253 compare(ws1->getNPoints(), ws2->getNPoints(), "Workspaces have a different number of points");
254 for (size_t i = 0; i < ws1->getNPoints(); i++) {
255 double diff = fabs(ws1->getSignalAt(i) - ws2->getSignalAt(i));
256 if (diff > m_tolerance)
257 throw CompareFailsException("MDHistoWorkspaces have a different signal at index " + Strings::toString(i) + " " +
258 versus(ws1->getSignalAt(i), ws2->getSignalAt(i)));
259
260 double diffErr = fabs(ws1->getErrorAt(i) - ws2->getErrorAt(i));
261 if (diffErr > m_tolerance)
262 throw CompareFailsException("MDHistoWorkspaces have a different error at index " + Strings::toString(i) + " " +
263 versus(ws1->getErrorAt(i), ws2->getErrorAt(i)));
264 }
265}
266
267//----------------------------------------------------------------------------------------------
272template <typename MDE, size_t nd>
274 typename MDEventWorkspace<MDE, nd>::sptr ws2 = std::dynamic_pointer_cast<MDEventWorkspace<MDE, nd>>(inWS2);
275 if (!ws1 || !ws2)
276 throw std::runtime_error("Incompatible workspace types passed to PlusMD.");
277
278 std::vector<API::IMDNode *> boxes1;
279 std::vector<API::IMDNode *> boxes2;
280
281 ws1->getBox()->getBoxes(boxes1, 1000, false);
282 ws2->getBox()->getBoxes(boxes2, 1000, false);
283 std::stringstream ess;
284 ess << "Workspace1 has " << boxes1.size() << " boxes; Workspace2 has " << boxes2.size() << " boxes";
285 std::string boxinfo(ess.str());
286
287 this->compare(boxes1.size(), boxes2.size(), "Workspaces do not have the same number of boxes. " + boxinfo);
288 g_log.information(boxinfo);
289
290 bool boxes_same(true);
291 std::string errormessage("");
292 int num_boxes = static_cast<int>(boxes1.size());
293 // workspace with file backed cannot work with OpenMP
294 // segmentation fault is generated on Mac build
295 bool filebacked = ws1->isFileBacked() || ws2->isFileBacked();
296
297 PRAGMA_OMP( parallel for if (!filebacked))
298 for (int ibox = 0; ibox < num_boxes; ibox++) {
300 // No need to compare because the boxes are not same already
301 if (!boxes_same) {
302 continue;
303 }
304
305 bool local_fail(false);
306 std::string local_error("");
307
308 API::IMDNode *box1 = boxes1[ibox];
309 API::IMDNode *box2 = boxes2[ibox];
310 g_log.debug() << "Box " << ibox << "ws1 npoints = " << box1->getNPoints()
311 << "; ws2 npoints = " << box2->getNPoints() << "\n";
312
313 try {
314 CompareMDWorkspaces::compare2Boxes<MDE, nd>(box1, box2, static_cast<size_t>(ibox));
315 } catch (CompareFailsException &err) {
316 local_fail = true;
317 local_error += err.what();
318 }
319
320 PARALLEL_CRITICAL(FindPeaks_WriteOutput) {
321 if (local_fail) {
322 boxes_same = false;
323 errormessage += local_error;
324 }
325 }
326
328 } // for box
330
331 // throw altogether
332 if (!boxes_same) {
333 throw CompareFailsException(errormessage);
334 }
335}
336
337template <typename MDE, size_t nd>
339
340 if (m_CompareBoxID)
341 this->compare(box1->getID(), box2->getID(), "Boxes have different ID");
342 else {
343 if (box1->getID() != box2->getID())
344 g_log.debug() << " Boxes N: " << ibox << " have box ID: " << box1->getID() << " and " << box2->getID()
345 << " correspondingly\n";
346 }
347 this->compare(size_t(box1->getDepth()), size_t(box2->getDepth()), "Boxes are at a different depth");
348 this->compare(box1->getNumChildren(), box2->getNumChildren(), "Boxes do not have the same number of children");
349
350 for (size_t i = 0; i < box1->getNumChildren(); i++) {
351 if (m_CompareBoxID)
352 this->compare(box1->getChild(i)->getID(), box2->getChild(i)->getID(), "Child of boxes do not match IDs");
353 else {
354 if (box1->getID() != box2->getID())
355 g_log.debug() << " Boxes N: " << ibox << " children N: " << i << " have box ID: " << box1->getChild(i)->getID()
356 << " and " << box2->getChild(i)->getID() << " correspondingly\n";
357 }
358 }
359
360 for (size_t d = 0; d < nd; d++) {
361 this->compareTol(box1->getExtents(d).getMin(), box2->getExtents(d).getMin(), "Extents of box do not match");
362 this->compareTol(box1->getExtents(d).getMax(), box2->getExtents(d).getMax(), "Extents of box do not match");
363 }
364 this->compareTol(box1->getInverseVolume(), box2->getInverseVolume(), "Box inverse volume does not match");
365 this->compareTol(box1->getSignal(), box2->getSignal(), "Box signal does not match");
366 this->compareTol(box1->getErrorSquared(), box2->getErrorSquared(), "Box error squared does not match");
367 if (m_CheckEvents)
368 this->compare(box1->getNPoints(), box2->getNPoints(), "Number of points in box does not match");
369
370 // Are both MDGridBoxes ?
371 auto *gridbox1 = dynamic_cast<MDGridBox<MDE, nd> *>(box1);
372 auto *gridbox2 = dynamic_cast<MDGridBox<MDE, nd> *>(box2);
373 if (gridbox1 && gridbox2) {
374 // MDGridBox: compare box size on each dimension
375 for (size_t d = 0; d < nd; d++)
376 this->compareTol(gridbox1->getBoxSize(d), gridbox2->getBoxSize(d), "Box sizes do not match");
377 } else {
378 // Could be both MDBoxes (with events)
379 auto *mdbox1 = dynamic_cast<MDBox<MDE, nd> *>(box1);
380 auto *mdbox2 = dynamic_cast<MDBox<MDE, nd> *>(box2);
381 g_log.debug() << "Box " << ibox << "ws1 npoints = " << box1->getNPoints()
382 << "; ws2 npoints = " << box2->getNPoints() << "\n";
383
384 // Rule out the case if one and only one box is MDBox
385 if (mdbox1 && !mdbox2) {
386 // workspace 2's is MDBox but workspace 1 is not
387 throw CompareFailsException("Worksapce 2's Box " + std::to_string(ibox) + " is not MDBox");
388 } else if (!mdbox1 && mdbox2) {
389 // workspace 2's is MDBox but workspace 1 is not
390 throw CompareFailsException("Worksapce 1's Box " + std::to_string(ibox) + " is not MDBox");
391 }
392
393 // Both boxes are MDBoxes:
394 if (m_CheckEvents) {
395 const std::vector<MDE> &events1 = mdbox1->getConstEvents();
396 const std::vector<MDE> &events2 = mdbox2->getConstEvents();
397
398 try {
399 this->compare(events1.size(), events2.size(), "Box event vectors are not the same length");
400
401 if (events1.size() == events2.size() && events1.size() > 2) {
402
403 std::vector<SimpleMDEvent> events_vec1;
404 std::vector<SimpleMDEvent> events_vec2;
405
406 // convert MDEvents vectors to SimpleMDEvent vectors for comparison
407 for (size_t i = 0; i < events1.size(); i++) {
408 std::vector<float> centers1(nd);
409 std::vector<float> centers2(nd);
410 for (size_t d = 0; d < nd; d++) {
411 centers1[d] = events1[i].getCenter(d);
412 centers2[d] = events2[i].getCenter(d);
413 }
414 SimpleMDEvent se1(centers1, events1[i].getSignal(), events1[i].getErrorSquared());
415 SimpleMDEvent se2(centers2, events2[i].getSignal(), events2[i].getErrorSquared());
416 events_vec1.push_back(se1);
417 events_vec2.push_back(se2);
418 }
419
420 // sort events for comparing
421 std::sort(events_vec1.begin(), events_vec1.end());
422 std::sort(events_vec2.begin(), events_vec2.end());
423
424 // compare MEEvents
425 bool same = true;
426 size_t numdiff = 0;
427 for (size_t i = 0; i < events_vec1.size(); ++i) {
428 try {
429 // coordinate
430 for (size_t d = 0; d < nd; ++d) {
431 compareTol(events_vec1[i].getCenter(d), events_vec2[i].getCenter(d), "dim " + std::to_string(d) + " ");
432 }
433 // signal
434 compareTol(events_vec1[i].getSignal(), events_vec2[i].getSignal(), "");
435 // error
436 compareTol(events_vec1[i].getError(), events_vec2[i].getError(), "");
437 } catch (CompareFailsException &e) {
438 g_log.debug() << "Box " << ibox << " Event " << i << ": " << e.what()
439 << "\n [ws1] : " + events_vec1[i].str() << "\n [ws2] : " + events_vec2[i].str()
440 << "\n";
441 numdiff++;
442 same = false;
443 }
444 }
445
446 if (!same) {
447 std::string diffmessage("Box " + std::to_string(ibox) +
448 " Number of different MDEvents = " + std::to_string(numdiff));
449 throw CompareFailsException("MDEvents are not the same!\n" + diffmessage);
450 }
451 }
452 } catch (CompareFailsException &) {
453 // Boxes must release events if the check fails
454 mdbox1->releaseEvents();
455 mdbox2->releaseEvents();
456 // Rethrow with the same type of error message!
457 throw;
458 }
459 mdbox1->releaseEvents();
460 mdbox2->releaseEvents();
461 } // if check events
462 } // if-else for MDGridBox or MDBox
463}
464
465//----------------------------------------------------------------------------------------------
469 m_tolerance = getProperty("Tolerance");
470 m_CheckEvents = getProperty("CheckEvents");
471 if (m_CheckEvents) {
472 double x = getProperty("MDEventTolerance");
473 SimpleMDEvent::s_tolerance = static_cast<float>(x);
474 }
475
476 IMDWorkspace_sptr ws1 = getProperty("Workspace1");
477 IMDWorkspace_sptr ws2 = getProperty("Workspace2");
478 inWS2 = ws2;
479 if (!ws1 || !ws2)
480 throw std::invalid_argument("Invalid workspace given.");
481
482 MatrixWorkspace_sptr mws1 = std::dynamic_pointer_cast<MatrixWorkspace>(ws1);
483 MatrixWorkspace_sptr mws2 = std::dynamic_pointer_cast<MatrixWorkspace>(ws2);
484 if (mws1 || mws2)
485 throw std::invalid_argument("Cannot compare MatrixWorkspaces. Please use "
486 "CompareWorkspaces algorithm instead.");
487
488 MDHistoWorkspace_sptr histo1 = std::dynamic_pointer_cast<MDHistoWorkspace>(ws1);
489 MDHistoWorkspace_sptr histo2 = std::dynamic_pointer_cast<MDHistoWorkspace>(ws2);
490 IMDEventWorkspace_sptr event1 = std::dynamic_pointer_cast<IMDEventWorkspace>(ws1);
491 IMDEventWorkspace_sptr event2 = std::dynamic_pointer_cast<IMDEventWorkspace>(ws2);
492
493 try {
494 compare(ws1->id(), ws2->id(), "Workspaces are of different types");
495
496 this->compareMDGeometry(ws1, ws2);
497
498 if (histo1 && histo2) {
499 this->compareMDHistoWorkspaces(histo1, histo2);
500 } else if (event1 && event2) {
502 } else
503 m_result = "Workspaces are of different types.";
504 } catch (CompareFailsException &e) {
505 m_result = e.getMessage();
506 }
507}
508
509//----------------------------------------------------------------------------------------------
513 m_result.clear();
514 m_CompareBoxID = !getProperty("IgnoreBoxID");
515
516 this->doComparison();
517
518 if (!m_result.empty()) {
519 g_log.notice() << "The workspaces did not match: " << m_result << '\n';
520 this->setProperty("Equals", false);
521 } else {
522 m_result = "Success!";
523 g_log.notice("The workspaces did match");
524 this->setProperty("Equals", true);
525 }
526 setProperty("Result", m_result);
527}
528
529} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double error
Definition: IndexPeaks.cpp:133
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
#define fabs(x)
Definition: Matrix.cpp:22
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
Definition: MultiThreaded.h:94
#define PARALLEL_CRITICAL(name)
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PRAGMA_OMP(expression)
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
Custom exception class to signal a failure in the comparison.
CompareFailsException(const std::string &msg)
std::string getMessage() const
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
virtual size_t getNumChildren() const =0
Get the # of children MDBoxBase'es (non-recursive)
virtual coord_t getInverseVolume() const =0
virtual signal_t getErrorSquared() const =0
virtual size_t getID() const =0
virtual uint64_t getNPoints() const =0
Get total number of points both in memory and on file if present;.
virtual Mantid::Geometry::MDDimensionExtents< coord_t > & getExtents(size_t dim)=0
virtual uint32_t getDepth() const =0
virtual signal_t getSignal() const =0
virtual IMDNode * getChild(size_t index)=0
Return the indexth child MDBoxBase.
A property class for workspaces.
coord_t getBoxSize(size_t d)
For testing: return the internal-stored size of each box in each dimension.
Definition: MDBoxBase.h:203
Templated class for a multi-dimensional event "box".
Definition: MDBox.h:45
const std::vector< MDE > & getConstEvents() const
Get vector of constant events to use.
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
Templated class for a GRIDDED multi-dimensional event "box".
Definition: MDGridBox.h:42
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void notice(const std::string &msg)
Logs at notice level.
Definition: Logger.cpp:95
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
The concrete, templated class for properties.
Compare two MDWorkspaces for equality.
void doComparison()
Perform comparison, set m_result if not matching.
int version() const override
Algorithm's version for identification.
void exec() override
Execute the algorithm.
void compareMDEventWorkspaces(typename Mantid::DataObjects::MDEventWorkspace< MDE, nd >::sptr ws)
Perform the comparison on MDEventWorkspaces.
void compareMDGeometry(const Mantid::API::IMDWorkspace_sptr &ws1, const Mantid::API::IMDWorkspace_sptr &ws2)
Compare the dimensions etc.
void compare2Boxes(API::IMDNode *box1, API::IMDNode *box2, size_t ibox)
const std::string category() const override
Algorithm's category for identification.
void compareTol(T a, T b, const std::string &message)
Compare a and b.
void init() override
Initialize the algorithm's properties.
void compareMDHistoWorkspaces(const Mantid::DataObjects::MDHistoWorkspace_sptr &ws1, const Mantid::DataObjects::MDHistoWorkspace_sptr &ws2)
Compare the dimensions etc.
void compare(T a, T b, const std::string &message)
Compare a and b.
Mantid::API::IMDWorkspace_sptr inWS2
bool operator()(const SimpleMDEvent &event1, const SimpleMDEvent &event2) const
SimpleMDEvent(const SimpleMDEvent &other)=default
bool operator<(const SimpleMDEvent &event2) const
override operator < order
static float s_tolerance
static tolerance
SimpleMDEvent(std::vector< float > coordinates, const float &signal, const float &error)
SimpleMDEvent & operator=(const SimpleMDEvent &event2)
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
Definition: IMDWorkspace.h:146
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
std::shared_ptr< const IMDDimension > IMDDimension_const_sptr
Shared Pointer to const IMDDimension.
Definition: IMDDimension.h:101
std::string toString(const T &value)
Convert a number to a string.
Definition: Strings.cpp:703
std::string versus(T a, T b)
Return a string "(a vs b)".
bool compareSimpleEvents(const SimpleMDEvent &self, const SimpleMDEvent &other)
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54