Skip to content

Commit

Permalink
Merge pull request #816 from mantidproject/11617_calculate_chi_square…
Browse files Browse the repository at this point in the history
…d_over_dof

Calculate chi squared over dof
  • Loading branch information
peterfpeterson committed Jun 3, 2015
2 parents 31b82fd + c7d4e03 commit 0e121af
Show file tree
Hide file tree
Showing 10 changed files with 1,108 additions and 373 deletions.
5 changes: 5 additions & 0 deletions Code/Mantid/Framework/CurveFitting/CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -53,6 +54,7 @@ set ( SRC_FILES
src/Gaussian.cpp
src/GaussianComptonProfile.cpp
src/GramCharlierComptonProfile.cpp
src/IFittingAlgorithm.cpp
src/IkedaCarpenterPV.cpp
src/LatticeDomainCreator.cpp
src/LatticeFunction.cpp
Expand Down Expand Up @@ -126,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
Expand Down Expand Up @@ -170,6 +173,7 @@ set ( INC_FILES
inc/MantidCurveFitting/Gaussian.h
inc/MantidCurveFitting/GaussianComptonProfile.h
inc/MantidCurveFitting/GramCharlierComptonProfile.h
inc/MantidCurveFitting/IFittingAlgorithm.h
inc/MantidCurveFitting/IkedaCarpenterPV.h
inc/MantidCurveFitting/Jacobian.h
inc/MantidCurveFitting/LatticeDomainCreator.h
Expand Down Expand Up @@ -240,6 +244,7 @@ set ( TEST_FILES
BivariateNormalTest.h
Bk2BkExpConvPVTest.h
BoundaryConstraintTest.h
CalculateChiSquaredTest.h
CalculateGammaBackgroundTest.h
CalculateMSVesuvioTest.h
ChebyshevTest.h
Expand Down
@@ -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 <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
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_ */
39 changes: 9 additions & 30 deletions Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/Fit.h
Expand Up @@ -4,10 +4,11 @@
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/IFunction.h"
#include "MantidAPI/Workspace.h"
#include "MantidAPI/IDomainCreator.h"
//#include "MantidAPI/Algorithm.h"
//#include "MantidAPI/IFunction.h"
//#include "MantidAPI/Workspace.h"
//#include "MantidAPI/IDomainCreator.h"
#include "MantidCurveFitting/IFittingAlgorithm.h"

namespace Mantid {

Expand Down Expand Up @@ -93,10 +94,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport Fit : public API::Algorithm {
class DLLExport Fit : public IFittingAlgorithm {
public:
/// Default constructor
Fit() : API::Algorithm(), m_domainType(API::IDomainCreator::Simple){};
Fit() : IFittingAlgorithm(){}
/// Algorithm's name for identification overriding a virtual method
virtual const std::string name() const { return "Fit"; }
/// Summary of algorithms purpose
Expand All @@ -106,33 +107,11 @@ class DLLExport Fit : public API::Algorithm {

/// Algorithm's version for identification overriding a virtual method
virtual int version() const { return (1); }
/// Algorithm's category for identification overriding a virtual method
virtual const std::string category() const { return "Optimization"; }

protected:
// Overridden Algorithm methods
void init();
void exec();
/// Override this method to perform a custom action right after a property was
/// set.
/// The argument is the property name. Default - do nothing.
virtual void afterPropertySet(const std::string &propName);
void setFunction();
void addWorkspace(const std::string &workspaceNameProperty,
bool addProperties = true);
void addWorkspaces();
/// Read domain type property and cache the value
void setDomainType();
void initConcrete();
void execConcrete();
void copyMinimizerOutput(const API::IFuncMinimizer &minimizer);

/// Pointer to the fitting function
API::IFunction_sptr m_function;
/// Pointer to a domain creator
boost::shared_ptr<API::IDomainCreator> m_domainCreator;
friend class API::IDomainCreator;
std::vector<std::string> m_workspacePropertyNames;
/// Keep the domain type
API::IDomainCreator::DomainType m_domainType;
};

} // namespace CurveFitting
Expand Down
@@ -0,0 +1,89 @@
#ifndef MANTID_CURVEFITTING_IFITTINGALGORITHM_H_
#define MANTID_CURVEFITTING_IFITTINGALGORITHM_H_

#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/IDomainCreator.h"

namespace Mantid {

namespace API {
class IFunction;
}

namespace CurveFitting {

/**
A base class for fitting algorithms. It declares two properties:
"Function" and "InputWorkspace". When these properties are set it
creates an appropriate domain creator.
The concrete classes must implement methods:
- name()
- version()
- summary()
- exec()
- initConcrete() to declare more properties
Copyright &copy; 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 <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport IFittingAlgorithm : public API::Algorithm {
public:
IFittingAlgorithm();
virtual ~IFittingAlgorithm();

virtual const std::string category() const;

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);
/// Read domain type property and cache the value
void setDomainType();

protected:
void setFunction();
void addWorkspaces();

/// Keep the domain type
API::IDomainCreator::DomainType m_domainType;
/// Pointer to the fitting function
boost::shared_ptr<API::IFunction> m_function;
/// Pointer to a domain creator
boost::shared_ptr<API::IDomainCreator> m_domainCreator;
std::vector<std::string> m_workspacePropertyNames;

friend class API::IDomainCreator;
};

} // namespace CurveFitting
} // namespace Mantid

#endif /* MANTID_CURVEFITTING_IFITTINGALGORITHM_H_ */
115 changes: 115 additions & 0 deletions Code/Mantid/Framework/CurveFitting/src/CalculateChiSquared.cpp
@@ -0,0 +1,115 @@
#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.", Direction::Output);
declareProperty("ChiSquaredDividedByDOF", 0.0,
"Output value of chi squared divided by the "
"number of degrees of freedom (NofData "
"- nOfParams).", Direction::Output);
declareProperty("ChiSquaredWeighted", 0.0, "Output value of weighted chi squared.", Direction::Output);
declareProperty("ChiSquaredWeightedDividedByDOF", 0.0,
"Output value of weighted chi squared divided by the "
"number of degrees of freedom (NofData "
"- nOfParams).", Direction::Output);
}

//----------------------------------------------------------------------------------------------
/// Execute the algorithm.
void CalculateChiSquared::execConcrete() {

// Function may need some preparation.
m_function->setUpForFit();

API::FunctionDomain_sptr domain;
API::FunctionValues_sptr values;
m_domainCreator->createDomain(domain, values);

// Do something with the function which may depend on workspace.
m_domainCreator->initFunction(m_function);

// Calculate function values.
m_function->function(*domain, *values);

// Get the number of free fitting parameters
size_t nParams = 0;
for (size_t i = 0; i < m_function->nParams(); ++i) {
if (!m_function->isFixed(i))
nParams += 1;
}
double dof = - static_cast<double>(nParams);

// Calculate the chi squared.
double chiSquared = 0.0;
double chiSquaredWeighted = 0.0;
for(size_t i = 0; i < values->size(); ++i) {
auto weight = values->getFitWeight(i);
if (weight > 0.0) {
double tmp = values->getFitData(i) - values->getCalculated(i);
chiSquared += tmp * tmp;
tmp *= weight;
chiSquaredWeighted += tmp * tmp;
dof += 1.0;
}
}
g_log.notice() << "Chi squared " << chiSquared << std::endl;
g_log.notice() << "Chi squared weighted " << chiSquaredWeighted << std::endl;

// Store the result.
setProperty("ChiSquared", chiSquared);
setProperty("chiSquaredWeighted", chiSquaredWeighted);

// Divide by the DOF
g_log.debug() << "DOF " << dof << std::endl;
if (dof <= 0.0) {
dof = 1.0;
g_log.warning() << "DOF has a non-positive value, changing to 1.0."
<< std::endl;
}
chiSquared /= dof;
chiSquaredWeighted /= dof;
g_log.notice() << "Chi squared / DOF " << chiSquared << std::endl;
g_log.notice() << "Chi squared weighed / DOF " << chiSquaredWeighted << std::endl;

// Store the result.
setProperty("ChiSquaredDividedByDOF", chiSquared);
setProperty("ChiSquaredWeightedDividedByDOF", chiSquaredWeighted);
}

} // namespace CurveFitting
} // namespace Mantid

0 comments on commit 0e121af

Please sign in to comment.