diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index ffdc03127aa01e7ab7ac7c0709dc18702b974170..6dcd2409082839d00dc2f0f2e808de7357979003 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -16,6 +16,7 @@ set ( SRC_FILES src/Convolution.cpp src/CostFuncFitting.cpp src/CostFuncLeastSquares.cpp + src/CostFuncRwp.cpp src/CubicSpline.cpp src/DampingMinimizer.cpp src/DeltaFunction.cpp @@ -111,6 +112,7 @@ set ( INC_FILES inc/MantidCurveFitting/Convolution.h inc/MantidCurveFitting/CostFuncFitting.h inc/MantidCurveFitting/CostFuncLeastSquares.h + inc/MantidCurveFitting/CostFuncRwp.h inc/MantidCurveFitting/CubicSpline.h inc/MantidCurveFitting/DampingMinimizer.h inc/MantidCurveFitting/DeltaFunction.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CostFuncLeastSquares.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CostFuncLeastSquares.h index 5909b3553ab5917e4eb3bace70668a973a527a1b..311f0b82256c792f8aecd0d5ef9444531529be0f 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CostFuncLeastSquares.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CostFuncLeastSquares.h @@ -94,7 +94,14 @@ protected: API::FunctionValues_sptr values, bool evalFunction = true, bool evalDeriv = true, bool evalHessian = true) const; -private: + /// Get weight (1/sigma) + virtual double getWeight(API::FunctionValues_sptr values, size_t i, double sqrtW=1.0) const; + + /// Calcualte sqrt(W). Final cost function = sum_i [ (obs_i - cal_i) / (sigma * sqrt(W))]**2 + virtual double calSqrtW(API::FunctionValues_sptr values) const; + + /// Flag to include constraint in cost function value + bool m_includePenalty; mutable double m_value; mutable GSLVector m_der; @@ -107,6 +114,8 @@ private: friend class SeqDomain; friend class ParDomain; + double m_factor; + Kernel::Logger & m_log; }; diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CostFuncRwp.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CostFuncRwp.h new file mode 100644 index 0000000000000000000000000000000000000000..6df2e860cbd1f3f88ccb2bb5458f6a3ee5fac1af --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CostFuncRwp.h @@ -0,0 +1,74 @@ +#ifndef MANTID_CURVEFITTING_COSTFUNCRWP_H_ +#define MANTID_CURVEFITTING_COSTFUNCRWP_H_ + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidCurveFitting/CostFuncLeastSquares.h" +#include "MantidCurveFitting/GSLMatrix.h" +#include "MantidCurveFitting/GSLVector.h" + +namespace Mantid +{ +namespace Kernel +{ + class Logger; +} +namespace CurveFitting +{ + class SeqDomain; + class ParDomain; + +/** Cost function for Rwp = (sum_i (( obs_i - cal_i )/sigma_i)**2 ) / (sum_i (obs_i/sigma_i)**2) + + @author + @date + + Copyright © + + 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 CostFuncRwp : public CostFuncLeastSquares +{ +public: + /// Constructor + CostFuncRwp(); + /// Virtual destructor + virtual ~CostFuncRwp() {} + + /// Get name of minimizer + virtual std::string name() const { return "Rwp";} + + /// Get short name of minimizer - useful for say labels in guis + virtual std::string shortName() const {return "Rwp";} + +private: + + /// Get weight (1/sigma) + virtual double getWeight(API::FunctionValues_sptr values, size_t i, double sqrtW=1.0) const; + + /// Calcualte sqrt(W). Final cost function = sum_i [ (obs_i - cal_i) / (sigma * sqrt(W))]**2 + virtual double calSqrtW(API::FunctionValues_sptr values) const; + +}; + +} // namespace CurveFitting +} // namespace Mantid + +#endif /*MANTID_CURVEFITTING_COSTFUNCRWP_H_*/ diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/SeqDomain.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/SeqDomain.h index 688a682f58f2061f3c1e3c45086d5678fe64fb33..54789aab995e4cf87068572731bb8699eedd1407 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/SeqDomain.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/SeqDomain.h @@ -9,6 +9,7 @@ #include "MantidAPI/FunctionValues.h" #include "MantidAPI/IDomainCreator.h" #include "MantidCurveFitting/CostFuncLeastSquares.h" +#include "MantidCurveFitting/CostFuncRwp.h" #include <stdexcept> #include <vector> @@ -60,6 +61,11 @@ public: virtual void leastSquaresVal(const CostFuncLeastSquares& leastSquares); /// Calculate the value, first and second derivatives of a least squares cost function virtual void leastSquaresValDerivHessian(const CostFuncLeastSquares& leastSquares, bool evalFunction, bool evalDeriv, bool evalHessian); + /// Calculate the value of a Rwp cost function + void rwpVal(const CostFuncRwp& rwp); + /// Calculate the value, first and second derivatives of a RWP cost function + void rwpValDerivHessian(const CostFuncRwp& rwp, bool evalFunction, bool evalDeriv, bool evalHessian); + /// Create an instance of SeqDomain in one of two forms: either SeqDomain for sequential domain creation /// or ParDomain for parallel calculations static SeqDomain* create(API::IDomainCreator::DomainType type); diff --git a/Code/Mantid/Framework/CurveFitting/src/CostFuncLeastSquares.cpp b/Code/Mantid/Framework/CurveFitting/src/CostFuncLeastSquares.cpp index d746a2ce1513a9730f7d476bd489d49e4072d637..80fc94ee38c6398c3f4c098abcd976121c6fc9db 100644 --- a/Code/Mantid/Framework/CurveFitting/src/CostFuncLeastSquares.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/CostFuncLeastSquares.cpp @@ -25,7 +25,11 @@ DECLARE_COSTFUNCTION(CostFuncLeastSquares,Least squares) /** * Constructor */ -CostFuncLeastSquares::CostFuncLeastSquares() : CostFuncFitting(),m_value(0),m_pushed(false), +CostFuncLeastSquares::CostFuncLeastSquares() : CostFuncFitting(), + m_includePenalty(true), + m_value(0), + m_pushed(false), + m_factor(0.5), m_log(Kernel::Logger::get("CostFuncLeastSquares")) {} /** Calculate value of cost function @@ -56,13 +60,16 @@ double CostFuncLeastSquares::val() const } // add penalty - for(size_t i=0;i<m_function->nParams();++i) + if (m_includePenalty) { - if ( !m_function->isActive(i) ) continue; - API::IConstraint* c = m_function->getConstraint(i); - if (c) + for(size_t i=0;i<m_function->nParams();++i) { - m_value += c->check(); + if ( !m_function->isActive(i) ) continue; + API::IConstraint* c = m_function->getConstraint(i); + if (c) + { + m_value += c->check(); + } } } @@ -82,15 +89,19 @@ void CostFuncLeastSquares::addVal(API::FunctionDomain_sptr domain, API::Function double retVal = 0.0; + double sqrtw = calSqrtW(values); + for (size_t i = 0; i < ny; i++) { - double val = ( values->getCalculated(i) - values->getFitData(i) ) * values->getFitWeight(i); + // double val = ( values->getCalculated(i) - values->getFitData(i) ) * values->getFitWeight(i); + double val = ( values->getCalculated(i) - values->getFitData(i) ) * getWeight(values, i, sqrtw); retVal += val * val; } - + PARALLEL_ATOMIC - m_value += 0.5 * retVal; + m_value += m_factor * retVal; + return; } @@ -183,12 +194,15 @@ double CostFuncLeastSquares::valDerivHessian(bool evalFunction, bool evalDeriv, size_t np = m_function->nParams(); if (evalFunction) { - for(size_t i = 0; i < np; ++i) + if (m_includePenalty) { - API::IConstraint* c = m_function->getConstraint(i); - if (c) + for(size_t i = 0; i < np; ++i) { - m_value += c->check(); + API::IConstraint* c = m_function->getConstraint(i); + if (c) + { + m_value += c->check(); + } } } m_dirtyVal = false; @@ -196,34 +210,40 @@ double CostFuncLeastSquares::valDerivHessian(bool evalFunction, bool evalDeriv, if (evalDeriv) { - size_t i = 0; - for(size_t ip = 0; ip < np; ++ip) + if (m_includePenalty) { - if ( !m_function->isActive(ip) ) continue; - API::IConstraint* c = m_function->getConstraint(ip); - if (c) + size_t i = 0; + for(size_t ip = 0; ip < np; ++ip) { - double d = m_der.get(i) + c->checkDeriv(); - m_der.set(i,d); + if ( !m_function->isActive(ip) ) continue; + API::IConstraint* c = m_function->getConstraint(ip); + if (c) + { + double d = m_der.get(i) + c->checkDeriv(); + m_der.set(i,d); + } + ++i; } - ++i; } m_dirtyDeriv = false; } if (evalDeriv) { - size_t i = 0; - for(size_t ip = 0; ip < np; ++ip) + if (m_includePenalty) { - if ( !m_function->isActive(ip) ) continue; - API::IConstraint* c = m_function->getConstraint(ip); - if (c) + size_t i = 0; + for(size_t ip = 0; ip < np; ++ip) { - double d = m_hessian.get(i,i) + c->checkDeriv2(); - m_hessian.set(i,i,d); + if ( !m_function->isActive(ip) ) continue; + API::IConstraint* c = m_function->getConstraint(ip); + if (c) + { + double d = m_hessian.get(i,i) + c->checkDeriv2(); + m_hessian.set(i,i,d); + } + ++i; } - ++i; } // clear the dirty flag if hessian was actually calculated m_dirtyHessian = m_hessian.isEmpty(); @@ -273,6 +293,7 @@ void CostFuncLeastSquares::addValDerivHessian( std::cerr << std::endl; } } + double sqrtw = calSqrtW(values); for(size_t ip = 0; ip < np; ++ip) { if ( !function->isActive(ip) ) continue; @@ -281,7 +302,8 @@ void CostFuncLeastSquares::addValDerivHessian( { double calc = values->getCalculated(i); double obs = values->getFitData(i); - double w = values->getFitWeight(i); + // double w = values->getFitWeight(i); + double w = getWeight(values, i, sqrtw); double y = ( calc - obs ) * w; d += y * jacobian.get(i,ip) * w; if (iActiveP == 0 && evalFunction) @@ -319,7 +341,8 @@ void CostFuncLeastSquares::addValDerivHessian( double d = 0.0; for(size_t k = 0; k < ny; ++k) // over fitting data { - double w = values->getFitWeight(k); + // double w = values->getFitWeight(k); + double w = getWeight(values, k, sqrtw); d += jacobian.get(k,i) * jacobian.get(k,j) * w * w; } PARALLEL_CRITICAL(hessian_set) @@ -497,5 +520,24 @@ void CostFuncLeastSquares::calActiveCovarianceMatrix(GSLMatrix& covar, double ep } +//---------------------------------------------------------------------------------------------- +/** Get weight of data point i(1/sigma) + */ +double CostFuncLeastSquares::getWeight(API::FunctionValues_sptr values, size_t i, double sqrtW) const +{ + UNUSED_ARG(sqrtW); + return (values->getFitWeight(i)); +} + +//---------------------------------------------------------------------------------------------- +/** Get square root of normalization weight (W) + */ +double CostFuncLeastSquares::calSqrtW(API::FunctionValues_sptr values) const +{ + UNUSED_ARG(values); + + return 1.0; +} + } // namespace CurveFitting } // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/CostFuncRwp.cpp b/Code/Mantid/Framework/CurveFitting/src/CostFuncRwp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3efe90cc71ad16a3b3f9448d3dbe43814297f342 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/CostFuncRwp.cpp @@ -0,0 +1,61 @@ +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidCurveFitting/CostFuncRwp.h" +#include "MantidCurveFitting/Jacobian.h" +#include "MantidCurveFitting/SeqDomain.h" +#include "MantidAPI/IConstraint.h" +#include "MantidAPI/CompositeDomain.h" +#include "MantidAPI/FunctionValues.h" + +#include <iomanip> + +namespace Mantid +{ +namespace CurveFitting +{ + +DECLARE_COSTFUNCTION(CostFuncRwp,Rwp) + +//---------------------------------------------------------------------------------------------- +/** + * Constructor + */ +CostFuncRwp::CostFuncRwp() : CostFuncLeastSquares() +{ + m_includePenalty = false; + m_value = 0.; + m_pushed = false; + m_factor = 1.; +} + +//---------------------------------------------------------------------------------------------- +/** Get weight of data point i(1/sigma) + */ +double CostFuncRwp::getWeight(API::FunctionValues_sptr values, size_t i, double sqrtW) const +{ + return (values->getFitWeight(i)/sqrtW); +} + +//---------------------------------------------------------------------------------------------- +/** Get square root of normalization weight (W) + */ +double CostFuncRwp::calSqrtW(API::FunctionValues_sptr values) const +{ + double weight = 0.0; + + // FIXME : This might give a wrong answer in case of multiple-domain + size_t ny = values->size(); + for (size_t i = 0; i < ny; ++i) + { + double obsval = values->getFitData(i); + double inv_sigma = values->getFitWeight(i); + weight += obsval * obsval * inv_sigma * inv_sigma; + } + + return sqrt(weight); +} + + +} // namespace CurveFitting +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp index 9cfa125dccd682e053812f13ac64eea6be0f2612..544dd129e72d65ef79ce5e3f8b577eff0d979ab9 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp @@ -655,7 +655,8 @@ namespace CurveFitting // degrees of freedom size_t dof = values->size() - costFunc->nParams(); if (dof == 0) dof = 1; - double finalCostFuncVal = minimizer->costFunctionVal() / double(dof); + double rawcostfuncval = minimizer->costFunctionVal(); + double finalCostFuncVal = rawcostfuncval / double(dof); setProperty("OutputChi2overDoF",finalCostFuncVal); @@ -770,7 +771,21 @@ namespace CurveFitting } // Add chi-squared value at the end of parameter table Mantid::API::TableRow row = result->appendRow(); - row << "Cost function value" << finalCostFuncVal; +#if 1 + std::string costfuncname = getPropertyValue("CostFunction"); + if (costfuncname == "Rwp") + row << "Cost function value" << rawcostfuncval; + else + row << "Cost function value" << finalCostFuncVal; + setProperty("OutputParameters",result); +#else + row << "Cost function value" << finalCostFuncVal; + Mantid::API::TableRow row2 = result->appendRow(); + std::string name(getPropertyValue("CostFunction")); + name += " value"; + row2 << name << rawcostfuncval; +#endif + setProperty("OutputParameters",result); const bool unrollComposites = getProperty("OutputCompositeMembers"); diff --git a/Code/Mantid/Framework/CurveFitting/src/SeqDomain.cpp b/Code/Mantid/Framework/CurveFitting/src/SeqDomain.cpp index 0b318b387820850b673ac8a7c31307a1aef47799..c4a3ed24ac33dc6f2fd129b56be443f7ce13f470 100644 --- a/Code/Mantid/Framework/CurveFitting/src/SeqDomain.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/SeqDomain.cpp @@ -98,6 +98,29 @@ void SeqDomain::leastSquaresVal(const CostFuncLeastSquares& leastSquares) } } +//------------------------------------------------------------------------------------------------ +/** + * Calculate the value of a least squares cost function + * @param leastSquares :: The least squares cost func to calculate the value for + */ +void SeqDomain::rwpVal(const CostFuncRwp& rwp) +{ + API::FunctionDomain_sptr domain; + API::IFunctionValues_sptr values; + const size_t n = getNDomains(); + for(size_t i = 0; i < n; ++i) + { + values.reset(); + getDomainAndValues( i, domain, values ); + auto simpleValues = boost::dynamic_pointer_cast<API::FunctionValues>(values); + if (!simpleValues) + { + throw std::runtime_error("LeastSquares: unsupported IFunctionValues."); + } + rwp.addVal( domain, simpleValues ); + } +} + /** * Calculate the value, first and second derivatives of a least squares cost function * @param leastSquares :: The least squares cost func to calculate the value for @@ -123,5 +146,30 @@ void SeqDomain::leastSquaresValDerivHessian(const CostFuncLeastSquares& leastSqu } } +/** + * Calculate the value, first and second derivatives of a RWP cost function + * @param rwp :: The rwp cost func to calculate the value for + * @param evalFunction :: Flag to evaluate the value of the cost function + * @param evalDeriv :: Flag to evaluate the first derivatives + * @param evalHessian :: Flag to evaluate the Hessian (second derivatives) + */ +void SeqDomain::rwpValDerivHessian(const CostFuncRwp& rwp, bool evalFunction, bool evalDeriv, bool evalHessian) +{ + API::FunctionDomain_sptr domain; + API::IFunctionValues_sptr values; + const size_t n = getNDomains(); + for(size_t i = 0; i < n; ++i) + { + values.reset(); + getDomainAndValues( i, domain, values ); + auto simpleValues = boost::dynamic_pointer_cast<API::FunctionValues>(values); + if (!simpleValues) + { + throw std::runtime_error("Rwp: unsupported IFunctionValues."); + } + rwp.addValDerivHessian(rwp.getFittingFunction(),domain,simpleValues,evalFunction,evalDeriv,evalHessian); + } +} + } // namespace CurveFitting } // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/test/LeastSquaresTest.h b/Code/Mantid/Framework/CurveFitting/test/LeastSquaresTest.h index 3b98a531ef4d93edc2b78d3acf24ee6c9e2803e0..9028e3f2bef90869474e5e0fcbd89c0c01ac552d 100644 --- a/Code/Mantid/Framework/CurveFitting/test/LeastSquaresTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/LeastSquaresTest.h @@ -4,8 +4,10 @@ #include <cxxtest/TestSuite.h> #include "MantidCurveFitting/CostFuncLeastSquares.h" +#include "MantidCurveFitting/CostFuncRwp.h" #include "MantidCurveFitting/SimplexMinimizer.h" #include "MantidCurveFitting/BFGS_Minimizer.h" +#include "MantidCurveFitting/LevenbergMarquardtMDMinimizer.h" #include "MantidCurveFitting/UserFunction.h" #include "MantidCurveFitting/ExpDecay.h" #include "MantidAPI/FunctionDomain1D.h" @@ -50,6 +52,37 @@ public: boost::shared_ptr<CostFuncLeastSquares> costFun(new CostFuncLeastSquares); costFun->setFittingFunction(fun,domain,values); + SimplexMinimizer s; + s.initialize(costFun); + TS_ASSERT(s.minimize()); + TS_ASSERT_DELTA(costFun->val(),0.0000,0.0001); + TS_ASSERT_DELTA(fun->getParameter("a"),3.3,0.01); + TS_ASSERT_DELTA(fun->getParameter("b"),4.4,0.01); + TS_ASSERT_EQUALS(s.getError(),"success"); + } + + void test_With_Simplex_Rwp() + { + std::vector<double> x(10),y(10), sqrty(10); + for(size_t i = 0; i < x.size(); ++i) + { + x[i] = 0.1 * double(i); + y[i] = 3.3 * x[i] + 4.4; + sqrty[i] = sqrt(fabs(y[i])); + } + API::FunctionDomain1D_sptr domain(new API::FunctionDomain1DVector(x)); + API::FunctionValues_sptr values(new API::FunctionValues(*domain)); + values->setFitData(y); + values->setFitWeights(sqrty); + + boost::shared_ptr<UserFunction> fun(new UserFunction); + fun->setAttributeValue("Formula","a*x+b"); + fun->setParameter("a",1.1); + fun->setParameter("b",2.2); + + boost::shared_ptr<CostFuncRwp> costFun(new CostFuncRwp); + costFun->setFittingFunction(fun,domain,values); + SimplexMinimizer s; s.initialize(costFun); TS_ASSERT(s.minimize()); @@ -200,6 +233,40 @@ public: } + void test_With_LM_Rwp() + { + std::vector<double> x(10),y(10), e(10); + for(size_t i = 0; i < x.size(); ++i) + { + x[i] = 0.1 * double(i); + y[i] = 9.9 * exp( -(x[i])/0.5 ); + e[i] = 1./sqrt(y[i]); + } + API::FunctionDomain1D_sptr domain(new API::FunctionDomain1DVector(x)); + API::FunctionValues_sptr values(new API::FunctionValues(*domain)); + values->setFitData(y); + values->setFitWeights(e); + + API::IFunction_sptr fun(new ExpDecay); + fun->setParameter("Height", 19.); + fun->setParameter("Lifetime", 0.1); + + boost::shared_ptr<CostFuncRwp> costFun(new CostFuncRwp); + costFun->setFittingFunction(fun,domain,values); + + LevenbergMarquardtMDMinimizer s; + s.initialize(costFun); + + TS_ASSERT_DELTA(costFun->val(),0.64, 0.05); + TS_ASSERT(s.minimize()); + TS_ASSERT_DELTA(costFun->val(),0.0000, 0.00001); + + TS_ASSERT_DELTA(fun->getParameter("Height"), 9.9,0.01); + TS_ASSERT_DELTA(fun->getParameter("Lifetime"), 0.5,1e-9); + TS_ASSERT_EQUALS(s.getError(),"success"); + + } + void testDerivatives() { API::FunctionDomain1D_sptr domain(new API::FunctionDomain1DVector(79300.,79600.,41)); diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp index ec8b9f3eb88975104162605a6d5786ae7be32200..265028737e63781995121e337cba6dc22d5e2ea1 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp @@ -221,7 +221,7 @@ void FitPropertyBrowser::init() m_enumManager->setEnumNames(m_minimizer, m_minimizers); m_costFunction = m_enumManager->addProperty("Cost function"); - m_costFunctions << "Least squares"; + m_costFunctions << "Least squares" << "Rwp"; //<< "Ignore positive peaks"; m_enumManager->setEnumNames(m_costFunction,m_costFunctions);