8#include "MantidHistogramData/Exception.h"
9#include "MantidHistogramData/Rebin.h"
27using namespace Kernel;
29using DataObjects::EventList;
30using DataObjects::EventWorkspace;
33using HistogramData::BinEdges;
34using HistogramData::Frequencies;
35using HistogramData::FrequencyStandardDeviations;
36using HistogramData::Histogram;
37using HistogramData::Exception::InvalidBinEdgesError;
52 std::vector<double> rbParams;
54 if (inParams.size() >= 3) {
57 }
else if (inParams.size() == 1) {
62 logger.
information() <<
"Using the current min and max as default " << xmin <<
", " << xmax <<
'\n';
65 rbParams[1] = inParams[0];
67 if ((rbParams[1] < 0.) && (xmin < 0.) && (xmax > 0.)) {
68 std::stringstream msg;
69 msg <<
"Cannot create logarithmic binning that changes sign (xmin=" << xmin <<
", xmax=" << xmax <<
")";
70 throw std::runtime_error(msg.str());
82 std::map<std::string, std::string> helpMessages;
87 double roughEstimate = 0;
90 const std::vector<double> params =
getProperty(
"Params");
93 double eulerMascheroni = 0.57721;
96 for (
size_t i = 0; i < params.size() - 2; i += 2) {
97 double upperLimit = params[i + 2];
98 double lowerLimit = params[i];
99 double factor = params[i + 1];
102 helpMessages[
"Params"] =
"Provided width value cannot be negative for inverse power binning.";
107 roughEstimate += std::exp((upperLimit - lowerLimit) / factor - eulerMascheroni);
109 roughEstimate += std::pow(((upperLimit - lowerLimit) / factor) * (1 - power) + 1, 1 / (1 - power));
115 if (roughEstimate > 10000) {
116 helpMessages[
"Power"] =
"This binning is expected to give more than 10000 bins.";
127 "Workspace containing the input data");
129 "The name to give the output workspace");
132 "A comma separated list of first bin boundary, width, last bin boundary. "
133 "Optionally this can be followed by a comma and more widths and last boundary pairs. "
134 "Optionally this can also be a single number, which is the bin width. In this case, the boundary of "
135 "binning will be determined by minimum and maximum TOF values among all events, or previous binning "
136 "boundary, in case of event Workspace, or non-event Workspace, respectively. "
137 "Negative width values indicate logarithmic binning.");
140 "Keep the output workspace as an EventWorkspace, if the input has events. If the input and output "
141 "EventWorkspace names are the same, only the X bins are set, which is very quick. If false, then the "
142 "workspace gets converted to a Workspace2D histogram.");
144 declareProperty(
"FullBinsOnly",
false,
"Omit the final bin if its width is smaller than the step size");
147 "Ignore errors related to zero/negative bin widths in input/output workspaces. When ignored, the "
148 "signal and errors are set to zero");
151 "UseReverseLogarithmic",
false,
152 "For logarithmic intervals, the splitting starts from the end and goes back to the start, ie the bins are bigger "
153 "at the start getting exponentially smaller until they reach the end. For these bins, the FullBinsOnly flag is "
156 auto powerValidator = std::make_shared<Mantid::Kernel::BoundedValidator<double>>();
157 powerValidator->setLower(0);
158 powerValidator->setUpper(1);
160 "Splits the interval in bins which actual width is equal to requested width / (i ^ power); default "
161 "is linear. Power must be between 0 and 1.");
175 bool PreserveEvents =
getProperty(
"PreserveEvents");
178 bool inPlace = (inputWS == outputWS);
182 const bool dist = inputWS->isDistribution();
183 const bool isHist = inputWS->isHistogramData();
186 const auto histnumber =
static_cast<int>(inputWS->getNumberHistograms());
189 bool useReverseLog =
getProperty(
"UseReverseLogarithmic");
194 inputWS->getXMinMax(xmin, xmax);
196 HistogramData::BinEdges XValues_new(0);
199 xmin, xmax, useReverseLog, power));
204 if (eventInputWS !=
nullptr) {
207 if (PreserveEvents) {
209 outputWS = inputWS->clone();
211 auto eventOutputWS = std::dynamic_pointer_cast<EventWorkspace>(outputWS);
214 eventOutputWS->setAllX(XValues_new);
217 g_log.
information() <<
"Creating a Workspace2D from the EventWorkspace " << eventInputWS->getName() <<
".\n";
218 outputWS = DataObjects::create<DataObjects::Workspace2D>(*inputWS, histnumber, XValues_new);
221 Progress prog(
this, 0.0, 1.0, histnumber);
225 for (
int i = 0; i < histnumber; ++i) {
228 const EventList &el = eventInputWS->getSpectrum(i);
231 el.generateHistogram(XValues_new.rawData(), y_data, e_data);
234 outputWS->mutableY(i) = y_data;
235 outputWS->mutableE(i) = e_data;
244 for (
int i = 1; i < inputWS->axes(); i++) {
245 outputWS->replaceAxis(i, std::unique_ptr<Axis>(inputWS->getAxis(i)->clone(outputWS.get())));
246 outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
250 for (
int i = 0; i < outputWS->axes(); ++i)
251 outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
252 outputWS->setYUnit(eventInputWS->YUnit());
253 outputWS->setYUnitLabel(eventInputWS->YUnitLabel());
268 ChildAlg->initialize();
269 ChildAlg->setProperty(
"InputWorkspace", inputWS);
271 inputWS = ChildAlg->getProperty(
"OutputWorkspace");
276 outputWS = DataObjects::create<API::HistoWorkspace>(*inputWS, histnumber, XValues_new);
279 if (inputWS->axes() > 1)
280 outputWS->replaceAxis(1, std::unique_ptr<Axis>(inputWS->getAxis(1)->clone(outputWS.get())));
281 bool ignoreBinErrors =
getProperty(
"IgnoreBinErrors");
283 Progress prog(
this, 0.0, 1.0, histnumber);
285 for (
int hist = 0; hist < histnumber; ++hist) {
289 outputWS->setHistogram(hist, HistogramData::rebin(inputWS->histogram(hist), XValues_new));
290 }
catch (InvalidBinEdgesError &) {
292 outputWS->setBinEdges(hist, XValues_new);
300 outputWS->setDistribution(dist);
305 for (
int i = 0; i < histnumber; ++i) {
306 if (inputWS->hasMaskedBins(i))
312 for (
int i = 0; i < outputWS->axes(); ++i) {
313 outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
319 ChildAlg->initialize();
322 outputWS = ChildAlg->getProperty(
"OutputWorkspace");
350 auto it = mask.cbegin();
351 auto &XValues = inputWS->x(hist);
352 masked_bins.emplace_back(XValues[(*it).first]);
353 weights.emplace_back((*it).second);
354 masked_bins.emplace_back(XValues[(*it).first + 1]);
355 for (++it; it != mask.end(); ++it) {
356 const double currentX = XValues[(*it).first];
359 if (masked_bins.back() != currentX) {
360 weights.emplace_back(0.0);
361 masked_bins.emplace_back(currentX);
363 weights.emplace_back((*it).second);
364 masked_bins.emplace_back(XValues[(*it).first + 1]);
368 auto errSize = weights.size();
369 Histogram oldHist(BinEdges(std::move(masked_bins)), Frequencies(std::move(weights)),
370 FrequencyStandardDeviations(errSize, 0));
373 bool ignoreErrors =
getProperty(
"IgnoreBinErrors");
376 auto newHist = HistogramData::rebin(oldHist, outputWS->binEdges(hist));
377 auto &newWeights = newHist.y();
381 if (newWeights[
index] > 0.0)
382 outputWS->flagMasked(hist,
index, newWeights[
index]);
384 }
catch (InvalidBinEdgesError &) {
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
#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_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_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#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.
bool existsProperty(const std::string &name) const override
Checks whether the named property is already in the list of managed property.
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.
bool isDefault(const std::string &name) const
Base MatrixWorkspace Abstract Class.
std::map< size_t, double > MaskList
Masked bins for each spectrum are stored as a set of pairs containing <bin index, weight>
virtual void getXMinMax(double &xmin, double &xmax) const
Helper class for reporting progress from algorithms.
A property class for workspaces.
void propagateMasks(const API::MatrixWorkspace_const_sptr &inputWS, const API::MatrixWorkspace_sptr &outputWS, int hist)
Takes the masks in the input workspace and apportions the weights into the new bins that overlap with...
void exec() override
Executes the rebin algorithm.
void init() override
Initialisation method.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
static std::vector< double > rebinParamsFromInput(const std::vector< double > &inParams, const API::MatrixWorkspace &inputWS, Kernel::Logger &logger)
Return the rebin parameters from a user input.
std::map< std::string, std::string > validateInputs() override
Validate that the input properties are sane.
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 information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const EventWorkspace > EventWorkspace_const_sptr
shared pointer to a const Workspace2D
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
int MANTID_KERNEL_DLL createAxisFromRebinParams(const std::vector< double > ¶ms, std::vector< double > &xnew, const bool resize_xnew=true, const bool full_bins_only=false, const double xMinHint=std::nan(""), const double xMaxHint=std::nan(""), const bool useReverseLogarithmic=false, const double power=-1)
Creates a new output X array given a 'standard' set of rebinning parameters.
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
@ Input
An input workspace.
@ Output
An output workspace.