Mantid
Loading...
Searching...
No Matches
CropWorkspaceRagged.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 +
13
14#include <algorithm>
15#include <span>
16
17namespace {
18std::vector<double> getSubVector(std::span<double const> const data, const int64_t &lowerIndex,
19 const int64_t &upperIndex) {
20 auto low = std::next(data.begin(), lowerIndex);
21 auto up = std::next(data.begin(), upperIndex);
22 // get new vectors
23 std::vector<double> newData(low, up);
24 return newData;
25}
26
27} // namespace
28
29namespace Mantid::Algorithms {
30
31using namespace Kernel;
32using namespace API;
33
34DECLARE_ALGORITHM(CropWorkspaceRagged)
35
36
37void CropWorkspaceRagged::init() {
38 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
39 "The input workspace");
40 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
41 "Name to be given to the cropped workspace.");
42
43 auto required = std::make_shared<MandatoryValidator<std::vector<double>>>();
44 declareProperty(std::make_unique<ArrayProperty<double>>("XMin", required),
45 "The value(s) to start the cropping from. Should be either a "
46 "single value or a list.");
47 declareProperty(std::make_unique<ArrayProperty<double>>("XMax", required),
48 "The value(s) to end the cropping at. Should be either a "
49 "single value or a list.");
50}
51
53std::map<std::string, std::string> CropWorkspaceRagged::validateInputs() {
54 std::map<std::string, std::string> issues;
55 MatrixWorkspace_sptr ws = getProperty("InputWorkspace");
56 auto numSpectra = ws->getNumberHistograms();
57 std::vector<double> xMin = getProperty("XMin");
58 std::vector<double> xMax = getProperty("XMax");
59 if (xMin.size() == 0 || (xMin.size() != numSpectra && xMin.size() > 1)) {
60 issues["XMin"] = "XMin must be a single value or one value per sepctrum.";
61 }
62 if (xMax.size() == 0 || (xMax.size() > 1 && xMax.size() != numSpectra)) {
63 issues["XMax"] = "XMax must be a single value or one value per sepctrum.";
64 }
65 if (xMin.size() == 1 && xMax.size() == 1 && xMin[0] > xMax[0]) {
66 issues["XMax"] = "XMax must be greater than XMin.";
67 } else if (xMin.size() == 1 && xMax.size() > 1) {
68 auto it = std::find_if(xMax.cbegin(), xMax.cend(), [&xMin](auto max) { return max < xMin[0]; });
69 if (it != xMax.cend()) {
70 issues["XMax"] = "XMax must be greater than XMin.";
71 return issues;
72 }
73 } else if (xMin.size() > 1 && xMax.size() == 1) {
74 auto it = std::find_if(xMin.cbegin(), xMin.cend(), [&xMax](auto min) { return min > xMax[0]; });
75 if (it != xMin.cend()) {
76 issues["XMin"] = "XMin must be less than XMax.";
77 return issues;
78 }
79 } else if (xMin.size() > 1 && xMax.size() > 1) {
80 for (size_t k = 0; k < xMin.size(); k++) {
81 if (xMin[k] > xMax[k]) {
82 issues["XMin"] = "XMin must be less than XMax.";
83 return issues;
84 }
85 }
86 }
87 return issues;
88} // namespace Algorithms
89
92 MatrixWorkspace_sptr ws = getProperty("InputWorkspace");
93 auto numSpectra = ws->getNumberHistograms();
94 // clone ws to copy logs etc.
95 MatrixWorkspace_sptr outputWS = ws->clone();
96
97 std::vector<double> xMin = getProperty("XMin");
98 std::vector<double> xMax = getProperty("XMax");
99 if (xMin.size() == 1) {
100 auto value = xMin[0];
101 xMin.assign(numSpectra, value);
102 }
103 if (xMax.size() == 1) {
104 auto value = xMax[0];
105 xMax.assign(numSpectra, value);
106 }
107
108 // Its easier to work with point data -> index is same for x, y, E
109 MatrixWorkspace_sptr tmp = outputWS;
110 bool histogram = false;
111 if (outputWS->isHistogramData()) {
112 auto alg = createChildAlgorithm("ConvertToPointData");
113 alg->initialize();
114 alg->setRethrows(true);
115 alg->setProperty("InputWorkspace", outputWS);
116 alg->setProperty("OutputWorkspace", outputWS);
117 alg->execute();
118 tmp = alg->getProperty("OutputWorkspace");
119 histogram = true;
120 }
122 for (int64_t i = 0; i < int64_t(numSpectra); ++i) {
124 auto points = tmp->points(i);
125 const auto &xValues = outputWS->x(i);
126 const auto &yValues = outputWS->y(i);
127 const auto &eValues = outputWS->e(i);
128
129 // get iterators for cropped region using points
130 auto low = std::lower_bound(points.begin(), points.end(), xMin[i]);
131 auto up = std::upper_bound(points.begin(), points.end(), xMax[i]);
132 // convert to index
133 int64_t lowerIndex = std::distance(points.begin(), low);
134 int64_t upperIndex = std::distance(points.begin(), up);
135
136 // get new vectors
137 std::vector<double> newY = getSubVector(yValues, lowerIndex, upperIndex);
138 std::vector<double> newE = getSubVector(eValues, lowerIndex, upperIndex);
139 if (histogram && upperIndex + (size_t)1 <= xValues.size()) {
140 // the offset adds one to the upper index for histograms
141 // only use the offset if the end is cropped
142 upperIndex += 1;
143 }
144 std::vector<double> newX = getSubVector(xValues, lowerIndex, upperIndex);
145
146 // resize the histogram; this keeps X, Y and E consistent with the storage mode
147 outputWS->resizeHistogram(i, newY.size());
148
149 // update the data
150 outputWS->mutableX(i) = newX;
151 outputWS->mutableY(i) = newY;
152 outputWS->mutableE(i) = newE;
154 }
156
157 setProperty("OutputWorkspace", outputWS);
158}
159
160} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:542
gsl_vector * tmp
double value
The value of the point.
Definition FitMW.cpp:51
#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.
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.
A property class for workspaces.
Extracts a 'block' from a workspace and places it in a new workspace.
std::map< std::string, std::string > validateInputs() override
Input validation.
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.
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.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54