Mantid
Loading...
Searching...
No Matches
TransposeMD.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 "MantidAPI/Progress.h"
19
20#include <algorithm>
21#include <memory>
22#include <numeric>
23#include <vector>
24
25namespace Mantid::MDAlgorithms {
26
27using namespace Mantid::Kernel;
28using namespace Mantid::API;
29using namespace Mantid::DataObjects;
30
31// Register the algorithm into the AlgorithmFactory
32DECLARE_ALGORITHM(TransposeMD)
33
34//----------------------------------------------------------------------------------------------
35
36
37const std::string TransposeMD::name() const { return "TransposeMD"; }
38
40int TransposeMD::version() const { return 1; }
41
43const std::string TransposeMD::category() const { return "MDAlgorithms\\Transforms"; }
44
46const std::string TransposeMD::summary() const {
47 return "Transpose the dimensions of a MDWorkspace to create a new output "
48 "MDWorkspace";
49}
50
51//----------------------------------------------------------------------------------------------
55 declareProperty(std::make_unique<WorkspaceProperty<IMDHistoWorkspace>>("InputWorkspace", "", Direction::Input),
56 "An input workspace.");
57
58 auto axisValidator = std::make_shared<ArrayBoundedValidator<int>>();
59 axisValidator->setLower(0);
60
61 declareProperty(std::make_unique<ArrayProperty<int>>("Axes", std::vector<int>(0), axisValidator, Direction::Input),
62 "Permutes the axes according to the indexes given. Zero "
63 "based indexing. Defaults to no transpose.");
64
65 declareProperty(std::make_unique<WorkspaceProperty<IMDHistoWorkspace>>("OutputWorkspace", "", Direction::Output),
66 "An output workspace.");
67}
68
69//----------------------------------------------------------------------------------------------
73 IMDHistoWorkspace_sptr inWSProp = getProperty("InputWorkspace");
74 auto inWS = std::dynamic_pointer_cast<MDHistoWorkspace>(inWSProp);
75 if (!inWS) {
76 throw std::invalid_argument("Expect the InputWorkspace to be a MDHistoWorkspace");
77 }
78
79 size_t nDimsInput = inWS->getNumDims();
80 size_t nDimsOutput = inWS->getNumDims(); // The assumed default.
81 std::vector<int> axesInts = this->getProperty("Axes");
82 std::vector<size_t> axes(axesInts.begin(), axesInts.end());
83 Property const *axesProperty = this->getProperty("Axes");
84 if (!axesProperty->isDefault()) {
85 Kernel::MDAxisValidator checker(axesInts, nDimsInput, false);
86 auto axisErrors = checker.validate();
87 if (!axisErrors.empty()) {
88 std::string error = axisErrors.begin()->second;
89 throw std::invalid_argument(error.c_str());
90 }
91 nDimsOutput = axes.size();
92 } else {
93 axes = std::vector<size_t>(nDimsOutput);
94 std::iota(axes.begin(), axes.end(), 0);
95 }
96
97 std::vector<coord_t> origin(nDimsOutput, 0.0);
98 std::vector<Geometry::IMDDimension_sptr> targetGeometry;
99 for (size_t i = 0; i < nDimsOutput; ++i) {
100 // Clone the dimension corresponding to the axis requested.
101 auto cloneDim = Geometry::IMDDimension_sptr(new Geometry::MDHistoDimension(inWS->getDimension(axes[i]).get()));
102 targetGeometry.emplace_back(cloneDim);
103 }
104
105 // Make the output workspace in the right shape.
106 auto outWS = MDHistoWorkspace_sptr(new MDHistoWorkspace(targetGeometry));
107 outWS->copyExperimentInfos(*inWS);
108
109 // Configure the coordinate transform.
110 std::vector<coord_t> scaling(nDimsOutput, 1); // No scaling
111 CoordTransformAligned coordTransform(nDimsInput, nDimsOutput, axes, origin, scaling);
112
113 uint64_t nPoints = inWS->getNPoints();
114 Progress progress(this, 0.0, 1.0, size_t(nPoints));
115
116 progress.reportIncrement(size_t(double(nPoints) * 0.1)); // Report ~10% progress
117
118 const int nThreads = Mantid::API::FrameworkManager::Instance().getNumOMPThreads(); // NThreads to Request
119
120 auto iterators = inWS->createIterators(nThreads, nullptr);
121
123 for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT
124
126 auto inIterator = iterators[it].get();
127 do {
128 auto center = inIterator->getCenter();
129 const coord_t *incoords = center.getBareArray();
130 std::vector<coord_t> outcoords(nDimsOutput);
131 coordTransform.apply(incoords, &outcoords[0]);
132
133 size_t index = outWS->getLinearIndexAtCoord(&outcoords[0]);
134 outWS->setSignalAt(index, inIterator->getSignal());
135 const signal_t error = inIterator->getError();
136 outWS->setErrorSquaredAt(index, error * error);
137 outWS->setNumEventsAt(index, Mantid::signal_t(inIterator->getNumEvents()));
138 outWS->setMDMaskAt(index, inIterator->getIsMasked());
139 progress.report();
140 } while (inIterator->next());
142 }
144
145 this->setProperty("OutputWorkspace", outWS);
146}
147
148} // namespace Mantid::MDAlgorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double error
std::map< DeltaEMode::Type, std::string > index
#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_FOR_NO_WSP_CHECK()
#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_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.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
Unique type declaration for which dimensions are used in the input workspace.
void apply(const coord_t *inputVector, coord_t *outVector) const override
Apply the coordinate transformation.
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.
MDAxisValidator is a class that checks the number of MD axes match the number of workspace dimensions...
virtual std::map< std::string, std::string > validate() const
Checks the MD axes given against the given number of dimensions of the input workspace.
Base class for properties.
Definition Property.h:94
virtual bool isDefault() const =0
Overriden function that returns if property has the same value that it was initialised with,...
TransposeMD : Transpose an MDWorkspace.
Definition TransposeMD.h:18
const std::string category() const override
Algorithm's category for identification.
void exec() override
Execute the algorithm.
int version() const override
Algorithm's version for identification.
void init() override
Initialize the algorithm's properties.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
std::shared_ptr< IMDHistoWorkspace > IMDHistoWorkspace_sptr
shared pointer to Mantid::API::IMDHistoWorkspace
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
std::shared_ptr< IMDDimension > IMDDimension_sptr
Shared Pointer for IMDDimension. Frequently used type in framework.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition MDTypes.h:27
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition MDTypes.h:36
STL namespace.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54