Newer
Older
for (size_t i = 0; i < num_repeat; i++) {
Janik Zikovsky
committed
// Make an event in the middle of each box
double centers[2] = {1e-10, 1e-10};
events.push_back(MDLeanEvent<2>(2.0, 2.0, centers));
Janik Zikovsky
committed
}
TS_ASSERT_THROWS_NOTHING(b0->addEvents(events););
Janik Zikovsky
committed
Janik Zikovsky
committed
// Split into sub-grid boxes
TS_ASSERT_THROWS_NOTHING(b0->splitAllIfNeeded(NULL);)
Janik Zikovsky
committed
// Dig recursively into the gridded box hierarchies
Janik Zikovsky
committed
size_t expected_depth = 0;
Janik Zikovsky
committed
expected_depth++;
boxes = b->getBoxes();
// Get the 0th box
b = dynamic_cast<gbox_t *>(boxes[0]);
Janik Zikovsky
committed
// The 0-th box is a MDGridBox (it was split)
// (though it is normal for b to be a MDBox when you reach the max depth)
if (expected_depth < 4) {
TS_ASSERT(b)
}
Janik Zikovsky
committed
// The 0-th box has all the points
TS_ASSERT_EQUALS(boxes[0]->getNPoints(), num_repeat);
Janik Zikovsky
committed
// The 0-th box is at the expected_depth
TS_ASSERT_EQUALS(boxes[0]->getDepth(), expected_depth);
Janik Zikovsky
committed
// The other boxes have nothing
TS_ASSERT_EQUALS(boxes[1]->getNPoints(), 0);
Janik Zikovsky
committed
// The other box is a MDBox (it was not split)
TS_ASSERT(dynamic_cast<box_t *>(boxes[1]))
Janik Zikovsky
committed
}
// We went this many levels (and no further) because recursion depth is
// limited
Janik Zikovsky
committed
TS_ASSERT_EQUALS(boxes[0]->getDepth(), 4);
BoxController *const bcc = b0->getBoxController();
Janik Zikovsky
committed
}
//------------------------------------------------------------------------------------------------
Janik Zikovsky
committed
/** This test splits a large number of events, and uses a ThreadPool
* to use all cores.
*/
void test_splitAllIfNeeded_usingThreadPool() {
typedef MDGridBox<MDLeanEvent<2>, 2> gbox_t;
typedef MDBoxBase<MDLeanEvent<2>, 2> ibox_t;
Janik Zikovsky
committed
gbox_t *b = MDEventsTestHelper::makeMDGridBox<2>();
Janik Zikovsky
committed
b->getBoxController()->setSplitThreshold(100);
b->getBoxController()->setMaxDepth(4);
Janik Zikovsky
committed
// Make a 1000 events in each sub-box
size_t num_repeat = 1000;
if (DODEBUG)
num_repeat = 2000;
Janik Zikovsky
committed
Timer tim;
if (DODEBUG)
std::cout << "Adding " << num_repeat * 100 << " events...\n";
Janik Zikovsky
committed
MDEventsTestHelper::feedMDBox<2>(b, num_repeat, 10, 0.5, 1.0);
if (DODEBUG)
std::cout << "Adding events done in " << tim.elapsed() << "!\n";
Janik Zikovsky
committed
// Split those boxes in parallel.
ThreadSchedulerFIFO *ts = new ThreadSchedulerFIFO();
Janik Zikovsky
committed
ThreadPool tp(ts);
b->splitAllIfNeeded(ts);
tp.joinAll();
if (DODEBUG)
std::cout << "Splitting events done in " << tim.elapsed() << " sec.\n";
Janik Zikovsky
committed
// Now check the results. Each sub-box should be MDGridBox and have that
// many events
std::vector<ibox_t *> boxes = b->getBoxes();
Janik Zikovsky
committed
TS_ASSERT_EQUALS(boxes.size(), 100);
for (size_t i = 0; i < boxes.size(); i++) {
ibox_t *box = boxes[i];
TS_ASSERT_EQUALS(box->getNPoints(), num_repeat);
TS_ASSERT(dynamic_cast<gbox_t *>(box));
size_t numChildren = box->getNumChildren();
size_t lastId = box->getChild(0)->getID();
for (size_t i = 1; i < numChildren; i++) {
TSM_ASSERT_EQUALS("Children IDs need to be sequential!",
box->getChild(i)->getID(), lastId + 1);
lastId = box->getChild(i)->getID();
}
}
}
BoxController *const bcc = b->getBoxController();
delete b;
delete bcc;
Janik Zikovsky
committed
}
//------------------------------------------------------------------------------------------------
MDBin<MDLeanEvent<2>, 2> makeMDBin2(double minX, double maxX, double minY,
double maxY) {
MDBin<MDLeanEvent<2>, 2> bin;
bin.m_min[0] = static_cast<coord_t>(minX);
bin.m_max[0] = static_cast<coord_t>(maxX);
bin.m_min[1] = static_cast<coord_t>(minY);
bin.m_max[1] = static_cast<coord_t>(maxY);
Gigg, Martyn Anthony
committed
//------------------------------------------------------------------------------------------------
/** Helper to test the binning of a 2D bin */
void doTestMDBin2(MDGridBox<MDLeanEvent<2>, 2> *b, const std::string &message,
double minX, double maxX, double minY, double maxY,
double expectedSignal) {
// std::cout << "Bins: X " << std::setw(5) << minX << " to "<<
// std::setw(5) << maxX << ", Y " << std::setw(5) << minY << " to "<<
// std::setw(5) << maxY << ". " << message << '\n';
MDBin<MDLeanEvent<2>, 2> bin;
bin = makeMDBin2(minX, maxX, minY, maxY);
b->centerpointBin(bin, NULL);
TSM_ASSERT_DELTA(message, bin.m_signal, expectedSignal, 1e-5);
}
//------------------------------------------------------------------------------------------------
/** Test binning in orthogonal axes */
void test_centerpointBin() {
typedef MDGridBox<MDLeanEvent<2>, 2> gbox_t;
Janik Zikovsky
committed
// 10x10 bins, 2 events per bin, each weight of 1.0
gbox_t *b = MDEventsTestHelper::makeMDGridBox<2>();
MDEventsTestHelper::feedMDBox<2>(b, 2);
TS_ASSERT_DELTA(b->getSignal(), 200.0, 1e-5);
doTestMDBin2(b, "Bin that is completely off", 10.1, 11.2, 1.9, 3.12, 0.0);
doTestMDBin2(b, "Bin that is completely off (2)", 2, 3, -0.6, -0.1, 0.0);
doTestMDBin2(b, "Bin that holds one entire MDBox (bigger than it)", 0.8,
2.2, 1.9, 3.12, 2.0);
doTestMDBin2(b, "Bin that holds one entire MDBox (going off one edge)",
doTestMDBin2(b,
"Bin that holds one entire MDBox (going off the other edge)",
8.9, 10.2, 1.9, 3.12, 2.0);
doTestMDBin2(b, "Bin that holds one entire MDBox (going off both edge)",
doTestMDBin2(b, "Bin that holds one entire MDBox and a fraction of at "
"least one more with something",
0.8, 2.7, 1.9, 3.12, 4.0);
doTestMDBin2(b, "Bin that holds four entire MDBoxes", 0.8, 3.1, 0.9, 3.2,
8.0);
doTestMDBin2(b, "Bin goes off two edges in one direction", -0.3, 10.2, 1.9,
3.1, 10 * 2.0);
doTestMDBin2(
b, "Bin that fits all within a single MDBox, and contains the center",
0.2, 0.8, 0.2, 0.8, 2.0);
doTestMDBin2(b, "Bin that fits all within a single MDBox, and DOES NOT "
"contain anything",
0.2, 0.3, 0.1, 0.2, 0.0);
doTestMDBin2(b, "Bin that fits partially in two MDBox'es, and DOES NOT "
"contain anything",
0.8, 1.2, 0.1, 0.2, 0.0);
doTestMDBin2(
b, "Bin that fits partially in two MDBox'es, and contains the centers",
0.2, 1.8, 0.1, 0.9, 4.0);
doTestMDBin2(
b, "Bin that fits partially in one MDBox'es, and goes of the edge",
-3.2, 0.8, 0.1, 0.9, 2.0);
delete b->getBoxController();
delete b;
Janik Zikovsky
committed
Gigg, Martyn Anthony
committed
//------------------------------------------------------------------------------------------------
/** For test_integrateSphere
*
* @param box
* @param radius :: radius to integrate
* @param numExpected :: how many events should be in there
*/
void do_check_integrateSphere(MDGridBox<MDLeanEvent<2>, 2> &box, double x,
double y, const double radius,
double numExpected, std::string message) {
Gigg, Martyn Anthony
committed
// The sphere transformation
bool dimensionsUsed[2] = {true, true};
coord_t center[2] = {static_cast<coord_t>(x), static_cast<coord_t>(y)};
Gigg, Martyn Anthony
committed
CoordTransformDistance sphere(2, center, dimensionsUsed);
Janik Zikovsky
committed
signal_t signal = 0;
signal_t errorSquared = 0;
box.integrateSphere(sphere, static_cast<coord_t>(radius * radius), signal,
errorSquared);
TSM_ASSERT_DELTA(message, signal, 1.0 * numExpected, 1e-5);
TSM_ASSERT_DELTA(message, errorSquared, 1.0 * numExpected, 1e-5);
Gigg, Martyn Anthony
committed
}
/** Re-used suite of tests */
void do_test_integrateSphere(MDGridBox<MDLeanEvent<2>, 2> *box_ptr) {
Gigg, Martyn Anthony
committed
// Events are at 0.5, 1.5, etc.
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
MDGridBox<MDLeanEvent<2>, 2> &box = *box_ptr;
TS_ASSERT_EQUALS(box.getNPoints(), 10 * 10);
do_check_integrateSphere(box, 4.5, 4.5, 0.5, 1.0,
"Too small to contain any vertices");
do_check_integrateSphere(box, 4.5, 4.5, 0.001, 1.0,
"Tiny but still has an event.");
do_check_integrateSphere(box, 4.51, 4.5, 0.001, 0.0,
"Tiny but off the event.");
do_check_integrateSphere(box, 2.0, 2.0, 0.49, 0.0,
"At a corner but grabbing nothing");
do_check_integrateSphere(box, 4.8, 4.5, 0.35, 1.0,
"Too small to contain any vertices");
do_check_integrateSphere(box, 5.0, 5.0, 1.0, 4.0,
"At a corner, containing 4 neighbors");
do_check_integrateSphere(box, 4.5, 4.5, 0.9, 1.0,
"Contains one box completely");
do_check_integrateSphere(box, 0.5, 0.5, 0.9, 1.0,
"Contains one box completely, at the edges");
do_check_integrateSphere(box, 9.5, 0.5, 0.9, 1.0,
"Contains one box completely, at the edges");
do_check_integrateSphere(box, 0.5, 9.5, 0.9, 1.0,
"Contains one box completely, at the edges");
do_check_integrateSphere(box, 4.5, 9.5, 0.9, 1.0,
"Contains one box completely, at the edges");
do_check_integrateSphere(box, 9.5, 9.5, 0.9, 1.0,
"Contains one box completely, at the edges");
do_check_integrateSphere(
box, 1.5, 1.5, 1.95, 9.0,
"Contains 5 boxes completely, and 4 boxes with a point");
do_check_integrateSphere(box, -1.0, 0.5, 1.55, 1.0,
"Off an edge but enough to get an event");
Gigg, Martyn Anthony
committed
// Now I add an event very near an edge
double center[2] = {0.001, 0.5};
Janik Zikovsky
committed
box.addEvent(MDLeanEvent<2>(1.0, 1.0, center));
do_check_integrateSphere(
box, -1.0, 0.5, 1.01, 1.0,
"Off an edge but just barely enough to get an event");
do_check_integrateSphere(box, 0.0, 0.5, 0.01, 1.0,
"Tiny, but just barely enough to get an event");
Gigg, Martyn Anthony
committed
}
/** Test of sphere integration with even splitting*/
Gigg, Martyn Anthony
committed
// 10x10 sized box
MDGridBox<MDLeanEvent<2>, 2> *box_ptr =
MDEventsTestHelper::makeMDGridBox<2>();
MDEventsTestHelper::feedMDBox<2>(box_ptr, 1);
Gigg, Martyn Anthony
committed
do_test_integrateSphere(box_ptr);
BoxController *const bcc = box_ptr->getBoxController();
delete box_ptr;
delete bcc;
Gigg, Martyn Anthony
committed
}
void test_integrateSphere_unevenSplit() {
Gigg, Martyn Anthony
committed
// 10x5 sized box
MDGridBox<MDLeanEvent<2>, 2> *box_ptr =
MDEventsTestHelper::makeMDGridBox<2>(10, 5);
MDEventsTestHelper::feedMDBox<2>(box_ptr, 1);
Gigg, Martyn Anthony
committed
do_test_integrateSphere(box_ptr);
BoxController *const bcc = box_ptr->getBoxController();
delete box_ptr;
delete bcc;
Gigg, Martyn Anthony
committed
}
void test_integrateSphere_unevenSplit2() {
Gigg, Martyn Anthony
committed
// Funnier splitting: 3x7 sized box
MDGridBox<MDLeanEvent<2>, 2> *box_ptr =
MDEventsTestHelper::makeMDGridBox<2>(3, 7);
MDEventsTestHelper::feedMDBox<2>(box_ptr, 1);
Gigg, Martyn Anthony
committed
do_test_integrateSphere(box_ptr);
BoxController *const bcc = box_ptr->getBoxController();
delete box_ptr;
delete bcc;
Gigg, Martyn Anthony
committed
}
Janik Zikovsky
committed
/** Had a really-hard to find bug where the tests worked only
* if the extents started at 0.0.
* This test has a box from -10.0 to +10.0 to check for that
*/
void test_integrateSphere_dimensionsDontStartAtZero() {
MDGridBox<MDLeanEvent<2>, 2> *box_ptr =
MDEventsTestHelper::makeMDGridBox<2>(10, 10, -10.0);
Janik Zikovsky
committed
// One event at center of each box
MDEventsTestHelper::feedMDBox<2>(box_ptr, 1, 10, -9.0, 2.0);
MDGridBox<MDLeanEvent<2>, 2> &box = *box_ptr;
TS_ASSERT_EQUALS(box.getNPoints(), 10 * 10);
Janik Zikovsky
committed
do_check_integrateSphere(box, 1.0, 1.0, 1.45, 1.0,
"Contains one box completely");
do_check_integrateSphere(box, 9.0, 9.0, 1.45, 1.0,
"Contains one box completely, at the edges");
BoxController *const bcc = box_ptr->getBoxController();
delete box_ptr;
delete bcc;
Janik Zikovsky
committed
}
//------------------------------------------------------------------------------------------------
/** For test_integrateSphere3d
*
* @param box
* @param radius :: radius to integrate
* @param numExpected :: how many events should be in there
*/
void do_check_integrateSphere3d(MDGridBox<MDLeanEvent<3>, 3> &box, double x,
double y, double z, const double radius,
double numExpected, std::string message) {
Janik Zikovsky
committed
// The sphere transformation
bool dimensionsUsed[3] = {true, true, true};
coord_t center[3] = {static_cast<coord_t>(x), static_cast<coord_t>(y),
static_cast<coord_t>(z)};
Janik Zikovsky
committed
CoordTransformDistance sphere(3, center, dimensionsUsed);
Janik Zikovsky
committed
signal_t signal = 0;
signal_t errorSquared = 0;
box.integrateSphere(sphere, static_cast<coord_t>(radius * radius), signal,
errorSquared);
TSM_ASSERT_DELTA(message, signal, 1.0 * numExpected, 1e-5);
TSM_ASSERT_DELTA(message, errorSquared, 1.0 * numExpected, 1e-5);
Janik Zikovsky
committed
}
//------------------------------------------------------------------------------------------------
void test_integrateSphere3d() {
MDGridBox<MDLeanEvent<3>, 3> *box_ptr =
MDEventsTestHelper::makeMDGridBox<3>();
MDEventsTestHelper::feedMDBox<3>(box_ptr, 1);
MDGridBox<MDLeanEvent<3>, 3> &box = *box_ptr;
TS_ASSERT_EQUALS(box.getNPoints(), 10 * 10 * 10);
do_check_integrateSphere3d(box, 0.5, 0.5, 0.5, 0.9, 1.0,
"Contains one box completely, at a corner");
do_check_integrateSphere3d(box, 9.5, 9.5, 9.5, 0.9, 1.0,
"Contains one box completely, at a corner");
do_check_integrateSphere3d(
box, 9.5, 9.5, 9.5, 0.85, 1.0,
"Does NOT contain one box completely, at a corner");
do_check_integrateSphere3d(box, 9.0, 9.0, 9.0, 1.75, 20.0,
"Contains 8 boxes completely, at a corner");
do_check_integrateSphere3d(
box, 9.0, 9.0, 9.0, 1.70, 20.0,
"Does NOT contains one box completely, at a corner");
Janik Zikovsky
committed
// Now I add an event very near an edge
double center[3] = {0.001, 0.5, 0.5};
Janik Zikovsky
committed
box.addEvent(MDLeanEvent<3>(2.0, 2.0, center));
// do_check_integrateSphere(box, -1.0,0.5, 1.01, 1.0, "Off an edge but
// just barely enough to get an event");
// do_check_integrateSphere(box, 0.0,0.5, 0.01, 1.0, "Tiny, but just
// barely enough to get an event");
delete box_ptr->getBoxController();
delete box_ptr;
Janik Zikovsky
committed
}
Janik Zikovsky
committed
//------------------------------------------------------------------------------------------------
/** For test_integrateSphere
*
* @param box
* @param radius :: radius to integrate
* @param xExpected :: expected centroid
* @param yExpected :: expected centroid
*/
void do_check_centroidSphere(MDGridBox<MDLeanEvent<2>, 2> &box, double x,
double y, const double radius,
double numExpected, double xExpected,
double yExpected, std::string message) {
Janik Zikovsky
committed
// The sphere transformation
bool dimensionsUsed[2] = {true, true};
coord_t center[2] = {static_cast<coord_t>(x), static_cast<coord_t>(y)};
Janik Zikovsky
committed
CoordTransformDistance sphere(2, center, dimensionsUsed);
Janik Zikovsky
committed
signal_t signal = 0;
Janik Zikovsky
committed
coord_t centroid[2] = {0., 0.};
box.centroidSphere(sphere, static_cast<coord_t>(radius * radius), centroid,
signal);
Janik Zikovsky
committed
// Normalized
if (signal != 0.0) {
for (size_t d = 0; d < 2; d++)
centroid[d] /= static_cast<coord_t>(signal);
Janik Zikovsky
committed
}
TSM_ASSERT_DELTA(message, signal, 1.0 * numExpected, 1e-5);
TSM_ASSERT_DELTA(message, centroid[0], xExpected, 1e-5);
TSM_ASSERT_DELTA(message, centroid[1], yExpected, 1e-5);
Janik Zikovsky
committed
}
/** Re-used suite of tests */
Janik Zikovsky
committed
// 10x10 sized box
MDGridBox<MDLeanEvent<2>, 2> *box_ptr =
MDEventsTestHelper::makeMDGridBox<2>();
MDEventsTestHelper::feedMDBox<2>(box_ptr, 1);
Janik Zikovsky
committed
// Events are at 0.5, 1.5, etc.
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
MDGridBox<MDLeanEvent<2>, 2> &box = *box_ptr;
TS_ASSERT_EQUALS(box.getNPoints(), 10 * 10);
do_check_centroidSphere(box, 4.5, 4.5, 0.5, 1.0, 4.5, 4.5,
"Too small to contain any vertices");
do_check_centroidSphere(box, 4.5, 4.5, 0.001, 1.0, 4.5, 4.5,
"Tiny but still has an event.");
do_check_centroidSphere(box, 4.51, 4.5, 0.001, 0.0, 0.0, 0.0,
"Tiny but off the event.");
do_check_centroidSphere(box, 2.0, 2.0, 0.49, 0.0, 0.0, 0.0,
"At a corner but grabbing nothing");
do_check_centroidSphere(box, 4.8, 4.5, 0.35, 1.0, 4.5, 4.5,
"Too small to contain any vertices");
do_check_centroidSphere(box, 5.0, 5.0, 1.0, 4.0, 5.0, 5.0,
"At a corner, containing 4 neighbors");
do_check_centroidSphere(box, 4.5, 4.5, 0.9, 1.0, 4.5, 4.5,
"Contains one box completely");
do_check_centroidSphere(box, 0.5, 0.5, 0.9, 1.0, 0.5, 0.5,
"Contains one box completely, at the edges");
do_check_centroidSphere(box, 9.5, 0.5, 0.9, 1.0, 9.5, 0.5,
"Contains one box completely, at the edges");
do_check_centroidSphere(box, 0.5, 9.5, 0.9, 1.0, 0.5, 9.5,
"Contains one box completely, at the edges");
do_check_centroidSphere(box, 4.5, 9.5, 0.9, 1.0, 4.5, 9.5,
"Contains one box completely, at the edges");
do_check_centroidSphere(box, 9.5, 9.5, 0.9, 1.0, 9.5, 9.5,
"Contains one box completely, at the edges");
do_check_centroidSphere(
box, 1.5, 1.5, 1.95, 9.0, 1.5, 1.5,
"Contains 5 boxes completely, and 4 boxes with a point");
do_check_centroidSphere(box, -1.0, 0.5, 1.55, 1.0, 0.5, 0.5,
"Off an edge but enough to get an event");
Janik Zikovsky
committed
// Now I add an event very near an edge
double center[2] = {0.001, 0.5};
Janik Zikovsky
committed
box.addEvent(MDLeanEvent<2>(1.0, 1.0, center));
do_check_integrateSphere(
box, -1.0, 0.5, 1.01, 1.0,
"Off an edge but just barely enough to get an event");
do_check_integrateSphere(box, 0.0, 0.5, 0.01, 1.0,
"Tiny, but just barely enough to get an event");
delete box_ptr->getBoxController();
delete box_ptr;
Janik Zikovsky
committed
}
void test_getIsMasked_WhenNoMasking() {
std::vector<API::IMDNode *> boxes;
MockMDBox *a = new MockMDBox;
MockMDBox *b = new MockMDBox;
EXPECT_CALL(*a, getIsMasked())
.Times(1)
.WillOnce(Return(false)); // Not masked
EXPECT_CALL(*b, getIsMasked())
.Times(1)
.WillOnce(Return(false)); // Not masked
boxes.push_back(a);
boxes.push_back(b);
std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extentsVector(1);
MDGridBox<MDLeanEvent<1>, 1> g(bc, 0, extentsVector);
g.setChildren(boxes, 0, 2);
TSM_ASSERT("No inner boxes were masked so the MDGridBox should not report "
"that it is masked",
!g.getIsMasked());
TS_ASSERT(Mock::VerifyAndClearExpectations(a));
TS_ASSERT(Mock::VerifyAndClearExpectations(b));
}
void test_getIsMasked_WhenFirstMasked() {
std::vector<API::IMDNode *> boxes;
MockMDBox *a = new MockMDBox;
MockMDBox *b = new MockMDBox;
Janik Zikovsky
committed
EXPECT_CALL(*a, getIsMasked()).Times(1).WillOnce(Return(true)); // MASKED
EXPECT_CALL(*b, getIsMasked())
.Times(0); // Not masked, but will never be called.
boxes.push_back(a);
boxes.push_back(b);
std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extentsVector(1);
MDGridBox<MDLeanEvent<1>, 1> g(bc, 0, extentsVector);
g.setChildren(boxes, 0, 2);
TSM_ASSERT("First inner box masked, so should return masked",
g.getIsMasked());
TS_ASSERT(Mock::VerifyAndClearExpectations(a));
TS_ASSERT(Mock::VerifyAndClearExpectations(b));
}
void test_getIsMasked_WhenLastMasked() {
std::vector<API::IMDNode *> boxes;
MockMDBox *a = new MockMDBox;
MockMDBox *b = new MockMDBox;
EXPECT_CALL(*a, getIsMasked())
.Times(1)
.WillOnce(Return(false)); // NOT MASKED
EXPECT_CALL(*b, getIsMasked()).Times(1).WillOnce(Return(true)); // MASKED
boxes.push_back(a);
boxes.push_back(b);
std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extentsVector(1);
MDGridBox<MDLeanEvent<1>, 1> g(bc, 0, extentsVector);
g.setChildren(boxes, 0, 2);
TSM_ASSERT("Second inner box masked, so should return masked",
g.getIsMasked());
TS_ASSERT(Mock::VerifyAndClearExpectations(a));
TS_ASSERT(Mock::VerifyAndClearExpectations(b));
}
std::vector<API::IMDNode *> boxes;
MockMDBox *a = new MockMDBox;
MockMDBox *b = new MockMDBox;
EXPECT_CALL(*a, mask()).Times(1);
EXPECT_CALL(*b, mask()).Times(1);
boxes.push_back(a);
boxes.push_back(b);
std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extentsVector(1);
MDGridBox<MDLeanEvent<1>, 1> griddedBox(bc, 0, extentsVector);
griddedBox.setChildren(boxes, 0, 2);
TS_ASSERT_THROWS_NOTHING(griddedBox.mask()); // Mask the gridded box
TS_ASSERT(Mock::VerifyAndClearExpectations(a));
TS_ASSERT(Mock::VerifyAndClearExpectations(b));
}
std::vector<API::IMDNode *> boxes;
MockMDBox *a = new MockMDBox;
MockMDBox *b = new MockMDBox;
EXPECT_CALL(*a, unmask()).Times(1);
EXPECT_CALL(*b, unmask()).Times(1);
boxes.push_back(a);
boxes.push_back(b);
std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extentsVector(1);
MDGridBox<MDLeanEvent<1>, 1> griddedBox(bc, 0, extentsVector);
griddedBox.setChildren(boxes, 0, 2);
TS_ASSERT_THROWS_NOTHING(griddedBox.unmask()); // Un-Mask the gridded box
TS_ASSERT(Mock::VerifyAndClearExpectations(a));
TS_ASSERT(Mock::VerifyAndClearExpectations(b));
}
};
//=====================================================================================
//===================================== Performance Test
//==============================
//=====================================================================================
class MDGridBoxTestPerformance : public CxxTest::TestSuite {
public:
Janik Zikovsky
committed
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static MDGridBoxTestPerformance *createSuite() {
return new MDGridBoxTestPerformance();
}
static void destroySuite(MDGridBoxTestPerformance *suite) { delete suite; }
Janik Zikovsky
committed
MDGridBox<MDLeanEvent<3>, 3> *box3;
MDGridBox<MDLeanEvent<3>, 3> *box3b;
std::vector<MDLeanEvent<3>> events;
MDGridBox<MDLeanEvent<1>, 1> *recursiveParent;
MDGridBox<MDLeanEvent<1>, 1> *recursiveParent2;
// Split 5x5x5, 2 deep.
box3b = MDEventsTestHelper::makeRecursiveMDGridBox<3>(5, 1);
// Make the list of fake events, random dist.
Gigg, Martyn Anthony
committed
events.clear();
boost::mt19937 rng;
Gigg, Martyn Anthony
committed
boost::uniform_real<double> u(0, 5.0); // Range
boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>> gen(
rng, u);
for (size_t i = 0; i < num; ++i) {
double centers[3];
centers[d] = gen();
// Create and add the event.
events.push_back(MDLeanEvent<3>(1.0, 1.0, centers));
}
Gigg, Martyn Anthony
committed
box3b->addEvents(events);
box3b->refreshCache();
Janik Zikovsky
committed
// Recursively gridded box with 1,111,111 boxes total.
recursiveParent = MDEventsTestHelper::makeRecursiveMDGridBox<1>(10, 6);
// Recursively gridded box with 111,111 boxes total.
recursiveParent2 = MDEventsTestHelper::makeRecursiveMDGridBox<1>(10, 5);
}
~MDGridBoxTestPerformance() override { delete box3b; }
Janik Zikovsky
committed
void setUp() override {
Janik Zikovsky
committed
// Make a fresh box.
box3 = MDEventsTestHelper::makeRecursiveMDGridBox<3>(5, 1);
}
void tearDown() override { delete box3; }
void test_refreshCache() { box3b->refreshCache(); }
/** Performance test that adds lots of events to a recursively split box.
* SINGLE-THREADED!
*/
// We built this many MDBoxes
TS_ASSERT_EQUALS(box3->getBoxController()->getTotalNumMDBoxes(),
125 * 125 + 1); // +1 might be a test issue
TS_ASSERT_EQUALS(events.size(), 1e6);
// Add them!
for (size_t i = 0; i < 5; ++i) {
Gigg, Martyn Anthony
committed
box3->addEvents(events);
}
}
Janik Zikovsky
committed
//-----------------------------------------------------------------------------
/** Do a sphere integration
*
* @param center :: coordinate of the center
* @param radius :: radius
*/
void do_test_sphereIntegrate(coord_t *center, coord_t radius,
double expectSignal, double tol) {
Gigg, Martyn Anthony
committed
// The sphere transformation
bool dimensionsUsed[3] = {true, true, true};
Gigg, Martyn Anthony
committed
CoordTransformDistance sphere(3, center, dimensionsUsed);
Janik Zikovsky
committed
// Repeat the integration a lot
Janik Zikovsky
committed
signal_t signal, errorSquared;
for (size_t i = 0; i < 1000; i++) {
Gigg, Martyn Anthony
committed
signal = 0;
errorSquared = 0;
box3b->integrateSphere(sphere, radius * radius, signal, errorSquared);
Gigg, Martyn Anthony
committed
}
Janik Zikovsky
committed
TS_ASSERT_DELTA(signal, expectSignal, tol);
Gigg, Martyn Anthony
committed
TS_ASSERT_DELTA(signal, errorSquared, 1e-3);
}
Janik Zikovsky
committed
/** Smallish sphere in the middle goes partially through lots of boxes */
void test_sphereIntegrate_inTheMiddle() {
Janik Zikovsky
committed
coord_t center[3] = {2.5, 2.5, 2.5};
do_test_sphereIntegrate(center, 1.0, (1e6 / 125) * (4.0 * M_PI / 3.0),
2000.0);
Janik Zikovsky
committed
}
Gigg, Martyn Anthony
committed
/** Huge sphere containing all within */
void test_sphereIntegrate_inTheMiddle_largeSphere() {
Janik Zikovsky
committed
do_test_sphereIntegrate(center, 5.0, 1e6, 1e-3);
Gigg, Martyn Anthony
committed
}
/** Peak that is off the box entirely */
void test_sphereIntegrate_OffTheBox() {
Janik Zikovsky
committed
coord_t center[3] = {11., 5., 5.};
do_test_sphereIntegrate(center, 1.0, 0.0, 1e-3);
}
//-----------------------------------------------------------------------------
/** Do a sphere centroiding
*
* @param center :: coordinate of the center
* @param radius :: radius
*/
void do_test_sphereCentroid(coord_t *center, coord_t radius,
double expectSignal, double tol) {
Gigg, Martyn Anthony
committed
// The sphere transformation
bool dimensionsUsed[3] = {true, true, true};
Gigg, Martyn Anthony
committed
CoordTransformDistance sphere(3, center, dimensionsUsed);
Janik Zikovsky
committed
// Repeat the integration a lot
Janik Zikovsky
committed
signal_t signal;
Janik Zikovsky
committed
coord_t centroid[3];
for (size_t i = 0; i < 100; i++) {
Gigg, Martyn Anthony
committed
signal = 0;
Janik Zikovsky
committed
centroid[d] = 0.0;
box3b->centroidSphere(sphere, radius * radius, centroid, signal);
if (signal != 0.0) {
for (size_t d = 0; d < 3; d++)
centroid[d] /= static_cast<coord_t>(signal);
Janik Zikovsky
committed
}
Gigg, Martyn Anthony
committed
}
Janik Zikovsky
committed
// The expected number of events, given a sphere of radius "radius"
TS_ASSERT_DELTA(signal, expectSignal, tol);
Janik Zikovsky
committed
// And the centroid should be close to the sphere center
Janik Zikovsky
committed
TS_ASSERT_DELTA(centroid[d], center[d], 1e-2);
}
}
Janik Zikovsky
committed
/** Smallish sphere in the middle goes partially through lots of boxes */
void test_sphereCentroid_inTheMiddle() {
Janik Zikovsky
committed
coord_t center[3] = {2.5, 2.5, 2.5};
do_test_sphereCentroid(center, 1.0, (1e6 / 125) * (4.0 * M_PI / 3.0), 2000);
Janik Zikovsky
committed
}
/** Huge sphere containing all within */
void test_sphereCentroid_inTheMiddle_largeSphere() {
Janik Zikovsky
committed
coord_t center[3] = {2.5, 2.5, 2.5};
do_test_sphereCentroid(center, 5.0, 1e6, 1e-3);
}
/** Peak that is off the box entirely */
void test_sphereCentroid_OffTheBox() {
Janik Zikovsky
committed
coord_t center[3] = {11., 5., 5.};
do_test_sphereCentroid(center, 1.0, 0.0, 1e-3);
}
/** Recursive getting of a list of MDBoxBase.
Janik Zikovsky
committed
* Gets about 11 million boxes */
std::vector<API::IMDNode *> boxes;
for (size_t i = 0; i < 10; i++) {
Janik Zikovsky
committed
boxes.clear();
Janik Zikovsky
committed
boxes.reserve(1111111);
Janik Zikovsky
committed
recursiveParent->getBoxes(boxes, 6, false);
TS_ASSERT_EQUALS(boxes.size(), 1111111);
TS_ASSERT_EQUALS(boxes[0], recursiveParent);
Janik Zikovsky
committed
}
}
};