Newer
Older
Steve Williams
committed
#ifndef DETECTOREFFICIENCYVARIATION_H_
#define DETECTOREFFICIENCYVARIATION_H_
#include <cxxtest/TestSuite.h>
Gigg, Martyn Anthony
committed
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
Steve Williams
committed
#include "MantidAlgorithms/DetectorEfficiencyVariation.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidDataObjects/Workspace2D.h"
Peterson, Peter
committed
#include "MantidDataHandling/LoadInstrument.h"
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
Gigg, Martyn Anthony
committed
#include <Poco/Path.h>
Peterson, Peter
committed
#include <cmath>
Steve Williams
committed
#include <sstream>
#include <fstream>
#include <ios>
#include <string>
using namespace Mantid::Kernel;
using namespace Mantid::Geometry;
using namespace Mantid::API;
using namespace Mantid::Algorithms;
using namespace Mantid::DataObjects;
class DetectorEfficiencyVariationTest : public CxxTest::TestSuite {
Steve Williams
committed
public:
static DetectorEfficiencyVariationTest *createSuite() {
return new DetectorEfficiencyVariationTest();
}
static void destroySuite(DetectorEfficiencyVariationTest *suite) {
delete suite;
}
Michael Whitty
committed
bool runInit(DetectorEfficiencyVariation &alg) // this is run by both tests so
// I thought I'd take it out
// and split things up
Steve Williams
committed
{
TS_ASSERT_THROWS_NOTHING(alg.initialize());
bool good = alg.isInitialized();
// Set the properties
alg.setPropertyValue("WhiteBeamBase", m_WB1Name);
alg.setPropertyValue("WhiteBeamCompare", m_WB2Name);
alg.setPropertyValue("OutputWorkspace", "DetEfficVariTestWSO");
return good;
}
Steve Williams
committed
DetectorEfficiencyVariation alg;
// the spectra were setup in the constructor and passed to our algorithm
// through this function
TS_ASSERT_THROWS_NOTHING(TS_ASSERT(runInit(alg)))
Steve Williams
committed
// these are realistic values that I just made up
Peterson, Peter
committed
double variation = 1.1;
alg.setProperty("Variation", variation);
Peterson, Peter
committed
// we are using the defaults on StartSpectrum, EndSpectrum,
// RangeLower and RangeUpper which is to use the whole spectrum
Steve Williams
committed
Gigg, Martyn Anthony
committed
alg.setRethrows(true);
alg.execute();
Steve Williams
committed
// Get back the saved workspace
Workspace_sptr output;
TS_ASSERT_THROWS_NOTHING(output = AnalysisDataService::Instance().retrieve(
"DetEfficVariTestWSO"));
MatrixWorkspace_sptr outputMat =
boost::dynamic_pointer_cast<MatrixWorkspace>(output);
TS_ASSERT(outputMat);
TS_ASSERT_EQUALS(outputMat->YUnit(), "");
Gigg, Martyn Anthony
committed
const int numFailed = alg.getProperty("NumberOfFailures");
TS_ASSERT_EQUALS(numFailed, 65);
int firstGoodSpec = (Nhist / 2) - int((variation - 1) / m_ramp) + 1;
int lastGoodSpec = (Nhist / 2) + int((variation - 1) / m_ramp) - 1;
for (int lHist = 0; lHist < firstGoodSpec; lHist++) {
Steve Williams
committed
TS_ASSERT_EQUALS(static_cast<double>(outputMat->readY(lHist).front()),
Steve Williams
committed
}
for (int lHist = firstGoodSpec; lHist <= lastGoodSpec; lHist++) {
Steve Williams
committed
TS_ASSERT_EQUALS(static_cast<double>(outputMat->readY(lHist).front()),
Steve Williams
committed
}
for (int lHist = lastGoodSpec + 1; lHist < Nhist; lHist++) {
TS_ASSERT_EQUALS(static_cast<double>(outputMat->readY(lHist).front()),
static_cast<double>(BadVal))
Steve Williams
committed
}
}
DetectorEfficiencyVariationTest()
: m_WB1Name("DetEfficVariTestWSI1"), m_WB2Name("DetEfficVariTestWSI2"),
m_ramp(0.01) {
Steve Williams
committed
using namespace Mantid;
// Set up a small workspace for testing
Workspace_sptr spaceA =
WorkspaceFactory::Instance().create("Workspace2D", Nhist, NXs, NXs - 1);
Workspace_sptr spaceB =
WorkspaceFactory::Instance().create("Workspace2D", Nhist, NXs, NXs - 1);
Steve Williams
committed
Workspace2D_sptr inputA = boost::dynamic_pointer_cast<Workspace2D>(spaceA);
Workspace2D_sptr inputB = boost::dynamic_pointer_cast<Workspace2D>(spaceB);
boost::shared_ptr<MantidVec> x(new MantidVec(NXs));
for (int i = 0; i < NXs; ++i) {
(*x)[i] = i * 1000;
Steve Williams
committed
}
Peterson, Peter
committed
// random numbers that will be copied into the workspace spectra
const short ySize = NXs - 1;
double yArray[ySize] = {
0.2, 4, 50, 14, 0.001, 0, 0, 0, 1, 0, 1e-3, 15,
4, 0, 9, 0.001, 2e-10, 1, 0, 8, 0, 7, 1e-4, 1,
7, 11, 101, 6, 53, 0.345324, 3444, 13958, 0.8}; // NXs = 34 so
// we need that
// many numbers
// the error values aren't used and aren't tested so we'll use some basic
// data
boost::shared_ptr<MantidVec> errors(new MantidVec(ySize, 1));
Peterson, Peter
committed
boost::shared_ptr<MantidVec> forInputA, forInputB;
Steve Williams
committed
for (int j = 0; j < Nhist; ++j) {
Peterson, Peter
committed
inputA->setX(j, x);
// both workspaces must have the same x bins
inputB->setX(j, x);
forInputA.reset(new MantidVec);
forInputB.reset(new MantidVec);
Peterson, Peter
committed
// the spectravalues will be multiples of the random numbers above
for (int l = 0; l < ySize; ++l) {
Peterson, Peter
committed
forInputA->push_back(yArray[l]);
// there is going to be a small difference between the workspaces that
// will vary with histogram number
forInputB->push_back(forInputA->back() *
(1 + m_ramp * (j - (Nhist / 2))));
Peterson, Peter
committed
}
// insert a particularly large value to pick up later
m_LargeValue = 3.1;
if (j == Nhist - 1)
for (int l = 0; l < ySize; ++l)
(*forInputB)[l] = (*forInputA)[l] * m_LargeValue;
inputA->setData(j, forInputA, errors);
inputB->setData(j, forInputB, errors);
// Just set the spectrum number to match the index, spectra numbers and
// detector maps must be indentical for both
inputA->getSpectrum(j)->setSpectrumNo(j + 1);
inputB->getSpectrum(j)->setSpectrumNo(j + 1);
Steve Williams
committed
}
// Register the input workspaces to the ADS where they can be accessed by
// the algorithm
Peterson, Peter
committed
AnalysisDataService::Instance().add(m_WB1Name, inputA);
AnalysisDataService::Instance().add(m_WB2Name, inputB);
Peterson, Peter
committed
// Load the instrument data
Mantid::DataHandling::LoadInstrument loader;
loader.initialize();
// Path to test input file assumes Test directory checked out from SVN
std::string inputFile = "INES_Definition.xml";
Peterson, Peter
committed
loader.setPropertyValue("Filename", inputFile);
loader.setPropertyValue("Workspace", m_WB1Name);
loader.execute();
// both workspaces should use the same instrument information
Peterson, Peter
committed
loader.setPropertyValue("Workspace", m_WB2Name);
Steve Williams
committed
inputA->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
inputB->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
}
private:
std::string m_WB1Name, m_WB2Name;
Peterson, Peter
committed
double m_ramp, m_LargeValue;
enum {
Nhist = 84,
NXs = 34,
// these values must match the values in DetectorEfficiencyVariation.h
BadVal = 1,
GoodVal = 0
};
Steve Williams
committed
};
#endif /*DETECTOREFFICIENCYVARIATION_H_*/