Mantid
Loading...
Searching...
No Matches
MaxMin.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//----------------------------------------------------------------------
15#include "MantidHistogramData/Histogram.h"
17
18namespace Mantid::Algorithms {
19
20// Register the class into the algorithm factory
22
23using namespace Kernel;
24using namespace API;
25using namespace Mantid::DataObjects;
26using namespace Mantid::HistogramData;
27
32 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input,
33 std::make_shared<HistogramValidator>()),
34 "The name of the Workspace2D to take as input");
35 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
36 "The name of the workspace in which to store the result");
37
38 declareProperty("ShowMin", false, "Flag to show minimum instead of maximum (default=false)");
39 declareProperty("RangeLower", EMPTY_DBL(), "The X value to search from (default min)");
40 declareProperty("RangeUpper", EMPTY_DBL(), "The X value to search to (default max)");
41 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
42 mustBePositive->setLower(0);
43 declareProperty("StartWorkspaceIndex", 0, mustBePositive, "Start spectrum number (default 0)");
44 declareProperty("EndWorkspaceIndex", EMPTY_INT(), mustBePositive, "End spectrum number (default max)");
45}
46
52 // Try and retrieve the optional properties
53
55 double MinRange = getProperty("RangeLower");
57 double MaxRange = getProperty("RangeUpper");
59 int MinSpec = getProperty("StartWorkspaceIndex");
61 int MaxSpec = getProperty("EndWorkspaceIndex");
63 bool showMin = getProperty("ShowMin");
64
65 // Get the input workspace
66 MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");
67
68 const auto numberOfSpectra = static_cast<int>(localworkspace->getNumberHistograms());
69
70 // Check 'StartSpectrum' is in range 0-numberOfSpectra
71 if (MinSpec > numberOfSpectra) {
72 g_log.warning("StartSpectrum out of range! Set to 0.");
73 MinSpec = 0;
74 }
75 if (isEmpty(MaxSpec))
76 MaxSpec = numberOfSpectra - 1;
77 if (MaxSpec > numberOfSpectra - 1 || MaxSpec < MinSpec) {
78 g_log.warning("EndSpectrum out of range! Set to max detector number");
79 MaxSpec = numberOfSpectra;
80 }
81 if (MinRange > MaxRange) {
82 g_log.warning("Range_upper is less than Range_lower. Will integrate up to "
83 "frame maximum.");
84 MaxRange = 0.0;
85 }
86
87 // Create the 1D workspace for the output
88 MatrixWorkspace_sptr outputWorkspace;
89
90 outputWorkspace = create<HistoWorkspace>(*localworkspace, MaxSpec - MinSpec + 1, BinEdges(2));
91
92 Progress progress(this, 0.0, 1.0, (MaxSpec - MinSpec + 1));
93 PARALLEL_FOR_IF(Kernel::threadSafe(*localworkspace, *outputWorkspace))
94 // Loop over spectra
95 for (int i = MinSpec; i <= MaxSpec; ++i) {
97 int newindex = i - MinSpec;
98 // Copy over spectrum and detector number info
99 outputWorkspace->getSpectrum(newindex).copyInfoFrom(localworkspace->getSpectrum(i));
100
101 // Retrieve the spectrum into a vector
102 auto &X = localworkspace->x(i);
103 auto &Y = localworkspace->y(i);
104
105 // Find the range [min,max]
106 MantidVec::const_iterator lowit, highit;
107 if (MinRange == EMPTY_DBL())
108 lowit = X.begin();
109 else
110 lowit = std::lower_bound(X.begin(), X.end(), MinRange);
111
112 if (MaxRange == EMPTY_DBL())
113 highit = X.end();
114 else {
115 using std::placeholders::_1;
116 highit = std::find_if(lowit, X.end(), std::bind(std::greater<double>(), _1, MaxRange));
117 }
118
119 // If range specified doesn't overlap with this spectrum then bail out
120 if (lowit == X.end() || highit == X.begin() || lowit == highit)
121 continue;
122
123 --highit; // Upper limit is the bin before, i.e. the last value smaller than
124 // MaxRange
125
126 MantidVec::difference_type distmin = std::distance(X.begin(), lowit);
127 MantidVec::difference_type distmax = std::distance(X.begin(), highit);
128
129 MantidVec::const_iterator maxY;
130 // Find the max/min element
131 if (showMin) {
132 maxY = std::min_element(Y.begin() + distmin, Y.begin() + distmax);
133 } else {
134 maxY = std::max_element(Y.begin() + distmin, Y.begin() + distmax);
135 }
136 MantidVec::difference_type d = std::distance(Y.begin(), maxY);
137 // X boundaries for the max/min element
138 outputWorkspace->mutableX(newindex)[0] = *(X.begin() + d);
139 outputWorkspace->mutableX(newindex)[1] = *(X.begin() + d + 1); // This is safe since X is of dimension Y+1
140 outputWorkspace->mutableY(newindex)[0] = *maxY;
141 progress.report();
143 }
145
146 // Assign it to the output workspace property
147 setProperty("OutputWorkspace", outputWorkspace);
148}
149
150} // namespace Mantid::Algorithms
#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
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
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
void exec() override
Executes the algorithm.
Definition: MaxMin.cpp:51
void init() override
Initialisation method.
Definition: MaxMin.cpp:31
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
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
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition: EmptyValues.h:25
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition: EmptyValues.h:43
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54