Skip to content

Commit

Permalink
Refs #10432. Adding tests to PoldiAnalyseResiduals
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Nov 21, 2014
1 parent 555c1ba commit c467f9d
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 110 deletions.
16 changes: 3 additions & 13 deletions Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiAnalyseResiduals.h
Expand Up @@ -47,23 +47,13 @@ class MANTID_SINQ_DLL PoldiAnalyseResiduals : public API::Algorithm


protected:
void setMeasuredCounts(const DataObjects::Workspace2D_sptr &measuredCounts);
void setFittedCounts(const DataObjects::Workspace2D_sptr &fittedCounts);
void setInstrumentFromWorkspace(const DataObjects::Workspace2D_const_sptr &instrumentWorkspace);

double sumCounts(const DataObjects::Workspace2D_sptr &workspace) const;
size_t numberOfPoints(const DataObjects::Workspace2D_sptr &workspace) const;
void addValue(DataObjects::Workspace2D_sptr &workspace, double value) const;
double sumCounts(const DataObjects::Workspace2D_sptr &workspace, const std::vector<int> &workspaceIndices) const;
size_t numberOfPoints(const DataObjects::Workspace2D_sptr &workspace, const std::vector<int> &workspaceIndices) const;
void addValue(DataObjects::Workspace2D_sptr &workspace, double value, const std::vector<int> &workspaceIndices) const;

private:
void init();
void exec();

DataObjects::Workspace2D_sptr m_measured;
DataObjects::Workspace2D_sptr m_fitted;
DataObjects::Workspace2D_sptr m_difference;

PoldiInstrumentAdapter_sptr m_instrument;
};


Expand Down
92 changes: 37 additions & 55 deletions Code/Mantid/Framework/SINQ/src/PoldiAnalyseResiduals.cpp
Expand Up @@ -23,11 +23,7 @@ DECLARE_ALGORITHM(PoldiAnalyseResiduals)
/** Constructor
*/
PoldiAnalyseResiduals::PoldiAnalyseResiduals() :
Algorithm(),
m_measured(),
m_fitted(),
m_difference(),
m_instrument()
Algorithm()
{
}

Expand All @@ -53,55 +49,37 @@ const std::string PoldiAnalyseResiduals::category() const { return "SINQ\\Poldi"
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string PoldiAnalyseResiduals::summary() const { return "Analysis of residuals after fitting POLDI 2D-spectra."; }

void PoldiAnalyseResiduals::setMeasuredCounts(const DataObjects::Workspace2D_sptr &measuredCounts)
{
m_measured = measuredCounts;
}

void PoldiAnalyseResiduals::setFittedCounts(const DataObjects::Workspace2D_sptr &fittedCounts)
{
m_fitted = fittedCounts;
}

void PoldiAnalyseResiduals::setInstrumentFromWorkspace(const DataObjects::Workspace2D_const_sptr &instrumentWorkspace)
{
m_instrument = boost::make_shared<PoldiInstrumentAdapter>(instrumentWorkspace);
}

double PoldiAnalyseResiduals::sumCounts(const DataObjects::Workspace2D_sptr &workspace) const
/// Sums the counts of all spectra specified by the supplied list of workspace indices.
double PoldiAnalyseResiduals::sumCounts(const DataObjects::Workspace2D_sptr &workspace, const std::vector<int> &workspaceIndices) const
{
double sum = 0.0;
for(size_t i = 0; i < workspace->getNumberHistograms(); ++i) {
if(!workspace->getDetector(i)->isMasked()) {
const MantidVec &counts = workspace->readY(i);
sum += std::accumulate(counts.begin(), counts.end(), 0.0);
}
for(size_t i = 0; i < workspaceIndices.size(); ++i) {
const MantidVec &counts = workspace->readY(workspaceIndices[i]);
sum += std::accumulate(counts.begin(), counts.end(), 0.0);
}

return sum;
}

size_t PoldiAnalyseResiduals::numberOfPoints(const DataObjects::Workspace2D_sptr &workspace) const
/// Counts the number of values in each spectrum specified by the list of workspace indices.
size_t PoldiAnalyseResiduals::numberOfPoints(const DataObjects::Workspace2D_sptr &workspace, const std::vector<int> &workspaceIndices) const
{
size_t sum = 0;
for(size_t i = 0; i < workspace->getNumberHistograms(); ++i) {
if(!workspace->getDetector(i)->isMasked()) {
const MantidVec &counts = workspace->readY(i);
sum += counts.size();
}
for(size_t i = 0; i < workspaceIndices.size(); ++i) {
const MantidVec &counts = workspace->readY(workspaceIndices[i]);
sum += counts.size();
}

return sum;// - 500;
return sum;
}

void PoldiAnalyseResiduals::addValue(DataObjects::Workspace2D_sptr &workspace, double value) const
/// Adds the specified value to all spectra specified by the given workspace indices.
void PoldiAnalyseResiduals::addValue(DataObjects::Workspace2D_sptr &workspace, double value, const std::vector<int> &workspaceIndices) const
{
for(size_t i = 0; i < workspace->getNumberHistograms(); ++i) {
if(!workspace->getDetector(i)->isMasked()) {
MantidVec &counts = workspace->dataY(i);
for(size_t i = 0; i < counts.size(); ++i) {
counts[i] += value;
}
for(size_t i = 0; i < workspaceIndices.size(); ++i) {
MantidVec &counts = workspace->dataY(workspaceIndices[i]);
for(size_t j = 0; j < counts.size(); ++j) {
counts[j] += value;
}
}
}
Expand All @@ -125,34 +103,38 @@ void PoldiAnalyseResiduals::init()
*/
void PoldiAnalyseResiduals::exec()
{
setMeasuredCounts(getProperty("MeasuredCountData"));
setFittedCounts(getProperty("FittedCountData"));
DataObjects::Workspace2D_sptr measured = getProperty("MeasuredCountData");
DataObjects::Workspace2D_sptr calculated = getProperty("FittedCountData");

setInstrumentFromWorkspace(m_measured);
PoldiInstrumentAdapter_sptr poldiInstrument = boost::make_shared<PoldiInstrumentAdapter>(measured);
// Dead wires need to be taken into account
PoldiAbstractDetector_sptr deadWireDetector = boost::make_shared<PoldiDeadWireDecorator>(measured->getInstrument(), poldiInstrument->detector());

PoldiResidualCorrelationCore core(g_log);
core.setInstrument(PoldiAbstractDetector_sptr(new PoldiDeadWireDecorator(m_measured->getInstrument(), m_instrument->detector())), m_instrument->chopper());
core.setWavelengthRange(1.1, 5.0);
// Since the valid workspace indices are required for some calculations, we extract and keep them
const std::vector<int> &validWorkspaceIndices = deadWireDetector->availableElements();

double totalMeasured = sumCounts(m_measured);
double totalFitted = sumCounts(m_fitted);
double numberOfDataPoints = static_cast<double>(numberOfPoints(m_measured));
double totalMeasured = sumCounts(measured, validWorkspaceIndices);
double totalFitted = sumCounts(calculated, validWorkspaceIndices);
double numberOfDataPoints = static_cast<double>(numberOfPoints(measured, validWorkspaceIndices));

double difference = (totalMeasured - totalFitted) / numberOfDataPoints;

//DataObjects::Workspace2D_sptr fittedDifference
addValue(m_fitted, difference);
addValue(calculated, difference, validWorkspaceIndices);


IAlgorithm_sptr minus = createChildAlgorithm("Minus");
minus->setProperty("LHSWorkspace", m_measured);
minus->setProperty("RHSWorkspace", m_fitted);
minus->setProperty("LHSWorkspace", measured);
minus->setProperty("RHSWorkspace", calculated);
minus->execute();

MatrixWorkspace_sptr fg = minus->getProperty("OutputWorkspace");
DataObjects::Workspace2D_sptr residuals = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(fg);

DataObjects::Workspace2D_sptr sum = core.calculate(residuals, m_fitted);
PoldiResidualCorrelationCore core(g_log, 0.1);
core.setInstrument(deadWireDetector, poldiInstrument->chopper());
core.setWavelengthRange(1.1, 5.0);
DataObjects::Workspace2D_sptr sum = core.calculate(residuals, calculated);

const MantidVec &corrCounts = sum->readY(0);
double csum = 0.0;
Expand All @@ -171,7 +153,7 @@ void PoldiAnalyseResiduals::exec()
size_t iterations = 1;

while(percChange > 1.0 && iterations < maxIterations) {
DataObjects::Workspace2D_sptr corr = core.calculate(residuals, m_fitted);
DataObjects::Workspace2D_sptr corr = core.calculate(residuals, calculated);

const MantidVec &corrCounts = corr->readY(0);
double csum = 0.0;
Expand All @@ -191,7 +173,7 @@ void PoldiAnalyseResiduals::exec()
++iterations;
}

addValue(m_fitted, -difference);
addValue(calculated, -difference, validWorkspaceIndices);

setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(sum));
}
Expand Down
106 changes: 64 additions & 42 deletions Code/Mantid/Framework/SINQ/test/PoldiAnalyseResidualsTest.h
Expand Up @@ -4,55 +4,77 @@
#include <cxxtest/TestSuite.h>

#include "MantidSINQ/PoldiAnalyseResiduals.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"

using namespace Mantid::Poldi;
using namespace Mantid::API;
using namespace Mantid::DataObjects;

class PoldiAnalyseResidualsTest : 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 PoldiAnalyseResidualsTest *createSuite() { return new PoldiAnalyseResidualsTest(); }
static void destroySuite( PoldiAnalyseResidualsTest *suite ) { delete suite; }


void test_Init()
{
PoldiAnalyseResiduals alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}

void test_exec()
{
// Name of the output workspace.
std::string outWSName("PoldiAnalyseResidualsTest_OutputWS");

PoldiAnalyseResiduals alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("REPLACE_PROPERTY_NAME_HERE!!!!", "value") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) );
TS_ASSERT_THROWS_NOTHING( alg.execute(); );
TS_ASSERT( alg.isExecuted() );

// Retrieve the workspace from data service. TODO: Change to your desired type
Workspace_sptr ws;
TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<Workspace>(outWSName) );
TS_ASSERT(ws);
if (!ws) return;

// TODO: Check the results

// Remove workspace from the data service.
AnalysisDataService::Instance().remove(outWSName);
}

void test_Something()
{
TSM_ASSERT( "You forgot to write a test!", 0);
}
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static PoldiAnalyseResidualsTest *createSuite() { return new PoldiAnalyseResidualsTest(); }
static void destroySuite( PoldiAnalyseResidualsTest *suite ) { delete suite; }


void test_Init()
{
PoldiAnalyseResiduals alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}

void testSumCounts()
{
TestablePoldiAnalyseResiduals alg;

Workspace2D_sptr testWorkspace = WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
TS_ASSERT_EQUALS(alg.sumCounts(testWorkspace, std::vector<int>(1, 1)), 2.0);
TS_ASSERT_EQUALS(alg.sumCounts(testWorkspace, std::vector<int>(1, 0)), 0.0);

TS_ASSERT_THROWS_ANYTHING(alg.sumCounts(testWorkspace, std::vector<int>(1, 3)));
}

void testNumberOfPoints()
{
TestablePoldiAnalyseResiduals alg;

Workspace2D_sptr testWorkspace = WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
TS_ASSERT_EQUALS(alg.numberOfPoints(testWorkspace, std::vector<int>(1, 1)), 2);
TS_ASSERT_EQUALS(alg.numberOfPoints(testWorkspace, std::vector<int>(1, 0)), 2);

TS_ASSERT_THROWS_ANYTHING(alg.sumCounts(testWorkspace, std::vector<int>(1, 3)));
}

void testAddValue()
{
TestablePoldiAnalyseResiduals alg;

Workspace2D_sptr testWorkspace = WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
TS_ASSERT_THROWS_NOTHING(alg.addValue(testWorkspace, 3.0, std::vector<int>(1, 1)));
TS_ASSERT_THROWS_NOTHING(alg.addValue(testWorkspace, 3.0, std::vector<int>(1, 0)));

TS_ASSERT_EQUALS(testWorkspace->readY(0)[0], 3.0);
TS_ASSERT_EQUALS(testWorkspace->readY(0)[1], 3.0);
TS_ASSERT_EQUALS(testWorkspace->readY(1)[0], 4.0);
TS_ASSERT_EQUALS(testWorkspace->readY(1)[1], 4.0);

TS_ASSERT_THROWS_ANYTHING(alg.addValue(testWorkspace, 3.0, std::vector<int>(1, 3)));
}

private:
class TestablePoldiAnalyseResiduals : public PoldiAnalyseResiduals
{
friend class PoldiAnalyseResidualsTest;

public:
TestablePoldiAnalyseResiduals() :
PoldiAnalyseResiduals()
{ }
~TestablePoldiAnalyseResiduals() { }
};


};
Expand Down

0 comments on commit c467f9d

Please sign in to comment.