Newer
Older
Roman Tolchenov
committed
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/IPeakFunction.h"
#include "MantidKernel/Exception.h"
Roman Tolchenov
committed
#include "MantidKernel/ConfigService.h"
Roman Tolchenov
committed
Roman Tolchenov
committed
#include <boost/lexical_cast.hpp>
Roman Tolchenov
committed
#include <cmath>
namespace Mantid
{
namespace API
{
/** A Jacobian for individual functions
*/
class PartialJacobian1: public Jacobian
{
Jacobian* m_J; ///< pointer to the overall Jacobian
int m_iY0; ///< offset in the overall Jacobian for a particular function
public:
/** Constructor
* @param J A pointer to the overall Jacobian
* @param iY0 The data offset for a particular function
*/
PartialJacobian1(Jacobian* J,int iY0):m_J(J),m_iY0(iY0)
{}
/**
* Overridden Jacobian::set(...).
* @param iY The index of the data point
* @param iP The parameter index of an individual function.
* @param value The derivative value
*/
void set(int iY, int iP, double value)
{
m_J->set(m_iY0 + iY,iP,value);
}
};
Roman Tolchenov
committed
/// Default value for the peak radius
Roman Tolchenov
committed
int IPeakFunction::s_peakRadius = 5;
Roman Tolchenov
committed
/**
* Constructor. Sets peak radius to the value of curvefitting.peakRadius property
*/
IPeakFunction::IPeakFunction()
{
int peakRadius;
if ( Kernel::ConfigService::Instance().getValue("curvefitting.peakRadius",peakRadius) )
{
setPeakRadius(peakRadius);
}
}
Roman Tolchenov
committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* General implementation of the method for all peaks. Limits the peak evaluation to
* a certain number of FWHMs around the peak centre. The outside points are set to 0.
* Calls functionLocal() to compute the actual values
* @param out Output function values
* @param xValues X values for data points
* @param nData Number of data points
*/
void IPeakFunction::function(double* out, const double* xValues, const int& nData)const
{
double c = this->centre();
double dx = fabs(s_peakRadius*this->width());
int i0 = -1;
int n = 0;
for(int i = 0; i < nData; ++i)
{
if (fabs(xValues[i] - c) < dx)
{
if (i0 < 0) i0 = i;
++n;
}
else
{
out[i] = 0.;
}
}
if (i0 < 0 || n == 0) return;
this->functionLocal(out+i0,xValues+i0,n);
}
/**
* General implementation of the method for all peaks. Calculates derivatives only
* for a range of x values limited to a certain number of FWHM around the peak centre.
* For the points outside the range all derivatives are set to 0.
* Calls functionDerivLocal() to compute the actual values
* @param out Derivatives
* @param xValues X values for data points
* @param nData Number of data points
*/
void IPeakFunction::functionDeriv(Jacobian* out, const double* xValues, const int& nData)
{
double c = this->centre();
double dx = fabs(s_peakRadius*this->width());
int i0 = -1;
int n = 0;
for(int i = 0; i < nData; ++i)
{
if (fabs(xValues[i] - c) < dx)
{
if (i0 < 0) i0 = i;
++n;
}
else
{
for(int ip = 0; ip < this->nParams(); ++ip)
{
out->set(i,ip, 0.0);
}
}
}
if (i0 < 0 || n == 0) return;
PartialJacobian1 J(out,i0);
this->functionDerivLocal(&J,xValues+i0,n);
}
void IPeakFunction::setPeakRadius(const int& r)
{
if (r > 0)
{
s_peakRadius = r;
Roman Tolchenov
committed
std::string setting = boost::lexical_cast<std::string>(r);
Kernel::ConfigService::Instance().setString("curvefitting.peakRadius",setting);
Roman Tolchenov
committed
}
}
} // namespace API
} // namespace Mantid