40bool emptyBinning(
const std::vector<double> &binning) {
return binning.empty(); }
47bool integrationBinning(
const std::vector<double> &binning) {
return binning.size() == 2 && binning[0] < binning[1]; }
54bool similarBinning(
const std::vector<double> &binning) {
return binning.size() == 3 && binning[1] == 0.0; }
61std::string checkBinning(
const std::vector<double> &binning) {
63 if (!emptyBinning(binning)) {
64 if (binning.size() == 3) {
65 const double step = binning[1];
67 error =
"Only step size zero is allowed. Denotes copy of original step "
68 "size for that dimension.";
70 auto min = binning[0];
71 auto max = binning[2];
73 error =
"Min must be < max limit for binning";
77 }
else if (binning.size() == 2) {
78 auto min = binning[0];
79 auto max = binning[1];
81 error =
"Min must be < max limit for binning";
84 error =
"Unknown binning prameters for dimension.";
98 const auto down = std::floor(
position);
101 const auto nearest = diffUp < diffDown ? up : down;
104 const auto deviation =
fabs((nearest -
position) / binWidth);
108 coordinate = nearest;
133 auto minBin = (pMin - offset) / width;
134 auto maxBin = (pMax - offset) / width;
138 minBin = getPrecisionCorrectedCoordinate(minBin, width);
139 maxBin = getPrecisionCorrectedCoordinate(maxBin, width);
140 auto snappedPMin = width * std::floor(minBin);
141 auto snappedPMax = width * std::ceil(maxBin);
144 snappedPMax += offset;
145 snappedPMin += offset;
147 if (snappedPMin < dimension->getMinimum()) {
148 snappedPMin = dimension->getMinimum();
149 }
else if (pMin != snappedPMin) {
150 std::stringstream buffer;
151 buffer <<
"Rounding min from: " << pMin <<
" to the nearest whole width at: " << snappedPMin;
155 if (snappedPMax > dimension->getMaximum()) {
156 snappedPMax = dimension->getMaximum();
157 }
else if (pMax != snappedPMax) {
158 std::stringstream buffer;
159 buffer <<
"Rounding max from: " << pMax <<
" to the nearest whole width at: " << snappedPMax;
167 numberOfBins = std::lround((pMax - pMin) / width);
181 std::vector<Mantid::Geometry::IMDDimension_sptr> dimensions(nDims);
182 for (
size_t i = 0; i < nDims; ++i) {
185 auto outDim = std::make_shared<MDHistoDimension>(inDim.get());
187 if (i < pbins.size() && integrationBinning(pbins[i])) {
188 auto binning = pbins[i];
191 }
else if (i < pbins.size() && similarBinning(pbins[i])) {
192 auto binning = pbins[i];
198 setMinMaxBins(pMin, pMax, numberOfBins, inDim, logger);
203 dimensions[i] = outDim;
205 return std::make_shared<MDHistoWorkspace>(dimensions);
218 double &sumSignal,
double &sumSQErrors,
double &sumNEvents) {
222 sumSignal += weight * iterator->
getSignal();
251 return "Performs axis aligned integration of MDHistoWorkspaces";
259 "An input workspace.");
261 const std::vector<double> defaultBinning;
269 "An output workspace.");
277 const size_t nDims = inWS->getNumDims();
278 std::vector<std::vector<double>> pbins(5);
285 const size_t emptyCount = std::count_if(pbins.begin(), pbins.end(), emptyBinning);
286 if (emptyCount == pbins.size()) {
289 this->
setProperty(
"OutputWorkspace", std::shared_ptr<IMDHistoWorkspace>(inWS->clone()));
301 std::vector<Mantid::coord_t> binWidthsOut(nDims);
302 std::vector<int> widthVector(nDims);
303 for (
size_t i = 0; i < nDims; ++i) {
304 binWidthsOut[i] = outWS->getDimension(i)->getBinWidth();
315 widthVector[i] = 2 *
static_cast<int>(std::ceil(binWidthsOut[i] / inWS->getDimension(i)->getBinWidth()));
317 if (widthVector[i] % 2 == 0) {
325 auto outIterators = outWS->createIterators(nThreads,
nullptr);
328 for (
int i = 0; i < int(outIterators.size()); ++i) {
332 throw std::logic_error(
"Failed to cast iterator to MDHistoWorkspaceIterator");
340 std::vector<Mantid::coord_t> mins(nDims);
341 std::vector<Mantid::coord_t> maxs(nDims);
342 for (
size_t j = 0; j < nDims; ++j) {
344 mins[j] = outIteratorCenter[j] -
delta;
345 maxs[j] = outIteratorCenter[j] +
delta;
349 double sumSignal = 0;
350 double sumSQErrors = 0;
351 double sumNEvents = 0;
355 auto iterator = inWS->createIterator();
358 throw std::runtime_error(
"Could not convert IMDIterator to a MDHistoWorkspaceIterator");
368 inIterator->jumpToNearest(outIteratorCenter);
374 auto neighbourIndexes = inIterator->findNeighbourIndexesByWidth(widthVector);
375 for (
auto neighbourIndex : neighbourIndexes) {
376 inIterator->jumpTo(neighbourIndex);
380 const size_t iteratorIndex = outIterator->getLinearIndex();
381 outWS->setSignalAt(iteratorIndex, sumSignal);
382 outWS->setErrorSquaredAt(iteratorIndex, sumSQErrors);
383 outWS->setNumEventsAt(iteratorIndex, sumNEvents);
386 }
while (outIterator->next());
390 outWS->setDisplayNormalization(inWS->displayNormalizationHisto());
401 std::map<std::string, std::string> errors;
403 for (
int i = 1; i < 6; ++i) {
404 std::stringstream propBuffer;
405 propBuffer <<
"P" << i <<
"Bin";
406 std::string propertyName = propBuffer.str();
407 std::vector<double> binning = this->getProperty(propertyName);
408 std::string result = checkBinning(binning);
409 if (!result.empty()) {
410 errors.emplace(propertyName, result);
#define DECLARE_ALGORITHM(classname)
MDHistoWorkspace_sptr createShapedOutput(IMDHistoWorkspace const *const inWS, std::vector< std::vector< double > > pbins, Logger &logger)
Create the output workspace in the right shape.
void performWeightedSum(MDHistoWorkspaceIterator const *const iterator, const MDBoxImplicitFunction &box, double &sumSignal, double &sumSQErrors, double &sumNEvents)
Perform a weighted sum at the iterator position.
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_FOR_NO_WSP_CHECK()
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
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.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Abstract interface to MDHistoWorkspace, for use in exposing to Python.
virtual std::shared_ptr< const Mantid::Geometry::IMDDimension > getDimension(size_t index) const
Get a dimension.
virtual size_t getNumDims() const
Helper class for reporting progress from algorithms.
A property class for workspaces.
An implementation of IMDIterator that iterates through a MDHistoWorkspace.
signal_t getSignal() const override
Returns the signal for this box, same as innerSignal.
virtual signal_t getNumEventsFraction() const
Returns the number of events/points contained in this box.
VecMDExtents getBoxExtents() const
Get the extents in n-dimensions corresponding to the position of the box of the current iterator.
signal_t getError() const override
Returns the error for this box, same as innerError.
bool getIsMasked() const override
Returns true if masking is used.
General N-dimensional box implicit function: Defines a cuboid in N dimensions that is aligned with th...
double fraction(const std::vector< boost::tuple< Mantid::coord_t, Mantid::coord_t > > &boxExtents) const
Calculate the fraction of a box residing inside this implicit function.
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
The Logger class is in charge of the publishing messages from the framework through various channels.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
IntegrateMDHistoWorkspace : Algorithm to perform axis aligned integration of an MDHistoWorkspace.
int version() const override
Algorithm's version for identification.
std::map< std::string, std::string > validateInputs() override
Overriden validate inputs.
const std::string category() const override
Algorithm's category for identification.
void exec() override
Execute the algorithm.
const std::string name() const override
Algorithms name for identification.
void init() override
Initialize the algorithm's properties.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
std::shared_ptr< IMDHistoWorkspace > IMDHistoWorkspace_sptr
shared pointer to Mantid::API::IMDHistoWorkspace
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
std::shared_ptr< const IMDDimension > IMDDimension_const_sptr
Shared Pointer to const IMDDimension.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.
@ Output
An output workspace.