Newer
Older
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source
// & Institut Laue - Langevin
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidAlgorithms/CompareWorkspaces.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidAPI/IMDHistoWorkspace.h"
#include "MantidAPI/IMDWorkspace.h"
#include "MantidAPI/IPeaksWorkspace.h"
#include "MantidAPI/NumericAxis.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/Sample.h"
#include "MantidAPI/TableRow.h"
#include "MantidAPI/WorkspaceGroup.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/TableWorkspace.h"
#include "MantidGeometry/Crystal/IPeak.h"
#include "MantidKernel/Unit.h"
#include "MantidParallel/Communicator.h"
namespace Mantid {
namespace Algorithms {
using namespace Mantid::API;
using namespace Mantid::Kernel;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
using Types::Event::TofEvent;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CompareWorkspaces)
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
namespace {
template <class ET> const std::vector<ET> &getEventVector(const EventList &el);
template <>
const std::vector<Types::Event::TofEvent> &getEventVector(const EventList &el) {
return el.getEvents();
}
template <>
const std::vector<DataObjects::WeightedEvent> &
getEventVector(const EventList &el) {
return el.getWeightedEvents();
}
template <>
const std::vector<DataObjects::WeightedEventNoTime> &
getEventVector(const EventList &el) {
return el.getWeightedEventsNoTime();
}
template <class ET>
int compareEventLists(Kernel::Logger &logger, const EventList &el1,
const EventList &el2, double tolTof, double tolWeight,
int64_t tolPulse, bool printdetails, size_t &numdiffpulse,
size_t &numdifftof, size_t &numdiffboth,
size_t &numdiffweight) {
// Initialize
numdiffpulse = 0;
numdifftof = 0;
numdiffboth = 0;
numdiffweight = 0;
// Compare event by event including all events
const auto &events1 = getEventVector<ET>(el1);
const auto &events2 = getEventVector<ET>(el2);
int returnint = 0;
size_t numevents = events1.size();
for (size_t i = 0; i < numevents; ++i) {
// Compare 2 individual events
const auto &e1 = events1[i];
const auto &e2 = events2[i];
bool diffpulse = false;
bool difftof = false;
bool diffweight = false;
if (std::abs(e1.pulseTime().totalNanoseconds() -
e2.pulseTime().totalNanoseconds()) > tolPulse) {
diffpulse = true;
++numdiffpulse;
}
if (fabs(e1.tof() - e2.tof()) > tolTof) {
difftof = true;
++numdifftof;
}
if (diffpulse && difftof)
++numdiffboth;
if (fabs(e1.weight() - e2.weight()) > tolWeight) {
diffweight = true;
++numdiffweight;
}
bool same = (!diffpulse) && (!difftof) && (!diffweight);
if (!same) {
returnint += 1;
if (printdetails) {
std::stringstream outss;
outss << "Spectrum ? Event " << i << ": ";
if (diffpulse)
outss << "Diff-Pulse: " << e1.pulseTime() << " vs. " << e2.pulseTime()
<< "; ";
if (difftof)
outss << "Diff-TOF: " << e1.tof() << " vs. " << e2.tof() << ";";
if (diffweight)
outss << "Diff-Weight: " << e1.weight() << " vs. " << e2.weight()
<< ";";
logger.information(outss.str());
}
}
} // End of loop on all events
// Anything that gets this far is equal within tolerances
return returnint;
}
} // namespace
/** Initialize the algorithm's properties.
*/
void CompareWorkspaces::init() {
declareProperty(std::make_unique<WorkspaceProperty<Workspace>>(
"Workspace1", "", Direction::Input),
"The name of the first input workspace.");
declareProperty(std::make_unique<WorkspaceProperty<Workspace>>(
"Workspace2", "", Direction::Input),
"The name of the second input workspace.");
declareProperty(
"Tolerance", 0.0,
"The maximum amount by which values may differ between the workspaces.");
declareProperty("CheckType", true,
"Whether to check that the data types "
"(Workspace2D vs EventWorkspace) match.");
declareProperty("CheckAxes", true, "Whether to check that the axes match.");
declareProperty("CheckSpectraMap", true,
"Whether to check that the spectra-detector maps match. ");
declareProperty("CheckInstrument", true,
"Whether to check that the instruments match. ");
declareProperty("CheckMasking", true,
"Whether to check that the bin masking matches. ");
// Have this one false by default - the logs are brittle
declareProperty("CheckSample", false,
"Whether to check that the sample (e.g. logs).");
declareProperty(
"ToleranceRelErr", false,
"Treat tolerance as relative error rather then the absolute error.\n"
"This is only applicable to Matrix workspaces.");
// Have this one false by default - it can be a lot of printing.
declareProperty("CheckAllData", false,
"Usually checking data ends when first mismatch occurs. This "
"forces algorithm to check all data and print mismatch to "
"the debug log.\n"
"Very often such logs are huge so making it true should be "
"the last option.");
declareProperty("NumberMismatchedSpectraToPrint", 1,
"Number of mismatched spectra from lowest to be listed. ");
declareProperty("DetailedPrintIndex", EMPTY_INT(),
"Mismatched spectra that will be printed out in details. ");
declareProperty("Result", false, Direction::Output);
declareProperty(
std::make_unique<WorkspaceProperty<ITableWorkspace>>(
"Messages", "compare_msgs", Direction::Output),
"TableWorkspace containing messages about any mismatches detected");
m_messages = boost::make_shared<TableWorkspace>();
m_messages->addColumn("str", "Message");
m_messages->addColumn("str", "Workspace 1");
m_messages->addColumn("str", "Workspace 2");
}
/** Execute the algorithm.
*/
void CompareWorkspaces::exec() {
m_result = true;
m_messages->setRowCount(0); // Clear table
if (g_log.is(Logger::Priority::PRIO_DEBUG))
m_parallelComparison = false;
this->doComparison();
if (!m_result) {
std::string message = m_messages->cell<std::string>(0, 0);
g_log.notice() << "The workspaces did not match: " << message << '\n';
Loading
Loading full blame...