Newer
Older
#ifndef MANTID_MDEVENTS_QUERYMDWORKSPACETEST_H_
#define MANTID_MDEVENTS_QUERYMDWORKSPACETEST_H_
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidMDAlgorithms/QueryMDWorkspace.h"
#include "MantidTestHelpers/MDEventsTestHelper.h"
#include "MantidDataObjects/TableWorkspace.h"
using namespace Mantid::API;
using namespace Mantid::DataObjects;
class QueryMDWorkspaceTest : 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 QueryMDWorkspaceTest *createSuite() {
return new QueryMDWorkspaceTest();
static void destroySuite(QueryMDWorkspaceTest *suite) { delete suite; }
QueryMDWorkspaceTest() { FrameworkManager::Instance(); }
void checkInputs(std::string strNormalisation) {
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(10, -10.0, 20.0, 3);
query.setRethrows(true);
query.setProperty("InputWorkspace", in_ws);
query.setProperty("OutputWorkspace", "QueryWS");
query.setProperty("Normalisation", strNormalisation);
TSM_ASSERT_EQUALS("Invalid property setup", true,
query.validateProperties());
void testDefaultInputs() {
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(10, -10.0, 20.0, 3);
QueryMDWorkspace query;
query.initialize();
query.setProperty("InputWorkspace", in_ws);
query.setProperty("OutputWorkspace", "QueryWS");
TSM_ASSERT_EQUALS("Invalid property setup", true,
query.validateProperties());
TSM_ASSERT("Should limit rows by default", query.getProperty("LimitRows"));
const int expectedRowLimit = 100000;
const int actualRowLimit = query.getProperty("MaximumRows");
TSM_ASSERT_EQUALS("Wrong default number of rows", expectedRowLimit,
actualRowLimit);
std::string defaultNormalisation = query.getProperty("Normalisation");
TSM_ASSERT_EQUALS("Wrong default normalisation", "none",
defaultNormalisation);
void testCheckInputsWithNoNormalisation() { checkInputs("none"); }
void testCheckInputsWithVolumeNormalisation() { checkInputs("volume"); }
void testCheckInputsWithNumberOfEventsNormalisation() {
checkInputs("number of events");
void testExecution() {
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(10, -10.0, 20.0, 3);
QueryMDWorkspace query;
query.initialize();
query.setProperty("InputWorkspace", in_ws);
query.setPropertyValue("OutputWorkspace", "QueryWS");
query.execute();
TSM_ASSERT("Did not execute", query.isExecuted());
}
void testDifferentNormalisation() {
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(10, -10.0, 20.0, 3);
boost::shared_ptr<IMDIterator> it(in_ws->createIterator());
QueryMDWorkspace A;
A.initialize();
A.setProperty("InputWorkspace", in_ws);
A.setPropertyValue("OutputWorkspace", "QueryWS_A");
A.setPropertyValue("Normalisation", "none"); // Not normalising
A.execute();
QueryMDWorkspace B;
B.initialize();
B.setProperty("InputWorkspace", in_ws);
B.setPropertyValue("OutputWorkspace", "QueryWS_B");
B.setPropertyValue("Normalisation",
"number of events"); // Normalising by n events
AnalysisDataServiceImpl &ADS = AnalysisDataService::Instance();
TableWorkspace_sptr queryA =
boost::dynamic_pointer_cast<TableWorkspace>(ADS.retrieve("QueryWS_A"));
TableWorkspace_sptr queryB =
boost::dynamic_pointer_cast<TableWorkspace>(ADS.retrieve("QueryWS_B"));
TS_ASSERT_EQUALS(queryA->rowCount(), queryB->rowCount());
for (size_t i = 0; i < queryA->rowCount(); ++i) {
TSM_ASSERT("The iterator should be valid over the range of table rows it "
"was used to create.",
it->valid());
double signalNotNormalised = queryA->cell<double>(i, 0);
double signalNormalisedByNumEvents = queryB->cell<double>(i, 0);
double errorNotNormalised = queryA->cell<double>(i, 1);
double errorNormalisedByNumEvents = queryB->cell<double>(i, 1);
const size_t nEvents = it->getNumEvents();
// Compare each signal and error result.
TS_ASSERT_DELTA(signalNotNormalised,
signalNormalisedByNumEvents * double(nEvents), 0.0001);
TS_ASSERT_DELTA(errorNotNormalised,
errorNormalisedByNumEvents * double(nEvents), 0.0001);
ADS.remove("QueryWS_A");
ADS.remove("QueryWS_B");
}
void testExecution_BoxData() {
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(10, -10.0, 20.0, 3);
QueryMDWorkspace query;
query.initialize();
query.setProperty("InputWorkspace", in_ws);
query.setPropertyValue("OutputWorkspace", "QueryWS");
query.setPropertyValue("BoxDataTable", "QueryWS_box");
query.execute();
TSM_ASSERT("Did not execute", query.isExecuted());
}
void testTableGenerated() {
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(10, -10.0, 20.0, 3);
QueryMDWorkspace query;
query.initialize();
query.setProperty("InputWorkspace", in_ws);
query.setPropertyValue("OutputWorkspace", "QueryWS");
query.execute();
TS_ASSERT(AnalysisDataService::Instance().doesExist("QueryWS"));
ITableWorkspace_sptr table =
AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("QueryWS");
TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
size_t expectedCount =
3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents
TSM_ASSERT_EQUALS("Four columns expected", expectedCount,
table->columnCount());
TSM_ASSERT_EQUALS("Wrong number of rows", 1000, table->rowCount());
}
void testNumberOfColumnsDependsOnDimensionality() {
MDEventWorkspace2Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<2>(10, -10.0, 20.0, 3);
QueryMDWorkspace query;
query.initialize();
query.setProperty("InputWorkspace", in_ws);
query.setPropertyValue("OutputWorkspace", "QueryWS");
query.execute();
TS_ASSERT(AnalysisDataService::Instance().doesExist("QueryWS"));
ITableWorkspace_sptr table =
AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("QueryWS");
TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
size_t expectedCount =
3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents
TSM_ASSERT_EQUALS("Five columns expected", expectedCount,
table->columnCount());
void testLimitRows() {
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(10, -10.0, 20.0, 3);
QueryMDWorkspace query;
query.initialize();
query.setProperty("InputWorkspace", in_ws);
query.setPropertyValue("OutputWorkspace", "QueryWS");
query.setProperty("LimitRows", true);
query.setProperty("MaximumRows", 3);
query.execute();
TS_ASSERT(AnalysisDataService::Instance().doesExist("QueryWS"));
ITableWorkspace_sptr table =
AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("QueryWS");
TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
size_t expectedCount =
3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents
TSM_ASSERT_EQUALS("Five columns expected", expectedCount,
table->columnCount());
TSM_ASSERT_EQUALS("Wrong number of rows", 3, table->rowCount());
}
IMDWorkspace_sptr createSlice() {
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
auto in_ws = MDEventsTestHelper::makeMDEW<2>(2, -10.0, 10, 3);
// Create a line slice at 45 degrees to the original workspace.
IAlgorithm_sptr binMDAlg = AlgorithmManager::Instance().create("BinMD");
binMDAlg->setRethrows(true);
binMDAlg->initialize();
binMDAlg->setChild(true);
binMDAlg->setProperty("InputWorkspace", in_ws);
binMDAlg->setProperty("AxisAligned", false);
binMDAlg->setPropertyValue(
"BasisVector0", "X,units,0.7071,0.7071"); // cos 45 to in_ws x-axis
// (consistent with a 45
// degree anti-clockwise
// rotation)
binMDAlg->setPropertyValue(
"BasisVector1", "Y,units,-0.7071,0.7071"); // cos 45 to in_ws y-axis
// (consistent with a 45
// degree anti-clockwise
// rotation)
binMDAlg->setPropertyValue("OutputExtents",
"0,28.284,-1,1"); // 0 to sqrt((-10-10)^2 +
// (-10-10)^2), -1 to 1 (in new
// coordinate axes)
binMDAlg->setPropertyValue("OutputBins", "10,1");
binMDAlg->setPropertyValue("OutputWorkspace", "temp");
binMDAlg->execute();
Workspace_sptr temp = binMDAlg->getProperty("OutputWorkspace");
auto slice = boost::dynamic_pointer_cast<IMDWorkspace>(temp);
return slice;
IMDWorkspace_sptr slice = createSlice();
QueryMDWorkspace query;
query.setRethrows(true);
query.setChild(true);
query.initialize();
query.setProperty("InputWorkspace", slice);
query.setPropertyValue("OutputWorkspace", "QueryWS");
query.execute();
ITableWorkspace_sptr table = query.getProperty("OutputWorkspace");
TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
size_t expectedCount =
3 + 2; // 3 fixed columns are Signal, Error, nEvents and then data is 2D
TSM_ASSERT_EQUALS("Six columns expected", expectedCount,
table->columnCount());
TSM_ASSERT_EQUALS("Wrong number of rows", 10, table->rowCount());
/*
Note that what we do in the following is to check that the y and x
coordinates are the same. They will ONLY be the same in the
original coordinate system owing to the way that they have been rotated. If
we were displaying the results in the new coordinate system
then y == 0 and x would increment from 0 to sqrt((-10-10)^2 + (-10-10)^2).
*/
for (size_t i = 0; i < table->rowCount(); ++i) {
auto xColumn = table->getColumn(3);
auto yColumn = table->getColumn(4);
double x = xColumn->toDouble(i);
double y = yColumn->toDouble(i);
std::stringstream messageBuffer;
messageBuffer << "X and Y should be equal at row index: " << i;
TSM_ASSERT_DELTA(messageBuffer.str(), x, y, 1e-3);
}
}
void testOnSlice_without_transform_to_original() {
IMDWorkspace_sptr slice = createSlice();
QueryMDWorkspace query;
query.setRethrows(true);
query.setChild(true);
query.initialize();
query.setProperty("TransformCoordsToOriginal",
false); // DO NOT, use the original workspace coordinates.
query.setProperty("InputWorkspace", slice);
query.setPropertyValue("OutputWorkspace", "QueryWS");
query.execute();
ITableWorkspace_sptr table = query.getProperty("OutputWorkspace");
TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
size_t expectedCount =
3 + 2; // 3 fixed columns are Signal, Error, nEvents and then data is 2D
TSM_ASSERT_EQUALS("Six columns expected", expectedCount,
table->columnCount());
TSM_ASSERT_EQUALS("Wrong number of rows", 10, table->rowCount());
/*
Since we were displaying the results in the new coordinate system
then y == 0 and x would increment from 0 to sqrt((-10-10)^2 + (-10-10)^2).
Note that what we do in the following is to check that the y and x
coordinates are NOT the same. They will ONLY be the same in the
original coordinate system owing to the way that they have been rotated.
*/
const double xMax = std::sqrt(20 * 20 * 2);
const double xMin = 0;
auto xColumn = table->getColumn(3);
auto yColumn = table->getColumn(4);
TS_ASSERT_EQUALS(0, yColumn->toDouble(0)); // Always zero
TS_ASSERT_EQUALS(0, yColumn->toDouble(table->rowCount() - 1));
const double binHalfWidth = 1.5;
TSM_ASSERT_DELTA("From zero", xMin, xColumn->toDouble(0),
binHalfWidth /*account for bin widths*/);
TSM_ASSERT_DELTA("To max", xMax, xColumn->toDouble(table->rowCount() - 1),
binHalfWidth /*account for bin widths*/);
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
void test_query_large_masked_workspace() {
/*
Regression test for a stack overflow bug caused by high recursion depth
when workspace iterator skips over many masked cells
*/
MDEventWorkspace3Lean::sptr in_ws =
MDEventsTestHelper::makeMDEW<3>(64, 0.0, 10.0, 3);
IAlgorithm_sptr binMDAlg = AlgorithmManager::Instance().create("BinMD");
binMDAlg->initialize();
binMDAlg->setRethrows(true);
binMDAlg->setChild(true);
binMDAlg->setProperty("InputWorkspace", in_ws);
binMDAlg->setProperty("AlignedDim0", "Axis0,0,10,64");
binMDAlg->setProperty("AlignedDim1", "Axis1,0,10,64");
binMDAlg->setProperty("AlignedDim2", "Axis2,0,10,64");
binMDAlg->setPropertyValue("OutputWorkspace", "temp_out_ws");
binMDAlg->execute();
Workspace_sptr binned_temp = binMDAlg->getProperty("OutputWorkspace");
IMDWorkspace_sptr binned_md_temp =
boost::dynamic_pointer_cast<IMDWorkspace>(binned_temp);
IAlgorithm_sptr maskMDAlg = AlgorithmManager::Instance().create("MaskMD");
maskMDAlg->initialize();
maskMDAlg->setRethrows(true);
maskMDAlg->setChild(true);
maskMDAlg->setProperty("Workspace", binned_md_temp);
maskMDAlg->setProperty("Dimensions", "Axis0,Axis1,Axis2");
maskMDAlg->setProperty("Extents", "0,10,0,10,0,10");
maskMDAlg->execute();
IMDWorkspace_sptr temp = maskMDAlg->getProperty("Workspace");
QueryMDWorkspace query;
query.setRethrows(true);
query.setChild(true);
query.initialize();
query.setProperty("InputWorkspace", temp);
query.setPropertyValue("OutputWorkspace", "QueryWS");
TSM_ASSERT_THROWS_NOTHING("Should execute successfully", query.execute());
}
#endif /* MANTID_MDEVENTS_QUERYMDWORKSPACETEST_H_ */