diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h index 6b369f86a94449b0c5091425791dac4a3e05b1fd..883e6b6055e148109a2bb3085ca874361faf4abe 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h @@ -56,12 +56,15 @@ namespace API /// Set the number of bins in each dimension to something corresponding to the estimated resolution of the finest binning virtual void estimateResolution() = 0; - /// get number of dimensions contained in initialized MD workspace - virtual size_t getNumDims()const=0; - /// split box function; - virtual void splitBox()=0; - // - virtual void refreshCache()=0; + + /// Split the top-level MDBox into a MDGridBox. + virtual void splitBox() = 0; + + /// Refresh the cache (integrated signal of each box) + virtual void refreshCache() = 0; + + /// Return the type of event contained, as a string. MDEvent or MDLeanEvent + virtual std::string getEventTypeName() const = 0; /// Split all boxes that exceed the split threshold. virtual void splitAllIfNeeded(Kernel::ThreadScheduler * ts) = 0; diff --git a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt index 7582d57127cc2c3faaf5b4946dd2979474643fa9..f545956a034687a4d7b1cdef0880c975e69e7f39 100644 --- a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt @@ -19,6 +19,7 @@ set ( SRC_FILES src/InvalidParameterParser.cpp src/LessThanMD.cpp src/LogarithmMD.cpp + src/MergeMD.cpp src/MergeMDFiles.cpp src/MinusMD.cpp src/MultiplyMD.cpp @@ -68,6 +69,7 @@ set ( INC_FILES inc/MantidMDAlgorithms/InvalidParameterParser.h inc/MantidMDAlgorithms/LessThanMD.h inc/MantidMDAlgorithms/LogarithmMD.h + inc/MantidMDAlgorithms/MergeMD.h inc/MantidMDAlgorithms/MergeMDFiles.h inc/MantidMDAlgorithms/MinusMD.h inc/MantidMDAlgorithms/MultiplyMD.h @@ -110,6 +112,7 @@ set ( TEST_FILES test/LessThanMDTest.h test/LogarithmMDTest.h test/MergeMDFilesTest.h + test/MergeMDTest.h test/MinusMDTest.h test/MultiplyMDTest.h test/NotMDTest.h diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h new file mode 100644 index 0000000000000000000000000000000000000000..130c3d049046a79a1330fbea1c232633f5b8bb03 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h @@ -0,0 +1,71 @@ +#ifndef MANTID_MDALGORITHMS_MERGEMD_H_ +#define MANTID_MDALGORITHMS_MERGEMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDEvents/BoxControllerSettingsAlgorithm.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidMDEvents/MDEventWorkspace.h" + + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** Merge several MDWorkspaces into one. + + @date 2012-01-17 + + Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + class DLLExport MergeMD : public Mantid::MDEvents::BoxControllerSettingsAlgorithm + { + public: + MergeMD(); + virtual ~MergeMD(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + + private: + virtual void initDocs(); + void init(); + void exec(); + void createOutputWorkspace(std::vector<std::string> & inputs); + + template<typename MDE, size_t nd> + void doPlus(typename Mantid::MDEvents::MDEventWorkspace<MDE, nd>::sptr ws); + + /// Vector of input MDWorkspaces + std::vector<Mantid::API::IMDEventWorkspace_sptr> m_workspaces; + + /// Output MDEventWorkspace + Mantid::API::IMDEventWorkspace_sptr out; + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_MERGEMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MergeMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MergeMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..92217e45dbae28a611e2228ff4b8f571d4245432 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/MergeMD.cpp @@ -0,0 +1,270 @@ +/*WIKI* + +Merge several [[MDWorkspace]]s into one. + +See also: [[MergeMDFiles]], for merging when system memory is too small to keep the entire workspace in memory. + +*WIKI*/ + +#include "MantidMDAlgorithms/MergeMD.h" +#include "MantidKernel/System.h" +#include "MantidKernel/Strings.h" +#include "MantidGeometry/MDGeometry/IMDDimension.h" +#include "MantidMDEvents/MDEventFactory.h" +#include "MantidGeometry/MDGeometry/MDHistoDimension.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidMDEvents/MDBoxIterator.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace Mantid::MDEvents; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(MergeMD) + + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + MergeMD::MergeMD() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + MergeMD::~MergeMD() + { + } + + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string MergeMD::name() const { return "MergeMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int MergeMD::version() const { return 1;}; + + /// Algorithm's category for identification. @see Algorithm::category + const std::string MergeMD::category() const { return "General";} + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void MergeMD::initDocs() + { + this->setWikiSummary("Merge several [[MDWorkspace]]s into one."); + this->setOptionalMessage("Merge several MDWorkspaces into one."); + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void MergeMD::init() + { + // declare arbitrary number of input m_workspaces as a list of strings at the moment + declareProperty( + new ArrayProperty<std::string>("InputWorkspaces", new MandatoryValidator<std::vector<std::string> >), + "The names of the input MDWorkspaces as a comma-separated list" ); + + declareProperty(new WorkspaceProperty<IMDEventWorkspace>("OutputWorkspace","",Direction::Output), + "Name of the output MDWorkspace."); + + // Set the box controller properties + this->initBoxControllerProps("2", 500, 16); + } + + //---------------------------------------------------------------------------------------------- + /** Create the output MDWorkspace from a list of input + * + * @param inputs :: list of names of input MDWorkspaces + */ + void MergeMD::createOutputWorkspace(std::vector<std::string> & inputs) + { + std::vector<std::string>::iterator it = inputs.begin(); + for (; it != inputs.end(); it++) + { + IMDEventWorkspace_sptr ws = boost::dynamic_pointer_cast<IMDEventWorkspace>( + AnalysisDataService::Instance().retrieve(*it) ); + if (!ws) + throw std::invalid_argument("Workspace " + *it + " is not a MDEventWorkspace. Cannot merge this workspace."); + else + m_workspaces.push_back(ws); + } + if (m_workspaces.empty()) + throw std::invalid_argument("No valid m_workspaces specified."); + + // Number of dimensions, start with the 0th one. They all have to match # of dims anyway + IMDEventWorkspace_const_sptr ws0 = m_workspaces[0]; + size_t numDims = ws0->getNumDims(); + + // Extents to create. + std::vector<double> dimMin(numDims, +1e100); + std::vector<double> dimMax(numDims, -1e100); + + // Validate each workspace + for (size_t i=0; i < m_workspaces.size(); i++) + { + IMDEventWorkspace_const_sptr ws = m_workspaces[i]; + if (ws->getNumDims() != numDims) + throw std::invalid_argument("Workspace " + ws->name() + " does not match the number of dimensions of the others (" + + Strings::toString(ws->getNumDims()) + ", expected " + Strings::toString(numDims) + ")" ); + + if (ws->getEventTypeName() != ws0->getEventTypeName()) + throw std::invalid_argument("Workspace " + ws->name() + " does not match the MDEvent type of the others (" + + ws->getEventTypeName() + ", expected " + ws0->getEventTypeName() + ")" ); + + for (size_t d=0; d<numDims; d++) + { + IMDDimension_const_sptr dim = ws->getDimension(d); + IMDDimension_const_sptr dim0 = ws0->getDimension(d); + if (dim->getName() != dim0->getName()) + throw std::invalid_argument("Workspace " + ws->name() + " does not have the same dimension " + + Strings::toString(d) + " as the others (" + dim->getName() + ", expected " + dim0->getName() + ")" ); + + // Find the extents + if (dim->getMaximum() > dimMax[d]) + dimMax[d] = dim->getMaximum(); + if (dim->getMinimum() < dimMin[d]) + dimMin[d] = dim->getMinimum(); + } + } + + // OK, now create the blank MDWorkspace + + // Have the factory create it + out = MDEventFactory::CreateMDWorkspace(numDims, ws0->getEventTypeName()); + + // Give all the dimensions + for (size_t d=0; d<numDims; d++) + { + IMDDimension_const_sptr dim0 = ws0->getDimension(d); + MDHistoDimension * dim = new MDHistoDimension(dim0->getName(), dim0->getDimensionId(), dim0->getUnits(), + dimMin[d], dimMax[d], dim0->getNBins()); + out->addDimension(MDHistoDimension_sptr(dim)); + } + + // Initialize it using the dimension + out->initialize(); + + // Set the box controller settings from the properties + this->setBoxController(out->getBoxController()); + + // Perform the initial box splitting + out->splitBox(); + + } + + + + //---------------------------------------------------------------------------------------------- + /** Perform the adding. + * Will do out += ws + * + * @param ws :: MDEventWorkspace to clone + */ + template<typename MDE, size_t nd> + void MergeMD::doPlus(typename MDEventWorkspace<MDE, nd>::sptr ws) + { + typename MDEventWorkspace<MDE, nd>::sptr ws1 = boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd> >(out); + typename MDEventWorkspace<MDE, nd>::sptr ws2 = ws; + if (!ws1 || !ws2) + throw std::runtime_error("Incompatible workspace types passed to MergeMD."); + + IMDBox<MDE,nd> * box1 = ws1->getBox(); + IMDBox<MDE,nd> * box2 = ws2->getBox(); + + // How many events you started with + size_t initial_numEvents = ws1->getNPoints(); + + // Make a leaf-only iterator through all boxes with events in the RHS workspace + MDBoxIterator<MDE,nd> it2(box2, 1000, true); + do + { + MDBox<MDE,nd> * box = dynamic_cast<MDBox<MDE,nd> *>(it2.getBox()); + if (box) + { + // Copy the events from WS2 and add them into WS1 + const std::vector<MDE> & events = box->getConstEvents(); + // Add events, with bounds checking + box1->addEvents(events); + box->releaseEvents(); + } + } while (it2.next()); + + //Progress * prog2 = new Progress(this, 0.4, 0.9, 100); + Progress * prog2 = NULL; + ThreadScheduler * ts = new ThreadSchedulerFIFO(); + ThreadPool tp(ts, 0, prog2); + ws1->splitAllIfNeeded(ts); + //prog2->resetNumSteps( ts->size(), 0.4, 0.6); + tp.joinAll(); + + // Set a marker that the file-back-end needs updating if the # of events changed. + if (ws1->getNPoints() != initial_numEvents) + ws1->setFileNeedsUpdating(true); + + } + + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void MergeMD::exec() + { + // Check that all input workspaces exist and match in certain important ways + const std::vector<std::string> inputs_orig = getProperty("InputWorkspaces"); + + // This will hold the inputs, with the groups separated off + std::vector<std::string> inputs; + for (size_t i=0; i < inputs_orig.size(); i++) + { + WorkspaceGroup_sptr wsgroup = boost::dynamic_pointer_cast<WorkspaceGroup>(AnalysisDataService::Instance().retrieve(inputs_orig[i])); + if (wsgroup) + {// Workspace group + std::vector<std::string> group = wsgroup->getNames(); + inputs.insert(inputs.end(), group.begin(), group.end()); + } + else + { + // Single workspace + inputs.push_back( inputs_orig[i] ); + } + } + + if ( inputs.size() == 1 ) + { + g_log.error("Only one input workspace specified"); + throw std::invalid_argument("Only one input workspace specified"); + } + + // Create a blank output workspace + this->createOutputWorkspace(inputs); + + // Run PlusMD on each of the input workspaces, in order. + double progStep = 1.0 / double(m_workspaces.size()); + for (size_t i=0; i<m_workspaces.size(); i++) + { + g_log.information() << "Adding workspace " << m_workspaces[i]->name() << std::endl; + progress(double(i) * progStep, m_workspaces[i]->name()); + CALL_MDEVENT_FUNCTION(doPlus, m_workspaces[i]); + } + + this->progress(0.95, "Refreshing cache"); + out->refreshCache(); + + // Add to data service + AnalysisDataService::Instance().addOrReplace(this->getPropertyValue("OutputWorkspace"), out); + this->setProperty("OutputWorkspace", out); + } + + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h index c45277fe76d1f3b4507dabff44a5c6bd5e2d507e..f60db5cf9c27e4b676d7e22a107f6f66b57068dc 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h @@ -35,7 +35,7 @@ public: void test_exec_fileBacked() { - do_test_exec("MergeMDTest_OutputWS.nxs"); + do_test_exec("MergeMDFilesTest_OutputWS.nxs"); } void do_test_exec(std::string OutputFilename) @@ -46,14 +46,14 @@ public: for (size_t i=0; i<3; i++) { std::ostringstream mess; - mess << "MergeMDTestInput" << i; + mess << "MergeMDFilesTestInput" << i; MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeFileBackedMDEW(mess.str(), true); inWorkspaces.push_back(ws); filenames.push_back(ws->getBoxController()->getFilename()); } // Name of the output workspace. - std::string outWSName("MergeMDTest_OutputWS"); + std::string outWSName("MergeMDFilesTest_OutputWS"); MergeMDFiles alg; TS_ASSERT_THROWS_NOTHING( alg.initialize() ) diff --git a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..62de493f22399828e011df3fba8716ed291402a1 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDTest.h @@ -0,0 +1,106 @@ +#ifndef MANTID_MDALGORITHMS_MERGEMDTEST_H_ +#define MANTID_MDALGORITHMS_MERGEMDTEST_H_ + +#include "MantidKernel/System.h" +#include "MantidKernel/Timer.h" +#include "MantidMDAlgorithms/MergeMD.h" +#include "MantidMDEvents/MDEventFactory.h" +#include "MantidTestHelpers/MDEventsTestHelper.h" +#include <cxxtest/TestSuite.h> +#include <iomanip> +#include <iostream> +#include <Poco/File.h> +#include "MantidGeometry/MDGeometry/IMDDimension.h" + +using namespace Mantid; +using namespace Mantid::MDEvents; +using namespace Mantid::Geometry; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDEventsTestHelper::makeAnyMDEW; + +class MergeMDTest : public CxxTest::TestSuite +{ +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static MergeMDTest *createSuite() { return new MergeMDTest(); } + static void destroySuite( MergeMDTest *suite ) { delete suite; } + + void setUp() + { + makeAnyMDEW<MDEvent<3>, 3>(2, 5., 10., 1, "mde3"); + makeAnyMDEW<MDEvent<4>, 4>(2, 5., 10., 1, "mde4"); + makeAnyMDEW<MDLeanEvent<3>, 3>(2, 5., 10., 1, "mdle3"); + // Several compatible 2D workspaces + makeAnyMDEW<MDLeanEvent<2>, 2>(2, 0., 10., 1, "ws0"); + makeAnyMDEW<MDLeanEvent<2>, 2>(6, -5., 10., 1, "ws1"); + makeAnyMDEW<MDLeanEvent<2>, 2>(10, 0., 20., 1, "ws2"); + } + + void test_Init() + { + MergeMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_failures() + { + do_test_fails("mde3, mde4"); + do_test_fails("mde3, mdle3"); + } + + /** Run MergeMD, expect it to fail */ + void do_test_fails(const std::string & inputs) + { + MergeMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspaces", inputs) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", "failed_output") ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( !alg.isExecuted() ); + } + + void test_exec() + { + // Name of the output workspace. + std::string outWSName("MergeMDTest_OutputWS"); + + MergeMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspaces", "ws0,ws1,ws2") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. + IMDEventWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = boost::dynamic_pointer_cast<IMDEventWorkspace>(AnalysisDataService::Instance().retrieve(outWSName)) ); + TS_ASSERT(ws); + if (!ws) return; + + // Number of events is the sum of the 3 input ones. + TS_ASSERT_EQUALS( ws->getNPoints(), 2*2 + 6*6 + 10*10); + for (size_t d=0; d<2; d++) + { + IMDDimension_const_sptr dim = ws->getDimension(d); + TS_ASSERT_DELTA( dim->getMinimum(), -5.0, 1e-3); + TS_ASSERT_DELTA( dim->getMaximum(), +20.0, 1e-3); + } + + // Remove workspace from the data service. + AnalysisDataService::Instance().remove(outWSName); + } + + void test_Something() + { + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_MERGEMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h index 6441592b7009066cd217c1f9078cce865b80b5a7..6d5da0779e72dda12a3994a5e71c249caa6c72d9 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h @@ -89,6 +89,9 @@ namespace MDEvents virtual void splitBox(); virtual void refreshCache(); + + std::string getEventTypeName() const; + //------------------------ (END) IMDEventWorkspace Methods ----------------------------------------- Mantid::API::ITableWorkspace_sptr makeBoxTable(size_t start, size_t num); diff --git a/Code/Mantid/Framework/MDEvents/src/CreateMDWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/CreateMDWorkspace.cpp index 66990ed715c8869aa7ac83934d9f5badd286a053..0b75b1792964a475d9effecff62bfc904248adaa 100644 --- a/Code/Mantid/Framework/MDEvents/src/CreateMDWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/CreateMDWorkspace.cpp @@ -1,18 +1,20 @@ /*WIKI* +This algorithm creates an empty MDEventWorkspace from scratch. The workspace can have any number of dimensions (up to ~20). +Each dimension must have its name, units, extents specified as comma-spearated string. +The SplitInto parameter determines how splitting of dense boxes will be performed. +For example, if SplitInto=5 and the number of dimensions is 3, then each box will get split into 5x5x5 sub-boxes. -This algorithm creates an empty MDEventWorkspace from scratch. The workspace can have any number of dimensions (up to ~20). Each dimension must have its name, units, extents specified as comma-spearated string. - -The SplitInto parameter determines how splitting of dense boxes will be performed. For example, if SplitInto=5 and the number of dimensions is 3, then each box will get split into 5x5x5 sub-boxes. - -The SplitThreshold parameter determines how many events to keep in a box before splitting it into sub-boxes. This value can significantly affect performance/memory use! Too many events per box will mean unnecessary iteration and a slowdown in general. Too few events per box will waste memory with the overhead of boxes. +The SplitThreshold parameter determines how many events to keep in a box before splitting it into sub-boxes. +This value can significantly affect performance/memory use! +Too many events per box will mean unnecessary iteration and a slowdown in general. +Too few events per box will waste memory with the overhead of boxes. You can create a file-backed MDEventWorkspace by specifying the Filename and Memory parameters. - - *WIKI*/ + #include "MantidAPI/FileProperty.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidGeometry/MDGeometry/MDHistoDimension.h" diff --git a/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp index 2a59a0e146be3bb4c381146ad2e417b6096272b8..2e76714cfd0dad532bb6eb1441e09d798e938de9 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp @@ -96,6 +96,17 @@ namespace MDEvents } + //----------------------------------------------------------------------------------------------- + /** Get the data type (id) of the events in the workspace. + * @return a string, either "MDEvent" or "MDLeanEvent" + */ + TMDE( + std::string MDEventWorkspace)::getEventTypeName() const + { + return MDE::getTypeName(); + } + + //----------------------------------------------------------------------------------------------- /** Returns the number of dimensions in this workspace */ TMDE( diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h index 5e8239685a8dbbca119b2c83d914cc50a62a61f0..58fdcbfb69f510009156aac05cde8cccd2b74950 100644 --- a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h +++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h @@ -10,6 +10,7 @@ #include "MantidMDEvents/MDLeanEvent.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/IMDEventWorkspace.h" +#include "MantidKernel/SingletonHolder.h" namespace Mantid { @@ -54,11 +55,12 @@ namespace MDEventsTestHelper * @param max :: extent of each dimension (max) * @param numEventsPerBox :: will create one MDLeanEvent in the center of each sub-box. * 0 = don't split box, don't add events - * @return + * @param wsName :: if specified, then add the workspace to the analysis data service + * @return shared ptr to the created workspace */ template<typename MDE, size_t nd> boost::shared_ptr<Mantid::MDEvents::MDEventWorkspace<MDE,nd> > - makeAnyMDEW(size_t splitInto, double min, double max, size_t numEventsPerBox = 0 ) + makeAnyMDEW(size_t splitInto, double min, double max, size_t numEventsPerBox = 0, std::string wsName = "" ) { boost::shared_ptr<Mantid::MDEvents::MDEventWorkspace<MDE,nd> > out(new Mantid::MDEvents::MDEventWorkspace<MDE,nd>()); @@ -98,6 +100,10 @@ namespace MDEventsTestHelper out->refreshCache(); } + // Add to ADS on option + if (!wsName.empty()) + Mantid::API::AnalysisDataService::Instance().addOrReplace(wsName, out); + return out; }