Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#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/TableRow.h"
#include "MantidDataObjects/TableWorkspace.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidGeometry/Crystal/IPeak.h"
namespace Mantid {
namespace Algorithms {
using namespace Mantid::API;
using namespace Mantid::Kernel;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CompareWorkspaces)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
CompareWorkspaces::CompareWorkspaces()
: API::Algorithm(), m_Result(false), m_Prog(NULL),
//----------------------------------------------------------------------------------------------
/** Destructor
*/
CompareWorkspaces::~CompareWorkspaces() { delete m_Prog; }
//----------------------------------------------------------------------------------------------
/// Algorithms name for identification. @see Algorithm::name
const std::string CompareWorkspaces::name() const {
return "CompareWorkspaces";
}
/// Algorithm's version for identification. @see Algorithm::version
int CompareWorkspaces::version() const { return 1; }
/// Algorithm's category for identification. @see Algorithm::category
const std::string CompareWorkspaces::category() const {
return "Utility\\Workspaces";
}
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string CompareWorkspaces::summary() const {
return "Compares two workspaces for equality. This algorithm is mainly "
"intended for use by the Mantid development team as part of the "
"testing process.";
}
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CompareWorkspaces::init() {
declareProperty(
new WorkspaceProperty<Workspace>("Workspace1", "", Direction::Input),
"The name of the first input workspace.");
declareProperty(
new 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(
new WorkspaceProperty<ITableWorkspace>("Messages", "compare_msgs",
"TableWorkspace containing messages about any mismatches detected");
m_Messages = WorkspaceFactory::Instance().createTable("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 << std::endl;
}
setProperty("Result", m_Result);
setProperty("Messages", m_Messages);
}
//----------------------------------------------------------------------------------------------
/**
* Process two groups and ensure the Result string is set properly on the final
* algorithm.
*
* @return A boolean true if execution was sucessful, false otherwise
*/
bool CompareWorkspaces::processGroups() {
m_Result = true;
m_Messages->setRowCount(0); // Clear table
// Get workspaces
Workspace_const_sptr w1 = getProperty("Workspace1");
Workspace_const_sptr w2 = getProperty("Workspace2");
// Attempt to cast to WorkspaceGroups (will be nullptr on failure)
WorkspaceGroup_const_sptr ws1 =
boost::dynamic_pointer_cast<const WorkspaceGroup>(w1);
WorkspaceGroup_const_sptr ws2 =
boost::dynamic_pointer_cast<const WorkspaceGroup>(w2);
if (ws1 && ws2) { // Both are groups
processGroups(ws1, ws2);
} else if (!ws1 && !ws2) { // Neither are groups (shouldn't happen)
m_Result = false;
throw std::runtime_error("CompareWorkspaces::processGroups - Neither "
"input is a WorkspaceGroup. This is a logical "
"error in the code.");
} else if (!ws1 || !ws2) {
recordMismatch(
"Type mismatch. One workspace is a group, the other is not.");
}
setProperty("Result", m_Result);
setProperty("Messages", m_Messages);
// Store output workspace in AnalysisDataService
if (!isChild())
this->store();
setExecuted(true);
notificationCenter().postNotification(
new FinishedNotification(this, this->isExecuted()));
return true;
}
//----------------------------------------------------------------------------------------------
/**
* @brief CompareWorkspaces::processGroups
* @param groupOne
* @param groupTwo
*/
void CompareWorkspaces::processGroups(
boost::shared_ptr<const API::WorkspaceGroup> groupOne,
boost::shared_ptr<const API::WorkspaceGroup> groupTwo) {
// Check their sizes
const size_t totalNum = static_cast<size_t>(groupOne->getNumberOfEntries());
if (groupOne->getNumberOfEntries() != groupTwo->getNumberOfEntries()) {
Loading
Loading full blame...