From bb3b07341df529807597797f5a343489291433d5 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Mon, 11 May 2015 09:00:13 +0100 Subject: [PATCH] Re #11617. Added CalculateChiSquared algorithm. --- .../Framework/CurveFitting/CMakeLists.txt | 3 + .../MantidCurveFitting/CalculateChiSquared.h | 52 ++++++++ .../CurveFitting/inc/MantidCurveFitting/Fit.h | 2 +- .../MantidCurveFitting/IFittingAlgorithm.h | 4 + .../CurveFitting/src/CalculateChiSquared.cpp | 50 ++++++++ .../Mantid/Framework/CurveFitting/src/Fit.cpp | 7 +- .../CurveFitting/src/IFittingAlgorithm.cpp | 12 ++ .../test/CalculateChiSquaredTest.h | 114 ++++++++++++++++++ .../algorithms/CalculateChiSquared-v1.rst | 44 +++++++ 9 files changed, 281 insertions(+), 7 deletions(-) create mode 100644 Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateChiSquared.h create mode 100644 Code/Mantid/Framework/CurveFitting/src/CalculateChiSquared.cpp create mode 100644 Code/Mantid/Framework/CurveFitting/test/CalculateChiSquaredTest.h create mode 100644 Code/Mantid/docs/source/algorithms/CalculateChiSquared-v1.rst diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index 8c52832c24a5..4b8b7c9fd2aa 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -12,6 +12,7 @@ set ( SRC_FILES src/BivariateNormal.cpp src/Bk2BkExpConvPV.cpp src/BoundaryConstraint.cpp + src/CalculateChiSquared.cpp src/CalculateGammaBackground.cpp src/CalculateMSVesuvio.cpp src/Chebyshev.cpp @@ -127,6 +128,7 @@ set ( INC_FILES inc/MantidCurveFitting/BivariateNormal.h inc/MantidCurveFitting/Bk2BkExpConvPV.h inc/MantidCurveFitting/BoundaryConstraint.h + inc/MantidCurveFitting/CalculateChiSquared.h inc/MantidCurveFitting/CalculateGammaBackground.h inc/MantidCurveFitting/CalculateMSVesuvio.h inc/MantidCurveFitting/Chebyshev.h @@ -242,6 +244,7 @@ set ( TEST_FILES BivariateNormalTest.h Bk2BkExpConvPVTest.h BoundaryConstraintTest.h + CalculateChiSquaredTest.h CalculateGammaBackgroundTest.h CalculateMSVesuvioTest.h ChebyshevTest.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateChiSquared.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateChiSquared.h new file mode 100644 index 000000000000..29f5386b2cea --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateChiSquared.h @@ -0,0 +1,52 @@ +#ifndef MANTID_CURVEFITTING_CALCULATECHISQUARED_H_ +#define MANTID_CURVEFITTING_CALCULATECHISQUARED_H_ + +#include "MantidKernel/System.h" +#include "MantidCurveFitting/IFittingAlgorithm.h" + +namespace Mantid { +namespace CurveFitting { + +/** + + Calculate chi squared for a function and a data set in a workspace. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + 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 CalculateChiSquared : public IFittingAlgorithm { +public: + CalculateChiSquared(); + virtual ~CalculateChiSquared(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string summary() const; + +private: + void initConcrete(); + void execConcrete(); +}; + +} // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_CALCULATECHISQUARED_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/Fit.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/Fit.h index bbdfe4f0a581..7bd44423f203 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/Fit.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/Fit.h @@ -110,7 +110,7 @@ class DLLExport Fit : public IFittingAlgorithm { protected: void initConcrete(); - void exec(); + void execConcrete(); void copyMinimizerOutput(const API::IFuncMinimizer &minimizer); }; diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h index 6cede6a73540..cc3c026e3821 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h @@ -56,8 +56,12 @@ class DLLExport IFittingAlgorithm : public API::Algorithm { private: void init(); + void exec(); /// Child classes declare their properties here. virtual void initConcrete() = 0; + /// Child classes implement the algorithm logic here. + virtual void execConcrete() = 0; + virtual void afterPropertySet(const std::string &propName); void addWorkspace(const std::string &workspaceNameProperty, bool addProperties = true); diff --git a/Code/Mantid/Framework/CurveFitting/src/CalculateChiSquared.cpp b/Code/Mantid/Framework/CurveFitting/src/CalculateChiSquared.cpp new file mode 100644 index 000000000000..292b48bc8a4e --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/CalculateChiSquared.cpp @@ -0,0 +1,50 @@ +#include "MantidCurveFitting/CalculateChiSquared.h" + +namespace Mantid { +namespace CurveFitting { + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +// Register the algorithm into the AlgorithmFactory +DECLARE_ALGORITHM(CalculateChiSquared) + +//---------------------------------------------------------------------------------------------- +/** Constructor + */ +CalculateChiSquared::CalculateChiSquared() {} + +//---------------------------------------------------------------------------------------------- +/** Destructor + */ +CalculateChiSquared::~CalculateChiSquared() {} + +//---------------------------------------------------------------------------------------------- + +/// Algorithms name for identification. @see Algorithm::name +const std::string CalculateChiSquared::name() const { + return "CalculateChiSquared"; +} + +/// Algorithm's version for identification. @see Algorithm::version +int CalculateChiSquared::version() const { return 1; } + +/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary +const std::string CalculateChiSquared::summary() const { + return "Calculate chi squared for a function and a data set in a workspace."; +} + +//---------------------------------------------------------------------------------------------- +/// Initialize the algorithm's properties. +void CalculateChiSquared::initConcrete() { + declareProperty("ChiSquared", 0.0, "Output value of chi squared."); +} + +//---------------------------------------------------------------------------------------------- +/// Execute the algorithm. +void CalculateChiSquared::execConcrete() { + +} + +} // namespace CurveFitting +} // namespace Mantid \ No newline at end of file diff --git a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp index 7519ffe94023..235f34e1e3e5 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp @@ -118,12 +118,7 @@ void Fit::copyMinimizerOutput(const API::IFuncMinimizer &minimizer) { * * @throw runtime_error Thrown if algorithm cannot execute */ -void Fit::exec() { - // this is to make it work with AlgorithmProxy - if (!m_domainCreator) { - setFunction(); - addWorkspaces(); - } +void Fit::execConcrete() { std::string ties = getPropertyValue("Ties"); if (!ties.empty()) { diff --git a/Code/Mantid/Framework/CurveFitting/src/IFittingAlgorithm.cpp b/Code/Mantid/Framework/CurveFitting/src/IFittingAlgorithm.cpp index 56e2e77c9657..996b0ea1f438 100644 --- a/Code/Mantid/Framework/CurveFitting/src/IFittingAlgorithm.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/IFittingAlgorithm.cpp @@ -269,6 +269,18 @@ void IFittingAlgorithm::addWorkspaces() { } } } +//---------------------------------------------------------------------------------------------- +/// Execute the algorithm. +void IFittingAlgorithm::exec() { + + // This is to make it work with AlgorithmProxy + if (!m_domainCreator) { + setFunction(); + addWorkspaces(); + } + // Execute the concrete algorithm. + this->execConcrete(); +} } // namespace CurveFitting } // namespace Mantid \ No newline at end of file diff --git a/Code/Mantid/Framework/CurveFitting/test/CalculateChiSquaredTest.h b/Code/Mantid/Framework/CurveFitting/test/CalculateChiSquaredTest.h new file mode 100644 index 000000000000..75765d79c0e3 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/CalculateChiSquaredTest.h @@ -0,0 +1,114 @@ +#ifndef MANTID_CURVEFITTING_CALCULATECHISQUAREDTEST_H_ +#define MANTID_CURVEFITTING_CALCULATECHISQUAREDTEST_H_ + +#include + +#include "MantidCurveFitting/CalculateChiSquared.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidKernel/EmptyValues.h" + +using Mantid::CurveFitting::CalculateChiSquared; +using namespace Mantid; +using namespace Mantid::API; + +class CalculateChiSquaredTest : 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 CalculateChiSquaredTest *createSuite() { return new CalculateChiSquaredTest(); } + static void destroySuite( CalculateChiSquaredTest *suite ) { delete suite; } + + + void test_Init() + { + CalculateChiSquared alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_exec() + { + Tester tester; + tester.set1DFunction(); + tester.set1DSpectrumEmpty(); + tester.runAlgorithm(); + } + +private: + + class Tester{ + + // input parameters + size_t nParams; + size_t nData; + bool isHisto; + double xMin; + double xMax; + std::vector xBins; + std::vector xValues; + + // values for algorithm input properties + IFunction_sptr function; + Workspace_sptr workspace; + int workspaceIndex; + double StartX; + double EndX; + + // algorithm output + double chiSquared; + + void makeXValues(){ + size_t dlt = isHisto ? 1 : 0; + xBins.resize(nData + dlt); + double dx = (xMax - xMin) / double(xBins.size() - 1); + for(size_t i = 0; i < xBins.size(); ++i) + { + xBins[i] = xMin + i * dx; + } + if (isHisto){ + xValues.resize(nData); + std::transform(xBins.begin(),xBins.end()-1, xValues.begin(), std::bind2nd(std::plus(),dx/2)); + } else { + xValues = xBins; + } + } + + public: + Tester(size_t np = 3, size_t nd = 10, bool histo = true) + : nParams(np), nData(nd), isHisto(histo), workspaceIndex(0), xMin(-10), + xMax(10), StartX(EMPTY_DBL()), EndX(EMPTY_DBL()) {} + + void runAlgorithm(){ + + CalculateChiSquared alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Function", function) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", workspace) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + chiSquared = alg.getProperty("ChiSquared"); + } + + void set1DFunction(){ + const std::string fun = "name=UserFunction,Formula=a+b*x+c*x^2,a=1,b=1,c=1"; + function = FunctionFactory::Instance().createInitialized(fun); + TS_ASSERT_EQUALS(function->nParams(), nParams); + } + + void set1DSpectrumEmpty(){ + makeXValues(); + const size_t nSpec = 1; + auto space = WorkspaceFactory::Instance().create("Workspace2D", nSpec, nData+1, nData); + space->dataX(0).assign(xBins.begin(),xBins.end()); + workspace = space; + } + + }; + +}; + + +#endif /* MANTID_CURVEFITTING_CALCULATECHISQUAREDTEST_H_ */ \ No newline at end of file diff --git a/Code/Mantid/docs/source/algorithms/CalculateChiSquared-v1.rst b/Code/Mantid/docs/source/algorithms/CalculateChiSquared-v1.rst new file mode 100644 index 000000000000..a31d932868a9 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/CalculateChiSquared-v1.rst @@ -0,0 +1,44 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +TODO: Enter a full rst-markup description of your algorithm here. + + +Usage +----- +.. Try not to use files in your examples, + but if you cannot avoid it then the (small) files must be added to + autotestdata\UsageData and the following tag unindented + .. include:: ../usagedata-note.txt + +**Example - CalculateChiSquared** + +.. testcode:: CalculateChiSquaredExample + + # Create a host workspace + ws = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + or + ws = CreateSampleWorkspace() + + wsOut = CalculateChiSquared() + + # Print the result + print "The output workspace has %i spectra" % wsOut.getNumberHistograms() + +Output: + +.. testoutput:: CalculateChiSquaredExample + + The output workspace has ?? spectra + +.. categories:: +