16#include <gsl/gsl_bspline.h>
17#include <gsl/gsl_multifit.h>
18#include <gsl/gsl_statistics.h>
24using namespace Kernel;
28void SplineBackground::init() {
30 "The name of the input workspace.");
32 "The name to use for the output workspace.");
33 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
34 mustBePositive->setLower(0);
35 declareProperty(
"WorkspaceIndex", 0, mustBePositive,
"The index of the spectrum for fitting.");
42void SplineBackground::exec() {
48 if (spec >
static_cast<int>(inWS->getNumberHistograms()))
49 throw std::out_of_range(
"WorkspaceIndex is out of range.");
54 if (numBins < ncoeffs) {
55 throw std::out_of_range(
"Too many basis functions (NCoeff)");
61 const auto &xVals = inWS->x(spec);
62 setupSpline(xVals.front(), xVals.back(), numBins, ncoeffs);
89 const auto &yInputVals = ws->
y(spec);
90 size_t ySize = yInputVals.size();
95 ySize -=
static_cast<int>(ws->
maskedBins(spec).size());
108void SplineBackground::addWsDataToSpline(
const API::MatrixWorkspace *ws,
const size_t specNum,
int expectedNumBins) {
109 const auto xPointData = ws->
points(specNum);
110 const auto &yInputVals = ws->
y(specNum);
111 const auto &eInputVals = ws->
e(specNum);
115 std::vector<bool> masked(yInputVals.size(),
false);
117 const auto &maskedBinsMap = ws->
maskedBins(specNum);
118 for (
const auto &maskedBin : maskedBinsMap) {
119 masked[maskedBin.first] =
true;
123 int numUnmaskedBins = 0;
124 for (
size_t i = 0; i < yInputVals.size(); ++i) {
125 if (hasMaskedBins && masked[i])
134 if (expectedNumBins != numUnmaskedBins) {
136 throw std::runtime_error(
"Assertion failed: number of unmasked bins found was"
137 " not equal to the number that was calculated");
148void SplineBackground::allocateBSplinePointers(
int numBins,
int ncoeffs) {
150 const int nbreak = ncoeffs - (k - 2);
153 throw std::out_of_range(
"Too low NCoeff");
161 sp.
xData = gsl_vector_alloc(numBins);
162 sp.
yData = gsl_vector_alloc(numBins);
163 sp.
fittedWs = gsl_matrix_alloc(numBins, ncoeffs);
166 sp.
covariance = gsl_matrix_alloc(ncoeffs, ncoeffs);
179double SplineBackground::calculateBinWeight(
double errValue) {
180 double outBinWeight = -1;
181 if (errValue <= 0 || !std::isfinite(errValue)) {
186 g_log.
warning(
"Spline background found an error value of 0 or less on an unmasked"
187 " bin. This bin will have no weight during the fitting process");
190 g_log.
warning(
"Spline background found an error value of nan or inf on an"
191 " unmasked bin. This bin will have no weight during the fitting"
196 outBinWeight = 1. / (errValue * errValue);
204void SplineBackground::freeBSplinePointers() {
212 gsl_vector_free(sp.
xData);
214 gsl_vector_free(sp.
yData);
238 const auto &xInputVals = ws->x(spec);
239 const auto &yInputVals = ws->y(spec);
243 outWS->getSpectrum(0).setSpectrumNo(ws->getSpectrum(spec).getSpectrumNo());
246 auto &yVals = outWS->mutableY(0);
247 auto &eVals = outWS->mutableE(0);
249 for (
size_t i = 0; i < yInputVals.size(); i++) {
250 double xi = xInputVals[i];
257 outWS->setSharedX(0, ws->sharedX(0));
269void SplineBackground::setupSpline(
double xMin,
double xMax,
int numBins,
int ncoeff) {
274 for (
int i = 0; i < numBins; ++i) {
281 for (
int j = 0; j < ncoeff; ++j) {
#define DECLARE_ALGORITHM(classname)
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Base MatrixWorkspace Abstract Class.
const MaskList & maskedBins(const size_t &workspaceIndex) const
Returns the list of masked bins for a spectrum.
const HistogramData::HistogramE & e(const size_t index) const
HistogramData::Points points(const size_t index) const
bool hasMaskedBins(const size_t &workspaceIndex) const
Does this spectrum contain any masked bins.
const HistogramData::HistogramY & y(const size_t index) const
A property class for workspaces.
void addWsDataToSpline(const API::MatrixWorkspace *ws, const size_t specNum, int expectedNumBins)
Adds data from the workspace to the GSL vectors for later processing.
API::MatrixWorkspace_sptr saveSplineOutput(const API::MatrixWorkspace_sptr &ws, const size_t spec)
Gets the values from the fitted GSL, and creates a clone of input workspace with new values.
void allocateBSplinePointers(int numBins, int ncoeffs)
Allocates various pointers used within GSL.
size_t calculateNumBinsToProcess(const API::MatrixWorkspace *ws)
Calculates the number on unmasked bins to process.
void freeBSplinePointers()
Deallocates various pointers within GSL.
bSplinePointers m_splinePointers
void setupSpline(double xMin, double xMax, int numBins, int ncoeff)
Sets up the splines for later fitting.
double calculateBinWeight(double errValue)
Calculates the bin weight using the error values in the WS.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
Struct holding various pointers required by GSL.
gsl_vector * coefficients
gsl_bspline_workspace * splineToProcess
gsl_multifit_linear_workspace * weightedLinearFitWs
gsl_vector * inputSplineWs
@ Input
An input workspace.
@ Output
An output workspace.