From 794dd34426024f0a6112c338b45a2e8f4dbfacf7 Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@stfc.ac.uk> Date: Tue, 25 Oct 2011 14:50:27 +0100 Subject: [PATCH] Fixes #4001. Make ExtractSingleSpectrum event aware by making it use CropWorkspace. --- .../Algorithms/src/CropWorkspace.cpp | 12 ++ .../Algorithms/src/ExtractSingleSpectrum.cpp | 54 ++------ .../test/ExtractSingleSpectrumTest.h | 117 ++++++++++++------ 3 files changed, 100 insertions(+), 83 deletions(-) diff --git a/Code/Mantid/Framework/Algorithms/src/CropWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CropWorkspace.cpp index 3a2fdbc021e..bd456ad236d 100644 --- a/Code/Mantid/Framework/Algorithms/src/CropWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CropWorkspace.cpp @@ -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 @@ -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)); } diff --git a/Code/Mantid/Framework/Algorithms/src/ExtractSingleSpectrum.cpp b/Code/Mantid/Framework/Algorithms/src/ExtractSingleSpectrum.cpp index 3e07f4d83b4..1f6087e3388 100644 --- a/Code/Mantid/Framework/Algorithms/src/ExtractSingleSpectrum.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ExtractSingleSpectrum.cpp @@ -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 diff --git a/Code/Mantid/Framework/Algorithms/test/ExtractSingleSpectrumTest.h b/Code/Mantid/Framework/Algorithms/test/ExtractSingleSpectrumTest.h index 9e187f089ef..d7afc8541ff 100644 --- a/Code/Mantid/Framework/Algorithms/test/ExtractSingleSpectrumTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ExtractSingleSpectrumTest.h @@ -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" @@ -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) { @@ -50,23 +51,12 @@ public: 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 ); @@ -76,36 +66,81 @@ public: 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_*/ -- GitLab