Mantid
Loading...
Searching...
No Matches
SetMDFrame.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 +
22
23#include <boost/pointer_cast.hpp>
24#include <map>
25#include <memory>
26
27namespace Mantid::MDAlgorithms {
28
31
32// Register the algorithm into the AlgorithmFactory
33DECLARE_ALGORITHM(SetMDFrame)
34
35const std::string SetMDFrame::mdFrameSpecifier = "MDFrame";
36
37//----------------------------------------------------------------------------------------------
38
40const std::string SetMDFrame::name() const { return "SetMDFrame"; }
41
43int SetMDFrame::version() const { return 1; }
44
46const std::string SetMDFrame::category() const {
47 return "MDAlgorithms";
48 ;
49}
50
52const std::string SetMDFrame::summary() const {
53 return "Sets a new MDFrame type for a selection of axes for legacy MDHisto "
54 "and MDEvent "
55 "workspaces.";
56}
57
58//----------------------------------------------------------------------------------------------
63 std::make_unique<WorkspaceProperty<Mantid::API::IMDWorkspace>>("InputWorkspace", "", Direction::InOut),
64 "The workspace for which the MDFrames are to be changed. "
65 "Note that only MDHisto and MDEvent workspaces can be "
66 "altered by this algorithm.");
67
68 // Options for the MDFrames
69 std::vector<std::string> mdFrames;
71 mdFrames.emplace_back(Mantid::Geometry::QSample::QSampleName);
72 mdFrames.emplace_back(Mantid::Geometry::QLab::QLabName);
73 mdFrames.emplace_back(Mantid::Geometry::HKL::HKLName);
75
76 // Create a selection of MDFrames and units for each dimension
77 std::string propName = mdFrameSpecifier;
78
80 std::make_shared<Mantid::Kernel::StringListValidator>(mdFrames), "MDFrame type selection.\n");
81
82 auto axisValidator = std::make_shared<Mantid::Kernel::ArrayBoundedValidator<int>>();
83 axisValidator->setLower(0);
85 std::make_unique<Kernel::ArrayProperty<int>>("Axes", std::vector<int>(0), axisValidator, Direction::Input),
86 "Selects the axes which are going to be set to the new MDFrame type.");
87}
88
89//----------------------------------------------------------------------------------------------
93 Mantid::API::IMDWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
94 std::vector<int> axesInts = this->getProperty("Axes");
95 std::vector<size_t> axes(axesInts.begin(), axesInts.end());
96
97 // If no axes were specified, then don't do anything
98 if (axes.empty()) {
99 return;
100 }
101
102 for (auto &axe : axes) {
103 // Get associated dimension
104 auto dimension = inputWorkspace->getDimension(axe);
105
106 // Provide a new MDFrame
107 std::string frameSelection = getProperty(mdFrameSpecifier);
108 const auto &mdFrame = dimension->getMDFrame();
109 auto newMDFrame = createMDFrame(frameSelection, mdFrame);
110
111 // Set the new MDFrame. We need to alter the MDFrame information
112 // of the MDHistoDimension which we only get as a const -- hence
113 // we need a const-cast at this point.
114 auto mdHistoDimension = std::const_pointer_cast<Mantid::Geometry::MDHistoDimension>(
115 std::dynamic_pointer_cast<const Mantid::Geometry::MDHistoDimension>(dimension));
116 if (!mdHistoDimension) {
117 throw std::runtime_error("SetMDFrame: Cannot convert to MDHistDimension");
118 }
119 mdHistoDimension->setMDFrame(*newMDFrame);
120 }
121}
122
127std::map<std::string, std::string> SetMDFrame::validateInputs() {
128 std::map<std::string, std::string> invalidProperties;
129 Mantid::API::IMDWorkspace_sptr ws = getProperty("InputWorkspace");
130
131 if (!std::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(ws) &&
132 !std::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(ws)) {
133 invalidProperties.insert(std::make_pair("InputWorkspace", "The input workspace has to be either "
134 "an MDEvent or MDHisto Workspace."));
135 return invalidProperties;
136 }
137
138 std::vector<int> axesInts = this->getProperty("Axes");
139 Kernel::MDAxisValidator axisChecker(axesInts, ws->getNumDims(), true);
140 auto axisErrors = axisChecker.validate();
141 for (auto &axisError : axisErrors) {
142 invalidProperties.insert(axisError);
143 }
144
145 return invalidProperties;
146}
147
155 const Mantid::Geometry::MDFrame &oldFrame) const {
156 auto mdFrameFactory = Mantid::Geometry::makeMDFrameFactoryChain();
159 oldFrame.getUnitLabel());
160 return mdFrameFactory->create(argument);
161 } else if (frameSelection == Mantid::Geometry::QSample::QSampleName) {
163 return mdFrameFactory->create(argument);
164 } else if (frameSelection == Mantid::Geometry::QLab::QLabName) {
166 return mdFrameFactory->create(argument);
167 } else if (frameSelection == Mantid::Geometry::HKL::HKLName) {
169 // We want to make sure here that we get an HKL MDFrame, hence we need to
170 // make sure that the HKL frame accepts the units
171 Mantid::Geometry::HKLFrameFactory hklFrameFactory;
172 auto canInterpret = hklFrameFactory.canInterpret(argument);
173 if (!canInterpret) {
174 throw std::invalid_argument("SetMDFrame: " + frameSelection +
175 " does not have units which are compatible "
176 "with an HKL frame. Please contact the "
177 "Mantid team if you believe that the units "
178 "should be compatible.");
179 }
180
181 return mdFrameFactory->create(argument);
182 } else if (frameSelection == Mantid::Geometry::UnknownFrame::UnknownFrameName) {
184 oldFrame.getUnitLabel());
185 return mdFrameFactory->create(argument);
186 } else {
187 throw std::invalid_argument("SetMDFrame: The selected MDFrame does not seem to be supported");
188 }
189}
190
191} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
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.
A property class for workspaces.
static const std::string GeneralFrameName
HKLFrame derived MDFrameFactory type.
bool canInterpret(const MDFrameArgument &argument) const override
Indicate an ability to intepret the string.
static const std::string HKLName
Definition HKL.h:26
Input argument type for MDFrameFactory chainable factory.
MDFrame : The coordinate frame for a dimension, or set of dimensions in a multidimensional workspace.
Definition MDFrame.h:22
virtual Mantid::Kernel::UnitLabel getUnitLabel() const =0
static const std::string QLabName
Definition QLab.h:34
static const std::string QSampleName
Definition QSample.h:22
static const std::string UnknownFrameName
Support for a property that holds an array of values.
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.
const std::string category() const override
Algorithm's category for identification.
Mantid::Geometry::MDFrame_uptr createMDFrame(const std::string &frameSelection, const Mantid::Geometry::MDFrame &oldFrame) const
Creates an MDFrame based on the users selection.
static const std::string mdFrameSpecifier
Definition SetMDFrame.h:22
std::map< std::string, std::string > validateInputs() override
Check the inputs for invalid values.
const std::string name() const override
Algorithms name 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< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
std::unique_ptr< MDFrame > MDFrame_uptr
Definition MDFrame.h:36
MDFrameFactory_uptr MANTID_GEOMETRY_DLL makeMDFrameFactoryChain()
Make a complete factory chain.
Describes the direction (within an algorithm) of a Property.
Definition Property.h:50
@ InOut
Both an input & output workspace.
Definition Property.h:55
@ Input
An input workspace.
Definition Property.h:53