Skip to content
Snippets Groups Projects
Commit 94f57f7c authored by Janik Zikovsky's avatar Janik Zikovsky
Browse files

Refs #4562: reusable method for MinRecursionDepth in MDWorkspaces

parent 29f11568
No related merge requests found
......@@ -63,6 +63,9 @@ namespace API
/// Refresh the cache (integrated signal of each box)
virtual void refreshCache() = 0;
/// Recurse down to a minimum depth
virtual void setMinRecursionDepth(size_t depth) = 0;
/// Return the type of event contained, as a string. MDEvent or MDLeanEvent
virtual std::string getEventTypeName() const = 0;
......@@ -73,6 +76,7 @@ namespace API
void setFileNeedsUpdating(bool value);
protected:
/// Marker set to true when a file-backed workspace needs its back-end file updated (by calling SaveMD(UpdateFileBackEnd=1) )
bool m_fileNeedsUpdating;
......
......@@ -86,12 +86,14 @@ namespace MDEvents
virtual void splitAllIfNeeded(Kernel::ThreadScheduler * ts);
virtual void splitBox();
virtual void splitBox();
virtual void refreshCache();
virtual void refreshCache();
std::string getEventTypeName() const;
virtual void setMinRecursionDepth(size_t minDepth);
//------------------------ (END) IMDEventWorkspace Methods -----------------------------------------
Mantid::API::ITableWorkspace_sptr makeBoxTable(size_t start, size_t num);
......
......@@ -126,35 +126,8 @@ namespace MDEvents
// Do we split more due to MinRecursionDepth?
int minDepth = this->getProperty("MinRecursionDepth");
double numBoxes = pow(double(bc->getNumSplit()), double(minDepth));
double memoryToUse = numBoxes * double(sizeof(MDBox<MDE,nd>)) / 1024.0;
MemoryStats stats;
if (double(stats.availMem()) < memoryToUse)
{
g_log.error() << "MinRecursionDepth is set to " << minDepth << ", which would create " << numBoxes << " boxes using " << memoryToUse << " kB of memory."
<< " You have " << stats.availMem() << " kB available." << std::endl;
throw std::runtime_error("Not enough memory available for the given MinRecursionDepth!");
}
for (int depth = 1; depth < minDepth; depth++)
{
// Get all the MDGridBoxes in the workspace
std::vector<IMDBox<MDE,nd>*> boxes;
boxes.clear();
ws->getBox()->getBoxes(boxes, depth-1, false);
for (size_t i=0; i<boxes.size(); i++)
{
IMDBox<MDE,nd> * box = boxes[i];
MDGridBox<MDE,nd>* gbox = dynamic_cast<MDGridBox<MDE,nd>*>(box);
if (gbox)
{
// Split ALL the contents.
for (size_t j=0; j<gbox->getNumChildren(); j++)
gbox->splitContents(j, NULL);
}
}
}
if (minDepth<0) throw std::invalid_argument("MinRecursionDepth must be >= 0.");
ws->setMinRecursionDepth(size_t(minDepth));
}
......
......@@ -18,6 +18,7 @@
#include <iomanip>
#include <functional>
#include "MantidMDEvents/MDBoxIterator.h"
#include "MantidKernel/Memory.h"
using namespace Mantid;
using namespace Mantid::Kernel;
......@@ -123,6 +124,56 @@ namespace MDEvents
return data->getNPoints();
}
//-----------------------------------------------------------------------------------------------
/** Recurse box structure down to a minimum depth.
*
* This will split all boxes so that all MDBoxes are at the depth indicated.
* 0 = no splitting, 1 = one level of splitting, etc.
*
* WARNING! This should ONLY be called before adding any events to a workspace.
*
* WARNING! Be careful using this since it can quickly create a huge
* number of boxes = (SplitInto ^ (MinRercursionDepth * NumDimensions))
*
* @param minDepth :: minimum recursion depth.
* @throw std::runtime_error if there is not enough memory for the boxes.
*/
TMDE(
void MDEventWorkspace)::setMinRecursionDepth(size_t minDepth)
{
BoxController_sptr bc = this->getBoxController();
double numBoxes = pow(double(bc->getNumSplit()), double(minDepth));
double memoryToUse = numBoxes * double(sizeof(MDBox<MDE,nd>)) / 1024.0;
MemoryStats stats;
if (double(stats.availMem()) < memoryToUse)
{
std::ostringstream mess;
mess << "Not enough memory available for the given MinRecursionDepth! "
<< "MinRecursionDepth is set to " << minDepth << ", which would create " << numBoxes << " boxes using " << memoryToUse << " kB of memory."
<< " You have " << stats.availMem() << " kB available." << std::endl;
throw std::runtime_error(mess.str());
}
for (size_t depth = 1; depth < minDepth; depth++)
{
// Get all the MDGridBoxes in the workspace
std::vector<IMDBox<MDE,nd>*> boxes;
boxes.clear();
this->getBox()->getBoxes(boxes, depth-1, false);
for (size_t i=0; i<boxes.size(); i++)
{
IMDBox<MDE,nd> * box = boxes[i];
MDGridBox<MDE,nd>* gbox = dynamic_cast<MDGridBox<MDE,nd>*>(box);
if (gbox)
{
// Split ALL the contents.
for (size_t j=0; j<gbox->getNumChildren(); j++)
gbox->splitContents(j, NULL);
}
}
}
}
//-----------------------------------------------------------------------------------------------
/// Set the number of bins in each dimension to something corresponding to the estimated resolution of the finest binning
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment