diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h index 32a5a735761e72b85a94a38125b1622f16ad05d0..d64deaf90f119f94081863d78cd05725f7b1e42b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h @@ -10,6 +10,7 @@ #include "MantidAPI/ITableWorkspace_fwd.h" #include "MantidAlgorithms/DllConfig.h" #include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/LeanElasticPeaksWorkspace.h" #include "MantidDataObjects/PeaksWorkspace.h" namespace Mantid { @@ -103,6 +104,9 @@ private: void doPeaksComparison(DataObjects::PeaksWorkspace_sptr tws1, DataObjects::PeaksWorkspace_sptr tws2); + void doLeanElasticPeaksComparison( + DataObjects::LeanElasticPeaksWorkspace_sptr tws1, + DataObjects::LeanElasticPeaksWorkspace_sptr tws2); void doTableComparison(const API::ITableWorkspace_const_sptr &tws1, const API::ITableWorkspace_const_sptr &tws2); void doMDComparison(const API::Workspace_sptr &w1, diff --git a/Framework/Algorithms/src/CompareWorkspaces.cpp b/Framework/Algorithms/src/CompareWorkspaces.cpp index 6c435f3ce71cd790e4f99f0a097a2d96c3f2d8d2..1a4bb7af11e11801fdee5f976865f2659fb38027 100644 --- a/Framework/Algorithms/src/CompareWorkspaces.cpp +++ b/Framework/Algorithms/src/CompareWorkspaces.cpp @@ -16,6 +16,7 @@ #include "MantidAPI/TableRow.h" #include "MantidAPI/WorkspaceGroup.h" #include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/LeanElasticPeaksWorkspace.h" #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidDataObjects/TableWorkspace.h" #include "MantidGeometry/Crystal/IPeak.h" @@ -322,18 +323,43 @@ void CompareWorkspaces::doComparison() { // ============================================================================== // Peaks workspaces // ============================================================================== + if (w1->id() == "PeaksWorkspace" || w2->id() == "PeaksWorkspace") { + // Check that both workspaces are the same type + PeaksWorkspace_sptr pws1 = std::dynamic_pointer_cast<PeaksWorkspace>(w1); + PeaksWorkspace_sptr pws2 = std::dynamic_pointer_cast<PeaksWorkspace>(w2); + + // if any one of the pointer is null, record the error + // -- meaning at least one of the input workspace cannot be casted + // into peakworkspace + if ((pws1 && !pws2) || (!pws1 && pws2)) { + recordMismatch("One workspace is a PeaksWorkspace and the other is not."); + return; + } - // Check that both workspaces are the same type - PeaksWorkspace_sptr pws1 = std::dynamic_pointer_cast<PeaksWorkspace>(w1); - PeaksWorkspace_sptr pws2 = std::dynamic_pointer_cast<PeaksWorkspace>(w2); - if ((pws1 && !pws2) || (!pws1 && pws2)) { - recordMismatch("One workspace is a PeaksWorkspace and the other is not."); - return; + // Check some peak-based stuff when both pointers are not null + if (pws1 && pws2) { + doPeaksComparison(pws1, pws2); + return; + } } - // Check some peak-based stuff - if (pws1 && pws2) { - doPeaksComparison(pws1, pws2); - return; + + // ============================================================================== + // Lean Elastic Peaks workspaces + // ============================================================================== + if (w1->id() == "LeanElasticPeaksWorkspace" || + w2->id() == "LeanElasticPeaksWorkspace") { + auto lpws1 = std::dynamic_pointer_cast<LeanElasticPeaksWorkspace>(w1); + auto lpws2 = std::dynamic_pointer_cast<LeanElasticPeaksWorkspace>(w2); + + if ((lpws1 && !lpws2) || (!lpws1 && lpws2)) { + recordMismatch( + "One workspace is a LeanElasticPeaksWorkspace and the other is not."); + } + + if (lpws1 && lpws2) { + doLeanElasticPeaksComparison(lpws1, lpws2); + return; + } } // ============================================================================== @@ -1062,14 +1088,16 @@ void CompareWorkspaces::doPeaksComparison(PeaksWorkspace_sptr tws1, sortPeaks->setProperty("ColumnNameToSortBy", "DSpacing"); sortPeaks->setProperty("SortAscending", true); sortPeaks->executeAsChildAlg(); - tws1 = sortPeaks->getProperty("OutputWorkspace"); + IPeaksWorkspace_sptr tmp1 = sortPeaks->getProperty("OutputWorkspace"); + tws1 = std::dynamic_pointer_cast<PeaksWorkspace>(tmp1); sortPeaks = createChildAlgorithm("SortPeaksWorkspace"); sortPeaks->setProperty("InputWorkspace", tws2); sortPeaks->setProperty("ColumnNameToSortBy", "DSpacing"); sortPeaks->setProperty("SortAscending", true); sortPeaks->executeAsChildAlg(); - tws2 = sortPeaks->getProperty("OutputWorkspace"); + IPeaksWorkspace_sptr tmp2 = sortPeaks->getProperty("OutputWorkspace"); + tws2 = std::dynamic_pointer_cast<PeaksWorkspace>(tmp2); } const double tolerance = getProperty("Tolerance"); @@ -1124,6 +1152,100 @@ void CompareWorkspaces::doPeaksComparison(PeaksWorkspace_sptr tws1, s1 = peak1.getCol(); s2 = peak2.getCol(); } + if (std::fabs(s1 - s2) > tolerance) { + g_log.debug(name); + g_log.debug() << "s1 = " << s1 << "\n" + << "s2 = " << s2 << "\n" + << "std::fabs(s1 - s2) = " << std::fabs(s1 - s2) << "\n" + << "tolerance = " << tolerance << "\n"; + g_log.debug() << "Data mismatch at cell (row#,col#): (" << i << "," << j + << ")\n"; + recordMismatch("Data mismatch"); + return; + } + } + } +} + +//------------------------------------------------------------------------------------------------ +void CompareWorkspaces::doLeanElasticPeaksComparison( + LeanElasticPeaksWorkspace_sptr tws1, LeanElasticPeaksWorkspace_sptr tws2) { + // Check some table-based stuff + if (tws1->getNumberPeaks() != tws2->getNumberPeaks()) { + recordMismatch("Mismatched number of rows."); + return; + } + if (tws1->columnCount() != tws2->columnCount()) { + recordMismatch("Mismatched number of columns."); + return; + } + + // sort the workspaces before comparing + auto sortPeaks = createChildAlgorithm("SortPeaksWorkspace"); + sortPeaks->setProperty("InputWorkspace", tws1); + sortPeaks->setProperty("ColumnNameToSortBy", "DSpacing"); + sortPeaks->setProperty("SortAscending", true); + sortPeaks->executeAsChildAlg(); + IPeaksWorkspace_sptr ipws1 = sortPeaks->getProperty("OutputWorkspace"); + + sortPeaks = createChildAlgorithm("SortPeaksWorkspace"); + sortPeaks->setProperty("InputWorkspace", tws2); + sortPeaks->setProperty("ColumnNameToSortBy", "DSpacing"); + sortPeaks->setProperty("SortAscending", true); + sortPeaks->executeAsChildAlg(); + IPeaksWorkspace_sptr ipws2 = sortPeaks->getProperty("OutputWorkspace"); + + const double tolerance = getProperty("Tolerance"); + for (int i = 0; i < ipws1->getNumberPeaks(); i++) { + for (size_t j = 0; j < ipws1->columnCount(); j++) { + std::shared_ptr<const API::Column> col = ipws1->getColumn(j); + std::string name = col->name(); + double s1 = 0.0; + double s2 = 0.0; + if (name == "RunNumber") { + s1 = double(ipws1->getPeak(i).getRunNumber()); + s2 = double(ipws2->getPeak(i).getRunNumber()); + } else if (name == "h") { + s1 = ipws1->getPeak(i).getH(); + s2 = ipws2->getPeak(i).getH(); + } else if (name == "k") { + s1 = ipws1->getPeak(i).getK(); + s2 = ipws2->getPeak(i).getK(); + } else if (name == "l") { + s1 = ipws1->getPeak(i).getL(); + s2 = ipws2->getPeak(i).getL(); + } else if (name == "Wavelength") { + s1 = ipws1->getPeak(i).getWavelength(); + s2 = ipws2->getPeak(i).getWavelength(); + } else if (name == "DSpacing") { + s1 = ipws1->getPeak(i).getDSpacing(); + s2 = ipws2->getPeak(i).getDSpacing(); + } else if (name == "Intens") { + s1 = ipws1->getPeak(i).getIntensity(); + s2 = ipws2->getPeak(i).getIntensity(); + } else if (name == "SigInt") { + s1 = ipws1->getPeak(i).getSigmaIntensity(); + s2 = ipws2->getPeak(i).getSigmaIntensity(); + } else if (name == "BinCount") { + s1 = ipws1->getPeak(i).getBinCount(); + s2 = ipws2->getPeak(i).getBinCount(); + } else if (name == "QLab") { + V3D q1 = ipws1->getPeak(i).getQLabFrame(); + V3D q2 = ipws2->getPeak(i).getQLabFrame(); + // using s1 here as the diff + for (int i = 0; i < 3; ++i) { + s1 += (q1[i] - q2[i]) * (q1[i] - q2[i]); + } + s1 = std::sqrt(s1); + } else if (name == "QSample") { + V3D q1 = ipws1->getPeak(i).getQSampleFrame(); + V3D q2 = ipws2->getPeak(i).getQSampleFrame(); + // using s1 here as the diff + for (int i = 0; i < 3; ++i) { + s1 += (q1[i] - q2[i]) * (q1[i] - q2[i]); + } + s1 = std::sqrt(s1); + } if (std::fabs(s1 - s2) > tolerance) { g_log.debug() << "Data mismatch at cell (row#,col#): (" << i << "," << j << ")\n"; diff --git a/Framework/Algorithms/test/CompareWorkspacesTest.h b/Framework/Algorithms/test/CompareWorkspacesTest.h index bc0044309df884931fdcf390f1d32a5d635e98bd..84da1e095bb30c7c4462ebc88a78b17b67f1d7ef 100644 --- a/Framework/Algorithms/test/CompareWorkspacesTest.h +++ b/Framework/Algorithms/test/CompareWorkspacesTest.h @@ -17,6 +17,7 @@ #include "MantidAlgorithms/CompareWorkspaces.h" #include "MantidAlgorithms/CreatePeaksWorkspace.h" #include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/LeanElasticPeaksWorkspace.h" #include "MantidDataObjects/MDBoxBase.h" #include "MantidDataObjects/MDHistoWorkspace.h" #include "MantidDataObjects/PeaksWorkspace.h" @@ -124,6 +125,23 @@ public: TS_ASSERT_EQUALS(checker.getPropertyValue("Result"), PROPERTY_VALUE_TRUE); } + void test_LeanPeaksWorkspaceMatches() { + // generate a lean elastic peak workspace with two peaks + auto lpws = std::make_shared<LeanElasticPeaksWorkspace>(); + // add peaks + LeanElasticPeak pk1(V3D(0.0, 0.0, 6.28319), 2.0); // (100) + LeanElasticPeak pk2(V3D(6.28319, 0.0, 6.28319), 1.0); // (110) + lpws->addPeak(pk1); + lpws->addPeak(pk2); + + TS_ASSERT_THROWS_NOTHING(checker.setProperty( + "Workspace1", std::dynamic_pointer_cast<Workspace>(lpws))); + TS_ASSERT_THROWS_NOTHING(checker.setProperty( + "Workspace2", std::dynamic_pointer_cast<Workspace>(lpws))); + TS_ASSERT(checker.execute()); + TS_ASSERT_EQUALS(checker.getPropertyValue("Result"), PROPERTY_VALUE_TRUE); + } + void testPeaks_extrapeak() { if (!checker.isInitialized()) checker.initialize(); diff --git a/Framework/Crystal/src/SortPeaksWorkspace.cpp b/Framework/Crystal/src/SortPeaksWorkspace.cpp index 830f9c5ecdae860c6bdf2f834240a65babdeb7ba..595975f6dba0d45ffbcacc697705794e7266a534 100644 --- a/Framework/Crystal/src/SortPeaksWorkspace.cpp +++ b/Framework/Crystal/src/SortPeaksWorkspace.cpp @@ -37,10 +37,10 @@ const std::string SortPeaksWorkspace::category() const { /** Initialize the algorithm's properties. */ void SortPeaksWorkspace::init() { - declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>( + declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>( "InputWorkspace", "", Direction::Input), "An input workspace."); - declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>( + declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>( "OutputWorkspace", "", Direction::Output), "An output workspace."); @@ -58,8 +58,8 @@ void SortPeaksWorkspace::init() { void SortPeaksWorkspace::exec() { const std::string columnToSortBy = getProperty("ColumnNameToSortBy"); const bool sortAscending = getProperty("SortAscending"); - PeaksWorkspace_sptr inputWS = getProperty("InputWorkspace"); - PeaksWorkspace_sptr outputWS = getProperty("OutputWorkspace"); + IPeaksWorkspace_sptr inputWS = getProperty("InputWorkspace"); + IPeaksWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // Try to get the column. This will throw if the column does not exist. inputWS->getColumn(columnToSortBy); @@ -68,7 +68,6 @@ void SortPeaksWorkspace::exec() { outputWS = inputWS->clone(); } - // Perform the sorting. std::vector<PeaksWorkspace::ColumnAndDirection> sortCriteria; sortCriteria.emplace_back(columnToSortBy, sortAscending); outputWS->sort(sortCriteria); diff --git a/Framework/Crystal/test/SortPeaksWorkspaceTest.h b/Framework/Crystal/test/SortPeaksWorkspaceTest.h index d61cdca4685990eb5d446a1b36d2e346e2db4ad2..d889eff22256dad0058cd005f259dbccb19d064c 100644 --- a/Framework/Crystal/test/SortPeaksWorkspaceTest.h +++ b/Framework/Crystal/test/SortPeaksWorkspaceTest.h @@ -8,6 +8,7 @@ #include "MantidAPI/TableRow.h" #include "MantidCrystal/SortPeaksWorkspace.h" +#include "MantidDataObjects/LeanElasticPeaksWorkspace.h" #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" #include <algorithm> @@ -44,8 +45,9 @@ private: TS_ASSERT_THROWS_NOTHING(alg.execute()); TS_ASSERT(alg.isExecuted()); - PeaksWorkspace_sptr outWS = - AnalysisDataService::Instance().retrieveWS<PeaksWorkspace>(outWSName); + IPeaksWorkspace_sptr tmp = + AnalysisDataService::Instance().retrieveWS<IPeaksWorkspace>(outWSName); + PeaksWorkspace_sptr outWS = std::dynamic_pointer_cast<PeaksWorkspace>(tmp); // Extract the sorted column values out into a containtainer. const size_t columnIndex = outWS->getColumnIndex(columnName); @@ -187,7 +189,38 @@ public: } void test_modify_workspace_in_place() { - PeaksWorkspace_sptr inWS = WorkspaceCreationHelper::createPeaksWorkspace(2); + PeaksWorkspace_sptr tmp = WorkspaceCreationHelper::createPeaksWorkspace(2); + IPeaksWorkspace_sptr inWS = std::dynamic_pointer_cast<IPeaksWorkspace>(tmp); + + SortPeaksWorkspace alg; + alg.setChild(true); + alg.setRethrows(true); + TS_ASSERT_THROWS_NOTHING(alg.initialize()) + TS_ASSERT(alg.isInitialized()) + TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inWS)); + alg.setPropertyValue("OutputWorkspace", "OutName"); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", inWS)); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("ColumnNameToSortBy", "h")); + TS_ASSERT_THROWS_NOTHING(alg.execute()); + TS_ASSERT(alg.isExecuted()); + + IPeaksWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); + + TSM_ASSERT_EQUALS("Sorting should have happened in place. Output and input " + "workspaces should be the same.", + outWS, inWS); + } + + void test_leanPeakWorkspace_sort_inplace() { + // generate a lean elastic peak workspace with two peaks + auto lpws = std::make_shared<LeanElasticPeaksWorkspace>(); + // add peaks + LeanElasticPeak pk1(Mantid::Kernel::V3D(0.0, 0.0, 6.28319), 2.0); + LeanElasticPeak pk2(Mantid::Kernel::V3D(6.28319, 0.0, 6.28319), 1.0); + lpws->addPeak(pk1); + lpws->addPeak(pk2); + IPeaksWorkspace_sptr inWS = + std::dynamic_pointer_cast<IPeaksWorkspace>(lpws); SortPeaksWorkspace alg; alg.setChild(true); @@ -201,7 +234,7 @@ public: TS_ASSERT_THROWS_NOTHING(alg.execute()); TS_ASSERT(alg.isExecuted()); - PeaksWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); + IPeaksWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); TSM_ASSERT_EQUALS("Sorting should have happened in place. Output and input " "workspaces should be the same.",