Mantid
Loading...
Searching...
No Matches
MaskBins.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 +
12
13#include <limits>
14#include <sstream>
15
16using Mantid::HistogramData::BinEdges;
17
18namespace Mantid::Algorithms {
19
20// Register the algorithm into the AlgorithmFactory
21DECLARE_ALGORITHM(MaskBins)
22
23using namespace Kernel;
24using namespace API;
25using DataObjects::EventWorkspace;
28
30 declareWorkspaceInputProperties<MatrixWorkspace, static_cast<int>(IndexType::WorkspaceIndex) |
31 static_cast<int>(IndexType::SpectrumNum)>(
32 "InputWorkspace", "The name of the input workspace. Must contain histogram data.",
33 std::make_shared<HistogramValidator>());
34 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
35 "The name of the Workspace containing the masked bins.");
36
37 // This validator effectively makes these properties mandatory
38 // Would be nice to have an explicit validator for this, but
39 // MandatoryValidator is already taken!
40 auto required = std::make_shared<BoundedValidator<double>>();
41 required->setUpper(std::numeric_limits<double>::max() * 0.99);
42 declareProperty("XMin", std::numeric_limits<double>::max(), required, "The value to start masking from.");
43 declareProperty("XMax", std::numeric_limits<double>::max(), required, "The value to end masking at.");
44
45 this->declareProperty(std::make_unique<ArrayProperty<int64_t>>("SpectraList"),
46 "Deprecated, use InputWorkspaceIndexSet.");
47}
48
53 // Check for valid X limits
54 m_startX = getProperty("XMin");
55 m_endX = getProperty("XMax");
56
57 if (m_startX > m_endX) {
58 std::stringstream msg;
59 msg << "XMax (" << m_endX << ") must be greater than XMin (" << m_startX << ")";
60 g_log.error(msg.str());
61 throw std::invalid_argument(msg.str());
62 }
63
64 // Copy indices from legacy property
65 std::vector<int64_t> spectraList = this->getProperty("SpectraList");
66 if (!spectraList.empty()) {
67 if (!isDefault("InputWorkspaceIndexSet"))
68 throw std::runtime_error("Cannot provide both InputWorkspaceIndexSet and "
69 "SpectraList at the same time.");
70 setProperty("InputWorkspaceIndexSet", spectraList);
71 g_log.warning("The 'SpectraList' property is deprecated. Use "
72 "'InputWorkspaceIndexSet' instead.");
73 }
74
76 std::tie(inputWS, indexSet) = getWorkspaceAndIndices<MatrixWorkspace>("InputWorkspace");
77
78 // Only create the output workspace if it's different to the input one
79 MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
80 if (outputWS != inputWS) {
81 outputWS = inputWS->clone();
82 setProperty("OutputWorkspace", outputWS);
83 }
84
85 if (std::dynamic_pointer_cast<const EventWorkspace>(inputWS)) {
86 this->execEvent();
87 } else {
88 MantidVec::difference_type startBin(0), endBin(0);
89
90 // If the binning is the same throughout, we only need to find the index
91 // limits once
92 const bool commonBins = inputWS->isCommonBins();
93 if (commonBins) {
94 auto X = inputWS->binEdges(0);
95 this->findIndices(X, startBin, endBin);
96 }
97
98 Progress progress(this, 0.0, 1.0, indexSet.size());
99 // Parallel running has problems with a race condition, leading to
100 // occaisional test failures and crashes
101
102 for (const auto wi : indexSet) {
103 MantidVec::difference_type startBinLoop(startBin), endBinLoop(endBin);
104 if (!commonBins)
105 this->findIndices(outputWS->binEdges(wi), startBinLoop, endBinLoop);
106
107 // Loop over masking each bin in the range
108 for (auto j = static_cast<int>(startBinLoop); j < static_cast<int>(endBinLoop); ++j) {
109 outputWS->maskBin(wi, j);
110 }
111 progress.report();
112 }
113 }
114}
115
119 MatrixWorkspace_sptr outputMatrixWS = getProperty("OutputWorkspace");
120 auto outputWS = std::dynamic_pointer_cast<EventWorkspace>(outputMatrixWS);
121
122 Progress progress(this, 0.0, 1.0, outputWS->getNumberHistograms() * 2);
123
124 {
125 const auto timerStart = std::chrono::high_resolution_clock::now();
126 outputWS->sortAll(Mantid::DataObjects::TOF_SORT, &progress);
127 addTimer("sortEvents", timerStart, std::chrono::high_resolution_clock::now());
128 }
129
131 for (int i = 0; i < static_cast<int>(indexSet.size()); // NOLINT
132 ++i) {
134 outputWS->getSpectrum(indexSet[i]).maskTof(m_startX, m_endX);
135 progress.report();
137 }
139
140 outputWS->clearMRU();
141}
142
148void MaskBins::findIndices(const BinEdges &X, MantidVec::difference_type &startBin,
149 MantidVec::difference_type &endBin) {
150 startBin = std::distance(X.begin(), std::upper_bound(X.cbegin(), X.cend(), m_startX));
151 if (startBin != 0)
152 --startBin;
153 auto last = std::lower_bound(X.cbegin(), X.cend(), m_endX);
154 if (last == X.cend())
155 --last;
156 endBin = std::distance(X.cbegin(), last);
157}
158
159} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
#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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Kernel::Logger & g_log
Definition Algorithm.h:422
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
bool isDefault(const std::string &name) const
void addTimer(const std::string &name, const Kernel::time_point_ns &begin, const Kernel::time_point_ns &end)
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
double m_endX
The range end point.
Definition MaskBins.h:67
double m_startX
The range start point.
Definition MaskBins.h:66
void execEvent()
Execution code for EventWorkspaces.
Definition MaskBins.cpp:118
Indexing::SpectrumIndexSet indexSet
the list of Spectra (workspace index) to load
Definition MaskBins.h:68
void exec() override
Execution code.
Definition MaskBins.cpp:52
void init() override
Initialisation code.
Definition MaskBins.cpp:29
void findIndices(const HistogramData::BinEdges &X, MantidVec::difference_type &startBin, MantidVec::difference_type &endBin)
Finds the indices of the bins at the limits of the range given.
Definition MaskBins.cpp:148
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.
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
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
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.
@ Output
An output workspace.
Definition Property.h:54