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
14using namespace Mantid;
15using namespace Mantid::API;
16using namespace Mantid::Kernel;
17using namespace Mantid::Algorithms;
18using namespace Mantid::DataObjects;
19using namespace Mantid::HistogramData;
20
21namespace Mantid::Algorithms {
22
24
25const std::string SortXAxis::name() const { return "SortXAxis"; }
26
27int SortXAxis::version() const { return 1; }
28
29const std::string SortXAxis::category() const { return "Transforms\\Axes;Utility\\Sorting"; }
30
31const std::string SortXAxis::summary() const {
32 return "Clones the input MatrixWorkspace(s) and orders the x-axis in an "
33 "ascending or descending fashion.";
34}
35
37 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
38 "Input Workspace");
39
40 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
41 "Sorted Output Workspace");
42
43 auto orderingValues = std::vector<std::string>({"Ascending", "Descending"});
44 auto orderingValidator = std::make_shared<StringListValidator>(orderingValues);
45 declareProperty("Ordering", orderingValues[0], orderingValidator, "Ascending or descending sorting",
47}
48
50 MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
51 MatrixWorkspace_sptr outputWorkspace = inputWorkspace->clone();
52 // Check if it is a valid histogram here
53 const bool isAProperHistogram = determineIfHistogramIsValid(*inputWorkspace);
54
55 // Define everything you can outside of the for loop
56 // Assume that all spec are the same size
57 const auto sizeOfX = inputWorkspace->x(0).size();
58
59 PARALLEL_FOR_IF(Kernel::threadSafe(*inputWorkspace, *outputWorkspace))
60 for (int specNum = 0u; specNum < (int)inputWorkspace->getNumberHistograms(); specNum++) {
62 auto workspaceIndices = createIndexes(sizeOfX);
63
64 sortIndicesByX(workspaceIndices, getProperty("Ordering"), *inputWorkspace, specNum);
65
66 copyToOutputWorkspace(workspaceIndices, *inputWorkspace, *outputWorkspace, specNum, isAProperHistogram);
68 }
70
71 setProperty("OutputWorkspace", outputWorkspace);
72}
73
80std::vector<std::size_t> SortXAxis::createIndexes(const size_t sizeOfX) {
81 std::vector<std::size_t> workspaceIndices;
82 workspaceIndices.reserve(sizeOfX);
83 for (auto workspaceIndex = 0u; workspaceIndex < sizeOfX; workspaceIndex++) {
84 workspaceIndices.emplace_back(workspaceIndex);
85 }
86 return workspaceIndices;
87}
88
99template <typename Comparator>
100void sortByXValue(std::vector<std::size_t> &workspaceIndices, const Mantid::API::MatrixWorkspace &inputWorkspace,
101 unsigned int specNum, Comparator const &compare) {
102 std::sort(workspaceIndices.begin(), workspaceIndices.end(), [&](std::size_t lhs, std::size_t rhs) -> bool {
103 return compare(inputWorkspace.x(specNum)[lhs], inputWorkspace.x(specNum)[rhs]);
104 });
105}
106
107void SortXAxis::sortIndicesByX(std::vector<std::size_t> &workspaceIndices, const std::string &order,
108 const Mantid::API::MatrixWorkspace &inputWorkspace, unsigned int specNum) {
109 if (order == "Ascending") {
110 sortByXValue(workspaceIndices, inputWorkspace, specNum, std::less<double>());
111 } else if (order == "Descending") {
112 sortByXValue(workspaceIndices, inputWorkspace, specNum, std::greater<double>());
113 }
114}
115
126void SortXAxis::copyXandDxToOutputWorkspace(const std::vector<std::size_t> &workspaceIndices,
127 const Mantid::API::MatrixWorkspace &inputWorkspace,
128 Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum) {
129 // Move an ordered X to the output workspace
130 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.x(specNum).size(); workspaceIndex++) {
131 outputWorkspace.mutableX(specNum)[workspaceIndex] = inputWorkspace.x(specNum)[workspaceIndices[workspaceIndex]];
132 }
133
134 // If Dx's are present, move Dx's to the output workspace
135 // If Dx's are present, move Dx's to the output workspace
136 if (inputWorkspace.hasDx(specNum)) {
137 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.dx(specNum).size(); workspaceIndex++) {
138 outputWorkspace.mutableDx(specNum)[workspaceIndex] = inputWorkspace.dx(specNum)[workspaceIndices[workspaceIndex]];
139 }
140 }
141}
142
155void SortXAxis::copyYandEToOutputWorkspace(std::vector<std::size_t> &workspaceIndices,
156 const Mantid::API::MatrixWorkspace &inputWorkspace,
157 Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum,
158 bool isAProperHistogram) {
159 // If Histogram data find the biggest index value and remove it from
160 // workspaceIndices
161 if (isAProperHistogram) {
162 auto lastIndexIt = std::find(workspaceIndices.begin(), workspaceIndices.end(), inputWorkspace.y(specNum).size());
163 workspaceIndices.erase(lastIndexIt);
164 }
165
166 const auto &inSpaceY = inputWorkspace.y(specNum);
167 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.y(specNum).size(); workspaceIndex++) {
168 outputWorkspace.mutableY(specNum)[workspaceIndex] = inSpaceY[workspaceIndices[workspaceIndex]];
169 }
170
171 const auto &inSpaceE = inputWorkspace.e(specNum);
172 for (auto workspaceIndex = 0u; workspaceIndex < inputWorkspace.e(specNum).size(); workspaceIndex++) {
173 outputWorkspace.mutableE(specNum)[workspaceIndex] = inSpaceE[workspaceIndices[workspaceIndex]];
174 }
175}
176
177void SortXAxis::copyToOutputWorkspace(std::vector<std::size_t> &workspaceIndices,
178 const Mantid::API::MatrixWorkspace &inputWorkspace,
179 Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum,
180 bool isAProperHistogram) {
181 copyXandDxToOutputWorkspace(workspaceIndices, inputWorkspace, outputWorkspace, specNum);
182 copyYandEToOutputWorkspace(workspaceIndices, inputWorkspace, outputWorkspace, specNum, isAProperHistogram);
183}
184
196template <typename Comparator>
197bool isItSorted(Comparator const &compare, const Mantid::API::MatrixWorkspace &inputWorkspace) {
198 for (auto specNum = 0u; specNum < inputWorkspace.getNumberHistograms(); specNum++) {
199 if (!std::is_sorted(inputWorkspace.x(specNum).begin(), inputWorkspace.x(specNum).end(),
200 [&](double lhs, double rhs) -> bool { return compare(lhs, rhs); })) {
201 return false;
202 }
203 }
204 return true;
205}
206
215 // Assuming all X and Ys are the same, if X is not the same size as y, assume
216 // it is a histogram
217 if (inputWorkspace.x(0).size() != inputWorkspace.y(0).size()) {
218 // The only way to guarantee that a histogram is a proper histogram, is to
219 // check whether each data value is in the correct order.
220 if (!isItSorted(std::greater<double>(), inputWorkspace)) {
221 if (!isItSorted(std::less<double>(), inputWorkspace)) {
222 throw std::runtime_error("The data entered contains an invalid histogram: histogram has an "
223 "unordered x-axis.");
224 }
225 }
226 return true;
227 }
228 return false;
229}
230
231} // namespace Mantid::Algorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
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...
#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.
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:80
void init() override
Virtual method - must be overridden by concrete algorithm.
Definition SortXAxis.cpp:36
bool determineIfHistogramIsValid(const Mantid::API::MatrixWorkspace &inputWorkspace)
Determines whether it is a valid histogram or not.
void exec() override
Virtual method - must be overridden by concrete algorithm.
Definition SortXAxis.cpp:49
int version() const override
function to return a version of the algorithm, must be overridden in all algorithms
Definition SortXAxis.cpp:27
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:31
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...
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...
void sortIndicesByX(std::vector< std::size_t > &workspaceIndices, const std::string &order, const Mantid::API::MatrixWorkspace &inputWorkspace, unsigned int specNum)
void copyToOutputWorkspace(std::vector< std::size_t > &workspaceIndices, const Mantid::API::MatrixWorkspace &inputWorkspace, Mantid::API::MatrixWorkspace &outputWorkspace, unsigned int specNum, bool isAProperHistogram)
const std::string category() const override
function to return a category of the algorithm.
Definition SortXAxis.cpp:29
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
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.
bool compare(const mypair &left, const mypair &right)
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.
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