Skip to content

Commit

Permalink
Re #2702. Changed FindPeaks to make use of FunctionProperty.
Browse files Browse the repository at this point in the history
Also removed implicit conversion of a function to a string.
  • Loading branch information
mantid-roman committed Feb 10, 2012
1 parent 377ac63 commit 1320cf2
Show file tree
Hide file tree
Showing 33 changed files with 158 additions and 96 deletions.
2 changes: 0 additions & 2 deletions Code/Mantid/Framework/API/inc/MantidAPI/IFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ class MANTID_API_DLL IFunction
virtual std::string name()const = 0;
/// Writes itself into a string
virtual std::string asString()const;
/// The string operator
virtual operator std::string()const{return asString();}
/// Set the workspace. Make
/// @param ws :: Shared pointer to a workspace
virtual void setWorkspace(boost::shared_ptr<const Workspace> ws) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class DLLExport FindPeaks : public API::Algorithm

bool checkFitResultParameterNames(std::vector<std::string> paramnames, std::string backgroundtype, std::string &errormessage);

void createFunctions(const std::string& backgroundtype);

/// The number of smoothing iterations. Set to 5, the optimum value according to Mariscotti.
static const int g_z = 5;

Expand All @@ -108,6 +110,11 @@ class DLLExport FindPeaks : public API::Algorithm
bool singleSpectrum; ///<flag for if only a single spectrum is present
bool mHighBackground; ///<flag for find relatively weak peak in high background

// Functions for reused
API::IFitFunction_sptr m_peakFunction;
API::IFitFunction_sptr m_backgroundFunction;
API::IFitFunction_sptr m_peakAndBackgroundFunction;

unsigned int minGuessedPeakWidth;
unsigned int maxGuessedPeakWidth;
unsigned int stepGuessedPeakWidth;
Expand Down
120 changes: 88 additions & 32 deletions Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ FindPeaks uses the [[SmoothData]] algorithm to, well, smooth the data - a necess
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/VectorHelper.h"
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidAPI/FunctionFactory.h"
#include "MantidDataObjects/Workspace2D.h"
#include <boost/algorithm/string.hpp>
#include <numeric>
Expand Down Expand Up @@ -243,6 +244,9 @@ void FindPeaks::exec()
// c) Background
std::string backgroundtype = getProperty("BackgroundType");

// c.5) Create functions
createFunctions(backgroundtype);

// d) Choice of fitting approach
mHighBackground = getProperty("HighBackground");

Expand Down Expand Up @@ -806,34 +810,43 @@ void FindPeaks::fitPeakOneStep(const API::MatrixWorkspace_sptr &input, const int
// b) Guess sigma
const double in_sigma = (i0 + width < X.size()) ? X[i0 + width] - X[i0] : 0.;

// c) Construct Function string
std::stringstream ss;
// c) Set initial fitting parameters
if (backgroundtype.compare("Linear") == 0)
{
ss << "name=Gaussian,Height=" << in_height << ",PeakCentre=" << in_centre << ",Sigma="
<< in_sigma << ";name=LinearBackground,A0=" << in_bg0 << ",A1=" << in_bg1;
m_peakAndBackgroundFunction->setParameter("f0.Height", in_height);
m_peakAndBackgroundFunction->setParameter("f0.PeakCentre", in_centre);
m_peakAndBackgroundFunction->setParameter("f0.Sigma", in_sigma);
m_peakAndBackgroundFunction->setParameter("f1.A0", in_bg0);
m_peakAndBackgroundFunction->setParameter("f1.A1", in_bg1);
//ss << "name=Gaussian,Height=" << in_height << ",PeakCentre=" << in_centre << ",Sigma="
// << in_sigma << ";name=LinearBackground,A0=" << in_bg0 << ",A1=" << in_bg1;
}
else if (backgroundtype.compare("Quadratic") == 0)
{
ss << "name=Gaussian,Height=" << in_height << ",PeakCentre=" << in_centre << ",Sigma="
<< in_sigma << ";name=QuadraticBackground,A0=" << in_bg0 << ",A1=" << in_bg1 << ",A2="
<< in_bg2;
m_peakAndBackgroundFunction->setParameter("f0.Height", in_height);
m_peakAndBackgroundFunction->setParameter("f0.PeakCentre", in_centre);
m_peakAndBackgroundFunction->setParameter("f0.Sigma", in_sigma);
m_peakAndBackgroundFunction->setParameter("f1.A0", in_bg0);
m_peakAndBackgroundFunction->setParameter("f1.A1", in_bg1);
m_peakAndBackgroundFunction->setParameter("f1.A2", in_bg2);
//ss << "name=Gaussian,Height=" << in_height << ",PeakCentre=" << in_centre << ",Sigma="
// << in_sigma << ";name=QuadraticBackground,A0=" << in_bg0 << ",A1=" << in_bg1 << ",A2="
// << in_bg2;
}
else
{
g_log.error() << "Background type " << backgroundtype << " is not supported in FindPeak.cpp!"
<< std::endl;
throw std::invalid_argument("Background type is not supported in FindPeak.cpp");
}
std::string function = ss.str();
g_log.debug() << " Function: " << function << "; Background Type = " << backgroundtype << std::endl;
g_log.debug() << " Function: " << *m_peakAndBackgroundFunction << "; Background Type = " << backgroundtype << std::endl;

// d) complete fit
fit->setProperty("StartX", (X[i0] - 5 * (X[i0] - X[i2])));
fit->setProperty("EndX", (X[i0] + 5 * (X[i0] - X[i2])));
fit->setProperty("Minimizer", "Levenberg-Marquardt");
fit->setProperty("CostFunction", "Least squares");
fit->setPropertyValue("Function", function);
fit->setProperty("Function", m_peakAndBackgroundFunction);

// e) Fit and get result
fit->executeAsSubAlg();
Expand Down Expand Up @@ -986,31 +999,34 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co
fit->setProperty("WorkspaceIndex", 0);
fit->setProperty("MaxIterations", 50);

// c) Construct Function string
std::stringstream ss;
// c) Set initial fitting parameters
if (backgroundtype.compare("Linear") == 0)
{
ss << "name=LinearBackground,A0=" << in_bg0 << ",A1=" << in_bg1;
m_backgroundFunction->setParameter("A0", in_bg0);
m_backgroundFunction->setParameter("A1", in_bg1);
//ss << "name=LinearBackground,A0=" << in_bg0 << ",A1=" << in_bg1;
}
else if (backgroundtype.compare("Quadratic") == 0)
{
ss << "name=QuadraticBackground,A0=" << in_bg0 << ",A1=" << in_bg1 << ",A2="<< in_bg2;
m_backgroundFunction->setParameter("A0", in_bg0);
m_backgroundFunction->setParameter("A1", in_bg1);
m_backgroundFunction->setParameter("A2", in_bg2);
//ss << "name=QuadraticBackground,A0=" << in_bg0 << ",A1=" << in_bg1 << ",A2="<< in_bg2;
}
else
{
g_log.error() << "Background type " << backgroundtype << " is not supported in FindPeak.cpp!"
<< std::endl;
throw std::invalid_argument("Background type is not supported in FindPeak.cpp");
}
std::string function = ss.str();
g_log.debug() << "Background Type = " << backgroundtype << " Function: " << function << std::endl;
g_log.debug() << "Background Type = " << backgroundtype << " Function: " << *m_backgroundFunction << std::endl;

// d) complete fit
fit->setProperty("StartX", (X[i0] - 5 * (X[i0] - X[i2])));
fit->setProperty("EndX", (X[i0] + 5 * (X[i0] - X[i2])));
fit->setProperty("Minimizer", "Levenberg-Marquardt");
fit->setProperty("CostFunction", "Least squares");
fit->setPropertyValue("Function", function);
fit->setProperty("Function", m_backgroundFunction);

// e) Fit and get result of fitting background
fit->executeAsSubAlg();
Expand Down Expand Up @@ -1098,19 +1114,21 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co
double in_centre = xPeak;
double in_height = vPeak;

// c) Construct Function string
std::stringstream ss;
ss << "name=Gaussian,Height=" << in_height << ",PeakCentre=" << in_centre << ",Sigma=" << in_sigma;
std::string function = ss.str();
// c) Set initial fitting parameters
m_peakFunction->setParameter("Height", in_height);
m_peakFunction->setParameter("PeakCentre", in_centre);
m_peakFunction->setParameter("Sigma", in_sigma);
//ss << "name=Gaussian,Height=" << in_height << ",PeakCentre=" << in_centre << ",Sigma=" << in_sigma;
//std::string function = ss.str();

// d) Complete fit
gfit->setProperty("StartX", (X[i4] - 5 * (X[i0] - X[i2])));
gfit->setProperty("EndX", (X[i4] + 5 * (X[i0] - X[i2])));
gfit->setProperty("Minimizer", "Levenberg-Marquardt");
gfit->setProperty("CostFunction", "Least squares");
gfit->setPropertyValue("Function", function);
gfit->setProperty("Function", m_peakFunction);

g_log.debug() << "Function: " << function << " From " << (X[i4] - 5 * (X[i0] - X[i2]))
g_log.debug() << "Function: " << *m_peakFunction<< " From " << (X[i4] - 5 * (X[i0] - X[i2]))
<< " to " << (X[i4] + 5 * (X[i0] - X[i2])) << std::endl;

// e) Fit and get result
Expand Down Expand Up @@ -1187,33 +1205,42 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co
lastfit->setProperty("WorkspaceIndex", spectrum);
lastfit->setProperty("MaxIterations", 50);

// c) Construct Function string
std::stringstream ss2;
// c) Set initial fitting parameters
if (backgroundtype.compare("Linear") == 0)
{
ss2 << "name=Gaussian,Height=" << bestheight << ",PeakCentre=" << bestcenter << ",Sigma="
<< bestsigma << ";name=LinearBackground,A0=" << a0 << ",A1=" << a1;
m_peakAndBackgroundFunction->setParameter("f0.Height", bestheight);
m_peakAndBackgroundFunction->setParameter("f0.PeakCentre", bestcenter);
m_peakAndBackgroundFunction->setParameter("f0.Sigma", bestsigma);
m_peakAndBackgroundFunction->setParameter("f1.A0", a0);
m_peakAndBackgroundFunction->setParameter("f1.A1", a1);
//ss2 << "name=Gaussian,Height=" << bestheight << ",PeakCentre=" << bestcenter << ",Sigma="
// << bestsigma << ";name=LinearBackground,A0=" << a0 << ",A1=" << a1;
}
else if (backgroundtype.compare("Quadratic") == 0)
{
ss2 << "name=Gaussian,Height=" << bestheight << ",PeakCentre=" << bestcenter << ",Sigma="
<< bestsigma << ";name=QuadraticBackground,A0=" << a0 << ",A1=" << a1 << ",A2=" << a2;
m_peakAndBackgroundFunction->setParameter("f0.Height", bestheight);
m_peakAndBackgroundFunction->setParameter("f0.PeakCentre", bestcenter);
m_peakAndBackgroundFunction->setParameter("f0.Sigma", bestsigma);
m_peakAndBackgroundFunction->setParameter("f1.A0", a0);
m_peakAndBackgroundFunction->setParameter("f1.A1", a1);
m_peakAndBackgroundFunction->setParameter("f1.A2", a2);
//ss2 << "name=Gaussian,Height=" << bestheight << ",PeakCentre=" << bestcenter << ",Sigma="
// << bestsigma << ";name=QuadraticBackground,A0=" << a0 << ",A1=" << a1 << ",A2=" << a2;
}
else
{
g_log.error() << "Background type " << backgroundtype << " is not supported in FindPeak.cpp!"
<< std::endl;
throw std::invalid_argument("Background type is not supported in FindPeak.cpp");
}
function = ss2.str();
g_log.debug() << "(High Background) Final Fit Function: " << function << std::endl;
g_log.debug() << "(High Background) Final Fit Function: " << *m_peakAndBackgroundFunction << std::endl;

// d) complete fit
lastfit->setProperty("StartX", (X[i4] - 2 * (X[i0] - X[i2])));
lastfit->setProperty("EndX", (X[i4] + 2 * (X[i0] - X[i2])));
lastfit->setProperty("Minimizer", "Levenberg-Marquardt");
lastfit->setProperty("CostFunction", "Least squares");
lastfit->setPropertyValue("Function", function);
lastfit->setProperty("Function", m_peakAndBackgroundFunction);

// e) Fit and get result
lastfit->executeAsSubAlg();
Expand Down Expand Up @@ -1328,6 +1355,35 @@ bool FindPeaks::checkFitResultParameterNames(std::vector<std::string> paramnames
return correct;
}

/**
* Create the functions for fitting.
* @param backgroundtype :: Type of the function to fit the background.
*/
void FindPeaks::createFunctions(const std::string& backgroundtype)
{
m_peakFunction.reset(API::FunctionFactory::Instance().createFunction("Gaussian"));
if (backgroundtype.compare("Linear") == 0)
{
m_backgroundFunction.reset(API::FunctionFactory::Instance().createFunction("LinearBackground"));
m_peakAndBackgroundFunction.reset(API::FunctionFactory::Instance().createInitialized("name=Gaussian;name=LinearBackground"));
//ss2 << "name=Gaussian,Height=" << bestheight << ",PeakCentre=" << bestcenter << ",Sigma="
// << bestsigma << ";name=LinearBackground,A0=" << a0 << ",A1=" << a1;
}
else if (backgroundtype.compare("Quadratic") == 0)
{
m_backgroundFunction.reset(API::FunctionFactory::Instance().createFunction("QuadraticBackground"));
m_peakAndBackgroundFunction.reset(API::FunctionFactory::Instance().createInitialized("name=Gaussian;name=QuadraticBackground"));
//ss2 << "name=Gaussian,Height=" << bestheight << ",PeakCentre=" << bestcenter << ",Sigma="
// << bestsigma << ";name=QuadraticBackground,A0=" << a0 << ",A1=" << a1 << ",A2=" << a2;
}
else
{
g_log.error() << "Background type " << backgroundtype << " is not supported in FindPeak.cpp!"
<< std::endl;
throw std::invalid_argument("Background type is not supported in FindPeak.cpp");
}
}


} // namespace Algorithms
} // namespace Mantid
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ namespace Mantid
/// overwrite IFunction base class methods
std::string name()const{return "Convolution";}
virtual const std::string category() const { return "General";}
/// Writes itself into a string
std::string asString()const;
void functionMW(double* out, const double* xValues, const size_t nData)const;
void functionDerivMW(API::Jacobian* out, const double* xValues, const size_t nData);

Expand All @@ -132,8 +134,6 @@ namespace Mantid
protected:
/// overwrite IFunction base class method, which declare function parameters
virtual void init();
/// Writes itself into a string
std::string asString()const;

private:
/// To keep the Fourier transform of the resolution function (divided by the step in xValues)
Expand Down
4 changes: 2 additions & 2 deletions Code/Mantid/Framework/CurveFitting/src/Fit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ namespace CurveFitting
// if Constraints property isn't empty change the function by adding the constraints to it
if (!inputConstraints.empty())
{
function_input = *m_function;
function_input = m_function->asString();
std::string::size_type i = function_input.find_last_not_of(" \t\n\r");
if (i == std::string::npos) return;
if (function_input[i] == ';')
Expand Down Expand Up @@ -361,7 +361,7 @@ namespace CurveFitting
{
if (function_input.empty())
{
function_input = *m_function;
function_input = m_function->asString();
}
if (function_input.find(';') != std::string::npos)
{
Expand Down
7 changes: 4 additions & 3 deletions Code/Mantid/Framework/CurveFitting/src/GenericFit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ namespace CurveFitting

Progress prog(this,0.0,1.0,maxInterations?maxInterations:1);

std::string funIni = getProperty("Function");
m_function.reset( API::FunctionFactory::Instance().createInitialized(funIni) );
//std::string funIni = getProperty("Function");
//m_function.reset( API::FunctionFactory::Instance().createInitialized(funIni) );
m_function = getProperty("Function");

if (m_function.get() == NULL)
{
Expand Down Expand Up @@ -281,7 +282,7 @@ namespace CurveFitting
setProperty("OutputStatus", reportOfFit);
setProperty("OutputChi2overDoF", finalCostFuncVal);
setProperty("Minimizer", methodUsed);
setPropertyValue("Function",*m_function);
setProperty("Function",m_function);


// if Output property is specified output additional workspaces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class BackToBackExponentialTest : public CxxTest::TestSuite
fnWithBk.addFunction(bk);

//alg2.setFunction(fnWithBk);
alg2.setPropertyValue("Function",fnWithBk);
alg2.setPropertyValue("Function",fnWithBk.asString());

// execute fit
TS_ASSERT_THROWS_NOTHING(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class BoundaryConstraintTest : public CxxTest::TestSuite
TS_ASSERT( !bc->hasLower() );

gaus.addConstraint(bc);
IFitFunction* fun = FunctionFactory::Instance().createInitialized(gaus);
IFitFunction* fun = FunctionFactory::Instance().createInitialized(gaus.asString());
TS_ASSERT(fun);

IConstraint* c = fun->getConstraint(2);
Expand Down Expand Up @@ -185,7 +185,7 @@ class BoundaryConstraintTest : public CxxTest::TestSuite
bcHeight->initialize(&gaus,exprHeight);
gaus.addConstraint(bcHeight);

IFitFunction* fun = FunctionFactory::Instance().createInitialized(gaus);
IFitFunction* fun = FunctionFactory::Instance().createInitialized(gaus.asString());
TS_ASSERT(fun);

IConstraint* c = fun->getConstraint(2);
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/CurveFitting/test/ChebyshevTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class ChebyshevTest : public CxxTest::TestSuite

Chebyshev cheb;
cheb.setAttribute("n",IFitFunction::Attribute(3));
fit.setPropertyValue("Function",cheb);
fit.setPropertyValue("Function",cheb.asString());

fit.execute();
IFitFunction::Attribute StartX = cheb.getAttribute("StartX");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class CompositeFunctionTest : public CxxTest::TestSuite
alg.setPropertyValue("WorkspaceIndex","0");
alg.setPropertyValue("Output","out");
//alg.setFunction(mfun);
alg.setPropertyValue("Function",mfun);
alg.setPropertyValue("Function",mfun.asString());
TS_ASSERT_THROWS_NOTHING(alg.execute());
TS_ASSERT(alg.isExecuted());
WS_type outWS = getWS("out_Workspace");
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/CurveFitting/test/ConvolutionTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ class ConvolutionTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS(conv.parameterLocalName(6),"f1.h");
TS_ASSERT_EQUALS(conv.parameterLocalName(10),"f2.s");

IFitFunction* fun = FunctionFactory::Instance().createInitialized(conv);
IFitFunction* fun = FunctionFactory::Instance().createInitialized(conv.asString());
TS_ASSERT(fun);

Convolution* conv1 = dynamic_cast<Convolution*>(fun);
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/CurveFitting/test/ExpDecayMuonTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class ExpDecayMuonTest : public CxxTest::TestSuite
fn.initialize();

//alg2.setFunction(fn);
alg2.setPropertyValue("Function",fn);
alg2.setPropertyValue("Function",fn.asString());


// Set which spectrum to fit against and initial starting values
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/CurveFitting/test/ExpDecayOscTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class ExpDecayOscTest : public CxxTest::TestSuite
fn.initialize();

//alg2.setFunction(fn);
alg2.setPropertyValue("Function",fn);
alg2.setPropertyValue("Function",fn.asString());


// Set which spectrum to fit against and initial starting values
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/CurveFitting/test/ExpDecayTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class ExpDecayTest : public CxxTest::TestSuite
fn->initialize();

//alg2.setFunction(fn);
alg2.setPropertyValue("Function",*fn);
alg2.setPropertyValue("Function",fn->asString());


// Set which spectrum to fit against and initial starting values
Expand Down

0 comments on commit 1320cf2

Please sign in to comment.