diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index 8a9e2a07462e..d530eb7d5e8b 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -59,6 +59,7 @@ set ( SRC_FILES src/MultiDomainCreator.cpp src/MuonFInteraction.cpp src/NeutronBk2BkExpConvPVoigt.cpp + src/NormaliseByPeakArea.cpp src/PRConjugateGradientMinimizer.cpp src/ParDomain.cpp src/PlotPeakByLogValue.cpp @@ -164,6 +165,7 @@ set ( INC_FILES inc/MantidCurveFitting/MultiDomainCreator.h inc/MantidCurveFitting/MuonFInteraction.h inc/MantidCurveFitting/NeutronBk2BkExpConvPVoigt.h + inc/MantidCurveFitting/NormaliseByPeakArea.h inc/MantidCurveFitting/PRConjugateGradientMinimizer.h inc/MantidCurveFitting/ParDomain.h inc/MantidCurveFitting/PlotPeakByLogValue.h @@ -255,6 +257,7 @@ set ( TEST_FILES MultiDomainFunctionTest.h MuonFInteractionTest.h NeutronBk2BkExpConvPVoigtTest.h + NormaliseByPeakAreaTest.h PRConjugateGradientTest.h PlotPeakByLogValueTest.h PolynomialTest.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/NormaliseByPeakArea.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/NormaliseByPeakArea.h new file mode 100644 index 000000000000..415831fba38e --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/NormaliseByPeakArea.h @@ -0,0 +1,67 @@ +#ifndef MANTID_CURVEFITTING_NORMALISEBYPEAKAREA_H_ +#define MANTID_CURVEFITTING_NORMALISEBYPEAKAREA_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ + namespace CurveFitting + { + + /** + + Copyright © 2013 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 . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport NormaliseByPeakArea : public API::Algorithm + { + public: + NormaliseByPeakArea(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + + private: + virtual void initDocs(); + void init(); + void exec(); + + /// Convert input workspace to Y coordinates for fitting + API::MatrixWorkspace_sptr convertInputToY(); + + /// Check and store appropriate input data + void retrieveInputs(); + /// Create the output workspace + void createOutputWorkspace(); + + API::MatrixWorkspace_sptr m_inputWS; + /// The input mass in AMU + double m_mass; + /// Output workspace + API::MatrixWorkspace_sptr m_outputWS; + }; + + + } // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_NORMALISEBYPEAKAREA_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/src/NormaliseByPeakArea.cpp b/Code/Mantid/Framework/CurveFitting/src/NormaliseByPeakArea.cpp new file mode 100644 index 000000000000..4e65046ceebb --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/NormaliseByPeakArea.cpp @@ -0,0 +1,116 @@ +/*WIKI* +Takes an input TOF spectrum and converts it to Y-space using the [[ConvertToYSpace]] algorithm. The result is +then fitted using the ComptonPeakProfile function to produce an estimate of the peak area. The input data is +normalised by this value. + *WIKI*/ + +#include "MantidCurveFitting/NormaliseByPeakArea.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidKernel/BoundedValidator.h" + +#include + +namespace Mantid +{ + namespace CurveFitting + { + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(NormaliseByPeakArea) + + using namespace API; + using namespace Kernel; + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + NormaliseByPeakArea::NormaliseByPeakArea() + : API::Algorithm(), m_inputWS(), m_mass(0.0) + { + } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string NormaliseByPeakArea::name() const { return "NormaliseByPeakArea"; } + + /// Algorithm's version for identification. @see Algorithm::version + int NormaliseByPeakArea::version() const { return 1; } + + /// Algorithm's category for identification. @see Algorithm::category + const std::string NormaliseByPeakArea::category() const { return "Corrections"; } + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void NormaliseByPeakArea::initDocs() + { + this->setWikiSummary("Normalises the input data by the area of of peak defined by the input mass value."); + this->setOptionalMessage("Normalises the input data by the area of of peak defined by the input mass value."); + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void NormaliseByPeakArea::init() + { + auto wsValidator = boost::make_shared(); + wsValidator->add(false); // point data + wsValidator->add(); + wsValidator->add("TOF"); + declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input,wsValidator), + "An input workspace."); + + auto mustBePositive = boost::make_shared >(); + mustBePositive->setLower(0.0); + mustBePositive->setLowerExclusive(true); //strictly greater than 0.0 + declareProperty("Mass",-1.0,mustBePositive,"The mass, in AMU, defining the recoil peak to fit"); + + declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), + "Input workspace normalised by the fitted peak area"); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void NormaliseByPeakArea::exec() + { + retrieveInputs(); + createOutputWorkspace(); + + // -- Convert to Y-space -- + auto yspace = convertInputToY(); + + setProperty("OutputWorkspace", yspace); + } + + /* + * Returns a workspace converted to Y-space coordinates. @see ConvertToYSpace + */ + MatrixWorkspace_sptr NormaliseByPeakArea::convertInputToY() + { + auto alg = createChildAlgorithm("ConvertToYSpace",0.0, 0.33,false); + alg->setProperty("InputWorkspace", m_inputWS); + alg->setProperty("Mass", m_mass); + alg->execute(); + return alg->getProperty("OutputWorkspace"); + } + + /** + * Caches input details for the peak information + */ + void NormaliseByPeakArea::retrieveInputs() + { + m_inputWS = getProperty("InputWorkspace"); + m_mass = getProperty("Mass"); + } + + /** + * Create & cache output workspaces + */ + void NormaliseByPeakArea::createOutputWorkspace() + { + m_outputWS = WorkspaceFactory::Instance().create(m_inputWS); + } + + + } // namespace CurveFitting +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/test/NormaliseByPeakAreaTest.h b/Code/Mantid/Framework/CurveFitting/test/NormaliseByPeakAreaTest.h new file mode 100644 index 000000000000..82cd872ffaab --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/NormaliseByPeakAreaTest.h @@ -0,0 +1,64 @@ +#ifndef MANTID_CURVEFITTING_NORMALISEBYPEAKAREATEST_H_ +#define MANTID_CURVEFITTING_NORMALISEBYPEAKAREATEST_H_ + +#include + +#include "MantidCurveFitting/NormaliseByPeakArea.h" +#include "ComptonProfileTestHelpers.h" + +using Mantid::CurveFitting::NormaliseByPeakArea; + +class NormaliseByPeakAreaTest : 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 NormaliseByPeakAreaTest *createSuite() { return new NormaliseByPeakAreaTest(); } + static void destroySuite( NormaliseByPeakAreaTest *suite ) { delete suite; } + + + void test_Init() + { + NormaliseByPeakArea alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_exec_with_TOF_input_gives_correct_X_values() + { + using namespace Mantid::API; + + auto alg = createAlgorithm(); + double x0(50.0),x1(300.0),dx(0.5); + auto testWS = ComptonProfileTestHelpers::createSingleSpectrumWorkspace(x0,x1,dx, true,true); + alg->setProperty("InputWorkspace", testWS); + alg->setProperty("Mass", 1.0097); + alg->execute(); + TS_ASSERT(alg->isExecuted()); + + MatrixWorkspace_sptr outputWS = alg->getProperty("OutputWorkspace"); + TS_ASSERT(outputWS != 0) + + TS_ASSERT_EQUALS(testWS->getNumberHistograms(), outputWS->getNumberHistograms()); + + // Test a few values + const auto &outX = outputWS->readX(0); + const auto &outY = outputWS->readY(0); + const auto &outE = outputWS->readE(0); + const size_t npts = outputWS->blocksize(); + } + +private: + Mantid::API::IAlgorithm_sptr createAlgorithm() + { + Mantid::API::IAlgorithm_sptr alg = boost::make_shared(); + alg->initialize(); + alg->setChild(true); + alg->setPropertyValue("OutputWorkspace", "__UNUSED__"); + return alg; + } + +}; + + +#endif /* MANTID_CURVEFITTING_NORMALISEBYPEAKAREATEST_H_ */