Newer
Older
Russell Taylor
committed
#ifndef CALCULATETRANSMISSIONTEST_H_
#define CALCULATETRANSMISSIONTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidAlgorithms/CalculateTransmission.h"
Steve Williams
committed
#include "MantidDataHandling/LoadRaw3.h"
#include "MantidAlgorithms/Rebin.h"
#include "MantidAlgorithms/ConvertUnits.h"
Russell Taylor
committed
#include "MantidKernel/UnitFactory.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
Russell Taylor
committed
#include "MantidTestHelpers/SANSInstrumentCreationHelper.h"
Russell Taylor
committed
#include <boost/assign/list_of.hpp>
Steve Williams
committed
using namespace Mantid::DataHandling;
using namespace Mantid::Algorithms;
Russell Taylor
committed
using Mantid::API::MatrixWorkspace;
Russell Taylor
committed
class CalculateTransmissionTest : public CxxTest::TestSuite {
Russell Taylor
committed
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static CalculateTransmissionTest *createSuite() {
return new CalculateTransmissionTest();
}
static void destroySuite(CalculateTransmissionTest *suite) { delete suite; }
Russell Taylor
committed
Mantid::Algorithms::CalculateTransmission trans;
Russell Taylor
committed
TS_ASSERT_EQUALS(trans.name(), "CalculateTransmission");
TS_ASSERT_EQUALS(trans.version(), 1);
Russell Taylor
committed
}
Russell Taylor
committed
void testDefiningBothTransmissionMonitorAndRegionOfInterestThrows() {
Mantid::Algorithms::CalculateTransmission trans;
auto inputWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
4, 50, true);
inputWS->getAxis(0)->unit() =
Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
const std::string outputWsName("CalculateTransmissionTest_outputWS");
trans.initialize();
TS_ASSERT_THROWS_NOTHING(trans.setProperty("SampleRunWorkspace", inputWS));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("DirectRunWorkspace", inputWS));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("IncidentBeamMonitor", 1));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("TransmissionMonitor", 2));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("TransmissionROI", "2,3"));
TS_ASSERT_THROWS_NOTHING(
trans.setPropertyValue("OutputWorkspace", outputWsName));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("OutputUnfittedData", true));
trans.execute();
Mantid::Algorithms::CalculateTransmission trans;
auto inputWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
4, 50, true);
inputWS->getAxis(0)->unit() =
Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
const std::string outputWsName("CalculateTransmissionTest_outputWS");
trans.initialize();
TS_ASSERT_THROWS_NOTHING(trans.setProperty("SampleRunWorkspace", inputWS));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("DirectRunWorkspace", inputWS));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("IncidentBeamMonitor", 1));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("TransmissionROI", "2,3"));
TS_ASSERT_THROWS_NOTHING(
trans.setPropertyValue("OutputWorkspace", outputWsName));
TS_ASSERT_THROWS_NOTHING(trans.setProperty("OutputUnfittedData", true));
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Mantid::API::MatrixWorkspace_const_sptr fitted, unfitted;
TS_ASSERT_THROWS_NOTHING(
fitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
outputWsName)));
TS_ASSERT_THROWS_NOTHING(
unfitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
outputWsName + "_unfitted")));
const Mantid::MantidVec &fit = fitted->readY(0),
&unfit = unfitted->readY(0);
TS_ASSERT_EQUALS(fit.size(), unfit.size())
for (unsigned int i = 0; i < fit.size(); ++i) {
// Should all be 1 because I used the same workspace twice as the input
TS_ASSERT_DELTA(fit[i], 1.0, 0.0005)
// a linear fit thorugh all 1s should result in all 1s
TS_ASSERT_DELTA(fit[i], unfit[i], 0.0005)
}
Mantid::API::AnalysisDataService::Instance().remove(outputWsName);
Mantid::API::AnalysisDataService::Instance().remove(outputWsName +
"_unfitted");
Russell Taylor
committed
Mantid::API::MatrixWorkspace_sptr inputWS =
WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
4, 50, true); // Make sure this has a spectrum 3
inputWS->getAxis(0)->unit() =
Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
Russell Taylor
committed
Russell Taylor
committed
Mantid::Algorithms::CalculateTransmission trans;
Russell Taylor
committed
TS_ASSERT_THROWS_NOTHING(trans.initialize());
TS_ASSERT(trans.isInitialized());
Russell Taylor
committed
TS_ASSERT_THROWS_NOTHING(trans.setProperty("SampleRunWorkspace", inputWS))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("DirectRunWorkspace", inputWS))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("IncidentBeamMonitor", 2))
Russell Taylor
committed
std::string outputWS("CalculateTransmissionTest_outputWS");
TS_ASSERT_THROWS_NOTHING(
trans.setPropertyValue("OutputWorkspace", outputWS))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("OutputUnfittedData", true))
Russell Taylor
committed
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Steve Williams
committed
Mantid::API::MatrixWorkspace_const_sptr fitted, unfitted;
TS_ASSERT_THROWS_NOTHING(
fitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)));
TS_ASSERT_THROWS_NOTHING(
unfitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
outputWS + "_unfitted")));
const Mantid::MantidVec &fit = fitted->readY(0),
&unfit = unfitted->readY(0);
Steve Williams
committed
TS_ASSERT_EQUALS(fit.size(), unfit.size())
for (unsigned int i = 0; i < fit.size(); ++i) {
Steve Williams
committed
// Should all be 1 because I used the same workspace twice as the input
TS_ASSERT_DELTA(fit[i], 1.0, 0.0005)
Steve Williams
committed
// a linear fit thorugh all 1s should result in all 1s
TS_ASSERT_DELTA(fit[i], unfit[i], 0.0005)
Russell Taylor
committed
}
Russell Taylor
committed
Mantid::API::AnalysisDataService::Instance().remove(outputWS);
Mantid::API::AnalysisDataService::Instance().remove(outputWS + "_unfitted");
Russell Taylor
committed
}
void testFittedNoBeamMonitor() {
Doucet, Mathieu
committed
Mantid::API::MatrixWorkspace_sptr inputWS =
WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
4, 50, true); // Make sure this has a spectrum 3
Doucet, Mathieu
committed
inputWS->getAxis(0)->unit() =
Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
Doucet, Mathieu
committed
Mantid::Algorithms::CalculateTransmission trans;
TS_ASSERT_THROWS_NOTHING(trans.initialize());
TS_ASSERT(trans.isInitialized());
Doucet, Mathieu
committed
TS_ASSERT_THROWS_NOTHING(trans.setProperty("SampleRunWorkspace", inputWS))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("DirectRunWorkspace", inputWS))
Doucet, Mathieu
committed
std::string outputWS("CalculateTransmissionTest_outputWS");
TS_ASSERT_THROWS_NOTHING(
trans.setPropertyValue("OutputWorkspace", outputWS))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("OutputUnfittedData", false))
Doucet, Mathieu
committed
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Doucet, Mathieu
committed
Mantid::API::MatrixWorkspace_const_sptr fitted, unfitted;
TS_ASSERT_THROWS_NOTHING(
fitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)));
Doucet, Mathieu
committed
const Mantid::MantidVec &fit = fitted->readY(0);
for (unsigned int i = 0; i < fit.size(); ++i) {
Doucet, Mathieu
committed
// Should all be 1 because I used the same workspace twice as the input
TS_ASSERT_DELTA(fit[i], 1.0, 0.0005)
Doucet, Mathieu
committed
}
Mantid::API::AnalysisDataService::Instance().remove(outputWS);
}
Doucet, Mathieu
committed
// Create an test workspace with a single wavelength bin and test that
// the algorithm completes.
Russell Taylor
committed
const std::string inputWS = "sampletransdata";
Doucet, Mathieu
committed
Mantid::DataObjects::Workspace2D_sptr ws =
SANSInstrumentCreationHelper::createSANSInstrumentWorkspace(inputWS);
Doucet, Mathieu
committed
Mantid::API::AnalysisDataService::Instance().addOrReplace(inputWS, ws);
Doucet, Mathieu
committed
const std::string emptyWS("directbeam_ws");
Mantid::DataObjects::Workspace2D_sptr empty_ws =
SANSInstrumentCreationHelper::createSANSInstrumentWorkspace(emptyWS);
Doucet, Mathieu
committed
// According to this detector geometry, Monitor #1 is spectrum 0, and
// Monitor #2 is spectrum 1.
Doucet, Mathieu
committed
empty_ws->dataY(0)[0] = 10.0;
Mantid::API::AnalysisDataService::Instance().addOrReplace(emptyWS,
empty_ws);
Doucet, Mathieu
committed
TS_ASSERT_EQUALS(ws->dataY(0).size(), 1)
Doucet, Mathieu
committed
Mantid::Algorithms::CalculateTransmission trans;
TS_ASSERT_THROWS_NOTHING(trans.initialize());
TS_ASSERT_THROWS_NOTHING(
trans.setPropertyValue("SampleRunWorkspace", inputWS))
TS_ASSERT_THROWS_NOTHING(
trans.setPropertyValue("DirectRunWorkspace", emptyWS))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("IncidentBeamMonitor", 1))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("TransmissionMonitor", 2))
Russell Taylor
committed
std::string outputWS("CalculateTransmissionTest_outputWS2");
TS_ASSERT_THROWS_NOTHING(
trans.setPropertyValue("OutputWorkspace", outputWS))
Doucet, Mathieu
committed
trans.execute();
Doucet, Mathieu
committed
Russell Taylor
committed
Mantid::API::MatrixWorkspace_const_sptr output;
TS_ASSERT_THROWS_NOTHING(
output = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)))
TS_ASSERT_DELTA(output->readY(0)[0], 5.0, 0.005)
Doucet, Mathieu
committed
// If we reverse the monitors, we should invert the output
TS_ASSERT_THROWS_NOTHING(trans.setProperty("IncidentBeamMonitor", 2))
TS_ASSERT_THROWS_NOTHING(trans.setProperty("TransmissionMonitor", 1))
Doucet, Mathieu
committed
trans.execute();
TS_ASSERT_THROWS_NOTHING(
output = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)))
TS_ASSERT_DELTA(output->readY(0)[0], 0.2, 0.005)
Doucet, Mathieu
committed
Mantid::API::AnalysisDataService::Instance().remove(inputWS);
Mantid::API::AnalysisDataService::Instance().remove(outputWS);
Doucet, Mathieu
committed
Mantid::API::AnalysisDataService::Instance().remove(emptyWS);
Doucet, Mathieu
committed
}
/// this tests where the output ranges is greater than the input range
void testExtrapolationFit() {
Steve Williams
committed
CalculateTransmission trans;
trans.initialize();
trans.setPropertyValue("SampleRunWorkspace", m_transWS);
trans.setPropertyValue("DirectRunWorkspace", m_dirWS);
trans.setPropertyValue("OutputWorkspace",
"CalculateTransmissionTest_extra");
trans.setProperty("IncidentBeamMonitor", 1);
trans.setProperty("TransmissionMonitor", 2);
trans.setProperty("RebinParams", "0.5, 0.1, 14");
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Mantid::API::MatrixWorkspace_const_sptr extra =
boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
"CalculateTransmissionTest_extra"));
// these values were dervived from the debugger when exprolation was first
// added and are believed to be correct on that basis
TS_ASSERT_DELTA(extra->readY(0)[0], 0.2, 0.8937)
TS_ASSERT_DELTA(extra->readY(0)[8], 0.2, 0.8801)
TS_ASSERT_DELTA(extra->readY(0)[18], 0.2, 0.8634)
TS_ASSERT_DELTA(extra->readY(0)[33], 0.2, 0.8390)
TS_ASSERT_DELTA(extra->readY(0)[54], 0.2, 0.8059)
TS_ASSERT_DELTA(extra->readY(0).back(), 0.2, 0.6914)
Mantid::API::AnalysisDataService::Instance().remove(
"CalculateTransmissionTest_extra");
Steve Williams
committed
}
/// fitting with log or linear should give similar results
void testLogLin() {
Steve Williams
committed
CalculateTransmission trans;
trans.initialize();
trans.setPropertyValue("SampleRunWorkspace", m_transWS);
trans.setPropertyValue("DirectRunWorkspace", m_dirWS);
trans.setPropertyValue("OutputWorkspace", "CalculateTransmissionTest_log");
trans.setProperty("IncidentBeamMonitor", 1);
trans.setProperty("TransmissionMonitor", 2);
trans.setProperty("RebinParams", "0.8, 0.1, 8");
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Steve Williams
committed
trans.setPropertyValue("SampleRunWorkspace", m_transWS);
trans.setPropertyValue("DirectRunWorkspace", m_dirWS);
trans.setProperty("FitMethod", "Linear");
trans.setPropertyValue("OutputWorkspace",
"CalculateTransmissionTest_linear");
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Steve Williams
committed
Mantid::API::MatrixWorkspace_const_sptr logged, lineared;
TS_ASSERT_THROWS_NOTHING(
logged = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
"CalculateTransmissionTest_log")));
TS_ASSERT_THROWS_NOTHING(
lineared = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
"CalculateTransmissionTest_linear")));
const Mantid::MantidVec &log = logged->readY(0),
&linear = lineared->readY(0);
Steve Williams
committed
TS_ASSERT_EQUALS(log.size(), linear.size())
for (unsigned int i = 0; i < linear.size(); ++i) {
// these are not expected to match exactly but, for sensible data, they
// should be close
TS_ASSERT_DELTA(log[i] / linear[i], 1.0, 0.02)
Steve Williams
committed
}
Mantid::API::AnalysisDataService::Instance().remove(
"CalculateTransmissionTest_log");
Mantid::API::AnalysisDataService::Instance().remove(
"CalculateTransmissionTest_linear");
Steve Williams
committed
}
CalculateTransmission trans;
trans.initialize();
trans.setPropertyValue("SampleRunWorkspace", m_transWS);
trans.setPropertyValue("DirectRunWorkspace", m_dirWS);
trans.setProperty("IncidentBeamMonitor", 1);
trans.setProperty("TransmissionMonitor", 2);
trans.setProperty("FitMethod", "Polynomial");
trans.setProperty("PolynomialOrder", 3);
std::string outputWS("CalculateTransmissionTest_poly");
trans.setPropertyValue("OutputWorkspace", outputWS);
TS_ASSERT_THROWS_NOTHING(trans.setProperty("OutputUnfittedData", true))
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Mantid::API::MatrixWorkspace_const_sptr fitted, unfitted;
TS_ASSERT_THROWS_NOTHING(
fitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)));
TS_ASSERT_THROWS_NOTHING(
unfitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
outputWS + "_unfitted")));
const Mantid::MantidVec &fitted_y = fitted->readY(0),
&fitted_x = fitted->readX(0);
// TS_ASSERT_EQUALS(fitted_y.size(), unfitted_y.size());
for (unsigned int i = 0; i < fitted_y.size(); ++i) {
x = fitted_x[i]; //(fitted_x[i] + fitted_x[i+1])* 0.5;
TS_ASSERT_DELTA(fitted_y[i], 26.6936 - 9.31494 * x + 1.11532 * x * x -
0.044502 * x * x * x,
0.01);
}
}
Mantid::API::AnalysisDataService::Instance().remove(outputWS);
Mantid::API::AnalysisDataService::Instance().remove(outputWS + "_unfitted");
CalculateTransmission trans;
trans.initialize();
trans.setPropertyValue("SampleRunWorkspace", m_transWS);
trans.setPropertyValue("DirectRunWorkspace", m_dirWS);
trans.setProperty("IncidentBeamMonitor", 1);
trans.setProperty("TransmissionMonitor", 2);
trans.setProperty("FitMethod", "Polynomial");
trans.setProperty("PolynomialOrder", 3);
trans.setProperty("RebinParams", "7.5, 0.1, 9");
std::string outputWS("CalculateTransmissionTest_poly2");
trans.setPropertyValue("OutputWorkspace", outputWS);
TS_ASSERT_THROWS_NOTHING(trans.setProperty("OutputUnfittedData", true))
TS_ASSERT_THROWS_NOTHING(trans.execute());
TS_ASSERT(trans.isExecuted());
Mantid::API::MatrixWorkspace_const_sptr fitted, unfitted;
TS_ASSERT_THROWS_NOTHING(
fitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)));
TS_ASSERT_THROWS_NOTHING(
unfitted = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(
outputWS + "_unfitted")));
const Mantid::MantidVec &fitted_y = fitted->readY(0),
&fitted_x = fitted->readX(0);
// TS_ASSERT_EQUALS(fitted_y.size(), unfitted_y.size());
for (unsigned int i = 0; i < fitted_y.size(); ++i) {
x = (fitted_x[i] + fitted_x[i + 1]) * 0.5;
TS_ASSERT_DELTA(fitted_y[i], 26.6936 - 9.31494 * x + 1.11532 * x * x -
0.044502 * x * x * x,
0.01);
}
}
Mantid::API::AnalysisDataService::Instance().remove(outputWS);
Mantid::API::AnalysisDataService::Instance().remove(outputWS + "_unfitted");
CalculateTransmissionTest()
: m_dirWS("CalculateTransmissionTest_direct"),
m_transWS("CalculateTransmissionTest_trans") {
Steve Williams
committed
loadSampleLOQMonitors();
}
Steve Williams
committed
Mantid::API::AnalysisDataService::Instance().remove(m_dirWS);
Mantid::API::AnalysisDataService::Instance().remove(m_transWS);
}
/// Load and convert some monitor spectra to create some non-trival input data
void loadSampleLOQMonitors() {
// load a couple of real montior spectra
Steve Williams
committed
std::string wkspName("LOQ48097");
LoadRaw3 loader;
loader.initialize();
loader.setPropertyValue("Filename", "LOQ48097.raw");
loader.setPropertyValue("OutputWorkspace", wkspName);
loader.setProperty("SpectrumMin", 1);
loader.setProperty("SpectrumMax", 2);
Steve Williams
committed
loader.execute();
Steve Williams
committed
ConvertUnits unis;
unis.initialize();
unis.setPropertyValue("InputWorkspace", wkspName);
unis.setPropertyValue("OutputWorkspace", wkspName);
unis.setProperty("Target", "Wavelength");
Steve Williams
committed
unis.execute();
Steve Williams
committed
Rebin crop;
crop.initialize();
crop.setPropertyValue("InputWorkspace", wkspName);
Steve Williams
committed
crop.setPropertyValue("OutputWorkspace", m_dirWS);
crop.setProperty("Params", "6, 0.01, 7.5");
Steve Williams
committed
crop.execute();
crop.setPropertyValue("InputWorkspace", wkspName);
Steve Williams
committed
crop.setPropertyValue("OutputWorkspace", m_transWS);
crop.setProperty("Params", "7.5, 0.01, 9");
Steve Williams
committed
crop.execute();
Mantid::API::AnalysisDataService::Instance().remove(wkspName);
Mantid::API::MatrixWorkspace_sptr
dir = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(m_dirWS)),
source = boost::dynamic_pointer_cast<MatrixWorkspace>(
Mantid::API::AnalysisDataService::Instance().retrieve(m_transWS));
Mantid::MantidVec &Xfiddle0 = dir->dataX(0), &Xsource = source->dataX(0);
Mantid::MantidVec &Xfiddle1 = dir->dataX(1);
for (unsigned int i = 0; i < Xfiddle0.size(); ++i) {
Steve Williams
committed
Xfiddle0[i] = Xsource[i];
Xfiddle1[i] = Xsource[i];
}
}
Doucet, Mathieu
committed
private:
/// these are the names of some sample data workspaces
std::string m_dirWS, m_transWS;
Russell Taylor
committed
};
#endif /*CALCULATETRANSMISSIONTEST_H_*/