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).rawData(),
176 iwspt->y(i).rawData());
182 if (!std::is_sorted(mwspt->x(0).rawData().begin(), mwspt->x(0).rawData().end())) {
183 throw std::runtime_error(
"X-axis of the workspace to match is not sorted. "
184 "Consider calling SortXAxis before.");
186 spline_creator = [iwspt](
size_t i) {
187 return std::make_unique<Mantid::Kernel::LinearSpline<double, double>>(iwspt->x(i).rawData(),
188 iwspt->y(i).rawData());
192 for (
size_t i = 0; i < histNo; ++i) {
197 auto spline = spline_creator(i);
201 std::span<double const> xInRange(mwspt->x(0).cbegin() + range.first, range.second - range.first);
202 auto &yNew = outputWorkspace->mutableY(i);
203 std::transform(xInRange.begin(), xInRange.end(), yNew.begin() + range.first,
204 [&spline](
double x) { return (*spline)(x); });
207 const double yFirst = iwspt->y(i).front();
208 const double yLast = iwspt->y(i).back();
209 std::fill(yNew.begin(), yNew.begin() + range.first, yFirst);
210 std::fill(yNew.begin() + range.second, yNew.end(), yLast);
213 for (
size_t j = 0; j < order; ++j) {
214 auto &deriv = derivs[i]->mutableY(j);
216 std::fill(deriv.begin(), deriv.begin() + range.first, 0.0);
217 std::fill(deriv.begin() + range.second, deriv.end(), 0.0);
219 std::transform(xInRange.begin(), xInRange.end(), deriv.begin() + range.first,
220 [&spline, j](
double x) { return spline->deriv(x, static_cast<unsigned int>(j + 1)); });
226 if (order > 0 && !
isDefault(
"OutputWorkspaceDeriv")) {
229 for (
size_t i = 0; i < histNo; ++i) {
230 wsg->addWorkspace(derivs[i]);
291 auto xAxisIn = iwspt->x(row).rawData();
292 std::sort(xAxisIn.begin(), xAxisIn.end());
293 const auto &xAxisOut = mwspt->x(0).rawData();
295 size_t firstIndex = 0;
296 size_t lastIndex = xAxisOut.size();
298 if (xAxisOut.empty() || xAxisIn.empty()) {
301 if (xAxisOut.front() >= xAxisIn.back()) {
302 lastIndex = firstIndex;
303 }
else if (xAxisOut.back() <= xAxisIn.front()) {
304 firstIndex = lastIndex;
307 std::find_if(xAxisOut.cbegin(), xAxisOut.cend(), [&xAxisIn](
double x) { return x >= xAxisIn.front(); });
308 firstIndex = std::distance(xAxisOut.begin(), start);
309 auto stop = std::find_if(start, xAxisOut.cend(), [&xAxisIn](
double x) { return x > xAxisIn.back(); });
310 lastIndex = std::distance(xAxisOut.begin(), stop);
315 ": Will perform flat extrapolation outside bin range: " +
std::to_string(firstIndex) +
" to " +
320 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.