52 std::string
str()
const {
55 for (
size_t i = 0; i < numdirs; ++i)
85 for (
size_t i = 0; i < numdirs; ++i) {
97 }
else if (diff < 0) {
130 for (
size_t i = 0; i < numdirs; ++i)
163 "First MDWorkspace to compare.");
165 "Second MDWorkspace to compare.");
167 declareProperty(
"Tolerance", 0.0,
"The maximum amount by which values may differ between the workspaces.");
169 "The maximum amount by which values may differ between 2 MDEvents to compare.");
171 "Whether to compare each MDEvent. If "
172 "False, will only look at the box "
176 "Boolean set to true if the workspaces match.");
178 "String describing the difference found between the workspaces");
180 "To ignore box ID-s when comparing MD "
181 "boxes as Multithreaded splitting "
182 "assigns box id-s randomly");
187template <
typename T> std::string
versus(T a, T b) {
213 double diff =
fabs(a - b);
218 diff = 0.5 * diff / (pa + pb);
231 compare(ws1->getNumDims(), ws2->getNumDims(),
"Workspaces have a different number of dimensions");
232 for (
size_t d = 0;
d < ws1->getNumDims();
d++) {
237 compare(dim1->getNBins(), dim2->getNBins(),
239 compareTol(dim1->getMinimum(), dim2->getMinimum(),
241 compareTol(dim1->getMaximum(), dim2->getMaximum(),
251 compare(ws1->getNumDims(), ws2->getNumDims(),
"Workspaces have a different number of dimensions");
252 compare(ws1->getNPoints(), ws2->getNPoints(),
"Workspaces have a different number of points");
253 for (
size_t i = 0; i < ws1->getNPoints(); i++) {
254 double diff =
fabs(ws1->getSignalAt(i) - ws2->getSignalAt(i));
257 versus(ws1->getSignalAt(i), ws2->getSignalAt(i)));
259 double diffErr =
fabs(ws1->getErrorAt(i) - ws2->getErrorAt(i));
262 versus(ws1->getErrorAt(i), ws2->getErrorAt(i)));
271template <
typename MDE,
size_t nd>
275 throw std::runtime_error(
"Incompatible workspace types passed to PlusMD.");
277 std::vector<API::IMDNode *> boxes1;
278 std::vector<API::IMDNode *> boxes2;
280 ws1->
getBox()->getBoxes(boxes1, 1000,
false);
281 ws2->
getBox()->getBoxes(boxes2, 1000,
false);
282 std::stringstream ess;
283 ess <<
"Workspace1 has " << boxes1.size() <<
" boxes; Workspace2 has " << boxes2.size() <<
" boxes";
284 std::string boxinfo(ess.str());
286 this->
compare(boxes1.size(), boxes2.size(),
"Workspaces do not have the same number of boxes. " + boxinfo);
289 bool boxes_same(
true);
290 std::string errormessage(
"");
291 int num_boxes =
static_cast<int>(boxes1.size());
297 for (
int ibox = 0; ibox < num_boxes; ibox++) {
304 bool local_fail(
false);
305 std::string local_error(
"");
310 <<
"; ws2 npoints = " << box2->
getNPoints() <<
"\n";
313 CompareMDWorkspaces::compare2Boxes<MDE, nd>(box1, box2,
static_cast<size_t>(ibox));
316 local_error += err.what();
322 errormessage += local_error;
336template <
typename MDE,
size_t nd>
343 g_log.
debug() <<
" Boxes N: " << ibox <<
" have box ID: " << box1->
getID() <<
" and " << box2->
getID()
344 <<
" correspondingly\n";
354 g_log.
debug() <<
" Boxes N: " << ibox <<
" children N: " << i <<
" have box ID: " << box1->
getChild(i)->
getID()
355 <<
" and " << box2->
getChild(i)->
getID() <<
" correspondingly\n";
359 for (
size_t d = 0;
d < nd;
d++) {
372 if (gridbox1 && gridbox2) {
374 for (
size_t d = 0;
d < nd;
d++)
381 <<
"; ws2 npoints = " << box2->
getNPoints() <<
"\n";
384 if (mdbox1 && !mdbox2) {
387 }
else if (!mdbox1 && mdbox2) {
394 const std::vector<MDE> &events1 = mdbox1->getConstEvents();
398 this->
compare(events1.size(), events2.size(),
"Box event vectors are not the same length");
400 if (events1.size() == events2.size() && events1.size() > 2) {
402 std::vector<SimpleMDEvent> events_vec1;
403 std::vector<SimpleMDEvent> events_vec2;
406 for (
size_t i = 0; i < events1.size(); i++) {
407 std::vector<float> centers1(nd);
408 std::vector<float> centers2(nd);
409 for (
size_t d = 0;
d < nd;
d++) {
410 centers1[
d] = events1[i].getCenter(
d);
411 centers2[
d] = events2[i].getCenter(
d);
413 SimpleMDEvent se1(centers1, events1[i].getSignal(), events1[i].getErrorSquared());
414 SimpleMDEvent se2(centers2, events2[i].getSignal(), events2[i].getErrorSquared());
415 events_vec1.push_back(se1);
416 events_vec2.push_back(se2);
420 std::sort(events_vec1.begin(), events_vec1.end());
421 std::sort(events_vec2.begin(), events_vec2.end());
426 for (
size_t i = 0; i < events_vec1.size(); ++i) {
429 for (
size_t d = 0;
d < nd; ++
d) {
433 compareTol(events_vec1[i].getSignal(), events_vec2[i].getSignal(),
"");
435 compareTol(events_vec1[i].getError(), events_vec2[i].getError(),
"");
437 g_log.
debug() <<
"Box " << ibox <<
" Event " << i <<
": " << e.what()
438 <<
"\n [ws1] : " + events_vec1[i].str() <<
"\n [ws2] : " + events_vec2[i].str()
453 mdbox1->releaseEvents();
458 mdbox1->releaseEvents();
479 throw std::invalid_argument(
"Invalid workspace given.");
484 throw std::invalid_argument(
"Cannot compare MatrixWorkspaces. Please use "
485 "CompareWorkspaces algorithm instead.");
493 compare(ws1->id(), ws2->id(),
"Workspaces are of different types");
497 if (histo1 && histo2) {
499 }
else if (event1 && event2) {
502 m_result =
"Workspaces are of different types.";
#define DECLARE_ALGORITHM(classname)
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
#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...
#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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
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.
Templated class for a multi-dimensional event "box".
const std::vector< MDE > & getConstEvents() const
Get vector of constant events to use.
void releaseEvents()
For file-backed MDBoxes, this marks that the data vector is no longer "busy", and so it is safe for t...
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
bool isFileBacked() const override
MDBoxBase< MDE, nd > * getBox()
Templated class for a GRIDDED multi-dimensional event "box".
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.
void notice(const std::string &msg)
Logs at notice level.
void information(const std::string &msg)
Logs at information level.
The concrete, templated class for properties.
Compare two MDWorkspaces for equality.
bool m_CheckEvents
Is CheckEvents true.
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)
double m_tolerance
Tolerance.
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
std::string m_result
Result string.
bool operator()(const SimpleMDEvent &event1, const SimpleMDEvent &event2) const
SimpleMDEvent(const SimpleMDEvent &other)=default
bool operator<(const SimpleMDEvent &event2) const
override operator < order
float getCenter(size_t dim) const
static float s_tolerance
static tolerance
SimpleMDEvent(std::vector< float > coordinates, const float &signal, const float &error)
SimpleMDEvent & operator=(const SimpleMDEvent &event2)
std::vector< float > mCoordinates
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.
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.
std::string toString(const T &value)
Convert a number to a string.
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,...
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.