Mantid
Loading...
Searching...
No Matches
ExtractQENSMembers.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 +
8
10#include "MantidAPI/Axis.h"
13
14#include <algorithm>
15#include <boost/numeric/conversion/cast.hpp>
16
17namespace {
18Mantid::Kernel::Logger g_log("ExtractQENSMembers");
19}
20
21namespace Mantid::Algorithms {
22
23using namespace API;
24using namespace Kernel;
25
26// Register the algorithm into the AlgorithmFactory
27DECLARE_ALGORITHM(ExtractQENSMembers)
28
29//----------------------------------------------------------------------------------------------
30
31
32const std::string ExtractQENSMembers::name() const { return "ExtractQENSMembers"; }
33
35int ExtractQENSMembers::version() const { return 1; }
36
38const std::string ExtractQENSMembers::category() const { return "Workflow\\MIDAS"; }
39
41const std::string ExtractQENSMembers::summary() const { return "Extracts the fit members from a QENS fit"; }
42
43//----------------------------------------------------------------------------------------------
47 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input, PropertyMode::Optional),
48 "The input workspace used in the fit. Ignored if 'InputWorkspaces' "
49 "property is provided.");
50 declareProperty(std::make_unique<ArrayProperty<std::string>>("InputWorkspaces", ""),
51 "List of the workspaces used in the fit.");
52 declareProperty(std::make_unique<WorkspaceProperty<WorkspaceGroup>>("ResultWorkspace", "", Direction::Input),
53 "The result group workspace produced in a QENS fit.");
54 declareProperty("RenameConvolvedMembers", false,
55 "If true, renames the n-th 'Convolution' member, to the n-th "
56 "supplied name in the ConvolvedMembers property.");
57 declareProperty(std::make_unique<ArrayProperty<std::string>>("ConvolvedMembers"),
58 "A list of the names of the members which were convolved "
59 "before being output by the fit routine. These must be "
60 "provided in the same order as originally provided to the "
61 "fit.");
62 declareProperty(std::make_unique<WorkspaceProperty<WorkspaceGroup>>("OutputWorkspace", "", Direction::Output),
63 "The output workspace group, containing the fit members.");
64}
65
66std::map<std::string, std::string> ExtractQENSMembers::validateInputs() {
67 std::map<std::string, std::string> errors;
68 std::vector<std::string> workspaceNames = getProperty("InputWorkspaces");
69 MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
70
71 if (workspaceNames.empty() && !inputWorkspace)
72 errors["InputWorkspace"] = "Neither the InputWorkspace or InputWorkspaces "
73 "property have been defined.";
74 return errors;
75}
76
78 auto inputWorkspaces = getInputWorkspaces();
79 WorkspaceGroup_sptr resultWS = getProperty("ResultWorkspace");
80 MatrixWorkspace_sptr initialWS = std::dynamic_pointer_cast<MatrixWorkspace>(resultWS->getItem(0));
81 const auto qValues = getQValues(inputWorkspaces);
82 auto members = getAxisLabels(initialWS, 1);
83
84 bool renameConvolved = getProperty("RenameConvolvedMembers");
85 if (renameConvolved)
86 members = renameConvolvedMembers(members, getProperty("ConvolvedMembers"));
87
88 auto memberWorkspaces = createMembersWorkspaces(initialWS, members);
89
90 for (auto i = 1u; i < resultWS->size(); ++i)
91 appendToMembers(std::dynamic_pointer_cast<MatrixWorkspace>(resultWS->getItem(i)), memberWorkspaces);
92 setNumericAxis(memberWorkspaces, qValues, 1);
93
94 std::string outputWSName = getProperty("OutputWorkspace");
95 auto workspaceNames = addMembersToADS(members, memberWorkspaces, outputWSName);
96 setProperty("OutputWorkspace", groupWorkspaces(workspaceNames));
97}
98
99std::vector<MatrixWorkspace_sptr> ExtractQENSMembers::getInputWorkspaces() const {
100 const std::vector<std::string> workspaceNames = getProperty("InputWorkspaces");
101 std::vector<MatrixWorkspace_sptr> workspaces;
102
103 if (!workspaceNames.empty()) {
104 workspaces.reserve(workspaceNames.size());
105 auto &ADS = AnalysisDataService::Instance();
106 std::transform(workspaceNames.cbegin(), workspaceNames.cend(), std::back_inserter(workspaces),
107 [&ADS](const auto &name) { return ADS.retrieveWS<MatrixWorkspace>(name); });
108 } else
109 workspaces.emplace_back(getProperty("InputWorkspace"));
110 return workspaces;
111}
112
119std::vector<double> ExtractQENSMembers::getQValues(const std::vector<MatrixWorkspace_sptr> &workspaces) {
120 std::vector<double> qValues;
121
122 for (const auto &workspace : workspaces) {
123 auto getQs = createChildAlgorithm("GetQsInQENSData", -1.0, -1.0, false);
124 getQs->setProperty("InputWorkspace", workspace);
125 getQs->executeAsChildAlg();
126 const std::vector<double> values = getQs->getProperty("Qvalues");
127 qValues.insert(std::end(qValues), std::begin(values), std::end(values));
128 }
129 return qValues;
130}
131
141 size_t axisIndex) const {
142 auto axis = workspace->getAxis(axisIndex);
143 std::vector<std::string> labels;
144 labels.reserve(axis->length());
145
146 for (auto i = 0u; i < axis->length(); ++i)
147 labels.emplace_back(axis->label(i));
148 return labels;
149}
150
159std::vector<std::string> ExtractQENSMembers::renameConvolvedMembers(const std::vector<std::string> &members,
160 const std::vector<std::string> &newNames) const {
161 std::vector<std::string> newMembers;
162 newMembers.reserve(members.size());
163 auto index = 0u;
164
165 for (const auto &member : members) {
166 if (member == "Convolution" && index < newNames.size())
167 newMembers.emplace_back(newNames[index++]);
168 else
169 newMembers.emplace_back(member);
170 }
171 return newMembers;
172}
173
182 auto extractAlg = createChildAlgorithm("ExtractSpectra", -1.0, -1.0, false);
183 extractAlg->setProperty("InputWorkspace", inputWS);
184 extractAlg->setProperty("OutputWorkspace", "__extracted");
185 extractAlg->setProperty("StartWorkspaceIndex", boost::numeric_cast<int>(spectrum));
186 extractAlg->setProperty("EndWorkspaceIndex", boost::numeric_cast<int>(spectrum));
187 extractAlg->executeAsChildAlg();
188 return extractAlg->getProperty("OutputWorkspace");
189}
190
199 const MatrixWorkspace_sptr &spectraWorkspace) {
200 auto appendAlg = createChildAlgorithm("AppendSpectra", -1.0, -1.0, false);
201 appendAlg->setProperty("InputWorkspace1", inputWS);
202 appendAlg->setProperty("InputWorkspace2", spectraWorkspace);
203 appendAlg->setProperty("OutputWorkspace", inputWS);
204 appendAlg->executeAsChildAlg();
205 return appendAlg->getProperty("OutputWorkspace");
206}
207
214WorkspaceGroup_sptr ExtractQENSMembers::groupWorkspaces(const std::vector<std::string> &workspaceNames) {
215 auto groupAlg = createChildAlgorithm("GroupWorkspaces", -1.0, -1.0, false);
216 groupAlg->setProperty("InputWorkspaces", workspaceNames);
217 groupAlg->setProperty("OutputWorkspace", "__grouped");
218 groupAlg->execute();
219 return groupAlg->getProperty("OutputWorkspace");
220}
221
230std::vector<MatrixWorkspace_sptr> ExtractQENSMembers::createMembersWorkspaces(const MatrixWorkspace_sptr &initialWS,
231 const std::vector<std::string> &members) {
232 std::vector<MatrixWorkspace_sptr> memberWorkspaces;
233 memberWorkspaces.reserve(members.size());
234 for (auto i = 0u; i < members.size(); ++i)
235 memberWorkspaces.emplace_back(extractSpectrum(initialWS, i));
236 return memberWorkspaces;
237}
238
247 std::vector<Mantid::API::MatrixWorkspace_sptr> &members) {
248 for (auto i = 0u; i < members.size(); ++i)
249 members[i] = appendSpectra(members[i], extractSpectrum(resultWS, i));
250}
251
260void ExtractQENSMembers::setNumericAxis(const std::vector<MatrixWorkspace_sptr> &workspaces,
261 const std::vector<double> &values, size_t axisIndex) const {
262 auto qAxis = NumericAxis(values.size());
263 for (auto i = 0u; i < values.size(); ++i)
264 qAxis.setValue(i, values[i]);
265
266 for (auto &workspace : workspaces) {
267 workspace->replaceAxis(axisIndex, std::make_unique<NumericAxis>(qAxis));
268 workspace->setYUnitLabel("MomentumTransfer");
269 }
270}
271
282std::vector<std::string>
283ExtractQENSMembers::addMembersToADS(const std::vector<std::string> &members,
284 const std::vector<Mantid::API::MatrixWorkspace_sptr> &memberWorkspaces,
285 const std::string &outputWSName) {
286 std::unordered_map<std::string, size_t> nameCounts;
287 std::vector<std::string> workspaceNames;
288 workspaceNames.reserve(members.size());
289
290 for (auto i = 0u; i < members.size(); ++i) {
291 std::string count = "";
292
293 if (nameCounts.find(members[i]) == nameCounts.end())
294 nameCounts[members[i]] = 1;
295 else
296 count = std::to_string(++nameCounts[members[i]]);
297
298 const auto name = outputWSName + "_" + members[i] + count;
299 AnalysisDataService::Instance().addOrReplace(name, memberWorkspaces[i]);
300 workspaceNames.emplace_back(name);
301 }
302 return workspaceNames;
303}
304
305} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
int count
counter
Definition: Matrix.cpp:37
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) override
Create a Child Algorithm.
Kernel::IPropertyManager::TypedValue getProperty(const std::string &name) const override
Get the property held by this object.
Class to represent a numeric axis of a workspace.
Definition: NumericAxis.h:29
A property class for workspaces.
ExtractQENSMembers : Extracts the fit members from a QENS fit.
std::vector< Mantid::API::MatrixWorkspace_sptr > createMembersWorkspaces(const Mantid::API::MatrixWorkspace_sptr &initialWS, const std::vector< std::string > &members)
Creates the member workspaces from an initial result workspace and the member names.
void setNumericAxis(const std::vector< Mantid::API::MatrixWorkspace_sptr > &workspaces, const std::vector< double > &values, size_t axisIndex) const
Creates and sets a numeric axis, filled with the specified values, on each of the specified workspace...
const std::string name() const override
Algorithms name for identification.
std::vector< std::string > addMembersToADS(const std::vector< std::string > &members, const std::vector< Mantid::API::MatrixWorkspace_sptr > &memberWorkspaces, const std::string &outputWSName)
Adds the specified member workspaces to the analysis data service.
Mantid::API::MatrixWorkspace_sptr appendSpectra(const Mantid::API::MatrixWorkspace_sptr &inputWS, const Mantid::API::MatrixWorkspace_sptr &spectraWorkspace)
Appends the spectra of a specified workspace to another specified input workspace.
std::map< std::string, std::string > validateInputs() override
void appendToMembers(const Mantid::API::MatrixWorkspace_sptr &resultWS, std::vector< Mantid::API::MatrixWorkspace_sptr > &members)
Appends the n-th spectra in the specified result workspace to the n-th specified member workspace.
void init() override
Initialize the algorithm's properties.
std::vector< double > getQValues(const std::vector< Mantid::API::MatrixWorkspace_sptr > &workspaces)
Extracts the Q-Values from the specified workspace.
std::vector< std::string > renameConvolvedMembers(const std::vector< std::string > &members, const std::vector< std::string > &newNames) const
Renames the convolved members in the specified vector of members, to the respective names in the spec...
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
Mantid::API::MatrixWorkspace_sptr extractSpectrum(const Mantid::API::MatrixWorkspace_sptr &inputWS, size_t spectrum)
Extracts the specified spectrum from the specified spectrum.
int version() const override
Algorithm's version for identification.
const std::string category() const override
Algorithm's category for identification.
std::vector< Mantid::API::MatrixWorkspace_sptr > getInputWorkspaces() const
std::vector< std::string > getAxisLabels(const Mantid::API::MatrixWorkspace_sptr &workspace, size_t axisIndex) const
Retrieves the axis labels from the axis with the specified index, in the specified workspace.
Mantid::API::WorkspaceGroup_sptr groupWorkspaces(const std::vector< std::string > &workspaceNames)
Groups the workspaces with the specified name.
Support for a property that holds an array of values.
Definition: ArrayProperty.h:28
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54