From 34b7a9fad05a9982b67a71c00b4379cc188d5500 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg <anton.piccardo-selg@tessella.com> Date: Wed, 14 Oct 2015 17:14:35 +0100 Subject: [PATCH] Refs #13872 Fix more unit tests for MDFrame --- Framework/Crystal/test/FindClusterFacesTest.h | 12 ++- .../Crystal/test/PeakClusterProjectionTest.h | 9 +- .../ImportMDHistoWorkspaceBase.h | 5 + .../MDAlgorithms/src/CreateMDWorkspace.cpp | 5 +- .../src/ImportMDHistoWorkspaceBase.cpp | 101 +++++++++++++++++- .../test/CreateMDHistoWorkspaceTest.h | 18 +++- .../test/ImportMDHistoWorkspaceTest.h | 15 ++- Framework/MDAlgorithms/test/LoadMDTest.h | 29 +++-- .../MantidTestHelpers/MDEventsTestHelper.h | 10 ++ 9 files changed, 185 insertions(+), 19 deletions(-) diff --git a/Framework/Crystal/test/FindClusterFacesTest.h b/Framework/Crystal/test/FindClusterFacesTest.h index 012e4bf6d0f..a17e21ccb53 100644 --- a/Framework/Crystal/test/FindClusterFacesTest.h +++ b/Framework/Crystal/test/FindClusterFacesTest.h @@ -9,8 +9,11 @@ #include "MantidAPI/FrameworkManager.h" #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidGeometry/Instrument.h" +#include "MantidGeometry/MDGeometry/HKL.h" #include "MantidTestHelpers/ComponentCreationHelper.h" #include "MantidTestHelpers/MDEventsTestHelper.h" +#include "MantidKernel/UnitLabelTypes.h" + #include <boost/assign/list_of.hpp> using namespace Mantid::API; @@ -54,7 +57,14 @@ IMDHistoWorkspace_sptr create_HKL_MDWS(double min = -10, double max = 10, std::vector<double> errorValues(totalBins, errorValue); mdworkspaceAlg->setProperty("ErrorInput", errorValues); mdworkspaceAlg->setPropertyValue("Names", "H,K,L"); - mdworkspaceAlg->setPropertyValue("Units", "-,-,-"); + std::string units = Mantid::Kernel::Units::Symbol::RLU.ascii() + "," + + Mantid::Kernel::Units::Symbol::RLU.ascii() + "," + + Mantid::Kernel::Units::Symbol::RLU.ascii(); + std::string frames = Mantid::Geometry::HKL::HKLName + "," + + Mantid::Geometry::HKL::HKLName + "," + + Mantid::Geometry::HKL::HKLName; + TS_ASSERT_THROWS_NOTHING(mdworkspaceAlg->setProperty("Frames", frames)); + TS_ASSERT_THROWS_NOTHING(mdworkspaceAlg->setProperty("Units", units)); mdworkspaceAlg->setPropertyValue("OutputWorkspace", "IntegratePeaksMDTest_MDEWS"); mdworkspaceAlg->execute(); diff --git a/Framework/Crystal/test/PeakClusterProjectionTest.h b/Framework/Crystal/test/PeakClusterProjectionTest.h index 59f8d147ea6..27143bd5779 100644 --- a/Framework/Crystal/test/PeakClusterProjectionTest.h +++ b/Framework/Crystal/test/PeakClusterProjectionTest.h @@ -63,7 +63,14 @@ private: std::vector<double> errorValues(totalBins, errorValue); mdworkspaceAlg->setProperty("ErrorInput", errorValues); mdworkspaceAlg->setPropertyValue("Names", "H,K,L"); - mdworkspaceAlg->setPropertyValue("Units", "-,-,-"); + std::string units = Mantid::Kernel::Units::Symbol::RLU.ascii() + "," + + Mantid::Kernel::Units::Symbol::RLU.ascii() + "," + + Mantid::Kernel::Units::Symbol::RLU.ascii(); + std::string frames = Mantid::Geometry::HKL::HKLName + "," + + Mantid::Geometry::HKL::HKLName + "," + + Mantid::Geometry::HKL::HKLName; + TS_ASSERT_THROWS_NOTHING(mdworkspaceAlg->setProperty("Frames", frames)); + TS_ASSERT_THROWS_NOTHING(mdworkspaceAlg->setProperty("Units", units)); mdworkspaceAlg->setPropertyValue("OutputWorkspace", "IntegratePeaksMDTest_MDEWS"); mdworkspaceAlg->execute(); diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspaceBase.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspaceBase.h index 81e9ec99362..94455e0a1a7 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspaceBase.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspaceBase.h @@ -39,6 +39,7 @@ class DLLExport ImportMDHistoWorkspaceBase : public API::Algorithm { public: ImportMDHistoWorkspaceBase(); virtual ~ImportMDHistoWorkspaceBase(); + virtual std::map<std::string, std::string> validateInputs(); protected: /// Vector containing the number of bins in each dimension. @@ -54,6 +55,10 @@ protected: private: // Product of the bins across all dimensions. size_t m_bin_product; + Mantid::Geometry::MDFrame_uptr createMDFrame(std::string frame, + std::string unit); + bool checkIfFrameValid(const std::string &frame, + const std::vector<std::string> &targetFrames); }; } // namespace MDAlgorithms diff --git a/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp b/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp index 72e3081434b..78f8b23defa 100644 --- a/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp +++ b/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp @@ -66,7 +66,10 @@ void CreateMDWorkspace::init() { " **General Frame**: Any frame which is not a Q-based frame." " **QLab**: Wave-vector converted into the lab frame." " **QSample**: Wave-vector converted into the frame of the sample." - " **HKL**: Wave-vector converted into the crystal's HKL indices."); + " **HKL**: Wave-vector converted into the crystal's HKL indices." + " Note if nothing is specified then the **General Frame** is being " + "selected. Also note that if you select a frame then this might override " + "your unit selection if it is not compatible with the frame."); // Set the box controller properties this->initBoxControllerProps("5", 1000, 5); diff --git a/Framework/MDAlgorithms/src/ImportMDHistoWorkspaceBase.cpp b/Framework/MDAlgorithms/src/ImportMDHistoWorkspaceBase.cpp index 59bbfbca787..84b71925e96 100644 --- a/Framework/MDAlgorithms/src/ImportMDHistoWorkspaceBase.cpp +++ b/Framework/MDAlgorithms/src/ImportMDHistoWorkspaceBase.cpp @@ -5,7 +5,11 @@ #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/CompositeValidator.h" #include "MantidKernel/MandatoryValidator.h" - +#include "MantidGeometry/MDGeometry/QSample.h" +#include "MantidGeometry/MDGeometry/QLab.h" +#include "MantidGeometry/MDGeometry/HKL.h" +#include "MantidGeometry/MDGeometry/GeneralFrame.h" +#include "MantidGeometry/MDGeometry/MDFrameFactory.h" #include <algorithm> using namespace Mantid::API; @@ -63,6 +67,17 @@ void ImportMDHistoWorkspaceBase::initGenericImportProps() { declareProperty(new WorkspaceProperty<IMDHistoWorkspace>( "OutputWorkspace", "", Direction::Output), "MDHistoWorkspace reflecting the input text file."); + declareProperty( + new ArrayProperty<std::string>("Frames"), + " A comma separated list of the frames of each dimension. " + " The frames can be" + " **General Frame**: Any frame which is not a Q-based frame." + " **QLab**: Wave-vector converted into the lab frame." + " **QSample**: Wave-vector converted into the frame of the sample." + " **HKL**: Wave-vector converted into the crystal's HKL indices." + " Note if nothing is specified then the **General Frame** is being " + "selected. Also note that if you select a frame then this might override " + "your unit selection if it is not compatible with the frame."); } //---------------------------------------------------------------------------------------------- @@ -81,6 +96,7 @@ MDHistoWorkspace_sptr ImportMDHistoWorkspaceBase::createEmptyOutputWorkspace() { std::vector<int> nbins = getProperty("NumberOfBins"); std::vector<std::string> names = getProperty("Names"); std::vector<std::string> units = getProperty("Units"); + std::vector<std::string> frames = getProperty("Frames"); // Perform all validation on inputs if (extents.size() != ndims * 2) @@ -96,11 +112,26 @@ MDHistoWorkspace_sptr ImportMDHistoWorkspaceBase::createEmptyOutputWorkspace() { throw std::invalid_argument( "You must specify as many units as there are dimensions."); + // If no frames are specified we want to default to the General Frame, + // to ensure backward compatibility. But if they are only partly specified, + // then we want to throw an error. It should be either used correctly or not + // at all + if (!frames.empty() && frames.size() != ndims) { + throw std::invalid_argument( + "You must specify as many frames as there are dimensions."); + } + + if (frames.empty()) { + frames.resize(ndims); + std::fill(frames.begin(), frames.end(), GeneralFrame::GeneralFrameName); + } + // Fabricate new dimensions from inputs std::vector<MDHistoDimension_sptr> dimensions; for (size_t k = 0; k < ndims; ++k) { + auto frame = createMDFrame(frames[k], units[k]); dimensions.push_back(MDHistoDimension_sptr(new MDHistoDimension( - names[k], names[k], units[k], static_cast<coord_t>(extents[k * 2]), + names[k], names[k], *frame, static_cast<coord_t>(extents[k * 2]), static_cast<coord_t>(extents[(k * 2) + 1]), nbins[k]))); } @@ -112,5 +143,71 @@ MDHistoWorkspace_sptr ImportMDHistoWorkspaceBase::createEmptyOutputWorkspace() { return ws; } +/** + * Create an MDFrame + * @param frame: the selected frame + * @param unit: the selected unit + * @returns a unique pointer to an MDFrame + */ +MDFrame_uptr ImportMDHistoWorkspaceBase::createMDFrame(std::string frame, + std::string unit) { + auto frameFactory = makeMDFrameFactoryChain(); + MDFrameArgument frameArg(frame, unit); + return frameFactory->create(frameArg); +} + +std::map<std::string, std::string> +ImportMDHistoWorkspaceBase::validateInputs() { + // Check Frame names + std::map<std::string, std::string> errors; + std::string framePropertyName = "Frames"; + std::vector<std::string> frames = getProperty(framePropertyName); + int ndims_prop = getProperty("Dimensionality"); + auto ndims = static_cast<size_t>(ndims_prop); + + std::vector<std::string> targetFrames; + targetFrames.push_back(Mantid::Geometry::GeneralFrame::GeneralFrameName); + targetFrames.push_back(Mantid::Geometry::HKL::HKLName); + targetFrames.push_back(Mantid::Geometry::QLab::QLabName); + targetFrames.push_back(Mantid::Geometry::QSample::QSampleName); + + auto isValidFrame = true; + for (auto it = frames.begin(); it != frames.end(); ++it) { + auto result = checkIfFrameValid(*it, targetFrames); + if (!result) { + isValidFrame = result; + } + } + + if (!frames.empty() && frames.size() != ndims) { + isValidFrame = false; + } + + if (!isValidFrame) { + std::string message = "The selected frames can be 'HKL', 'QSample', 'QLab' " + "or 'General Frame'. You must specify as many frames " + "as there are dimensions."; + errors.insert(std::make_pair(framePropertyName, message)); + } + return errors; +} + +/** + * Check if the specified frame matches a target frame + * @param frame: the frame name under investigation + * @param targetFrames: the allowed frame names + * @returns true if the frame name is valid else false + */ +bool ImportMDHistoWorkspaceBase::checkIfFrameValid( + const std::string &frame, const std::vector<std::string> &targetFrames) { + for (auto targetFrame = targetFrames.begin(); + targetFrame != targetFrames.end(); ++targetFrame) { + if (*targetFrame == frame) { + return true; + } + } + return false; +} + } // namespace Mantid } // namespace MDAlgorithms diff --git a/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h index 534d7b00cde..91a31c184ba 100644 --- a/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h +++ b/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h @@ -4,7 +4,8 @@ #include <cxxtest/TestSuite.h> #include "MantidKernel/Timer.h" #include "MantidKernel/System.h" - +#include "MantidGeometry/MDGeometry/QSample.h" +#include "MantidGeometry/MDGeometry/GeneralFrame.h" #include "MantidMDAlgorithms/CreateMDHistoWorkspace.h" using namespace Mantid; @@ -103,6 +104,7 @@ public: TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Extents", "-1,1")); TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Names", "A")); TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Units", "U")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Frames", "QSample")); TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName)); TS_ASSERT_THROWS_NOTHING(alg.execute();); @@ -122,7 +124,10 @@ public: TS_ASSERT_EQUALS("A", dim1->getName()); TS_ASSERT_EQUALS("A", dim1->getDimensionId()); - TS_ASSERT_EQUALS("U", dim1->getUnits().ascii()); + TSM_ASSERT("Should not be set to U any longer", "U" != dim1->getUnits().ascii()); + TSM_ASSERT_THROWS_NOTHING( + "Should be convertible to a QSample frame", + dynamic_cast<const Mantid::Geometry::QSample &>(dim1->getMDFrame())); TS_ASSERT_EQUALS(1, dim1->getMaximum()); TS_ASSERT_EQUALS(-1, dim1->getMinimum()); TS_ASSERT_EQUALS(5, dim1->getNBins()); @@ -177,6 +182,15 @@ public: TS_ASSERT_EQUALS(2, dim1->getNBins()); TS_ASSERT_EQUALS(3, dim2->getNBins()); + // Check frame and label + TSM_ASSERT("Should be set to U", "U" == dim1->getUnits().ascii()); + TSM_ASSERT_THROWS_NOTHING( + "Should be convertible to a General Frame", + dynamic_cast<const Mantid::Geometry::GeneralFrame &>(dim1->getMDFrame())); + TSM_ASSERT_THROWS_NOTHING( + "Should be convertible to a General Frame", + dynamic_cast<const Mantid::Geometry::GeneralFrame &>(dim2->getMDFrame())); + // Check the data double *signals = outWs->getSignalArray(); TS_ASSERT_DELTA(1, signals[0], 0.0001); // Check the first signal value diff --git a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h index cd09e88274d..8091c8b9006 100644 --- a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h +++ b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h @@ -4,7 +4,7 @@ #include "MantidAPI/IMDHistoWorkspace.h" #include "MantidKernel/ConfigService.h" #include "MantidMDAlgorithms/ImportMDHistoWorkspace.h" - +#include "MantidGeometry/MDGeometry/QSample.h" #include <cxxtest/TestSuite.h> #include <Poco/Path.h> @@ -277,7 +277,8 @@ public: alg->setPropertyValue("Extents", "-1,1,-1,1,-1,1"); alg->setPropertyValue("NumberOfBins", "2,2,2"); alg->setPropertyValue("Names", "A,B,C"); - alg->setPropertyValue("Units", "U1,U2,U3"); + alg->setPropertyValue("Units", "U,U,U"); + TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("Frames", "QSample, QSample, QSample")); alg->setPropertyValue("OutputWorkspace", "test_workspace"); alg->setRethrows(true); alg->execute(); @@ -296,6 +297,16 @@ public: // Check the dimensionality TS_ASSERT_EQUALS(3, outWs->getNumDims()); + // Check frame + for (size_t dim = 0; dim < outWs->getNumDims(); ++dim) { + auto dimension = outWs->getDimension(dim); + const auto &frame = dimension->getMDFrame(); + TSM_ASSERT_THROWS_NOTHING( + "Should be convertible to a QSample frame", + dynamic_cast<const Mantid::Geometry::QSample &>(frame)); + TSM_ASSERT("Should not be set to U any longer", "U" != dimension->getUnits().ascii()); + } + ADS.remove("test_workspace"); } }; diff --git a/Framework/MDAlgorithms/test/LoadMDTest.h b/Framework/MDAlgorithms/test/LoadMDTest.h index 855729c5f34..744d40d6a2e 100644 --- a/Framework/MDAlgorithms/test/LoadMDTest.h +++ b/Framework/MDAlgorithms/test/LoadMDTest.h @@ -11,6 +11,7 @@ #include "MantidDataObjects/MDEventFactory.h" #include "MantidDataObjects/MDEventWorkspace.h" #include "MantidDataObjects/BoxControllerNeXusIO.h" +#include "MantidGeometry/MDGeometry/QSample.h" #include "MantidMDAlgorithms/LoadMD.h" #include <cxxtest/TestSuite.h> @@ -593,9 +594,11 @@ public: /// More of an integration test as it uses both load and save. void test_save_and_load_special_coordinates_MDEventWorkspace() { + Mantid::Geometry::QSample frame; MDEventWorkspace1Lean::sptr mdeventWS = - MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2); - const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + MDEventsTestHelper::makeMDEWWithFrames<1>(10, 0.0, 10.0, frame, 2); + const Mantid::Kernel::SpecialCoordinateSystem appliedCoordinateSystem = + Mantid::Kernel::SpecialCoordinateSystem::QSample; mdeventWS->setCoordinateSystem(appliedCoordinateSystem); auto loadedWS = testSaveAndLoadWorkspace(mdeventWS, "MDEventWorkspace"); @@ -607,9 +610,11 @@ public: // backwards-compatability check for coordinate in log void test_load_coordinate_system_MDEventWorkspace_from_experiment_info() { + Mantid::Geometry::QSample frame; MDEventWorkspace1Lean::sptr mdeventWS = - MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2); - const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + MDEventsTestHelper::makeMDEWWithFrames<1>(10, 0.0, 10.0, frame, 2); + const Mantid::Kernel::SpecialCoordinateSystem appliedCoordinateSystem = + Mantid::Kernel::SpecialCoordinateSystem::QSample; mdeventWS->setCoordinateSystem(appliedCoordinateSystem); // Create a log in the first experiment info to simulated an old version of @@ -628,9 +633,11 @@ public: } void test_save_and_load_special_coordinates_MDHistoWorkspace() { - auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace( - 2.5, 2, 10, 10.0, 3.5, "", 4.5); - const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + Mantid::Geometry::QSample frame; + auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspaceWithMDFrame( + 2.5, 2, frame, 10, 10.0, 3.5, "", 4.5); + const Mantid::Kernel::SpecialCoordinateSystem appliedCoordinateSystem = + Mantid::Kernel::SpecialCoordinateSystem::QSample; mdhistoWS->setCoordinateSystem(appliedCoordinateSystem); auto loadedWS = testSaveAndLoadWorkspace(mdhistoWS, "MDHistoWorkspace"); @@ -642,9 +649,11 @@ public: // backwards-compatability check for coordinate in log void test_load_coordinate_system_MDHistoWorkspace_from_experiment_info() { - auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace( - 2.5, 2, 10, 10.0, 3.5, "", 4.5); - const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + Mantid::Geometry::QSample frame; + auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspaceWithMDFrame( + 2.5, 2, frame, 10, 10.0, 3.5, "", 4.5); + const Mantid::Kernel::SpecialCoordinateSystem appliedCoordinateSystem = + Mantid::Kernel::SpecialCoordinateSystem::QSample; mdhistoWS->setCoordinateSystem(appliedCoordinateSystem); // Create a log in the first experiment info to simulated an old version of diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h index fea8f0e6970..ea95ef80a6e 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h @@ -246,6 +246,16 @@ makeMDEW(size_t splitInto, coord_t min, coord_t max, return makeAnyMDEW<MDLeanEvent<nd>, nd>(splitInto, min, max, numEventsPerBox); } +/** Make a MDEventWorkspace with MDLeanEvents nad MDFrames*/ +template <size_t nd> +boost::shared_ptr<MDEventWorkspace<MDLeanEvent<nd>, nd>> +makeMDEWWithFrames(size_t splitInto, coord_t min, coord_t max, + const Mantid::Geometry::MDFrame &frame, + size_t numEventsPerBox = 0) { + return makeAnyMDEWWithFrames<MDLeanEvent<nd>, nd>(splitInto, min, max, frame, + numEventsPerBox); +} + /** Make a MDEventWorkspace with MDEvents - updated to split dims by splitInto, * not 10 */ template <size_t nd> -- GitLab