Newer
Older
#ifndef ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONE2TEST_H_
#define ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONE2TEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidAlgorithms/ReflectometryReductionOne2.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/Axis.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidHistogramData/HistogramY.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include <algorithm>
using namespace Mantid::API;
using namespace Mantid::Algorithms;
using namespace WorkspaceCreationHelper;
class ReflectometryReductionOne2Test : public CxxTest::TestSuite {
private:
MatrixWorkspace_sptr m_multiDetectorWS;
MatrixWorkspace_sptr m_wavelengthWS;
MatrixWorkspace_sptr m_transmissionWS;
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static ReflectometryReductionOne2Test *createSuite() {
return new ReflectometryReductionOne2Test();
}
static void destroySuite(ReflectometryReductionOne2Test *suite) {
delete suite;
}
ReflectometryReductionOne2Test() {
FrameworkManager::Instance();
// A multi detector ws
m_multiDetectorWS =
create2DWorkspaceWithReflectometryInstrumentMultiDetector();
// A workspace in wavelength
m_wavelengthWS =
create2DWorkspaceWithReflectometryInstrumentMultiDetector();
m_wavelengthWS->getAxis(0)->setUnit("Wavelength");
// A transmission ws with different spectrum numbers to the run
m_transmissionWS =
create2DWorkspaceWithReflectometryInstrumentMultiDetector();
m_transmissionWS->getSpectrum(0).setSpectrumNo(2);
m_transmissionWS->getSpectrum(1).setSpectrumNo(3);
m_transmissionWS->getSpectrum(2).setSpectrumNo(4);
m_transmissionWS->getSpectrum(3).setSpectrumNo(5);
// Set different values in each spectrum so that we can check the correct
// spectra were used for the transmission correction
using namespace Mantid::HistogramData;
m_transmissionWS->setCounts(0, Counts(m_transmissionWS->y(0).size(), 10));
m_transmissionWS->setCounts(1, Counts(m_transmissionWS->y(1).size(), 20));
m_transmissionWS->setCounts(2, Counts(m_transmissionWS->y(2).size(), 30));
m_transmissionWS->setCounts(3, Counts(m_transmissionWS->y(3).size(), 40));
}
void test_IvsLam() {
// Test IvsLam workspace
// No monitor normalization
// No direct beam normalization
// No transmission correction
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
TS_ASSERT(outLam->x(0)[0] >= 1.5);
TS_ASSERT(outLam->x(0)[7] <= 15.0);
TS_ASSERT_DELTA(outLam->y(0)[0], 2.0000, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 2.0000, 0.0001);
}
void test_IvsLam_processing_instructions_1to2() {
// Test IvsLam workspace
// No monitor normalization
// No direct beam normalization
// No transmission correction
// Processing instructions : 1+2
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1+2");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
TS_ASSERT(outLam->x(0)[0] >= 1.5);
TS_ASSERT(outLam->x(0)[7] <= 15.0);
// Y counts, should be 2.0000 * 2
TS_ASSERT_DELTA(outLam->y(0)[0], 4.0000, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 4.0000, 0.0001);
void test_IvsLam_processing_instructions_1to3() {
// Test IvsLam workspace
// No monitor normalization
// No direct beam normalization
// No transmission correction
// Processing instructions : 1-3
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1-3");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
TS_ASSERT(outLam->x(0)[0] >= 1.5);
TS_ASSERT(outLam->x(0)[7] <= 15.0);
// Y counts, should be 2.0000 * 3
TS_ASSERT_DELTA(outLam->y(0)[0], 6.0000, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 6.0000, 0.0001);
void test_bad_processing_instructions() {
// Processing instructions : 5+6
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "5+6");
// Must throw as spectrum 2 is not defined
TS_ASSERT_THROWS_ANYTHING(alg.execute());
void test_IvsLam_direct_beam() {
// Test IvsLam workspace
// No monitor normalization
// Direct beam normalization: 2-3
// No transmission correction
// Processing instructions : 1
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
alg.setPropertyValue("RegionOfDirectBeam", "2-3");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
// Y counts, should be 0.5 = 1 (from detector ws) / 2 (from direct beam)
TS_ASSERT_DELTA(outLam->y(0)[0], 0.5, 0.0001);
}
void test_bad_direct_beam() {
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
alg.setPropertyValue("RegionOfDirectBeam", "4-5");
TS_ASSERT_THROWS_ANYTHING(alg.execute());
}
void test_IvsLam_no_monitors() {
// Test IvsLam workspace
// No monitor normalization
// Direct beam normalization: 2-3
// No transmission correction
// Processing instructions : 1
// I0MonitorIndex: 0
// MonitorBackgroundWavelengthMin : Not given
// MonitorBackgroundWavelengthMax : Not given
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
alg.setProperty("I0MonitorIndex", "0");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
TS_ASSERT(outLam->x(0)[0] >= 1.5);
TS_ASSERT(outLam->x(0)[7] <= 15.0);
// No monitors considered because MonitorBackgroundWavelengthMin
// and MonitorBackgroundWavelengthMax were not set
// Y counts must be 2.0000
TS_ASSERT_DELTA(outLam->y(0)[0], 2.0000, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 2.0000, 0.0001);
void test_IvsLam_monitor_normalization() {
// Test IvsLam workspace
// Monitor normalization
// No direct beam normalization
// No transmission correction
// Processing instructions : 1
// I0MonitorIndex: 0
// MonitorBackgroundWavelengthMin : 0.5
// MonitorBackgroundWavelengthMax : 3.0
// Normalize by integrated monitors : No
// Modify counts in monitor (only for this test)
// Modify counts only for range that will be fitted
auto inputWS = m_multiDetectorWS;
auto &Y = m_multiDetectorWS->mutableY(0);
std::fill(Y.begin(), Y.begin() + 2, 1.0);
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 0.0, 15.0, "1");
alg.setProperty("InputWorkspace", inputWS);
alg.setProperty("I0MonitorIndex", "0");
alg.setProperty("MonitorBackgroundWavelengthMin", 0.5);
alg.setProperty("MonitorBackgroundWavelengthMax", 3.0);
alg.setProperty("NormalizeByIntegratedMonitors", "0");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg, 10);
TS_ASSERT(outLam->x(0)[0] >= 0.0);
TS_ASSERT(outLam->x(0)[7] <= 15.0);
// Expected values are 2.4996 = 3.15301 (detectors) / 1.26139 (monitors)
TS_ASSERT_DELTA(outLam->y(0)[2], 2.4996, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[4], 2.4996, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 2.4996, 0.0001);
}
void test_IvsLam_integrated_monitors() {
// Test IvsLam workspace
// Monitor normalization
// No direct beam normalization
// No transmission correction
// Processing instructions : 1
// I0MonitorIndex: 0
// MonitorBackgroundWavelengthMin : 0.5
// MonitorBackgroundWavelengthMax : 3.0
// Normalize by integrated monitors : Yes
// Modify counts in monitor (only for this test)
// Modify counts only for range that will be fitted
auto inputWS = m_multiDetectorWS;
auto &Y = inputWS->mutableY(0);
std::fill(Y.begin(), Y.begin() + 2, 1.0);
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 0.0, 15.0, "1");
alg.setProperty("InputWorkspace", inputWS);
alg.setProperty("I0MonitorIndex", "0");
alg.setProperty("MonitorBackgroundWavelengthMin", 0.5);
alg.setProperty("MonitorBackgroundWavelengthMax", 3.0);
alg.setProperty("NormalizeByIntegratedMonitors", "1");
alg.setProperty("MonitorIntegrationWavelengthMin", 1.5);
alg.setProperty("MonitorIntegrationWavelengthMax", 15.0);
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg, 16);
TS_ASSERT(outLam->x(0)[0] >= 0.0);
TS_ASSERT(outLam->x(0)[7] <= 15.0);
// Expected values are 0.1981 = 2.0000 (detectors) / (1.26139*8) (monitors)
TS_ASSERT_DELTA(outLam->y(0)[0], 0.1981, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 0.1981, 0.0001);
void test_transmission_correction_run() {
// Transmission run is the same as input run
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
alg.setProperty("FirstTransmissionRun", m_multiDetectorWS);
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
// Expected values are 1 = m_wavelength / m_wavelength
TS_ASSERT_DELTA(outLam->y(0)[0], 1.0000, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 1.0000, 0.0001);
}
void test_transmission_correction_two_runs() {
// Transmission run is the same as input run
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
alg.setProperty("FirstTransmissionRun", m_multiDetectorWS);
alg.setProperty("SecondTransmissionRun", m_multiDetectorWS);
alg.setProperty("StartOverlap", 2.5);
alg.setProperty("EndOverlap", 3.0);
alg.setProperty("Params", "0.1");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
// Expected values are 1 = m_wavelength / m_wavelength
TS_ASSERT_DELTA(outLam->y(0)[0], 1.0000, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 1.0000, 0.0001);
}
void test_transmission_correction_with_mapped_spectra() {
// Run workspace spectrum numbers are 1,2,3,4.
// Transmission workspace has spectrum numbers 2,3,4,5.
// Processing instructions 2-3 in the run workspace map to
// spectra 3-4, which map to indices 1-2 in the transmission
// workspace.
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "2-3");
alg.setProperty("FirstTransmissionRun", m_transmissionWS);
alg.setProperty("SecondTransmissionRun", m_transmissionWS);
alg.setProperty("StartOverlap", 2.5);
alg.setProperty("EndOverlap", 3.0);
alg.setProperty("Params", "0.1");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
// Expected values are 1 = m_wavelength / m_wavelength
TS_ASSERT_DELTA(outLam->y(0)[0], 0.08, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 0.08, 0.0001);
}
void test_transmission_correction_with_bad_mapped_spectra() {
// Run workspace spectrum numbers are 1,2,3,4.
// Transmission workspace has spectrum numbers 2,3,4,5.
// Processing instructions 0 in the run workspace maps to
// spectrum 1, which doesn't exist in the transmission
// workspace.
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "0");
alg.setProperty("FirstTransmissionRun", m_transmissionWS);
alg.setProperty("SecondTransmissionRun", m_transmissionWS);
alg.setProperty("StartOverlap", 2.5);
alg.setProperty("EndOverlap", 3.0);
alg.setProperty("Params", "0.1");
TS_ASSERT_THROWS_ANYTHING(alg.execute());
}
void test_exponential_correction() {
// CorrectionAlgorithm: ExponentialCorrection
setupAlgorithm(alg, 1.5, 15.0, "1");
alg.setProperty("CorrectionAlgorithm", "ExponentialCorrection");
alg.setProperty("C0", 0.2);
alg.setProperty("C1", 0.1);
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
TS_ASSERT_DELTA(outLam->y(0)[0], 12.5113, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 23.4290, 0.0001);
}
void test_polynomial_correction() {
// CorrectionAlgorithm: PolynomialCorrection
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
alg.setProperty("CorrectionAlgorithm", "PolynomialCorrection");
alg.setProperty("Polynomial", "0.1,0.3,0.5");
MatrixWorkspace_sptr outLam = runAlgorithmLam(alg);
TS_ASSERT_DELTA(outLam->y(0)[0], 0.6093, 0.0001);
TS_ASSERT_DELTA(outLam->y(0)[7], 0.0514, 0.0001);
void test_IvsQ() {
ReflectometryReductionOne2 alg;
setupAlgorithm(alg, 1.5, 15.0, "1");
MatrixWorkspace_sptr outQ = runAlgorithmQ(alg);
// X range in outQ
TS_ASSERT_DELTA(outQ->x(0)[0], 0.3353, 0.0001);
TS_ASSERT_DELTA(outQ->x(0)[7], 0.5962, 0.0001);
}
private:
// Do standard algorithm setup
void setupAlgorithm(ReflectometryReductionOne2 &alg,
const double wavelengthMin, const double wavelengthMax,
const std::string &procInstr) {
alg.setChild(true);
alg.initialize();
alg.setProperty("InputWorkspace", m_multiDetectorWS);
alg.setProperty("WavelengthMin", wavelengthMin);
alg.setProperty("WavelengthMax", wavelengthMax);
alg.setPropertyValue("ProcessingInstructions", procInstr);
alg.setPropertyValue("OutputWorkspace", "IvsQ");
alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
}
// Do standard algorithm execution and checks and return IvsLam
MatrixWorkspace_sptr runAlgorithmLam(ReflectometryReductionOne2 &alg,
const size_t blocksize = 14) {
MatrixWorkspace_sptr outLam = alg.getProperty("OutputWorkspaceWavelength");
TS_ASSERT(outLam);
TS_ASSERT_EQUALS(outLam->getNumberHistograms(), 1);
TS_ASSERT_EQUALS(outLam->blocksize(), blocksize);
return outLam;
}
// Do standard algorithm execution and checks and return IvsQ
MatrixWorkspace_sptr runAlgorithmQ(ReflectometryReductionOne2 &alg,
const size_t blocksize = 14) {
alg.execute();
MatrixWorkspace_sptr outQ = alg.getProperty("OutputWorkspace");
TS_ASSERT(outQ);
TS_ASSERT_EQUALS(outQ->getNumberHistograms(), 1);
TS_ASSERT_EQUALS(outQ->blocksize(), blocksize);
return outQ;
}
};
#endif /* ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONE2TEST_H_ */