25using namespace Kernel;
26using Functions::BSpline;
30SplineSmoothing::SplineSmoothing()
31 : M_START_SMOOTH_POINTS(10), m_cspline(
std::make_shared<
BSpline>()), m_inputWorkspace(),
32 m_inputWorkspacePointData(), m_derivativeWorkspaceGroup(new
WorkspaceGroup) {}
36const std::string SplineSmoothing::name()
const {
return "SplineSmoothing"; }
39int SplineSmoothing::version()
const {
return 1; }
42const std::string SplineSmoothing::category()
const {
43 return "Optimization;CorrectionFunctions\\BackgroundCorrections";
49void SplineSmoothing::init() {
51 "The workspace on which to perform the smoothing algorithm.");
54 "The workspace containing the calculated points");
58 "The workspace containing the calculated derivatives");
60 auto validator = std::make_shared<BoundedValidator<int>>();
61 validator->setLower(0);
62 validator->setUpper(2);
63 declareProperty(
"DerivOrder", 0, validator,
"Order to derivatives to calculate.");
65 auto errorSizeValidator = std::make_shared<BoundedValidator<double>>();
66 errorSizeValidator->setLower(0.0);
67 declareProperty(
"Error", 0.05, errorSizeValidator,
"The amount of error we wish to tolerate in smoothing");
69 auto numOfBreaks = std::make_shared<BoundedValidator<int>>();
70 numOfBreaks->setLower(0);
72 "To set the positions of the break-points, default 0 "
73 "equally spaced real values in interval 0.0 - 1.0");
79void SplineSmoothing::exec() {
83 int order =
static_cast<int>(
getProperty(
"DerivOrder"));
89 throw std::runtime_error(
"You must specify an output workspace for the spline derivatives.");
92 Progress pgress(
this, 0.0, 1.0, histNo);
93 for (
int i = 0; i < histNo; ++i) {
114void SplineSmoothing::smoothSpectrum(
const int index) {
116 m_cspline->setAttributeValue(
"Uniform",
false);
132void SplineSmoothing::calculateSpectrumDerivatives(
const int index,
const int order) {
136 for (
int j = 0; j < order; ++j) {
153 fit->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(
m_cspline));
154 fit->setProperty(
"InputWorkspace", ws);
155 fit->setProperty(
"MaxIterations", 5);
156 fit->setProperty(
"WorkspaceIndex", row);
169 const int size)
const {
175 auto tAxis = std::make_unique<API::TextAxis>(size);
176 for (
int i = 0; i < size; ++i) {
178 tAxis->setLabel(i,
"Y" +
index);
180 outputWorkspace->replaceAxis(1, std::move(tAxis));
182 return outputWorkspace;
193 alg->setProperty(
"InputWorkspace",
workspace);
195 return alg->getProperty(
"OutputWorkspace");
205void SplineSmoothing::convertToHistogram() {
222 const auto &xIn = inputWorkspace.
x(row);
223 const size_t nData = xIn.size();
224 const double *xValues = &(xIn[0]);
225 double *yValues = &(outputWorkspace.
mutableY(row)[0]);
228 m_cspline->function1D(yValues, xValues, nData);
240 const int order,
const size_t row)
const {
241 const auto &xIn = inputWorkspace.
x(row);
242 const double *xValues = &(xIn[0]);
243 double *yValues = &(outputWorkspace.
mutableY(order - 1)[0]);
244 const size_t nData = xIn.size();
246 m_cspline->derivative1D(yValues, xValues, nData, order);
258bool SplineSmoothing::checkSmoothingAccuracy(
const int start,
const int end,
const double *ys,
259 const double *ysmooth)
const {
263 for (
int i = start; i < end; ++i) {
266 double ydiff =
fabs(ys[i] - ysmooth[i]);
267 if (ydiff >
error && (end - start) > 1) {
281void SplineSmoothing::addSmoothingPoints(
const std::set<int> &points,
const double *xs,
const double *ys)
const {
283 auto num_points =
static_cast<int>(points.size());
284 std::vector<double> breakPoints;
285 breakPoints.reserve(num_points);
288 std::transform(points.begin(), points.end(), std::back_inserter(breakPoints),
289 [&xs](
const auto &point) { return xs[point]; });
296 for (
auto const &point : points) {
309void SplineSmoothing::selectSmoothingPoints(
const MatrixWorkspace &inputWorkspace,
const size_t row) {
310 std::set<int> smoothPts;
311 const auto &xs = inputWorkspace.
x(row);
312 const auto &ys = inputWorkspace.
y(row);
315 int maxBreaks =
static_cast<int>(
getProperty(
"MaxNumberOfBreaks"));
317 auto xSize =
static_cast<int>(xs.size());
323 bool incBreaks =
false;
325 if (maxBreaks != 0) {
327 int numSmoothPts(maxBreaks);
328 delta = xSize / numSmoothPts;
333 delta = xSize / numSmoothPts;
336 for (
int i = 0; i < xSize; i +=
delta) {
339 smoothPts.insert(xSize - 1);
345 if (smoothPts.size() >
static_cast<unsigned>(maxBreaks + 2)) {
350 if (smoothPts.size() >= xs.size() - 1) {
359 std::vector<double> ysmooth(xSize);
360 m_cspline->function1D(ysmooth.data(), &xs[0], xSize);
363 auto iter = smoothPts.cbegin();
366 for (++iter; iter != smoothPts.cend(); ++iter) {
376 smoothPts.insert((start + end) / 2);
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Attribute is a non-fitting parameter.
Base MatrixWorkspace Abstract Class.
const HistogramData::HistogramX & x(const size_t index) const
HistogramData::HistogramY & mutableY(const size_t index) &
const HistogramData::HistogramY & y(const size_t index) const
Helper class for reporting progress from algorithms.
Class to hold a set of workspaces.
A property class for workspaces.
bool checkSmoothingAccuracy(const int start, const int end, const double *ys, const double *ysmooth) const
check if the difference between smoothing points and data points is within a certain error bound
void selectSmoothingPoints(const API::MatrixWorkspace &inputWorkspace, const size_t row)
choose points to define a spline and smooth the data
std::shared_ptr< Functions::BSpline > m_cspline
CubicSpline member used to perform smoothing.
void calculateDerivatives(const API::MatrixWorkspace &inputWorkspace, API::MatrixWorkspace &outputWorkspace, const int order, const size_t row) const
calculate the derivatives for a set of points on the spline
API::MatrixWorkspace_sptr convertBinnedData(API::MatrixWorkspace_sptr workspace)
Converts histogram data to point data later processing convert a binned workspace to point data.
void addSmoothingPoints(const std::set< int > &points, const double *xs, const double *ys) const
add a set of smoothing points to the spline
API::MatrixWorkspace_sptr m_inputWorkspace
pointer to the input workspace
const int M_START_SMOOTH_POINTS
number of smoothing points to start with
API::MatrixWorkspace_sptr m_outputWorkspace
pointer to the smoothed output workspace
void calculateSmoothing(const API::MatrixWorkspace &inputWorkspace, API::MatrixWorkspace &outputWorkspace, const size_t row) const
calculate the spline based on the smoothing points chosen
API::MatrixWorkspace_sptr m_inputWorkspacePointData
pointer to the input workspace converted to point data
void convertToHistogram()
Handle converting point data back to histograms.
void performAdditionalFitting(const API::MatrixWorkspace_sptr &ws, const int row)
Use an existing fit function to tidy smoothing.
API::MatrixWorkspace_sptr setupOutputWorkspace(const API::MatrixWorkspace_sptr &inws, const int size) const
setup an output workspace using meta data from inws and taking a number of spectra
void calculateSpectrumDerivatives(const int index, const int order)
calculate derivatives for a single spectrum
API::WorkspaceGroup_sptr m_derivativeWorkspaceGroup
pointer to the output workspace group of derivatives
void smoothSpectrum(const int index)
smooth a single spectrum of the workspace
A wrapper around Eigen functions implementing a B-spline.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
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
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.