Commit b9f8967a authored by Janik Zikovsky's avatar Janik Zikovsky
Browse files

Refs #2830: Added constructor with HKL for Peak object. Improved random fake...

Refs #2830: Added constructor with HKL for Peak object. Improved random fake MDEventData generation for use in test. Fixed subtle bug in MDGridBox spherical integration. Finalized and added test for MDEWPeakIntegration. Added method on IMDBox to getExtentsStr()
parent 5a9ad202
......@@ -25,6 +25,7 @@ namespace DataObjects
friend class PeakColumn;
Peak(Mantid::Geometry::IInstrument_sptr m_inst, int m_DetectorID, double m_Wavelength);
Peak(Mantid::Geometry::IInstrument_sptr m_inst, int m_DetectorID, double m_Wavelength, Mantid::Geometry::V3D HKL);
// Copy constructor is compiler-provided.
// Peak(const Peak & other);
......
......@@ -21,17 +21,37 @@ namespace DataObjects
* @return
*/
Peak::Peak(Mantid::Geometry::IInstrument_sptr m_inst, int m_DetectorID, double m_Wavelength)
: m_inst(m_inst),
m_H(0), m_K(0), m_L(0),
m_Intensity(0), m_SigmaIntensity(0),
m_GoniometerMatrix(3,3,true),
m_RunNumber(0)
: m_inst(m_inst),
m_H(0), m_K(0), m_L(0),
m_Intensity(0), m_SigmaIntensity(0),
m_GoniometerMatrix(3,3,true),
m_InverseGoniometerMatrix(3,3,true),
m_RunNumber(0)
{
this->setDetectorID(m_DetectorID);
this->setWavelength(m_Wavelength);
}
//----------------------------------------------------------------------------------------------
/** Constructor
*
* @param m_inst :: Shared pointer to the instrument for this peak detection
* @param m_DetectorID :: ID to the detector of the center of the peak
* @param m_Wavelength :: incident neutron wavelength, in Angstroms
* @param HKL :: vector with H,K,L position of the peak
* @return
*/
Peak::Peak(Mantid::Geometry::IInstrument_sptr m_inst, int m_DetectorID, double m_Wavelength, Mantid::Geometry::V3D HKL) :
m_inst(m_inst),
m_H(HKL[0]), m_K(HKL[1]), m_L(HKL[2]),
m_Intensity(0), m_SigmaIntensity(0),
m_GoniometerMatrix(3,3,true),
m_InverseGoniometerMatrix(3,3,true),
m_RunNumber(0)
{
this->setDetectorID(m_DetectorID);
this->setWavelength(m_Wavelength);
// Calc the inverse rotation matrix
m_InverseGoniometerMatrix = m_GoniometerMatrix;
m_InverseGoniometerMatrix.Invert();
}
// /** Copy constructor
......@@ -330,6 +350,9 @@ namespace DataObjects
if ((goniometerMatrix.numCols() != 3) || (goniometerMatrix.numRows() != 3))
throw std::invalid_argument("Goniometer matrix must be 3x3.");
this->m_GoniometerMatrix = goniometerMatrix;
// Calc the inverse rotation matrix
m_InverseGoniometerMatrix = m_GoniometerMatrix;
m_InverseGoniometerMatrix.Invert();
}
......
......@@ -36,6 +36,18 @@ public:
TS_ASSERT_EQUALS(p.getInstrument(), inst)
}
void test_constructorHKL()
{
// detector IDs start at 10000
Peak p(inst, 10000, 2.0, V3D(1,2,3) );
TS_ASSERT_DELTA(p.getH(), 1.0, 1e-5)
TS_ASSERT_DELTA(p.getK(), 2.0, 1e-5)
TS_ASSERT_DELTA(p.getL(), 3.0, 1e-5)
TS_ASSERT_EQUALS(p.getDetectorID(), 10000)
TS_ASSERT_EQUALS(p.getDetector()->getID(), 10000)
TS_ASSERT_EQUALS(p.getInstrument(), inst)
}
void test_copyConstructor()
{
Peak p(inst, 10102, 2.0);
......
......@@ -8,6 +8,7 @@
#include "MantidMDEvents/MDBin.h"
#include "MantidMDEvents/MDDimensionExtents.h"
#include "MantidMDEvents/MDEvent.h"
#include <iosfwd>
namespace Mantid
{
......@@ -155,6 +156,19 @@ namespace MDEvents
return extents[dim];
}
//-----------------------------------------------------------------------------------------------
/** Returns the extents as a string, for convenience */
std::string getExtentsStr() const
{
std::stringstream mess;
for (size_t d=0; d<nd; ++d)
{
mess << extents[d].min << "-"<< extents[d].max;
if (d+1 < nd) mess << ",";
}
return mess.str();
}
//-----------------------------------------------------------------------------------------------
/** Get the center of the box
* @param center :: bare array of size[nd] that will get set with the mid-point of each dimension.
......
......@@ -47,6 +47,9 @@ namespace MDEvents
/// Peak workspace to integrate
Mantid::DataObjects::PeaksWorkspace_sptr peakWS;
/// Value of the CoordinatesToUse property.
std::string CoordinatesToUse;
};
......
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/System.h"
#include "MantidMDEvents/FakeMDEventData.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidMDEvents/MDEventFactory.h"
#include "MantidKernel/System.h"
#include "MantidKernel/ArrayProperty.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include <boost/math/distributions/normal.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/math/distributions/normal.hpp>
#include <math.h>
namespace Mantid
{
......@@ -64,18 +67,44 @@ namespace MDEvents
size_t num = size_t(params[0]);
// Width of the peak
double width = params.back();
double desiredRadius = params.back();
boost::mt19937 rng;
boost::uniform_real<double> u(-width, width); // Range
// boost::math::normal_distribution<double> u(0, width);
boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > gen(rng, u);
boost::uniform_real<double> u2(0, 1.0); // Random from 0 to 1.0
boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > genUnit(rng, u2);
int randomSeed = getProperty("RandomSeed");
rng.seed(randomSeed);
for (size_t i=0; i<num; ++i)
{
// Algorithm to generate points along a random n-sphere (sphere with not necessarily 3 dimensions)
// from http://en.wikipedia.org/wiki/N-sphere as of May 6, 2011.
// First, points in a hyper-cube of size 1.0, centered at 0.
CoordType centers[nd];
CoordType radiusSquared = 0;
for (size_t d=0; d<nd; d++)
centers[d] = params[d+1] + gen(); // Center + random variation
{
centers[d] = genUnit();
radiusSquared += centers[d]*centers[d];
}
// Make a unit vector pointing in this direction
CoordType radius = sqrt(radiusSquared);
for (size_t d=0; d<nd; d++)
centers[d] /= radius;
// Now place the point along this radius, scaled with ^1/n for uniformity.
double radPos = genUnit();
radPos = pow(radPos, 1.0/double(nd));
for (size_t d=0; d<nd; d++)
{
// Multiply by the scaling and the desired peak radius
centers[d] *= (radPos * desiredRadius);
// Also offset by the center of the peak, as taken in Params
centers[d] += params[d+1];
}
// Create and add the event.
ws->addEvent( MDE( 1.0, 1.0, centers) );
}
......@@ -113,6 +142,8 @@ namespace MDEvents
throw std::invalid_argument("UniformParams: needs to have ndims*2+1 arguments.");
boost::mt19937 rng;
int randomSeed = getProperty("RandomSeed");
rng.seed(randomSeed);
// Make a random generator for each dimensions
typedef boost::variate_generator<boost::mt19937&, boost::uniform_real<double> > gen_t;
......@@ -162,7 +193,10 @@ namespace MDEvents
declareProperty(new ArrayProperty<double>("PeakParams", ""),
"Add a peak with a normal distribution around a central point.\n"
"Parameters: number_of_events, x, y, z, ..., width.\n");
"Parameters: number_of_events, x, y, z, ..., radius.\n");
declareProperty(new PropertyWithValue<int>("RandomSeed", 0),
"Seed int for the random number generator.");
// declareProperty(new WorkspaceProperty<IMDEventWorkspace>("OutputWorkspace","",Direction::InOut),
// "An input workspace, that will get MDEvents added to it");
......
......@@ -49,6 +49,18 @@ namespace MDEvents
void MDEWPeakIntegration::init()
{
declareProperty(new WorkspaceProperty<IMDEventWorkspace>("InputWorkspace","",Direction::Input), "An input MDEventWorkspace.");
std::vector<std::string> propOptions;
propOptions.push_back("Q (lab frame)");
propOptions.push_back("Q (sample frame)");
propOptions.push_back("HKL");
declareProperty("CoordinatesToUse", "Q (lab frame)",new ListValidator(propOptions),
"Which coordinates of the peak center do you wish to use to integrate the peak? This should match the InputWorkspace's dimensions."
);
declareProperty(new PropertyWithValue<double>("PeakRadius",1.0,Direction::Input),
"Fixed radius around each peak position in which to integrate.");
declareProperty(new WorkspaceProperty<PeaksWorkspace>("PeaksWorkspace","",Direction::InOut),
"A PeaksWorkspace containing the peaks to integrate. The peaks' integrated intensities will be updated"
"with the new values.");
......@@ -61,13 +73,24 @@ namespace MDEvents
if (nd != 3)
throw std::invalid_argument("For now, we expect the input MDEventWorkspace to have 3 dimensions only.");
//TODO: PRAGMA_OMP(parallel for schedule(dynamic, 10) )
for (int i=0; i < int(peakWS->getNumberPeaks()); ++i)
{
// Get a direct ref to that peak.
Peak & p = peakWS->getPeak(i);
// Convert to a position in the dimensions of the workspace
V3D pos = p.getQLabFrame();
// Get the peak center as a position in the dimensions of the workspace
V3D pos;
if (CoordinatesToUse == "Q (lab frame)")
pos = p.getQLabFrame();
else if (CoordinatesToUse == "Q (sample frame)")
pos = p.getQSampleFrame();
else if (CoordinatesToUse == "HKL")
pos = p.getHKL();
double radius = getProperty("PeakRadius");
// std::cout << "\n\n\nStarting peak at " << pos << " with radius " << radius << "\n";
// Build the sphere transformation
bool dimensionsUsed[nd];
......@@ -79,13 +102,16 @@ namespace MDEvents
}
CoordTransformDistance sphere(nd, center, dimensionsUsed);
// TODO: Determine a radius that makes sense!
CoordType radius = 1.0;
// Perform the integration into whatever box is contained within.
double signal = 0;
double errorSquared = 0;
ws->getBox()->integrateSphere(sphere, radius*radius, signal, errorSquared);
// Save it back in the peak object.
p.setIntensity(signal);
p.setSigmaIntensity( sqrt(errorSquared) );
// std::cout << "Peak " << i << " at " << pos << ": signal " << signal << std::endl;
}
}
......@@ -97,6 +123,7 @@ namespace MDEvents
{
inWS = getProperty("InputWorkspace");
peakWS = getProperty("PeaksWorkspace");
CoordinatesToUse = getPropertyValue("CoordinatesToUse");
CALL_MDEVENT_FUNCTION(this->integrate, inWS);
}
......
......@@ -579,7 +579,7 @@ namespace MDEvents
// Coordinates of this vertex
CoordType vertexCoord[nd];
for (size_t d=0; d<nd; ++d)
vertexCoord[d] = double(vertexIndex[d]) * boxSize[d];
vertexCoord[d] = double(vertexIndex[d]) * boxSize[d] + this->extents[d].min;
// Is this vertex contained?
CoordType out[nd];
......@@ -587,7 +587,7 @@ namespace MDEvents
if (out[0] < radiusSquared)
{
// Yes, this vertex is contained within the integration volume!
//std::cout << "vertex at " << vertexCoord[0] << ", " << vertexCoord[1] << " is contained\n";
// std::cout << "vertex at " << vertexCoord[0] << ", " << vertexCoord[1] << ", " << vertexCoord[2] << " is contained\n";
// This vertex is shared by up to 2^nd adjacent boxes (left-right along each dimension).
for (size_t neighb=0; neighb<maxVertices; ++neighb)
......@@ -611,6 +611,7 @@ namespace MDEvents
size_t linearIndex = Utils::nestedForLoopGetLinearIndex(nd, boxIndex, indexMaker);
// So we have one more vertex touching this box that is contained in the integration volume. Whew!
verticesContained[linearIndex]++;
// std::cout << "... added 1 vertex to box " << boxes[linearIndex]->getExtentsStr() << "\n";
}
}
}
......@@ -632,10 +633,12 @@ namespace MDEvents
// Is this box fully contained?
if (verticesContained[i] >= maxVertices)
{
//std::cout << "box at " << i << " is fully contained\n";
// Use the integrated sum of signal in the box
signal += box->getSignal();
errorSquared += box->getErrorSquared();
// std::cout << "box at " << i << " (" << box->getExtentsStr() << ") is fully contained. Vertices = " << verticesContained[i] << "\n";
numFullyContained++;
// Go on to the next box
continue;
......@@ -659,14 +662,14 @@ namespace MDEvents
// If the center is closer than the size of the box, then it MIGHT be touching.
// (We multiply by 0.72 (about sqrt(2)) to look for half the diagonal).
// NOTE! Watch out for non-spherical transforms!
//std::cout << "box at " << i << " is maybe touching\n";
// std::cout << "box at " << i << " is maybe touching\n";
partialBox = true;
}
}
else
{
partialBox = true;
//std::cout << "box at " << i << " has a vertex touching\n";
// std::cout << "box at " << i << " has a vertex touching\n";
}
// We couldn't rule out that the box might be partially contained.
......@@ -674,11 +677,12 @@ namespace MDEvents
{
// Use the detailed integration method.
box->integrateSphere(radiusTransform, radiusSquared, signal, errorSquared);
// std::cout << ".signal=" << signal << "\n";
numPartiallyContained++;
}
} // (for each box)
// std::cout << "Depth " << this->getDepth() << " with " << numFullyContained << " fully contained; " << numPartiallyContained << " partial.\n";
// std::cout << "Depth " << this->getDepth() << " with " << numFullyContained << " fully contained; " << numPartiallyContained << " partial. Signal = " << signal <<"\n";
delete [] verticesContained;
delete [] boxMightTouch;
......
#ifndef MANTID_MDEVENTS_MDEWPEAKINTEGRATIONTEST_H_
#define MANTID_MDEVENTS_MDEWPEAKINTEGRATIONTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/IInstrument.h"
#include "MantidGeometry/MDGeometry/MDHistoDimension.h"
#include "MantidKernel/System.h"
#include <iostream>
#include <iomanip>
#include "MantidKernel/Timer.h"
#include "MantidMDEvents/MDEventFactory.h"
#include "MantidMDEvents/MDEWPeakIntegration.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidTestHelpers/AlgorithmHelper.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
#include <cxxtest/TestSuite.h>
#include <iomanip>
#include <iostream>
using Mantid::API::AnalysisDataService;
using Mantid::Geometry::MDHistoDimension;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
using namespace Mantid::MDEvents;
using Mantid::API::IMDEventWorkspace_sptr;
class MDEWPeakIntegrationTest : public CxxTest::TestSuite
{
public:
std::string outWSName;
void test_Init()
{
......@@ -25,14 +36,87 @@ public:
TS_ASSERT( alg.isInitialized() )
}
void test_exec()
{
// IMDEventWorkspace_sptr inWS;
void doRun(double PeakRadius)
{
MDEWPeakIntegration alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
// TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", inWS ) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", outWSName ) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("PeaksWorkspace", "MDEWPeakIntegrationTest_peaks" ) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CoordinatesToUse", "HKL" ) );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("PeakRadius", PeakRadius ) );
TS_ASSERT_THROWS_NOTHING( alg.execute() );
TS_ASSERT( alg.isExecuted() );
}
void test_exec()
{
outWSName = "MDEWPeakIntegrationTest_MDEWS";
// ---- Start with empty MDEW ----
AlgorithmHelper::runAlgorithm("CreateMDEventWorkspace", 16,
"Dimensions", "3",
"Extents", "-10,10,-10,10,-10,10",
"Names", "h,k,l",
"Units", "-,-,-",
"BinarySplit", "0",
"SplitInto", "5",
"MaxRecursionDepth", "2",
"OutputWorkspace", outWSName.c_str());
// --- Give it a fake peak ------
AlgorithmHelper::runAlgorithm("FakeMDEventData", 4,
"InputWorkspace", outWSName.c_str(), "PeakParams", "1000, 0.,0.,0., 1.0");
AlgorithmHelper::runAlgorithm("FakeMDEventData", 4,
"InputWorkspace", outWSName.c_str(), "PeakParams", "1000, 2.,3.,4., 0.5");
AlgorithmHelper::runAlgorithm("FakeMDEventData", 4,
"InputWorkspace", outWSName.c_str(), "PeakParams", "1000, 5.,5.,5., 2.0");
MDEventWorkspace3::sptr mdews = boost::dynamic_pointer_cast<MDEventWorkspace3>(AnalysisDataService::Instance().retrieve(outWSName));
TS_ASSERT_EQUALS( mdews->getNPoints(), 3000);
TS_ASSERT_DELTA( mdews->getBox()->getSignal(), 3000.0, 1e-2);
// Make a fake instrument - doesn't matter, we won't use it really
IInstrument_sptr inst = ComponentCreationHelper::createTestInstrumentCylindrical(5);
// --- Make a fake PeaksWorkspace ---
PeaksWorkspace_sptr peakWS(new PeaksWorkspace());
peakWS->addPeak( Peak(inst, 1, 1.0, V3D(0., 0., 0.) ) );
peakWS->addPeak( Peak(inst, 1, 1.0, V3D(2., 3., 4.) ) );
peakWS->addPeak( Peak(inst, 1, 1.0, V3D(5., 5., 5.) ) );
TS_ASSERT_EQUALS( peakWS->getPeak(0).getIntensity(), 0.0);
AnalysisDataService::Instance().add("MDEWPeakIntegrationTest_peaks",peakWS);
// ------------- Integrate with 1.0 radius ------------------------
doRun(1.0);
TS_ASSERT_DELTA( peakWS->getPeak(0).getIntensity(), 1000.0, 1e-2);
TS_ASSERT_DELTA( peakWS->getPeak(1).getIntensity(), 1000.0, 1e-2);
// Peak is of radius 2.0, but we get half that radius = 1/8th the volume
TS_ASSERT_DELTA( peakWS->getPeak(2).getIntensity(), 125.0, 10);
// ------------- Let's do it again with 2.0 radius ------------------------
doRun(2.0);
// All peaks are fully contained
TS_ASSERT_DELTA( peakWS->getPeak(0).getIntensity(), 1000.0, 1e-2);
TS_ASSERT_DELTA( peakWS->getPeak(1).getIntensity(), 1000.0, 1e-2);
TS_ASSERT_DELTA( peakWS->getPeak(2).getIntensity(), 1000.0, 1e-2);
// ------------- Let's do it again with 0.5 radius ------------------------
doRun(0.5);
TS_ASSERT_DELTA( peakWS->getPeak(0).getIntensity(), 125.0, 10);
TS_ASSERT_DELTA( peakWS->getPeak(1).getIntensity(), 1000.0, 1e-2);
TS_ASSERT_DELTA( peakWS->getPeak(2).getIntensity(), 15.0, 10);
AnalysisDataService::Instance().remove(outWSName);
AnalysisDataService::Instance().remove("MDEWPeakIntegrationTest_peaks");
}
......
......@@ -21,6 +21,7 @@
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include "MantidMDEvents/CoordTransformDistance.h"
#include "MantidKernel/Utils.h"
using namespace Mantid;
using namespace Mantid::Kernel;
......@@ -79,38 +80,65 @@ public:
/** Generate an empty MDBox with 2 dimensions, splitting in (default) 10x10 boxes.
* Box size is 10x10.
*
* @param numEventsPerBox :: each sub-box will get this many events (all
* placed in the middle of each sub-box, aka 0.5, 1.5, 2.5 etc.)
* @param split0, split1 :: for uneven splitting
* */
static MDGridBox<MDEvent<2>,2> * makeMDGridBox2(size_t numEventsPerBox, size_t split0=10, size_t split1=10)
template <size_t nd>
static MDGridBox<MDEvent<nd>,nd> * makeMDGridBox(size_t split0=10, size_t split1=10, CoordType dimensionMin=0.0)
{
// Split at 5 events
BoxController_sptr splitter(new BoxController(2));
BoxController_sptr splitter(new BoxController(nd));
splitter->setSplitThreshold(5);
// Splits into 10x10x.. boxes
splitter->setSplitInto(split0);
splitter->setSplitInto(0, split0);
splitter->setSplitInto(1, split1);
// Set the size to 10.0 in all directions
MDBox<MDEvent<2>,2> * box = new MDBox<MDEvent<2>,2>(splitter);
for (size_t d=0; d<2; d++)
box->setExtents(d, 0.0, 10.0);
MDBox<MDEvent<nd>,nd> * box = new MDBox<MDEvent<nd>,nd>(splitter);
for (size_t d=0; d<nd; d++)
box->setExtents(d, dimensionMin, 10.0);
// Split
MDGridBox<MDEvent<2>,2> * out = new MDGridBox<MDEvent<2>,2>(box);
MDGridBox<MDEvent<nd>,nd> * out = new MDGridBox<MDEvent<nd>,nd>(box);
// Make an event in the middle of each box
for (size_t i=0; i < numEventsPerBox; i++)
for (double x=0.5; x < 10; x += 1.0)
for (double y=0.5; y < 10; y += 1.0)
{
double centers[2] = {x,y};
out->addEvent( MDEvent<2>(2.0, 2.0, centers) );
}
out->refreshCache(NULL);
return out;
}
//-------------------------------------------------------------------------------------
/** Feed a MDGridBox with evenly-spaced events
*
* @param box :: MDGridBox pointer
* @param repeat :: how many events to stick in the same place
* @param numPerSide :: e.g. if 10, and 3 dimensions, there will be 10x10x10 events
* @param start :: x-coordinate starts at this for event 0
* @param step :: x-coordinate increases by this much.
*/
template <size_t nd>
static void feedMDBox(MDGridBox<MDEvent<nd>,nd> * box, size_t repeat=1, size_t numPerSide=10, CoordType start=0.5, CoordType step=1.0)
{
size_t * counters = Utils::nestedForLoopSetUp(nd,0);
size_t * index_max = Utils::nestedForLoopSetUp(nd,numPerSide);
// Recursive for loop
bool allDone = false;
while (!allDone)
{
// Generate the position from the counter
double centers[nd];
for (size_t d=0;d<nd;d++)
centers[d] = double(counters[d])*step + start;
// Add that event 'repeat' times
for (size_t i=0; i<repeat; ++i)
box->addEvent( MDEvent<nd>(1.0, 1.0, centers) );
// Increment the nested for loop
allDone = Utils::nestedForLoopIncrement(nd, counters, index_max);
}
box->refreshCache(NULL);
delete [] counters;
delete [] index_max;
}
//-------------------------------------------------------------------------------------
/** Recursively split an existing MDGridBox
*
......@@ -310,7 +338,7 @@ public:
/** Start with a grid box, split some of its contents into sub-gridded boxes. */
void test_splitContents()
{
MDGridBox<MDEvent<2>,2> * superbox = makeMDGridBox2(0);
MDGridBox<MDEvent<2>,2> * superbox = makeMDGridBox<2>();
MDGridBox<MDEvent<2>,2> * gb;
MDBox<MDEvent<2>,2> * b;
......@@ -356,7 +384,7 @@ public:
std::vector<IMDBox<MDEvent<2>,2>*> boxes;