Skip to content

Commit

Permalink
Fixes #4001. Make ExtractSingleSpectrum event aware by making it use …
Browse files Browse the repository at this point in the history
…CropWorkspace.
  • Loading branch information
martyngigg committed Oct 25, 2011
1 parent 910e936 commit 794dd34
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 83 deletions.
12 changes: 12 additions & 0 deletions Code/Mantid/Framework/Algorithms/src/CropWorkspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,16 @@ void CropWorkspace::execEvent()
std::set<detid_t>& dets = eventW->getEventList(i).getDetectorIDs();
std::set<detid_t>::iterator k;
for (k = dets.begin(); k != dets.end(); ++k)
{
outEL.addDetectorID(*k);
}
// Spectrum number
ISpectrum * inSpec = m_inputWorkspace->getSpectrum(i);
ISpectrum * outSpec = outputWorkspace->getSpectrum(j);
if( inSpec && outSpec )
{
outSpec->setSpectrumNo(inSpec->getSpectrumNo());
}

if (!m_commonBoundaries)
// If the X axis is NOT common, then keep the initial X axis, just clear the events
Expand Down Expand Up @@ -302,6 +311,9 @@ void CropWorkspace::execEvent()
}
PARALLEL_CHECK_INTERUPT_REGION

if( m_inputWorkspace->axes() > 1 && m_inputWorkspace->getAxis(1)->isSpectra() )
// Backwards compatability while the spectra axis is still here
outputWorkspace->generateSpectraMap();

setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(outputWorkspace));
}
Expand Down
54 changes: 12 additions & 42 deletions Code/Mantid/Framework/Algorithms/src/ExtractSingleSpectrum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,52 +36,22 @@ void ExtractSingleSpectrum::init()
void ExtractSingleSpectrum::exec()
{
// Get hold of the input workspace
MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
// Get the desired spectrum number and check it's in range
const int desiredSpectrum = getProperty("WorkspaceIndex");
if ( desiredSpectrum >= static_cast<int>(inputWorkspace->getNumberHistograms()) )
MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
const int indexToExtract = getProperty("WorkspaceIndex");
const size_t numHist = inputWorkspace->getNumberHistograms();
if( static_cast<size_t>(indexToExtract) >= numHist )
{
g_log.error("WorkspaceIndex is greater than the number of entries in this workspace.");
throw Exception::IndexError(desiredSpectrum,inputWorkspace->getNumberHistograms(),this->name());
throw Exception::IndexError(indexToExtract,inputWorkspace->getNumberHistograms(),this->name());
}

// Now create a single spectrum workspace for the output
MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace,1,inputWorkspace->readX(0).size(),inputWorkspace->blocksize());

progress(0.5);
// Copy in the data and spectrum number of the appropriate spectrum
outputWorkspace->dataX(0) = inputWorkspace->readX(desiredSpectrum);
outputWorkspace->dataY(0) = inputWorkspace->readY(desiredSpectrum);
outputWorkspace->dataE(0) = inputWorkspace->readE(desiredSpectrum);
// If Axis 1 on the original is a spectra axis copy over the correct spectrum number
const Axis * axisOne = inputWorkspace->getAxis(1);
if( axisOne->isSpectra() )
{
const specid_t outSpecNo = inputWorkspace->getAxis(1)->spectraNo(desiredSpectrum);
outputWorkspace->getAxis(1)->spectraNo(0) = outSpecNo;
ISpectrum* outSpec = outputWorkspace->getSpectrum(0);
// Also set the spectrum number to the group number
outSpec->setSpectrumNo(outSpecNo);
outSpec->clearDetectorIDs();
const ISpectrum* inSpec = inputWorkspace->getSpectrum(desiredSpectrum);
// Add the detectors for this spectrum to the output workspace's spectra-detector map
outSpec->addDetectorIDs( inSpec->getDetectorIDs() );
}
else
{
if( axisOne->isNumeric() )
{
outputWorkspace->getAxis(1)->setValue(0, axisOne->operator()(desiredSpectrum));
}
else
{
TextAxis *txtAxis = dynamic_cast<TextAxis*>(outputWorkspace->getAxis(1));
txtAxis->setLabel(0, axisOne->label(desiredSpectrum));
}
}
// Let crop do the rest
IAlgorithm_sptr cropper = this->createSubAlgorithm("CropWorkspace", 0.0, 1.0);
cropper->setProperty("InputWorkspace", inputWorkspace);
cropper->setProperty("StartWorkspaceIndex", indexToExtract);
cropper->setProperty("EndWorkspaceIndex", indexToExtract);
cropper->executeAsSubAlg();

setProperty("OutputWorkspace",outputWorkspace);
progress(1.0);
setProperty<MatrixWorkspace_sptr>("OutputWorkspace", cropper->getProperty("OutputWorkspace"));
}

} // namespace Algorithms
Expand Down
117 changes: 76 additions & 41 deletions Code/Mantid/Framework/Algorithms/test/ExtractSingleSpectrumTest.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef EXTRACTSINGLESPECTRUMTEST_H_
#define EXTRACTSINGLESPECTRUMTEST_H_

#include "CropWorkspaceTest.h" // Use the test lable functionality as it should do the same thing
#include "CropWorkspaceTest.h" // Use the test label functionality as it should do the same thing
#include "MantidAlgorithms/ExtractSingleSpectrum.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"

Expand All @@ -12,34 +12,35 @@ class ExtractSingleSpectrumTest : public CxxTest::TestSuite
public:
void testName()
{
TS_ASSERT_EQUALS( extractor.name(), "ExtractSingleSpectrum" )
IAlgorithm *nameTester = createExtractSingleSpectrum();
TS_ASSERT_EQUALS( nameTester->name(), "ExtractSingleSpectrum" );
}

void testVersion()
{
TS_ASSERT_EQUALS( extractor.version(), 1 )
IAlgorithm *versionTester = createExtractSingleSpectrum();
TS_ASSERT_EQUALS( versionTester->version(), 1 );
}

void testCategory()
{
TS_ASSERT_EQUALS( extractor.category(), "General" )
IAlgorithm *catTester = createExtractSingleSpectrum();
TS_ASSERT_EQUALS( catTester->category(), "General" );
}

void testInit()
{
TS_ASSERT_THROWS_NOTHING( extractor.initialize() )
TS_ASSERT( extractor.isInitialized() )

TS_ASSERT_EQUALS( extractor.getProperties().size(), 3 )
IAlgorithm *initTester = createExtractSingleSpectrum();
TS_ASSERT_THROWS_NOTHING( initTester->initialize() );
TS_ASSERT( initTester->isInitialized() );
TS_ASSERT_EQUALS( initTester->getProperties().size(), 3 );
}

void testExec()
{
using namespace Mantid::API;

const int nbins(5);
MatrixWorkspace_sptr inputWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(5,nbins);

const int wsIndex = 2;
for (int i=0; i<nbins+1; ++i)
{
Expand All @@ -50,23 +51,12 @@ class ExtractSingleSpectrumTest : public CxxTest::TestSuite
inputWS->dataE(wsIndex)[i] = 7;
}
}
inputWS->getAxis(1)->spectraNo(wsIndex) = wsIndex;
AnalysisDataService::Instance().add("input",inputWS);

TS_ASSERT_THROWS_NOTHING( extractor.setPropertyValue("InputWorkspace","input") )
TS_ASSERT_THROWS_NOTHING( extractor.setPropertyValue("OutputWorkspace","output") )
TS_ASSERT_THROWS_NOTHING( extractor.setProperty("WorkspaceIndex",wsIndex) )

TS_ASSERT_THROWS_NOTHING( extractor.execute() )
TS_ASSERT( extractor.isExecuted() )

Workspace_const_sptr output;
TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieve("output"); )
MatrixWorkspace_const_sptr outputWS;
TS_ASSERT( outputWS = boost::dynamic_pointer_cast<const MatrixWorkspace>(output) )
TS_ASSERT_EQUALS( outputWS->blocksize(), 5 )
TS_ASSERT_EQUALS( outputWS->readX(0).size(), nbins+1)
TS_ASSERT_EQUALS( outputWS->getAxis(1)->spectraNo(0), wsIndex )
MatrixWorkspace_sptr outputWS = runAlgorithm(inputWS, wsIndex);

TS_ASSERT(outputWS);
TS_ASSERT_EQUALS( outputWS->blocksize(), 5 );
TS_ASSERT_EQUALS( outputWS->readX(0).size(), nbins+1);
TS_ASSERT_EQUALS( outputWS->getAxis(1)->spectraNo(0), wsIndex + 1);
for (int j=0; j<nbins+1; ++j)
{
TS_ASSERT_EQUALS( outputWS->readX(0)[j], j );
Expand All @@ -76,36 +66,81 @@ class ExtractSingleSpectrumTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS( outputWS->readE(0)[j], 7 );
}
}
do_Spectrum_Tests(outputWS, 3, 3);
}

void test_Input_With_TextAxis()
{
Algorithm *extractorWithText = new ExtractSingleSpectrum;
extractorWithText->initialize();
extractorWithText->setPropertyValue("WorkspaceIndex", "1");
CropWorkspaceTest::doTestWithTextAxis(extractorWithText); //Takes ownership
}

void test_Input_With_Event_Workspace()
{
// Create and input event workspace
const int eventsPerPixel(25);
const int numPixels(10);
EventWorkspace_sptr eventWS = WorkspaceCreationHelper::CreateEventWorkspace(numPixels,50,eventsPerPixel,0.0, 1.0, 1/*EventPattern=1*/);
TS_ASSERT(eventWS);
const int wsIndex(4);
MatrixWorkspace_sptr output = runAlgorithm(eventWS, wsIndex);

EventWorkspace_sptr outputWS = boost::dynamic_pointer_cast<EventWorkspace>(output);
TSM_ASSERT("Output should be an event workspace",outputWS);
const size_t numEvents = outputWS->getNumberEvents();
TS_ASSERT_EQUALS(numEvents, eventsPerPixel);
do_Spectrum_Tests(outputWS, 4, 4);
TS_ASSERT_EQUALS(eventWS->blocksize(), 50);
TS_ASSERT_DELTA(outputWS->getEventList(0).getTofMin(), 4.5, 1e-08);
TS_ASSERT_DELTA(outputWS->getEventList(0).getTofMax(), 28.5, 1e-08);
}

private:

ExtractSingleSpectrum * createExtractSingleSpectrum()
{
return new ExtractSingleSpectrum();
}

MatrixWorkspace_sptr runAlgorithm(MatrixWorkspace_sptr inputWS, const int index)
{
Algorithm *extractor = createExtractSingleSpectrum();
extractor->initialize();
extractor->setChild(true); // Don't add the output to the ADS, then we don't have to clear it
TS_ASSERT_THROWS_NOTHING(extractor->setProperty("InputWorkspace",inputWS));
TS_ASSERT_THROWS_NOTHING(extractor->setPropertyValue("OutputWorkspace","child_algorithm"));
TS_ASSERT_THROWS_NOTHING(extractor->setProperty("WorkspaceIndex",index));
TS_ASSERT_THROWS_NOTHING(extractor->execute());
TS_ASSERT(extractor->isExecuted());
if(!extractor->isExecuted())
{
TS_FAIL("Error running algorithm");
}
return extractor->getProperty("OutputWorkspace");
}

void do_Spectrum_Tests(MatrixWorkspace_sptr outputWS, const specid_t specID, const detid_t detID)
{
TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1);
const Mantid::API::ISpectrum *spectrum(NULL);
TS_ASSERT_THROWS_NOTHING(spectrum = outputWS->getSpectrum(0));
if( spectrum )
{
TS_ASSERT_EQUALS(spectrum->getSpectrumNo(), specID);
std::set<detid_t> detids = spectrum->getDetectorIDs();
TS_ASSERT_EQUALS(detids.size(), 1);
const detid_t id = *(detids.begin());
TS_ASSERT_EQUALS(id, 3);
TS_ASSERT_EQUALS(id, detID);
}
else
{
TS_FAIL("No spectra/detectors associated with extracted histogram.");
}

AnalysisDataService::Instance().remove("input");
AnalysisDataService::Instance().remove("output");
}

void test_Input_With_TextAxis()
{
Algorithm *extractor = new ExtractSingleSpectrum;
extractor->initialize();
extractor->setPropertyValue("WorkspaceIndex", "1");
CropWorkspaceTest::doTestWithTextAxis(extractor); //Takes ownership

}

private:
Mantid::Algorithms::ExtractSingleSpectrum extractor;
};

#endif /*EXTRACTSINGLESPECTRUMTEST_H_*/

0 comments on commit 794dd34

Please sign in to comment.