12#include "MantidHistogramData/LinearGenerator.h"
23using Mantid::Types::Event::TofEvent;
31class NoEventWorkspaceDeleting {
51 return "Integrates spectra in a matrix workspace at a set of points.";
60 "InputWorkspace",
"",
Direction::Input, std::make_shared<API::WorkspaceUnitValidator>(
"Momentum")),
61 "An input workspace. Must have units of Momentum");
62 auto validator = std::make_shared<Kernel::BoundedValidator<int>>();
63 validator->setLower(2);
64 declareProperty(
"NPoints", 1000, validator,
"Number of points per output spectrum.");
66 "An output workspace.");
74 size_t nX =
static_cast<size_t>(
static_cast<int>(
getProperty(
"NPoints")));
95 throw std::runtime_error(
"Input workspace has no data.");
100 if (nX > maxPoints) {
106 throw std::runtime_error(
"Failed to create output."
107 "Output spectra should have at least two points.");
112 std::shared_ptr<const API::MatrixWorkspace>(&inputWS, NoEventWorkspaceDeleting()), nSpec, nX, nX);
116 double xMin = inputWS.
getXMin();
117 double xMax = inputWS.
getXMax();
118 double dx = (xMax - xMin) /
static_cast<double>(nX - 1);
119 const auto &
x = ws->x(0);
121 ws->setPoints(0, Points(
x.size(), LinearGenerator(xMin, dx)));
122 for (
size_t sp = 1; sp < nSpec; ++sp)
123 ws->setSharedX(sp, ws->sharedX(0));
142 integrateSpectraEvents<DataObjects::WeightedEventNoTime>(*eventWS, integrWS);
145 integrateSpectraEvents<DataObjects::WeightedEvent>(*eventWS, integrWS);
148 integrateSpectraEvents<TofEvent>(*eventWS, integrWS);
162template <
class EventType>
169 auto &
X = integrWS.
x(0);
171 for (
size_t sp = 0; sp < nSpec; ++sp) {
172 const std::vector<EventType> *el;
177 auto x =
X.begin() + 1;
180 for (
auto evnt = el->begin(); evnt != el->end(); ++evnt) {
181 double tof = evnt->tof();
182 while (
x !=
X.end() && *
x < tof) {
189 sum += evnt->weight();
193 while (
x !=
X.end()) {
228 auto &
X = integrWS.
x(0);
231 for (
size_t sp = 0; sp < nSpec; ++sp) {
232 auto &inX = inputWS.
x(sp);
233 auto inY = inputWS.
counts(sp);
236 auto outY = integrWS.
mutableY(sp).begin();
242 auto inXbegin = inX.begin();
243 auto inXend = inX.end();
246 for (
auto outX =
X.begin() + 1; outX !=
X.end(); ++outX, ++outY) {
255 const double &lowerBound = *(outX - 1);
256 double upperBound = *outX;
260 auto x1 = std::lower_bound(x0, inXend, upperBound);
276 if (*x0 < lowerBound) {
281 const double leftX = lowerBound;
282 const double rightX = std::min(upperBound, *(x0 + 1));
284 auto i =
static_cast<size_t>(std::distance(inXbegin, x0));
286 sum += inY[i] * (rightX - leftX) / (*(x0 + 1) - *x0);
290 if (rightX == upperBound) {
300 auto i0 =
static_cast<size_t>(std::distance(inXbegin, x0));
301 auto i1 =
static_cast<size_t>(std::distance(inXbegin, x1));
302 if (*x1 > upperBound)
304 for (
auto i = i0; i < i1; ++i) {
310 if (*x1 > upperBound) {
314 const double leftX = *(x1 - 1);
315 const double rightX = upperBound;
317 auto i =
static_cast<size_t>(std::distance(inXbegin, x1));
319 sum += inY[i - 1] * (rightX - leftX) / (*x1 - *(x1 - 1));
345 auto &
X = integrWS.
x(0);
348 for (
size_t sp = 0; sp < nSpec; ++sp) {
349 auto &inX = inputWS.
x(sp);
350 auto &inY = inputWS.
y(sp);
353 auto outY = integrWS.
mutableY(sp).begin();
359 auto inXbegin = inX.begin();
360 auto inXend = inX.end();
364 for (
auto outX =
X.begin() + 1; outX !=
X.end(); ++outX, ++outY) {
373 const double &lowerBound = *(outX - 1);
374 double upperBound = *outX;
378 auto x1 = std::lower_bound(x0, inXend, upperBound);
394 if (*x0 < lowerBound) {
399 const double leftX = lowerBound;
400 const double rightX = std::min(upperBound, *(x0 + 1));
402 auto i =
static_cast<size_t>(std::distance(inXbegin, x0));
404 double dy_dx = (inY[i + 1] - inY[i]) / (*(x0 + 1) - *x0);
407 sum += (inY[i] + 0.5 * dy_dx * (leftX + rightX - 2 * (*(x0)))) * (rightX - leftX);
411 if (rightX == upperBound) {
421 auto i0 =
static_cast<size_t>(std::distance(inXbegin, x0));
422 auto i1 =
static_cast<size_t>(std::distance(inXbegin, x1));
423 if (*x1 > upperBound)
426 for (
auto i = i0; i < i1; ++i) {
427 sum += (inY[i] + inY[i + 1]) / 2 * (inX[i + 1] - inX[i]);
432 if (*x1 > upperBound) {
436 const double leftX = *(x1 - 1);
437 const double rightX = upperBound;
439 auto i =
static_cast<size_t>(std::distance(inXbegin, x1));
441 double dy_dx = (inY[i] - inY[i - 1]) / (*x1 - *(x1 - 1));
444 sum += (inY[i - 1] + 0.5 * dy_dx * (rightX - *(x1 - 1))) * (rightX - leftX);
#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.
virtual std::size_t blocksize() const =0
Returns the size of each block of data returned by the dataY accessors.
virtual double getXMin() const
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
const HistogramData::HistogramX & x(const size_t index) const
HistogramData::Counts counts(const size_t index) const
virtual double getXMax() const
HistogramData::HistogramY & mutableY(const size_t index) &
const HistogramData::HistogramY & y(const size_t index) const
virtual bool isHistogramData() const
Returns true if the workspace contains data in histogram form (as opposed to point-like)
A property class for workspaces.
std::size_t getNumberEvents() const override
Return the number of events in the list.
This class is intended to fulfill the design specified in <https://github.com/mantidproject/documents...
EventList & getSpectrum(const size_t index) override
Return the underlying ISpectrum ptr at the given workspace index.
std::size_t getNumberHistograms() const override
Get the number of histograms, usually the same as the number of pixels or detectors.
void sortAll(EventSortType sortType, Mantid::API::Progress *prog) const
Mantid::API::EventType getEventType() const override
Get the EventType of the most-specialized EventList in the workspace.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
const std::string name() const override
Algorithms name for identification.
void integrateSpectraHistograms(const API::MatrixWorkspace &inputWS, API::MatrixWorkspace &integrWS) const
Integrate spectra in inputWS at x-values in integrWS and save the results in y-vectors of integrWS.
int version() const override
Algorithm's version for identification.
void integrateSpectraEvents(const DataObjects::EventWorkspace &inputWS, API::MatrixWorkspace &integrWS) const
Integrate spectra in inputWS at x-values in integrWS and save the results in y-vectors of integrWS.
void init() override
Initialize the algorithm's properties.
void integrateSpectra(const API::MatrixWorkspace &inputWS, API::MatrixWorkspace &integrWS) const
Integrate spectra in inputWS at x-values in integrWS and save the results in y-vectors of integrWS.
std::shared_ptr< API::MatrixWorkspace > createOutputWorkspace(const API::MatrixWorkspace &inputWS, size_t nX) const
Create an empty output workspace with required dimensions and defined x-values.
size_t getMaxNumberOfPoints(const API::MatrixWorkspace &inputWS) const
Calculate the maximun number of points in the integration grid.
const std::string category() const override
Algorithm's category for identification.
void integrateSpectraMatrix(const API::MatrixWorkspace &inputWS, API::MatrixWorkspace &integrWS) const
Integrate spectra in inputWS at x-values in integrWS and save the results in y-vectors of integrWS.
void integrateSpectraPointData(const API::MatrixWorkspace &inputWS, API::MatrixWorkspace &integrWS) const
Integrate spectra in inputWS at x-values in integrWS and save the results in y-vectors of integrWS.
void exec() override
Execute the algorithm.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
DLLExport void getEventsFrom(EventList &el, std::vector< Types::Event::TofEvent > *&events)
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.
@ Output
An output workspace.