From 25d01d44ed6e395e9e16c20c0f3d824770034bf1 Mon Sep 17 00:00:00 2001 From: Russell Taylor <taylorrj@ornl.gov> Date: Thu, 26 Jul 2012 17:47:05 -0400 Subject: [PATCH] Re #5572. Very quick first implementation of FilterPeaks. --- Code/Mantid/Framework/Crystal/CMakeLists.txt | 3 + .../Crystal/inc/MantidCrystal/FilterPeaks.h | 56 +++++++ .../Framework/Crystal/src/FilterPeaks.cpp | 145 ++++++++++++++++++ .../Framework/Crystal/test/FilterPeaksTest.h | 63 ++++++++ 4 files changed, 267 insertions(+) create mode 100644 Code/Mantid/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h create mode 100644 Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp create mode 100644 Code/Mantid/Framework/Crystal/test/FilterPeaksTest.h diff --git a/Code/Mantid/Framework/Crystal/CMakeLists.txt b/Code/Mantid/Framework/Crystal/CMakeLists.txt index b0c9781ca49..0d43c9c3f8b 100644 --- a/Code/Mantid/Framework/Crystal/CMakeLists.txt +++ b/Code/Mantid/Framework/Crystal/CMakeLists.txt @@ -5,6 +5,7 @@ set ( SRC_FILES src/CentroidPeaks.cpp src/CombinePeaksWorkspaces.cpp src/DiffPeaksWorkspaces.cpp + src/FilterPeaks.cpp src/FindSXPeaks.cpp src/FindUBUsingFFT.cpp src/FindUBUsingIndexedPeaks.cpp @@ -45,6 +46,7 @@ set ( INC_FILES inc/MantidCrystal/CentroidPeaks.h inc/MantidCrystal/CombinePeaksWorkspaces.h inc/MantidCrystal/DiffPeaksWorkspaces.h + inc/MantidCrystal/FilterPeaks.h inc/MantidCrystal/FindSXPeaks.h inc/MantidCrystal/FindUBUsingFFT.h inc/MantidCrystal/FindUBUsingIndexedPeaks.h @@ -85,6 +87,7 @@ set ( TEST_FILES test/CentroidPeaksTest.h test/CombinePeaksWorkspacesTest.h test/DiffPeaksWorkspacesTest.h + test/FilterPeaksTest.h test/FindSXPeaksTest.h test/FindUBUsingFFTTest.h test/FindUBUsingIndexedPeaksTest.h diff --git a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h new file mode 100644 index 00000000000..7f2c520a00b --- /dev/null +++ b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h @@ -0,0 +1,56 @@ +#ifndef MANTID_CRYSTAL_FILTERPEAKS_H_ +#define MANTID_CRYSTAL_FILTERPEAKS_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ +namespace Crystal +{ + + /** FilterPeaks : TODO: DESCRIPTION + + Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + class DLLExport FilterPeaks : public API::Algorithm + { + public: + FilterPeaks(); + virtual ~FilterPeaks(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + + private: + virtual void initDocs(); + void init(); + void exec(); + + + }; + + +} // namespace Crystal +} // namespace Mantid + +#endif /* MANTID_CRYSTAL_FILTERPEAKS_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp b/Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp new file mode 100644 index 00000000000..dd6b94f0c24 --- /dev/null +++ b/Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp @@ -0,0 +1,145 @@ +/*WIKI* +TODO: Enter a full wiki-markup description of your algorithm here. You can then use the Build/wiki_maker.py script to generate your full wiki page. +*WIKI*/ + +#include "MantidCrystal/FilterPeaks.h" +#include "MantidKernel/ListValidator.h" +#include "MantidKernel/MandatoryValidator.h" +#include "MantidDataObjects/PeaksWorkspace.h" + +namespace { + double HKL(const Mantid::DataObjects::Peak & p) + { + return p.getH() + p.getK() + p.getL(); + } + + double HKL2(const Mantid::DataObjects::Peak & p) + { + return p.getH()*p.getH() + p.getK()*p.getK() + p.getL()*p.getL(); + } + + double intensity(const Mantid::DataObjects::Peak & p) + { + return p.getIntensity(); + } + + double SN(const Mantid::DataObjects::Peak & p) + { + return p.getIntensity()/p.getSigmaIntensity(); + } +} + +namespace Mantid +{ +namespace Crystal +{ + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(FilterPeaks) + + using namespace Kernel; + using namespace API; + using DataObjects::PeaksWorkspace; + using DataObjects::PeaksWorkspace_const_sptr; + using DataObjects::PeaksWorkspace_sptr; + using DataObjects::Peak; + + /** Constructor + */ + FilterPeaks::FilterPeaks() + { + } + + /** Destructor + */ + FilterPeaks::~FilterPeaks() + { + } + + /// Algorithm's name for identification. @see Algorithm::name + const std::string FilterPeaks::name() const { return "FilterPeaks";}; + /// Algorithm's version for identification. @see Algorithm::version + int FilterPeaks::version() const { return 1;}; + /// Algorithm's category for identification. @see Algorithm::category + const std::string FilterPeaks::category() const { return "Crystal";} + + /// Sets documentation strings for this algorithm + void FilterPeaks::initDocs() + { + this->setWikiSummary("Filters the peaks in a peaks workspace based upon a chosen "); + this->setOptionalMessage("TODO: Enter a quick description of your algorithm."); + } + + /** Initialize the algorithm's properties. + */ + void FilterPeaks::init() + { + declareProperty(new WorkspaceProperty<PeaksWorkspace>("InputWorkspace","",Direction::Input), "The input workspace"); + declareProperty(new WorkspaceProperty<IPeaksWorkspace>("OutputWorkspace","",Direction::Output), "The filtered workspace"); + + std::vector<std::string> filters; + filters.push_back("H+K+L"); + filters.push_back("H2+K2+L2"); + filters.push_back("Intensity"); + filters.push_back("Signal/Noise"); + declareProperty("FilterVariable","",boost::make_shared<StringListValidator>(filters),"The variable on which to filter the peaks"); + + declareProperty("FilterValue", EMPTY_DBL(), boost::make_shared<MandatoryValidator<double>>(), + "The value of the FilterVariable to compare each peak to"); + + std::vector<std::string> operation; + operation.push_back("<"); + operation.push_back(">"); + operation.push_back("="); + operation.push_back("<="); + operation.push_back(">="); + declareProperty("Operator","<",boost::make_shared<StringListValidator>(operation),""); + } + + /** Execute the algorithm. + */ + void FilterPeaks::exec() + { + PeaksWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); + + IPeaksWorkspace_sptr filteredWS = WorkspaceFactory::Instance().createPeaks(); + // Copy over ExperimentInfo from input workspace + filteredWS->copyExperimentInfoFrom(inputWS.get()); + + // TODO: Refactor to avoid all the else-ifs and multiple edits required on adding new variables + + const std::string FilterVariable = getProperty("FilterVariable"); + double (*variable)(const Mantid::DataObjects::Peak &); + if ( FilterVariable == "H+K+L" ) + variable = &HKL; + else if ( FilterVariable == "H2+K2+L2" ) + variable = &HKL2; + else if ( FilterVariable == "Intensity" ) + variable = &intensity; + else if ( FilterVariable == "Signal/Noise" ) + variable = &SN; + + const double FilterValue = getProperty("FilterValue"); + const std::string Operator = getProperty("Operator"); + + for ( int i = 0; i < inputWS->getNumberPeaks(); ++i ) + { + bool pass; + const Peak& currentPeak = inputWS->getPeak(i); + const double currentValue = variable(currentPeak); + + if ( Operator == "<" ) pass = (currentValue < FilterValue); + else if ( Operator == ">" ) pass = (currentValue > FilterValue); + else if ( Operator == "=" ) pass = (currentValue == FilterValue); + else if ( Operator == "<=" ) pass = (currentValue <= FilterValue); + else if ( Operator == ">=" ) pass = (currentValue >= FilterValue); + + if ( pass ) filteredWS->addPeak(currentPeak); + } + + setProperty("OutputWorkspace", filteredWS); + } + + + +} // namespace Crystal +} // namespace Mantid diff --git a/Code/Mantid/Framework/Crystal/test/FilterPeaksTest.h b/Code/Mantid/Framework/Crystal/test/FilterPeaksTest.h new file mode 100644 index 00000000000..9f18a104194 --- /dev/null +++ b/Code/Mantid/Framework/Crystal/test/FilterPeaksTest.h @@ -0,0 +1,63 @@ +#ifndef MANTID_CRYSTAL_FILTERPEAKSTEST_H_ +#define MANTID_CRYSTAL_FILTERPEAKSTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidTestHelpers/WorkspaceCreationHelper.h" +#include "MantidCrystal/FilterPeaks.h" +#include "MantidDataObjects/PeaksWorkspace.h" + +using Mantid::Crystal::FilterPeaks; + +class FilterPeaksTest : 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 FilterPeaksTest *createSuite() { return new FilterPeaksTest(); } + static void destroySuite( FilterPeaksTest *suite ) { delete suite; } + + void test_Init() + { + FilterPeaks alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_exec() + { + using namespace Mantid::API; + using namespace Mantid::DataObjects; + + PeaksWorkspace_sptr inputWS = WorkspaceCreationHelper::createPeaksWorkspace(); + + // Name of the output workspace. + std::string outWSName("FilterPeaksTest_OutputWS"); + + FilterPeaks alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", inputWS) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("FilterVariable", "H+K+L") ) + TS_ASSERT_THROWS_NOTHING( alg.setProperty("FilterValue", 0.0) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Operator", ">") ) + TS_ASSERT( alg.execute() ) + + // Retrieve the workspace from data service. + IPeaksWorkspace_const_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<IPeaksWorkspace>(outWSName) ); + TS_ASSERT(ws); + if (!ws) return; + + // Will be empty as indices not set + TS_ASSERT_EQUALS( ws->getNumberPeaks(), 0 ) + + // Remove workspace from the data service. + AnalysisDataService::Instance().remove(outWSName); + } + +}; + + +#endif /* MANTID_CRYSTAL_FILTERPEAKSTEST_H_ */ -- GitLab