123void SplineInterpolation::exec() {
126 const auto order =
static_cast<size_t>(derivOrder);
132 const size_t histNo = iws->getNumberHistograms();
133 const size_t binsNo = iws->blocksize();
134 const size_t histNoToMatch = mws->getNumberHistograms();
137 std::vector<MatrixWorkspace_sptr> derivs(histNo);
140 if (histNoToMatch > 1 && !iws->isCommonBins()) {
141 g_log.
warning() <<
"The workspace to interpolate doesn't have common bins, SplineInterpolation algorithm will use "
142 "the x-axis of the first spectrum.\n";
147 Progress pgress(
this, 0.0, 1.0, histNo);
151 for (
size_t i = 0; i < histNo; ++i) {
153 auto vAxis = std::make_unique<NumericAxis>(order);
154 for (
size_t j = 0; j < order; ++j) {
155 vAxis->setValue(j,
static_cast<int>(j) + 1.);
156 derivs[i]->setSharedX(j, mws->sharedX(0));
158 derivs[i]->replaceAxis(1, std::move(vAxis));
170 std::function<std::unique_ptr<Mantid::Kernel::Spline<double, double>>(size_t)> spline_creator;
174 spline_creator = [iwspt](
size_t i) {
175 return std::make_unique<Mantid::Kernel::CubicSpline<double, double>>(iwspt->x(i), iwspt->y(i));
181 if (!std::is_sorted(mwspt->x(0).begin(), mwspt->x(0).end())) {
182 throw std::runtime_error(
"X-axis of the workspace to match is not sorted. "
183 "Consider calling SortXAxis before.");
185 spline_creator = [iwspt](
size_t i) {
186 return std::make_unique<Mantid::Kernel::LinearSpline<double, double>>(iwspt->x(i), iwspt->y(i));
190 for (
size_t i = 0; i < histNo; ++i) {
195 auto spline = spline_creator(i);
199 std::span<double const> xInRange(mwspt->x(0).cbegin() + range.first, range.second - range.first);
200 auto &yNew = outputWorkspace->mutableY(i);
201 std::transform(xInRange.begin(), xInRange.end(), yNew.begin() + range.first,
202 [&spline](
double x) { return (*spline)(x); });
205 const double yFirst = iwspt->y(i).front();
206 const double yLast = iwspt->y(i).back();
207 std::fill(yNew.begin(), yNew.begin() + range.first, yFirst);
208 std::fill(yNew.begin() + range.second, yNew.end(), yLast);
211 for (
size_t j = 0; j < order; ++j) {
212 auto &deriv = derivs[i]->mutableY(j);
214 std::fill(deriv.begin(), deriv.begin() + range.first, 0.0);
215 std::fill(deriv.begin() + range.second, deriv.end(), 0.0);
217 std::transform(xInRange.begin(), xInRange.end(), deriv.begin() + range.first,
218 [&spline, j](
double x) { return spline->deriv(x, static_cast<unsigned int>(j + 1)); });
224 if (order > 0 && !
isDefault(
"OutputWorkspaceDeriv")) {
227 for (
size_t i = 0; i < histNo; ++i) {
228 wsg->addWorkspace(derivs[i]);
290 auto xAxisIn = iwspt->x(row);
291 std::sort(xAxisIn.begin(), xAxisIn.end());
292 const auto &xAxisOut = mwspt->x(0);
294 size_t firstIndex = 0;
295 size_t lastIndex = xAxisOut.size();
297 if (xAxisOut.empty() || xAxisIn.empty()) {
300 if (xAxisOut.front() >= xAxisIn.back()) {
301 lastIndex = firstIndex;
302 }
else if (xAxisOut.back() <= xAxisIn.front()) {
303 firstIndex = lastIndex;
306 std::find_if(xAxisOut.cbegin(), xAxisOut.cend(), [&xAxisIn](
double x) { return x >= xAxisIn.front(); });
307 firstIndex = std::distance(xAxisOut.begin(), start);
308 auto stop = std::find_if(start, xAxisOut.cend(), [&xAxisIn](
double x) { return x > xAxisIn.back(); });
309 lastIndex = std::distance(xAxisOut.begin(), stop);
314 ": Will perform flat extrapolation outside bin range: " +
std::to_string(firstIndex) +
" to " +
319 return std::make_pair(firstIndex, lastIndex);
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.