Mantid
Loading...
Searching...
No Matches
Rebunch.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
11#include "MantidAPI/Axis.h"
16
17#include <cmath>
18#include <numeric>
19#include <sstream>
20
21namespace Mantid {
22using namespace HistogramData;
23namespace Algorithms {
24
25// Register the class into the algorithm factory
26DECLARE_ALGORITHM(Rebunch)
27
28using namespace Kernel;
29using API::MatrixWorkspace;
31using API::WorkspaceProperty;
32
37 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
38 "The input workspace");
39 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
40 "The result of rebinning");
41
42 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
43 mustBePositive->setLower(1);
44 declareProperty("NBunch", 1, mustBePositive, "The number of bins that will be summed in each bunch");
45}
46
52 // retrieve the properties
53 int n_bunch = getProperty("NBunch");
54
55 // Get the input workspace
56 MatrixWorkspace_const_sptr inputW = getProperty("InputWorkspace");
57
58 bool dist = inputW->isDistribution();
59
60 // workspace independent determination of length
61 auto histnumber = static_cast<int>(inputW->size() / inputW->blocksize());
62
63 auto size_x = static_cast<int>(inputW->x(0).size());
64 auto size_y = static_cast<int>(inputW->y(0).size());
65
66 // signal is the same length for histogram and point data
67 int ny = (size_y / n_bunch);
68 if (size_y % n_bunch > 0)
69 ny += 1;
70 // default is for hist
71 int nx = ny + 1;
72 bool point = false;
73 if (size_x == size_y) {
74 point = true;
75 nx = ny;
76 }
77
78 // make output Workspace the same type is the input, but with new length of
79 // signal array
80 API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(inputW, histnumber, nx, ny);
81
82 int progress_step = histnumber / 100;
83 if (progress_step == 0)
84 progress_step = 1;
85 PARALLEL_FOR_IF(Kernel::threadSafe(*inputW, *outputW))
86 for (int hist = 0; hist < histnumber; hist++) {
88 // output data arrays are implicitly filled by function
89 if (point) {
90 rebunch_point(inputW->x(hist), inputW->y(hist), inputW->e(hist), outputW->mutableX(hist), outputW->mutableY(hist),
91 outputW->mutableE(hist), n_bunch);
92 } else if (dist) {
93 rebunch_hist_frequencies(inputW->x(hist), inputW->y(hist), inputW->e(hist), outputW->mutableX(hist),
94 outputW->mutableY(hist), outputW->mutableE(hist), n_bunch);
95 } else {
96 rebunch_hist_counts(inputW->x(hist), inputW->y(hist), inputW->e(hist), outputW->mutableX(hist),
97 outputW->mutableY(hist), outputW->mutableE(hist), n_bunch);
98 }
99
100 if (hist % progress_step == 0) {
101 progress(double(hist) / histnumber);
103 }
105 }
107 outputW->setDistribution(dist);
108
109 // Copy units
110 if (outputW->getAxis(0)->unit().get())
111 outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit();
112 try {
113 if (inputW->getAxis(1)->unit().get())
114 outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit();
115 } catch (Exception::IndexError &) {
116 // OK, so this isn't a Workspace2D
117 }
118
119 // Assign it to the output workspace property
120 setProperty("OutputWorkspace", outputW);
121}
122
135void Rebunch::rebunch_hist_counts(const HistogramX &xold, const HistogramY &yold, const HistogramE &eold,
136 HistogramX &xnew, HistogramY &ynew, HistogramE &enew, const size_t n_bunch) {
137 size_t size_x = xold.size();
138 size_t size_y = yold.size();
139
140 double ysum, esum;
141 size_t hi_index = size_x - 1;
142 size_t wbins = size_y / n_bunch;
143 size_t rem = size_y % n_bunch;
144
145 size_t i, j;
146 int i_in = 0;
147 j = 0;
148 while (j < wbins) {
149 ysum = 0.0;
150 esum = 0.0;
151 for (i = 1; i <= n_bunch; i++) {
152 ysum += yold[i_in];
153 esum += eold[i_in] * eold[i_in];
154 i_in++;
155 }
156 // average contributing x values
157 ynew[j] = ysum;
158 enew[j] = sqrt(esum);
159 j++;
160 }
161 if (rem != 0) {
162 ysum = 0.0;
163 esum = 0.0;
164 for (i = 1; i <= rem; i++) {
165 ysum += yold[i_in];
166 esum += eold[i_in] * eold[i_in];
167 i_in++;
168 }
169 ynew[j] = ysum;
170 enew[j] = sqrt(esum);
171 }
172
173 j = 0;
174 xnew[j] = xold[0];
175 j++;
176 for (i = n_bunch; i < hi_index; i += n_bunch) {
177 xnew[j] = xold[i];
178 j++;
179 }
180 xnew[j] = xold[hi_index];
181}
182
195void Rebunch::rebunch_hist_frequencies(const HistogramX &xold, const HistogramY &yold, const HistogramE &eold,
196 HistogramX &xnew, HistogramY &ynew, HistogramE &enew, const size_t n_bunch) {
197 double width;
198 size_t size_x = xold.size();
199 size_t size_y = yold.size();
200
201 double ysum, esum;
202 size_t hi_index = size_x - 1;
203 size_t wbins = size_y / n_bunch;
204 size_t rem = size_y % n_bunch;
205
206 size_t i, j;
207 int i_in = 0;
208 j = 0;
209 while (j < wbins) {
210 ysum = 0.0;
211 esum = 0.0;
212 for (i = 1; i <= n_bunch; i++) {
213 width = xold[i_in + 1] - xold[i_in];
214 ysum += yold[i_in] * width;
215 esum += eold[i_in] * eold[i_in] * width * width;
216 i_in++;
217 }
218 // average contributing x values
219 ynew[j] = ysum;
220 enew[j] = sqrt(esum);
221 j++;
222 }
223 if (rem != 0) {
224 ysum = 0.0;
225 esum = 0.0;
226 for (i = 1; i <= rem; i++) {
227 width = xold[i_in + 1] - xold[i_in];
228 ysum += yold[i_in] * width;
229 esum += eold[i_in] * eold[i_in] * width * width;
230 i_in++;
231 }
232 ynew[j] = ysum;
233 enew[j] = sqrt(esum);
234 }
235
236 j = 0;
237 xnew[j] = xold[0];
238 j++;
239 for (i = n_bunch; i < hi_index; i += n_bunch) {
240 xnew[j] = xold[i];
241 j++;
242 }
243 xnew[j] = xold[hi_index];
244
245 for (i = 0; i < ynew.size(); i++) {
246 width = xnew[i + 1] - xnew[i];
247 ynew[i] = ynew[i] / width;
248 enew[i] = enew[i] / width;
249 }
250}
251
264void Rebunch::rebunch_point(const HistogramX &xold, const HistogramY &yold, const HistogramE &eold, HistogramX &xnew,
265 HistogramY &ynew, HistogramE &enew, const size_t n_bunch) {
266
267 size_t size_y = yold.size();
268 double xsum, ysum, esum;
269 size_t wbins = size_y / n_bunch;
270 size_t rem = size_y % n_bunch;
271
272 size_t i, j;
273 int i_in = 0;
274 j = 0;
275 while (j < wbins) {
276 xsum = 0.0;
277 ysum = 0.0;
278 esum = 0.0;
279 for (i = 1; i <= n_bunch; i++) {
280 xsum += xold[i_in];
281 ysum += yold[i_in];
282 esum += eold[i_in] * eold[i_in];
283 i_in++;
284 }
285 // average contributing x values
286 xnew[j] = xsum / static_cast<double>(n_bunch);
287 ynew[j] = ysum / static_cast<double>(n_bunch);
288 enew[j] = sqrt(esum) / static_cast<double>(n_bunch);
289 j++;
290 }
291 if (rem != 0) {
292 xsum = 0.0;
293 ysum = 0.0;
294 esum = 0.0;
295 for (i = 1; i <= rem; i++) {
296 xsum += xold[i_in];
297 ysum += yold[i_in];
298 esum += eold[i_in] * eold[i_in];
299 i_in++;
300 }
301 xnew[j] = xsum / static_cast<double>(rem);
302 ynew[j] = ysum / static_cast<double>(rem);
303 enew[j] = sqrt(esum) / static_cast<double>(rem);
304 }
305}
306
307} // namespace Algorithms
308} // namespace Mantid
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#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...
Definition: MultiThreaded.h:94
#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.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
void interruption_point()
This is called during long-running operations, and check if the algorithm has requested that it be ca...
Definition: Algorithm.cpp:1687
A property class for workspaces.
void rebunch_hist_counts(const HistogramData::HistogramX &xold, const HistogramData::HistogramY &yold, const HistogramData::HistogramE &eold, HistogramData::HistogramX &xnew, HistogramData::HistogramY &ynew, HistogramData::HistogramE &enew, const size_t n_bunch)
Rebunches histogram data data according to n_bunch input.
Definition: Rebunch.cpp:135
void init() override
Initialisation method.
Definition: Rebunch.cpp:36
void rebunch_hist_frequencies(const HistogramData::HistogramX &xold, const HistogramData::HistogramY &yold, const HistogramData::HistogramE &eold, HistogramData::HistogramX &xnew, HistogramData::HistogramY &ynew, HistogramData::HistogramE &enew, const size_t n_bunch)
Rebunches histogram data data according to n_bunch input.
Definition: Rebunch.cpp:195
void rebunch_point(const HistogramData::HistogramX &xold, const HistogramData::HistogramY &yold, const HistogramData::HistogramE &eold, HistogramData::HistogramX &xnew, HistogramData::HistogramY &ynew, HistogramData::HistogramE &enew, const size_t n_bunch)
Rebunches point data data according to n_bunch input.
Definition: Rebunch.cpp:264
void exec() override
Executes the rebin algorithm.
Definition: Rebunch.cpp:51
Exception for index errors.
Definition: Exception.h:284
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...
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
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.
Definition: MultiThreaded.h:22
Helper class which provides the Collimation Length for SANS instruments.
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54