Mantid
Loading...
Searching...
No Matches
SortXAxis.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 +
11#include "MantidHistogramData/Histogram.h"
13#include "MantidKernel/System.h"
14
15using namespace Mantid;
16using namespace Mantid::API;
17using namespace Mantid::Kernel;
18using namespace Mantid::Algorithms;
19using namespace Mantid::DataObjects;
20using namespace Mantid::HistogramData;
21
22namespace Mantid::Algorithms {
23
25
26const std::string SortXAxis::name() const { return "SortXAxis"; }
27
28int SortXAxis::version() const { return 1; }
29
30const std::string SortXAxis::category() const { return "Transforms\\Axes;Utility\\Sorting"; }
31
32const std::string SortXAxis::summary() const {
33 return "Clones the input MatrixWorkspace(s) and orders the x-axis in an "
34 "ascending or descending fashion.";
35}
36
38 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
39 "Input Workspace");
40
41 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
42 "Sorted Output Workspace");
43
44 auto orderingValues = std::vector<std::string>({"Ascending", "Descending"});
45 auto orderingValidator = std::make_shared<StringListValidator>(orderingValues);
46 declareProperty("Ordering", orderingValues[0], orderingValidator, "Ascending or descending sorting",
48}
49
51 MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
52 MatrixWorkspace_sptr outputWorkspace = inputWorkspace->clone();
53 // Check if it is a valid histogram here
54 const bool isAProperHistogram = determineIfHistogramIsValid(*inputWorkspace);
55
56 // Define everything you can outside of the for loop
57 // Assume that all spec are the same size
58 const auto sizeOfX = inputWorkspace->x(0).size();
59
60 PARALLEL_FOR_IF(Kernel::threadSafe(*inputWorkspace, *outputWorkspace))
61 for (int specNum = 0u; specNum < (int)inputWorkspace->getNumberHistograms(); specNum++) {
63 auto workspaceIndices = createIndexes(sizeOfX);
64
65 sortIndicesByX(workspaceIndices, getProperty("Ordering"), *inputWorkspace, specNum);
66
67 copyToOutputWorkspace(workspaceIndices, *inputWorkspace, *outputWorkspace, specNum, isAProperHistogram);
69 }
71
72 setProperty("OutputWorkspace", outputWorkspace);
73}
74
81std::vector<std::size_t> SortXAxis::createIndexes(const size_t sizeOfX) {
82 std::vector<std::size_t> workspaceIndices;
83 workspaceIndices.reserve(sizeOfX);
84 for (auto workspaceIndex = 0u; workspaceIndex < sizeOfX; workspaceIndex++) {
85 workspaceIndices.emplace_back(workspaceIndex);
86 }
87 return workspaceIndices;
88}
89
100template <typename Comparator>
101void sortByXValue(std::vector<std::size_t> &workspaceIndices, const Mantid::API::MatrixWorkspace &inputWorkspace,
102 unsigned int specNum, Comparator const &compare) {
103 std::sort(workspaceIndices.begin(), workspaceIndices.end(), [&](std::size_t lhs, std::size_t rhs) -> bool {
104 return compare(inputWorkspace.x(specNum)[lhs], inputWorkspace.x(specNum)[rhs]);
105 });
106}
107
108void SortXAxis::sortIndicesByX(std::vector<std::size_t> &workspaceIndices, const std::string &order,
109 const Mantid::API::MatrixWorkspace &inputWorkspace, unsigned int specNum) {
110 if (order == "Ascending") {
111 sortByXValue(workspaceIndices, inputWorkspace, specNum, std::less<double>());
112 } else if (order == "Descending") {
113 sortByXValue(workspaceIndices, inputWorkspace, specNum, std::greater<double>());
114 }
115}
116
127void SortXAxis::copyXandDxToOutputWorkspace(const std::vector<std::size_t> &workspaceIndices,
128 const Mantid::API::MatrixWorkspace &inputWorkspace,
129 Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum) {
130 // Move an ordered X to the output workspace
131 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.x(specNum).size(); workspaceIndex++) {
132 outputWorkspace.mutableX(specNum)[workspaceIndex] = inputWorkspace.x(specNum)[workspaceIndices[workspaceIndex]];
133 }
134
135 // If Dx's are present, move Dx's to the output workspace
136 // If Dx's are present, move Dx's to the output workspace
137 if (inputWorkspace.hasDx(specNum)) {
138 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.dx(specNum).size(); workspaceIndex++) {
139 outputWorkspace.mutableDx(specNum)[workspaceIndex] = inputWorkspace.dx(specNum)[workspaceIndices[workspaceIndex]];
140 }
141 }
142}
143
156void SortXAxis::copyYandEToOutputWorkspace(std::vector<std::size_t> &workspaceIndices,
157 const Mantid::API::MatrixWorkspace &inputWorkspace,
158 Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum,
159 bool isAProperHistogram) {
160 // If Histogram data find the biggest index value and remove it from
161 // workspaceIndices
162 if (isAProperHistogram) {
163 auto lastIndexIt = std::find(workspaceIndices.begin(), workspaceIndices.end(), inputWorkspace.y(specNum).size());
164 workspaceIndices.erase(lastIndexIt);
165 }
166
167 const auto &inSpaceY = inputWorkspace.y(specNum);
168 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.y(specNum).size(); workspaceIndex++) {
169 outputWorkspace.mutableY(specNum)[workspaceIndex] = inSpaceY[workspaceIndices[workspaceIndex]];
170 }
171
172 const auto &inSpaceE = inputWorkspace.e(specNum);
173 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.e(specNum).size(); workspaceIndex++) {
174 outputWorkspace.mutableE(specNum)[workspaceIndex] = inSpaceE[workspaceIndices[workspaceIndex]];
175 }
176}
177
178void SortXAxis::copyToOutputWorkspace(std::vector<std::size_t> &workspaceIndices,
179 const Mantid::API::MatrixWorkspace &inputWorkspace,
180 Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum,
181 bool isAProperHistogram) {
182 copyXandDxToOutputWorkspace(workspaceIndices, inputWorkspace, outputWorkspace, specNum);
183 copyYandEToOutputWorkspace(workspaceIndices, inputWorkspace, outputWorkspace, specNum, isAProperHistogram);
184}
185
197template <typename Comparator>
198bool isItSorted(Comparator const &compare, const Mantid::API::MatrixWorkspace &inputWorkspace) {
199 for (auto specNum = 0u; specNum < inputWorkspace.getNumberHistograms(); specNum++) {
200 if (!std::is_sorted(inputWorkspace.x(specNum).begin(), inputWorkspace.x(specNum).end(),
201 [&](double lhs, double rhs) -> bool { return compare(lhs, rhs); })) {
202 return false;
203 }
204 }
205 return true;
206}
207
216 // Assuming all X and Ys are the same, if X is not the same size as y, assume
217 // it is a histogram
218 if (inputWorkspace.x(0).size() != inputWorkspace.y(0).size()) {
219 // The only way to guarantee that a histogram is a proper histogram, is to
220 // check whether each data value is in the correct order.
221 if (!isItSorted(std::greater<double>(), inputWorkspace)) {
222 if (!isItSorted(std::less<double>(), inputWorkspace)) {
223 throw std::runtime_error("The data entered contains an invalid histogram: histogram has an "
224 "unordered x-axis.");
225 }
226 }
227 return true;
228 }
229 return false;
230}
231
232} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
const std::vector< double > & rhs
#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
Base MatrixWorkspace Abstract Class.
const HistogramData::HistogramE & e(const size_t index) const
HistogramData::HistogramX & mutableX(const size_t index) &
const HistogramData::HistogramDx & dx(const size_t index) const
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
const HistogramData::HistogramX & x(const size_t index) const
virtual bool hasDx(const std::size_t index) const
Probes if DX (X Error) values were set on a particular spectrum.
HistogramData::HistogramE & mutableE(const size_t index) &
HistogramData::HistogramDx & mutableDx(const size_t index) &
HistogramData::HistogramY & mutableY(const size_t index) &
const HistogramData::HistogramY & y(const size_t index) const
A property class for workspaces.
SortXAxis will take Histogram or Point data and reorder it based on the X Axis' values,...
Definition: SortXAxis.h:24
std::vector< std::size_t > createIndexes(const size_t)
Gets a vector of numbers from 0 to the sizeOfX-1 and returns it.
Definition: SortXAxis.cpp:81
void init() override
Virtual method - must be overridden by concrete algorithm.
Definition: SortXAxis.cpp:37
bool determineIfHistogramIsValid(const Mantid::API::MatrixWorkspace &inputWorkspace)
Determines whether it is a valid histogram or not.
Definition: SortXAxis.cpp:215
void exec() override
Virtual method - must be overridden by concrete algorithm.
Definition: SortXAxis.cpp:50
int version() const override
function to return a version of the algorithm, must be overridden in all algorithms
Definition: SortXAxis.cpp:28
const std::string summary() const override
function returns a summary message that will be displayed in the default GUI, and in the help.
Definition: SortXAxis.cpp:32
void copyYandEToOutputWorkspace(std::vector< std::size_t > &workspaceIndices, const Mantid::API::MatrixWorkspace &inputWorkspace, Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int SpecNum, bool isAProperHistogram)
Copies the sorted inputworkspace into the output workspace without using clone because of how histogr...
Definition: SortXAxis.cpp:156
void copyXandDxToOutputWorkspace(const std::vector< std::size_t > &workspaceIndices, const Mantid::API::MatrixWorkspace &inputWorkspace, Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum)
Copies the sorted inputworkspace into the output workspace without using clone because of how histogr...
Definition: SortXAxis.cpp:127
void sortIndicesByX(std::vector< std::size_t > &workspaceIndices, const std::string &order, const Mantid::API::MatrixWorkspace &inputWorkspace, unsigned int specNum)
Definition: SortXAxis.cpp:108
void copyToOutputWorkspace(std::vector< std::size_t > &workspaceIndices, const Mantid::API::MatrixWorkspace &inputWorkspace, Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum, bool isAProperHistogram)
Definition: SortXAxis.cpp:178
const std::string category() const override
function to return a category of the algorithm.
Definition: SortXAxis.cpp:30
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
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
bool isItSorted(Comparator const &compare, const Mantid::API::MatrixWorkspace &inputWorkspace)
determines whether or not a given spectrum is sorted based on a passed comparator
Definition: SortXAxis.cpp:198
void sortByXValue(std::vector< std::size_t > &workspaceIndices, const Mantid::API::MatrixWorkspace &inputWorkspace, unsigned int specNum, Comparator const &compare)
A template for sorting the values given a comparator.
Definition: SortXAxis.cpp:101
bool compare(const mypair &left, const mypair &right)
Definition: LoadSassena.cpp:91
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.
STL namespace.
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54