Newer
Older
#ifndef MUONCALCULATEASYMMETRYTEST_H_
#define MUONCALCULATEASYMMETRYTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidAlgorithms/CalculateAsymmetry.h"
#include "MantidKernel/PhysicalConstants.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidHistogramData/LinearGenerator.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
using namespace Mantid::API;
using Mantid::MantidVec;
using Mantid::Algorithms::CalculateAsymmetry;
const std::string outputName = "CalculateAsymmetry_Output";
namespace {
struct yData {
double operator()(const double x, size_t) {
// Create a fake muon dataset
double a = 10.0; // Amplitude of the oscillations
double w = 5.0; // Frequency of the oscillations
double tau = Mantid::PhysicalConstants::MuonLifetime *
1e6; // Muon life time in microseconds
double phi = 0.1;
double e = exp(-x / tau);
return (20. * (1.0 + a * cos(w * x + phi)) * e);
}
struct eData {
double operator()(const double, size_t) { return 0.005; }
};
struct yAsymmData {
double operator()(const double x, size_t) {
// Create a fake muon dataset
double a = 1.05; // Amplitude of the oscillations
double w = 5.0; // Frequency of the oscillations
double phi = 0.1;
return (a * cos(w * x + phi))+0.5;
}
};
struct eAsymmData {
double operator()(const double, size_t) { return 0.0005; }
};
MatrixWorkspace_sptr createWorkspace(size_t nspec, size_t maxt) {
MatrixWorkspace_sptr ws =
WorkspaceCreationHelper::create2DWorkspaceFromFunction(
yData(), static_cast<int>(nspec), 0.0, 10.0,
10.0 * (1.0 / static_cast<double>(maxt)), true, eData());
// Add number of good frames
ws->mutableRun().addProperty("goodfrm", 10);
return ws;
}
IAlgorithm_sptr setUpAlg() {
IAlgorithm_sptr asymmAlg =
AlgorithmManager::Instance().create("CalculateAsymmetry");
asymmAlg->initialize();
asymmAlg->setChild(true);
asymmAlg->setProperty("StartX", 0.1);
asymmAlg->setProperty("EndX", 10.);
asymmAlg->setProperty(
"FittingFunction",
"name=UserFunction,Formula=A*cos(omega*x+phi),A=10,omega=3.0,phi=0.0");
return asymmAlg;
}
class CalculateAsymmetryTest : 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 CalculateAsymmetryTest *createSuite() {
return new CalculateAsymmetryTest();
}
static void destroySuite(CalculateAsymmetryTest *suite) { delete suite; }
CalculateAsymmetryTest() { FrameworkManager::Instance(); }
void testInit() {
}
void test_Execute() {
auto ws = createWorkspace(1, 50);
alg->setProperty("InputWorkspace", ws);
alg->setPropertyValue("OutputWorkspace", outputName);
TS_ASSERT_THROWS_NOTHING(alg->execute());
TS_ASSERT(alg->isExecuted());
MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
}
void test_EmptySpectrumList() {
auto ws = createWorkspace(2, 50);
alg->setProperty("InputWorkspace", ws);
alg->setPropertyValue("OutputWorkspace", outputName);
TS_ASSERT_THROWS_NOTHING(alg->execute());
TS_ASSERT(alg->isExecuted());
MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
// Test some X values
for (int spec = 0; spec <= 1; spec++) {
TS_ASSERT_EQUALS(outWS->x(spec)[10], 2.000);
TS_ASSERT_DELTA(outWS->x(spec)[19], 3.800, delta);
TS_ASSERT_DELTA(outWS->x(spec)[49], 9.800, delta);
// Test some Y values
TS_ASSERT_DELTA(outWS->y(spec)[10], -7.8056, delta);
TS_ASSERT_DELTA(outWS->y(spec)[19], 9.6880, delta);
TS_ASSERT_DELTA(outWS->y(spec)[49], 3.9431, delta);
// Test some E values
TS_ASSERT_DELTA(outWS->e(spec)[10], 0.0006, delta);
TS_ASSERT_DELTA(outWS->e(spec)[19], 0.0014, delta);
TS_ASSERT_DELTA(outWS->e(spec)[49], 0.0216, delta);
std::vector<MatrixWorkspace_sptr> workspaces;
workspaces.push_back(createWorkspace(2, 50));
// First, run the algorithm without specifying any spectrum
alg1->setProperty("InputWorkspace", workspaces[0]);
alg1->setPropertyValue("OutputWorkspace", outputName);
TS_ASSERT_THROWS_NOTHING(alg1->execute());
TS_ASSERT(alg1->isExecuted());
workspaces.push_back(alg1->getProperty("OutputWorkspace"));
// Then run the algorithm on the second spectrum only
alg2->setProperty("InputWorkspace", workspaces[0]);
alg2->setPropertyValue("OutputWorkspace", outputName);
alg2->setPropertyValue("Spectra", "1");
TS_ASSERT_THROWS_NOTHING(alg2->execute());
TS_ASSERT(alg2->isExecuted());
workspaces.push_back(alg2->getProperty("OutputWorkspace"));
for (int j = 0; j < 3; j++) {
if (j != 0) { // check ws have 2 spectra
TS_ASSERT_EQUALS(workspaces[j]->getNumberHistograms(),
workspaces[0]->getNumberHistograms());
}
if (j != 2) { // check check results match
TS_ASSERT_EQUALS(workspaces[j]->x(j).rawData(),
workspaces[2]->x(j).rawData());
TS_ASSERT_EQUALS(workspaces[j]->y(j).rawData(),
workspaces[2]->y(j).rawData());
TS_ASSERT_EQUALS(workspaces[j]->e(j).rawData(),
workspaces[2]->e(j).rawData());
}
}
}
alg->setProperty("InputWorkspace", ws);
alg->setPropertyValue("OutputWorkspace", outputName);
TS_ASSERT_THROWS_NOTHING(alg->execute());
TS_ASSERT(alg->isExecuted())
MatrixWorkspace_sptr result = alg->getProperty("OutputWorkspace");
TS_ASSERT(result);
TS_ASSERT_EQUALS(result->YUnitLabel(), "Asymmetry");
}
void test_BackwardsRange() {
auto ws = createWorkspace(1, 50);
IAlgorithm_sptr alg = setUpAlg();
alg->setProperty("InputWorkspace", ws);
alg->setProperty("OutputWorkspace", outputName);
TS_ASSERT_THROWS(alg->execute(), std::runtime_error);
}
IAlgorithm_sptr alg =
AlgorithmManager::Instance().create("CalculateAsymmetry");
alg->initialize();
alg->setChild(true);
alg->setProperty("InputWorkspace", ws);
alg->setPropertyValue("OutputWorkspace", outputName);
alg->setProperty("StartX", 0.1);
alg->setProperty("EndX", 10.);
TS_ASSERT_THROWS_NOTHING(alg->execute());
TS_ASSERT(alg->isExecuted());
MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
TS_ASSERT_DELTA(outWS->x(0)[10], 2.000, Delta);
TS_ASSERT_DELTA(outWS->x(0)[19], 3.800, Delta);
TS_ASSERT_DELTA(outWS->x(0)[49], 9.800, Delta);
TS_ASSERT_DELTA(outWS->y(0)[10], -7.8056, Delta);
TS_ASSERT_DELTA(outWS->y(0)[19], 9.6880, Delta);
TS_ASSERT_DELTA(outWS->y(0)[49], 3.9431, Delta);
TS_ASSERT_DELTA(outWS->e(0)[10], 0.0006, Delta);
TS_ASSERT_DELTA(outWS->e(0)[19], 0.0014, Delta);
TS_ASSERT_DELTA(outWS->e(0)[49], 0.0216, Delta);
double dx = 10.0 * (1.0 / static_cast<double>(300.0));
auto fineWS = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
yData(), 1, 0.0, 10.0, dx, true, eData());
fineWS->mutableRun().addProperty("goodfrm", 10);
auto coarseWS = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
yData(), 1, dx, 10.0 + dx, 3.0 * dx, true, eData());
coarseWS->mutableRun().addProperty("goodfrm", 10);
fineAlg->setProperty("InputWorkspace", fineWS);
fineAlg->setPropertyValue("OutputWorkspace", "fineOutWS");
TS_ASSERT_THROWS_NOTHING(fineAlg->execute());
TS_ASSERT(fineAlg->isExecuted());
MatrixWorkspace_sptr fineOutWS = fineAlg->getProperty("OutputWorkspace");
coarseAlg->setProperty("InputWorkspace", coarseWS);
coarseAlg->setPropertyValue("OutputWorkspace", "coarseOutWS");
TS_ASSERT_THROWS_NOTHING(coarseAlg->execute());
TS_ASSERT(coarseAlg->isExecuted());
MatrixWorkspace_sptr coarseOutWS =
coarseAlg->getProperty("OutputWorkspace");
for (int j = 0; j < 28; j++) {
// Test some X values
TS_ASSERT_DELTA(fineOutWS->x(0)[1 + j * 3], coarseOutWS->x(0)[j], Delta);
// Test some Y values
TS_ASSERT_DELTA(fineOutWS->y(0)[1 + j * 3], coarseOutWS->y(0)[j], Delta);
// Test some E values
TS_ASSERT_DELTA(fineOutWS->e(0)[1 + j * 3], coarseOutWS->e(0)[j], Delta);
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
void test_FitToEstimateAsymmetry() {
double dx = 10.0 * (1.0 / static_cast<double>(100.0));
auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
yAsymmData(), 1, 0.0, 10.0, dx, true, eAsymmData());
ws->mutableRun().addProperty("goodfrm", 10);
IAlgorithm_sptr alg = setUpAlg();
alg->setProperty("InputWorkspace", ws);
alg->setPropertyValue("OutputWorkspace", "asymm");
alg->setPropertyValue("InputDataType", "asymmetry");
TS_ASSERT_THROWS_NOTHING(alg->execute());
TS_ASSERT(alg->isExecuted());
MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
double Delta = 0.0001;
// First spectrum
// Test some X values
TS_ASSERT_DELTA(outWS->x(0)[10], 1.000, Delta);
TS_ASSERT_DELTA(outWS->x(0)[19], 1.900, Delta);
TS_ASSERT_DELTA(outWS->x(0)[49], 4.900, Delta);
// Test some Y values
TS_ASSERT_DELTA(outWS->y(0)[10], 0.2742, Delta);
TS_ASSERT_DELTA(outWS->y(0)[19], -0.6869, Delta);
TS_ASSERT_DELTA(outWS->y(0)[49], 0.6152, Delta);
// Test some E values
TS_ASSERT_DELTA(outWS->e(0)[10], 0.0003, Delta);
TS_ASSERT_DELTA(outWS->e(0)[19], 0.0003, Delta);
TS_ASSERT_DELTA(outWS->e(0)[49], 0.0003, Delta);
}
class CalculateAsymmetryTestPerformance : 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 CalculateAsymmetryTestPerformance *createSuite() {
return new CalculateAsymmetryTestPerformance();
}
static void destroySuite(CalculateAsymmetryTestPerformance *suite) {
AnalysisDataService::Instance().clear();
delete suite;
}
CalculateAsymmetryTestPerformance() { FrameworkManager::Instance(); }
void setUp() override { input = createWorkspace(1000, 100); }
void testExec2D() {
CalculateAsymmetry alg;
alg.initialize();
alg.setProperty("InputWorkspace", input);
alg.setPropertyValue("OutputWorkspace", "output");
alg.setProperty("StartX", 0.1);
alg.setProperty("EndX", 10.);
"name=UserFunction,Formula=A*cos(omega*x+phi),A=10,omega=3.0,phi=0.0");
alg.execute();
}
private:
MatrixWorkspace_sptr input;
};
#endif /*ESTIMATEASYMMETRYFROMCOUNTSTEST_H_*/