Mantid
Loading...
Searching...
No Matches
DiffractionFocussing2.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 +
8#include "MantidAPI/Axis.h"
10#include "MantidAPI/ISpectrum.h"
19#include "MantidHistogramData/LogarithmicGenerator.h"
20#include "MantidIndexing/Group.h"
21#include "MantidIndexing/IndexInfo.h"
23
24#include <algorithm>
25#include <cfloat>
26#include <iterator>
27#include <numeric>
28
29using namespace Mantid::Kernel;
30using namespace Mantid::API;
31using namespace Mantid::DataObjects;
32using Mantid::HistogramData::BinEdges;
33using std::vector;
34
35namespace Mantid::Algorithms {
36
37// Register the class into the algorithm factory
38DECLARE_ALGORITHM(DiffractionFocussing2)
39
40
44
45 auto wsValidator = std::make_shared<API::RawCountValidator>();
46 declareProperty(
47 std::make_unique<API::WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input, wsValidator),
48 "A 2D workspace with X values of d-spacing, Q or TOF (TOF support deprecated on 29/04/21)");
49 declareProperty(std::make_unique<API::WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
50 "The result of diffraction focussing of InputWorkspace");
51
52 declareProperty(std::make_unique<FileProperty>("GroupingFileName", "", FileProperty::OptionalLoad, ".cal"),
53 "Optional: The name of the CalFile with grouping data.");
54
55 declareProperty(std::make_unique<WorkspaceProperty<GroupingWorkspace>>("GroupingWorkspace", "", Direction::Input,
57 "Optional: GroupingWorkspace to use instead of a grouping file.");
58
59 declareProperty("PreserveEvents", true,
60 "Keep the output workspace as an EventWorkspace, if the "
61 "input has events (default).\n"
62 "If false, then the workspace gets converted to a "
63 "Workspace2D histogram.");
64}
65
66//=============================================================================
71 // Clear maps and vectors to free up memory.
72 udet2group.clear();
74 std::vector<int>().swap(groupAtWorkspaceIndex);
75 group2xvector.clear();
76 group2wgtvector.clear();
77 this->m_validGroups.clear();
78 this->m_wsIndices.clear();
79}
80
81//=============================================================================
89 // retrieve the properties
90 std::string groupingFileName = getProperty("GroupingFileName");
91 groupWS = getProperty("GroupingWorkspace");
92
93 if (!groupingFileName.empty() && groupWS)
94 throw std::invalid_argument("You must enter a GroupingFileName or a GroupingWorkspace, not both!");
95
96 if (groupingFileName.empty() && !groupWS)
97 throw std::invalid_argument("You must enter a GroupingFileName or a GroupingWorkspace!");
98
99 // Get the input workspace
100 m_matrixInputW = getProperty("InputWorkspace");
101 nPoints = static_cast<int>(m_matrixInputW->blocksize());
102 nHist = static_cast<int>(m_matrixInputW->getNumberHistograms());
103
104 // Validate UnitID (spacing)
105 Axis *axis = m_matrixInputW->getAxis(0);
106 std::string unitid = axis->unit()->unitID();
107 if (unitid != "dSpacing" && unitid != "MomentumTransfer" && unitid != "TOF") {
108 g_log.error() << "UnitID " << unitid << " is not a supported spacing\n";
109 throw std::invalid_argument("Workspace Invalid Spacing/UnitID");
110 }
111 if (unitid == "TOF") {
112 g_log.error()
113 << "Support for TOF data in DiffractionFocussing is deprecated (on 29/04/21) - use GroupDetectors instead)"
114 << std::endl;
115 }
116 // --- Do we need to read the grouping workspace? ----
117 if (!groupingFileName.empty()) {
118 progress(0.01, "Reading grouping file");
119 auto childAlg = createChildAlgorithm("CreateGroupingWorkspace");
120 childAlg->setProperty("InputWorkspace", std::const_pointer_cast<MatrixWorkspace>(m_matrixInputW));
121 childAlg->setProperty("OldCalFilename", groupingFileName);
122 childAlg->executeAsChildAlg();
123 groupWS = childAlg->getProperty("OutputWorkspace");
124 }
125
126 // Fill the map
127 progress(0.2, "Determine Rebin Params");
128 udet2group.clear();
129 // std::cout << "(1) nGroups " << nGroups << "\n";
130 groupWS->makeDetectorIDToGroupVector(udet2group, nGroups);
131 if (nGroups <= 0)
132 throw std::runtime_error("No groups were specified.");
133 // std::cout << "(2) nGroups " << nGroups << "\n";
134
135 // This finds the rebin parameters (used in both versions)
136 // It also initializes the groupAtWorkspaceIndex[] array.
138
139 size_t totalHistProcess = this->setupGroupToWSIndices();
140
141 // determine event workspace min/max tof
142 double eventXMin = 0.;
143 double eventXMax = 0.;
144
145 m_eventW = std::dynamic_pointer_cast<const EventWorkspace>(m_matrixInputW);
146 if (m_eventW != nullptr) {
147 if (getProperty("PreserveEvents")) {
148 // Input workspace is an event workspace. Use the other exec method
149 this->execEvent();
150 this->cleanup();
151 return;
152 } else {
153 // get the full d-spacing range
154 m_eventW->sortAll(DataObjects::TOF_SORT, nullptr);
155 m_matrixInputW->getXMinMax(eventXMin, eventXMax);
156 }
157 }
158
159 // Check valida detectors are found in the .Cal file
160 if (nGroups <= 0) {
161 throw std::runtime_error("No selected Detectors found in .cal file for "
162 "input range. Please ensure spectra range has "
163 "atleast one selected detector.");
164 }
165 // Check the number of points
166 if (nPoints <= 0) {
167 throw std::runtime_error("No points found in the data range.");
168 }
171 // Caching containers that are either only read from or unused. Initialize
172 // them once.
173 // Helgrind will show a race-condition but the data is completely unused so it
174 // is irrelevant
175 MantidVec weights_default(1, 1.0), emptyVec(1, 0.0), EOutDummy(nPoints);
176
177 Progress prog(this, 0.2, 1.0, static_cast<int>(totalHistProcess) + nGroups);
178
180 for (int outWorkspaceIndex = 0; outWorkspaceIndex < static_cast<int>(m_validGroups.size()); outWorkspaceIndex++) {
182 auto group = static_cast<int>(m_validGroups[outWorkspaceIndex]);
183
184 // Get the group
185 auto &Xout = group2xvector.at(group);
186
187 // Assign the new X axis only once (i.e when this group is encountered the
188 // first time)
189 out->setBinEdges(outWorkspaceIndex, Xout);
190
191 // This is the output spectrum
192 auto &outSpec = out->getSpectrum(outWorkspaceIndex);
193 outSpec.setSpectrumNo(group);
194
195 // Get the references to Y and E output and rebin
196 // TODO can only be changed once rebin implemented in HistogramData
197 auto &Yout = outSpec.dataY();
198 auto &Eout = outSpec.dataE();
199
200 // Initialize the group's weight vector here and the dummy vector used for
201 // accumulating errors.
202 MantidVec groupWgt(nPoints, 0.0);
203
204 // loop through the contributing histograms
205 const std::vector<size_t> &indices = m_wsIndices[outWorkspaceIndex];
206 const size_t groupSize = indices.size();
207 for (size_t i = 0; i < groupSize; i++) {
208 size_t inWorkspaceIndex = indices[i];
209 // This is the input spectrum
210 const auto &inSpec = m_matrixInputW->getSpectrum(inWorkspaceIndex);
211 // Get reference to its old X,Y,and E.
212 auto &Xin = inSpec.x();
213 auto &Yin = inSpec.y();
214 auto &Ein = inSpec.e();
215 outSpec.addDetectorIDs(inSpec.getDetectorIDs());
216
217 try {
218 // TODO This should be implemented in Histogram as rebin
219 Mantid::Kernel::VectorHelper::rebinHistogram(Xin.rawData(), Yin.rawData(), Ein.rawData(), Xout.rawData(), Yout,
220 Eout, true);
221 } catch (...) {
222 // Should never happen because Xout is constructed to envelop all of the
223 // Xin vectors
224 std::ostringstream mess;
225 mess << "Error in rebinning process for spectrum:" << inWorkspaceIndex;
226 throw std::runtime_error(mess.str());
227 }
228
229 // Check for masked bins in this spectrum
230 if (m_matrixInputW->hasMaskedBins(i)) {
231 MantidVec weight_bins, weights;
232 weight_bins.emplace_back(Xin.front());
233 // If there are masked bins, get a reference to the list of them
234 const API::MatrixWorkspace::MaskList &mask = m_matrixInputW->maskedBins(i);
235 // Now iterate over the list, adjusting the weights for the affected
236 // bins
237 for (const auto &bin : mask) {
238 const double currentX = Xin[bin.first];
239 // Add an intermediate bin with full weight if masked bins aren't
240 // consecutive
241 if (weight_bins.back() != currentX) {
242 weights.emplace_back(1.0);
243 weight_bins.emplace_back(currentX);
244 }
245 // The weight for this masked bin is 1 - the degree to which this bin
246 // is masked
247 weights.emplace_back(1.0 - bin.second);
248 weight_bins.emplace_back(Xin[bin.first + 1]);
249 }
250 // Add on a final bin with full weight if masking doesn't go up to the
251 // end
252 if (weight_bins.back() != Xin.back()) {
253 weights.emplace_back(1.0);
254 weight_bins.emplace_back(Xin.back());
255 }
256
257 // Create a zero vector for the errors because we don't care about them
258 // here
259 const MantidVec zeroes(weights.size(), 0.0);
260 // Rebin the weights - note that this is a distribution
261 VectorHelper::rebin(weight_bins, weights, zeroes, Xout.rawData(), groupWgt, EOutDummy, true, true);
262 } else // If no masked bins we want to add 1 to the weight of the output
263 // bins that this input covers
264 {
265 // Initialized within the loop to avoid having to wrap writing to it
266 // with a PARALLEL_CRITICAL sections
267 MantidVec limits(2);
268
269 if (eventXMin > 0. && eventXMax > 0.) {
270 limits[0] = eventXMin;
271 limits[1] = eventXMax;
272 } else {
273 limits[0] = Xin.front();
274 limits[1] = Xin.back();
275 }
276
277 // Rebin the weights - note that this is a distribution
278 VectorHelper::rebin(limits, weights_default, emptyVec, Xout.rawData(), groupWgt, EOutDummy, true, true);
279 }
280 prog.report();
281 } // end of loop for input spectra
282
283 // Calculate the bin widths
284 std::vector<double> widths(Xout.size());
285 std::adjacent_difference(Xout.begin(), Xout.end(), widths.begin());
286
287 // Take the square root of the errors
288 std::transform(Eout.begin(), Eout.end(), Eout.begin(), static_cast<double (*)(double)>(sqrt));
289
290 // Multiply the data and errors by the bin widths because the rebin
291 // function, when used
292 // in the fashion above for the weights, doesn't put it back in
293 std::transform(Yout.begin(), Yout.end(), widths.begin() + 1, Yout.begin(), std::multiplies<double>());
294 std::transform(Eout.begin(), Eout.end(), widths.begin() + 1, Eout.begin(), std::multiplies<double>());
295
296 // Now need to normalise the data (and errors) by the weights
297 std::transform(Yout.begin(), Yout.end(), groupWgt.begin(), Yout.begin(), std::divides<double>());
298 std::transform(Eout.begin(), Eout.end(), groupWgt.begin(), Eout.begin(), std::divides<double>());
299 // Now multiply by the number of spectra in the group
300 std::for_each(Yout.begin(), Yout.end(), [groupSize](double &val) { val *= static_cast<double>(groupSize); });
301 std::for_each(Eout.begin(), Eout.end(), [groupSize](double &val) { val *= static_cast<double>(groupSize); });
302
303 prog.report();
305 } // end of loop for groups
307
308 setProperty("OutputWorkspace", out);
309
310 this->cleanup();
311}
312
313//=============================================================================
321 // Create a new outputworkspace with not much in it
322 auto out = create<EventWorkspace>(*m_matrixInputW, m_validGroups.size(), m_matrixInputW->binEdges(0));
323
324 MatrixWorkspace_const_sptr outputWS = getProperty("OutputWorkspace");
325 bool inPlace = (m_matrixInputW == outputWS);
326 if (inPlace)
327 g_log.debug("Focussing EventWorkspace in-place.");
328 g_log.debug() << nGroups << " groups found in .cal file (counting group 0).\n";
329
330 EventType eventWtype = m_eventW->getEventType();
331
332 std::unique_ptr<Progress> prog = std::make_unique<Progress>(this, 0.2, 0.25, nGroups);
333
334 // determine precount size
335 vector<size_t> size_required(this->m_validGroups.size(), 0);
336 int totalHistProcess = 0;
337 for (size_t iGroup = 0; iGroup < this->m_validGroups.size(); iGroup++) {
338 const vector<size_t> &indices = this->m_wsIndices[iGroup];
339
340 totalHistProcess += static_cast<int>(indices.size());
341 for (auto index : indices) {
342 size_required[iGroup] += m_eventW->getSpectrum(index).getNumberEvents();
343 }
344 prog->report(1, "Pre-counting");
345 }
346
347 // ------------- Pre-allocate Event Lists ----------------------------
348 prog.reset();
349 prog = std::make_unique<Progress>(this, 0.25, 0.3, totalHistProcess);
350
351 // This creates and reserves the space required
352 for (size_t iGroup = 0; iGroup < this->m_validGroups.size(); iGroup++) {
353 const auto group = static_cast<int>(m_validGroups[iGroup]);
354 EventList &groupEL = out->getSpectrum(iGroup);
355 groupEL.switchTo(eventWtype);
356 groupEL.reserve(size_required[iGroup]);
357 groupEL.clearDetectorIDs();
358 groupEL.setSpectrumNo(group);
359 prog->reportIncrement(1, "Allocating");
360 }
361
362 // ----------- Focus ---------------
363 prog.reset();
364 prog = std::make_unique<Progress>(this, 0.3, 0.9, totalHistProcess);
365
366 if (this->m_validGroups.size() == 1) {
367 g_log.information() << "Performing focussing on a single group\n";
368 // Special case of a single group - parallelize differently
369 EventList &groupEL = out->getSpectrum(0);
370 const std::vector<size_t> &indices = this->m_wsIndices[0];
371
372 int chunkSize = 200;
373
374 int end = (totalHistProcess / chunkSize) + 1;
375
376 PRAGMA_OMP(parallel for schedule(dynamic, 1) )
377 for (int wiChunk = 0; wiChunk < end; wiChunk++) {
379
380 // Perform in chunks for more efficiency
381 int max = (wiChunk + 1) * chunkSize;
382 if (max > totalHistProcess)
383 max = totalHistProcess;
384
385 // Make a blank EventList that will accumulate the chunk.
386 EventList chunkEL;
387 chunkEL.switchTo(eventWtype);
388 // chunkEL.reserve(numEventsInChunk);
389
390 // process the chunk
391 for (int i = wiChunk * chunkSize; i < max; i++) {
392 // Accumulate the chunk
393 size_t wi = indices[i];
394 chunkEL += m_eventW->getSpectrum(wi);
395 }
396
397 // Rejoin the chunk with the rest.
398 PARALLEL_CRITICAL(DiffractionFocussing2_JoinChunks) { groupEL += chunkEL; }
399
401 }
403 } else {
404 // ------ PARALLELIZE BY GROUPS -------------------------
405
406 auto nValidGroups = static_cast<int>(this->m_validGroups.size());
408 for (int iGroup = 0; iGroup < nValidGroups; iGroup++) {
410 const std::vector<size_t> &indices = this->m_wsIndices[iGroup];
411 for (auto wi : indices) {
412 // In workspace index iGroup, put what was in the OLD workspace index wi
413 out->getSpectrum(iGroup) += m_eventW->getSpectrum(wi);
414
415 prog->reportIncrement(1, "Appending Lists");
416
417 // When focussing in place, you can clear out old memory from the input
418 // one!
419 if (inPlace) {
420 std::const_pointer_cast<EventWorkspace>(m_eventW)->getSpectrum(wi).clear();
421 }
422 }
424 }
426 } // (done with parallel by groups)
427
428 // Now that the data is cleaned up, go through it and set the X vectors to the
429 // input workspace we first talked about.
430 prog.reset();
431 prog = std::make_unique<Progress>(this, 0.9, 1.0, nGroups);
432 for (size_t workspaceIndex = 0; workspaceIndex < this->m_validGroups.size(); workspaceIndex++) {
433 const auto group = static_cast<int>(m_validGroups[workspaceIndex]);
434 // Now this is the workspace index of that group; simply 1 offset
435 prog->reportIncrement(1, "Setting X");
436
437 if (workspaceIndex >= out->getNumberHistograms()) {
438 g_log.warning() << "Warning! Invalid workspace index found for group # " << group
439 << ". Histogram will be empty.\n";
440 continue;
441 }
442
443 // Now you set the X axis to the X you saved before.
444 if (!group2xvector.empty()) {
445 auto git = group2xvector.find(group);
446 if (git != group2xvector.end())
447 // Reset Histogram instead of BinEdges, the latter forbids size change.
448 out->setHistogram(workspaceIndex, BinEdges(git->second.cowData()));
449 else
450 // Just use the 1st X vector it found, instead of nothin.
451 // Reset Histogram instead of BinEdges, the latter forbids size change.
452 out->setHistogram(workspaceIndex, BinEdges(group2xvector.begin()->second.cowData()));
453 } else
454 g_log.warning() << "Warning! No X histogram bins were found for any "
455 "groups. Histogram will be empty.\n";
456 }
457 out->clearMRU();
458 setProperty("OutputWorkspace", std::move(out));
459}
460
461//=============================================================================
468 const auto &dets = m_matrixInputW->getSpectrum(wi).getDetectorIDs();
469 if (dets.empty()) // Not in group
470 {
471 g_log.debug() << wi << " <- this workspace index is empty!\n";
472 return -1;
473 }
474
475 auto it = dets.cbegin();
476 if (*it < 0) // bad pixel id
477 return -1;
478
479 try { // what if index out of range?
480 const int group = udet2group.at(*it);
481 if (group <= 0)
482 return -1;
483 it++;
484 for (; it != dets.end(); ++it) // Loop other all other udets
485 {
486 if (udet2group.at(*it) != group)
487 return -1;
488 }
489 return group;
490 } catch (...) {
491 }
492
493 return -1;
494}
495
496//=============================================================================
511 std::ostringstream mess;
512
513 // typedef for the storage of the group ranges
514 using group2minmaxmap = std::map<int, std::pair<double, double>>;
515 // Map from group number to its associated range parameters <Xmin,Xmax,step>
516 group2minmaxmap group2minmax;
517 group2minmaxmap::iterator gpit;
518
519 const double BIGGEST = std::numeric_limits<double>::max();
520
521 // whether or not to bother checking for a mask
522 bool checkForMask = false;
523 Geometry::Instrument_const_sptr instrument = m_matrixInputW->getInstrument();
524 if (instrument != nullptr) {
525 checkForMask = ((instrument->getSource() != nullptr) && (instrument->getSample() != nullptr));
526 }
527 const auto &spectrumInfo = m_matrixInputW->spectrumInfo();
528
530 for (int wi = 0; wi < nHist; wi++) // Iterate over all histograms to find X boundaries for each group
531 {
532 const int group = validateSpectrumInGroup(static_cast<size_t>(wi));
533 groupAtWorkspaceIndex[wi] = group;
534 if (group == -1)
535 continue;
536
537 if (checkForMask) {
538 if (spectrumInfo.isMasked(wi)) {
539 groupAtWorkspaceIndex[wi] = -1;
540 continue;
541 }
542 }
543 gpit = group2minmax.find(group);
544
545 // Create the group range in the map if it isn't already there
546 if (gpit == group2minmax.end()) {
547 gpit = group2minmax.emplace(group, std::make_pair(BIGGEST, -1. * BIGGEST)).first;
548 }
549 const double min = (gpit->second).first;
550 const double max = (gpit->second).second;
551 auto &X = m_matrixInputW->x(wi);
552 double temp = X.front();
553 if (temp < (min)) // New Xmin found
554 (gpit->second).first = temp;
555 temp = X.back();
556 if (temp > (max)) // New Xmax found
557 (gpit->second).second = temp;
558 }
559
560 nGroups = group2minmax.size(); // Number of unique groups
561
562 const int64_t xPoints = nPoints + 1;
563 // Iterator over all groups to create the new X vectors
564 for (gpit = group2minmax.begin(); gpit != group2minmax.end(); ++gpit) {
565 double Xmin, Xmax, step;
566 Xmin = (gpit->second).first;
567 Xmax = (gpit->second).second;
568
569 // Make sure that Xmin is not 0 - since it is not possible to do log binning
570 // from 0.0.
571 if (Xmin <= 0)
572 Xmin = Xmax / nPoints;
573 if (Xmin <= 0)
574 Xmin = 1.0;
575 if (Xmin == Xmax)
576 Xmin = Xmax / 2.0;
577
578 if (Xmax < Xmin) // Should never happen
579 {
580 mess << "Fail to determine X boundaries for group:" << gpit->first << "\n";
581 mess << "The boundaries are (Xmin,Xmax):" << Xmin << " " << Xmax;
582 throw std::runtime_error(mess.str());
583 }
584 // This log step size will give the right # of points
585 step = expm1((log(Xmax) - log(Xmin)) / nPoints);
586 mess << "Found Group:" << gpit->first << "(Xmin,Xmax,log step):" << (gpit->second).first << ","
587 << (gpit->second).second << "," << step;
588 // g_log.information(mess.str());
589 mess.str("");
590
591 HistogramData::BinEdges xnew(xPoints, HistogramData::LogarithmicGenerator(Xmin, step));
592 group2xvector[gpit->first] = xnew; // Register this vector in the map
593 }
594 // Not needed anymore
595 udet2group.clear();
596}
597
598/***
599 * Configure the mapping of output group to list of input workspace
600 * indices, and the list of valid group numbers.
601 *
602 * @return the total number of input histograms that will be read.
603 */
605 // set up the mapping of group to input workspace index
606 std::vector<std::vector<std::size_t>> wsIndices;
607 wsIndices.reserve(this->nGroups + 1);
608 auto nHist_st = static_cast<size_t>(nHist);
609 for (size_t wi = 0; wi < nHist_st; wi++) {
610 // wi is the workspace index (of the input)
611 const int group = groupAtWorkspaceIndex[wi];
612 if (group < 1) // Not in a group, or invalid group #
613 continue;
614
615 // resize the ws_indices if it is not big enough
616 if (wsIndices.size() < static_cast<size_t>(group + 1)) {
617 wsIndices.resize(group + 1);
618 }
619
620 // Also record a list of workspace indices
621 wsIndices[group].emplace_back(wi);
622 }
623
624 // initialize a vector of the valid group numbers
625 size_t totalHistProcess = 0;
626 for (const auto &item : group2xvector) {
627 const auto group = item.first;
628 m_validGroups.emplace_back(group);
629 totalHistProcess += wsIndices[group].size();
630 }
631
632 std::transform(m_validGroups.cbegin(), m_validGroups.cend(), std::back_inserter(m_wsIndices),
633 [&wsIndices](const auto &group) { return wsIndices[static_cast<int>(group)]; });
634
635 return totalHistProcess;
636}
637
638} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#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_CRITICAL(name)
#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 PRAGMA_OMP(expression)
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
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.
Definition: Algorithm.cpp:842
Kernel::Logger & g_log
Definition: Algorithm.h:451
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
Class to represent the axis of a workspace.
Definition: Axis.h:30
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
Definition: Axis.cpp:28
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Definition: FileProperty.h:53
void clearDetectorIDs()
Clear the detector IDs set.
Definition: ISpectrum.cpp:117
void setSpectrumNo(specnum_t num)
Sets the the spectrum number of this spectrum.
Definition: ISpectrum.cpp:127
std::map< size_t, double > MaskList
Masked bins for each spectrum are stored as a set of pairs containing <bin index, weight>
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
Algorithm to focus powder diffraction data into a number of histograms according to a grouping scheme...
int nPoints
Number of points in the 2D workspace.
Mantid::DataObjects::GroupingWorkspace_sptr groupWS
Grouping workspace with groups to build.
void execEvent()
Executes the algorithm in the case of an Event input workspace.
std::map< int, HistogramData::BinEdges > group2xvector
Map from the group number to the group's X vector.
int validateSpectrumInGroup(size_t wi)
Verify that all the contributing detectors to a spectrum belongs to the same group.
void determineRebinParameters()
Loop over the workspace and determine the rebin parameters (Xmin,Xmax,step) for each group.
DataObjects::EventWorkspace_const_sptr m_eventW
Shared pointer to the event workspace.
std::vector< int > groupAtWorkspaceIndex
The list of group numbers.
std::vector< std::vector< std::size_t > > m_wsIndices
Mapping of group number to vector of inputworkspace indices.
void exec() override
Executes the algorithm.
std::vector< Indexing::SpectrumNumber > m_validGroups
List of valid group numbers.
std::vector< int > udet2group
Map from udet to group.
group2vectormap group2wgtvector
Map from the group number to the group's summed weight vector.
API::MatrixWorkspace_const_sptr m_matrixInputW
Shared pointer to the input workspace.
void cleanup()
Perform clean-up of memory after execution but before destructor.
int64_t nGroups
The number of (used) groups.
A class for holding :
Definition: EventList.h:56
void reserve(size_t num) override
Reserve a certain number of entries in event list of the specified eventType.
Definition: EventList.cpp:895
void switchTo(Mantid::API::EventType newType) override
Switch the EventList to use the given EventType (TOF, WEIGHTED, or WEIGHTED_NOTIME)
Definition: EventList.cpp:649
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Definition: ProgressBase.h:51
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)
EventType
What kind of event list is being stored.
Definition: IEventList.h:18
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
void MANTID_KERNEL_DLL rebin(const std::vector< double > &xold, const std::vector< double > &yold, const std::vector< double > &eold, const std::vector< double > &xnew, std::vector< double > &ynew, std::vector< double > &enew, bool distribution, bool addition=false)
Rebins data according to a new output X array.
void MANTID_KERNEL_DLL rebinHistogram(const std::vector< double > &xold, const std::vector< double > &yold, const std::vector< double > &eold, const std::vector< double > &xnew, std::vector< double > &ynew, std::vector< double > &enew, bool addition)
Rebins histogram data according to a new output X array.
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
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
Definition: cow_ptr.h:172
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54