Mantid
Loading...
Searching...
No Matches
CreateLogPropertyTable.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
11#include "MantidAPI/Run.h"
12#include "MantidAPI/TableRow.h"
19
20#include "boost/shared_ptr.hpp"
21
22#include <algorithm>
23#include <cassert>
24#include <map>
25#include <vector>
26
27namespace Mantid::Algorithms {
28// Register the algorithm into the AlgorithmFactory
29DECLARE_ALGORITHM(CreateLogPropertyTable)
30
31using namespace Kernel;
32using namespace API;
33
34namespace {
35enum GroupPolicy { ALL, FIRST, NONE };
36
37// Forward declarations.
38std::vector<MatrixWorkspace_sptr> retrieveMatrixWsList(const std::vector<std::string> &wsNames,
39 GroupPolicy groupPolicy);
40GroupPolicy getGroupPolicyByName(const std::string &name);
41std::set<std::string> getAllGroupPolicyNames();
42Math::StatisticType getStatisticTypeByName(const std::string &name);
43std::set<std::string> getAllStatisticTypeNames();
44} // namespace
45
50 // Input workspaces
52 "InputWorkspaces", std::make_shared<MandatoryValidator<std::vector<std::string>>>()),
53 "Name of the Input Workspaces from which to get log properties.");
54
55 // Output workspace
56 declareProperty(std::make_unique<WorkspaceProperty<ITableWorkspace>>("OutputWorkspace", "", Direction::Output),
57 "Name of the output ITableWorkspace.");
58
59 // Which log properties to use
61 "LogPropertyNames", std::make_shared<MandatoryValidator<std::vector<std::string>>>()),
62 "The names of the log properties to place in table.");
63
64 // How to handle time series logs
65 const std::set<std::string> statisticNames = getAllStatisticTypeNames();
66 declareProperty("TimeSeriesStatistic", "Mean", std::make_shared<StringListValidator>(statisticNames),
67 "The statistic to use when adding a time series log.");
68
69 // How to handle workspace groups
70 const std::set<std::string> groupPolicies = getAllGroupPolicyNames();
71 declareProperty("GroupPolicy", "First", std::make_shared<StringListValidator>(groupPolicies),
72 "The policy by which to handle GroupWorkspaces. \"All\" "
73 "will include all children in the table, \"First\" will "
74 "include "
75 "the first child, and \"None\" will not include any.");
76}
77
82 std::vector<std::string> wsNames = this->getProperty("InputWorkspaces");
83
84 // Retrieve a list of MatrixWorkspace pointers, using the given "GroupPolicy".
85 const std::string groupPolicyName = this->getPropertyValue("GroupPolicy");
86 const GroupPolicy groupPolicy = getGroupPolicyByName(groupPolicyName);
87 const std::vector<MatrixWorkspace_sptr> matrixWsList = retrieveMatrixWsList(wsNames, groupPolicy);
88
89 // Get the names of the properties that will be stored.
90 const std::vector<std::string> propNames = this->getProperty("LogPropertyNames");
91
92 // Make sure all workspaces contain the properties.
93 for (const auto &matrixWs : matrixWsList) {
94 const Run &run = matrixWs->run();
95 const std::string wsName = matrixWs->getName();
96
97 // Throw if a run does not have a property.
98 auto it = std::find_if(propNames.cbegin(), propNames.cend(),
99 [&run](const auto &propName) { return !run.hasProperty(propName); });
100 if (it != propNames.cend())
101 throw std::runtime_error("\"" + wsName + "\" does not have a run property of \"" + (*it) + "\".");
102 }
103
104 // Set up output table.
105 auto outputTable = std::make_shared<DataObjects::TableWorkspace>();
106 // One column for each property.
107 for (const auto &propName : propNames)
108 outputTable->addColumn("str", propName);
109 // One row for each workspace.
110 for (size_t i = 0; i < matrixWsList.size(); ++i)
111 outputTable->appendRow();
112
113 // Set the first column to X and all others to Y
114 // This is to reduce the number of steps required to plot the data
115 for (size_t i = 0; i < outputTable->columnCount(); ++i)
116 outputTable->getColumn(i)->setPlotType(i == 0 ? 1 : 2);
117
118 const std::string timeSeriesStatName = this->getPropertyValue("TimeSeriesStatistic");
119 const Math::StatisticType timeSeriesStat = getStatisticTypeByName(timeSeriesStatName);
120 // Populate output table with the requested run properties.
121 for (size_t i = 0; i < outputTable->rowCount(); ++i) {
122 TableRow row = outputTable->getRow(i);
123 MatrixWorkspace_sptr matrixWs = matrixWsList[i];
124
125 for (const auto &propName : propNames) {
126 Property *prop = matrixWs->run().getProperty(propName);
127 std::stringstream propValue;
128
129 if (prop->type().find("TimeValue") != std::string::npos) {
130 propValue << matrixWs->run().getLogAsSingleValue(propName, timeSeriesStat);
131 } else {
132 propValue << prop->value();
133 }
134
135 row << propValue.str();
136 }
137 }
138
139 this->setProperty("OutputWorkspace", outputTable);
140}
141
142namespace {
159std::vector<MatrixWorkspace_sptr> retrieveMatrixWsList(const std::vector<std::string> &wsNames,
160 GroupPolicy groupPolicy) {
161 std::vector<MatrixWorkspace_sptr> matrixWsList;
162
163 // Get all the workspaces which are to be inspected for log proeprties.
164 auto &ADS = AnalysisDataService::Instance();
165 for (const auto &wsName : wsNames) {
166
167 WorkspaceGroup_sptr wsGroup = std::dynamic_pointer_cast<WorkspaceGroup>(ADS.retrieve(wsName));
168 MatrixWorkspace_sptr matrixWs = std::dynamic_pointer_cast<MatrixWorkspace>(ADS.retrieve(wsName));
169
170 if (wsGroup) {
171 const std::vector<std::string> childNames = wsGroup->getNames();
172
173 // If there are no child workspaces in the group (is this possible?), just
174 // ignore it.
175 if (childNames.empty())
176 break;
177
178 // Retrieve pointers to all the child workspaces.
179 std::vector<MatrixWorkspace_sptr> childWsList;
180 childWsList.reserve(childNames.size());
181
182 std::transform(childNames.begin(), childNames.end(), std::back_inserter(childWsList),
183 [&ADS](const auto &childName) { return ADS.retrieveWS<MatrixWorkspace>(childName); });
184
185 // Deal with child workspaces according to policy.
186 switch (groupPolicy) {
187 case ALL: {
188 // Append all the children to the list.
189 std::move(childWsList.cbegin(), childWsList.cend(), std::back_inserter(matrixWsList));
190 break;
191 }
192 case FIRST:
193 // Append only the first child to the list.
194 matrixWsList.emplace_back(childWsList[0]);
195 break;
196 case NONE:
197 // Add nothing to the list.
198 break;
199 default:
200 // We should never reach here.
201 assert(false);
202 }
203 } else if (matrixWs) {
204 matrixWsList.emplace_back(matrixWs);
205 }
206 }
207
208 return matrixWsList;
209}
210
217const std::map<std::string, GroupPolicy> &getGroupPolicyMap() {
218 static std::map<std::string, GroupPolicy> map;
219
220 // Populate the map if empty.
221 if (map.empty()) {
222 map.emplace("All", ALL);
223 map.emplace("First", FIRST);
224 map.emplace("None", NONE);
225 }
226
227 return map;
228}
229
238GroupPolicy getGroupPolicyByName(const std::string &name) {
239 const std::map<std::string, GroupPolicy> &map = getGroupPolicyMap();
240
241 // If we can find a policy with the given name, return it.
242 auto policy = map.find(name);
243 if (policy != map.end())
244 return policy->second;
245
246 // Else return ALL as default. Assert since we should never reach here.
247 assert(false);
248 return ALL;
249}
250
256std::set<std::string> getAllGroupPolicyNames() {
257 const std::map<std::string, GroupPolicy> &map = getGroupPolicyMap();
258 std::set<std::string> groupPolicyNames;
259
260 for (const auto &policy : map)
261 groupPolicyNames.insert(policy.first);
262
263 return groupPolicyNames;
264}
265
272const std::map<std::string, Math::StatisticType> &getStatisticTypeMap() {
273 static std::map<std::string, Math::StatisticType> map;
274
275 // Populate the map if empty.
276 if (map.empty()) {
277 map.emplace("FirstValue", Math::StatisticType::FirstValue);
278 map.emplace("LastValue", Math::StatisticType::LastValue);
279 map.emplace("Minimum", Math::StatisticType::Minimum);
280 map.emplace("Maximum", Math::StatisticType::Maximum);
281 map.emplace("Mean", Math::StatisticType::Mean);
282 map.emplace("Median", Math::StatisticType::Median);
283 }
284
285 return map;
286}
287
294Math::StatisticType getStatisticTypeByName(const std::string &name) {
295 const std::map<std::string, Math::StatisticType> &map = getStatisticTypeMap();
296
297 // If we can find a policy with the given name, return it.
298 auto policy = map.find(name);
299 if (policy != map.end())
300 return policy->second;
301
302 // Else return ALL as default. Assert since we should never reach here.
303 return Math::StatisticType::Mean;
304}
305
311std::set<std::string> getAllStatisticTypeNames() {
312 const std::map<std::string, Math::StatisticType> &map = getStatisticTypeMap();
313 std::set<std::string> statisticTypeNames;
314
315 for (const auto &policy : map)
316 statisticTypeNames.insert(policy.first);
317
318 return statisticTypeNames;
319}
320} // namespace
321} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
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
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
This class stores information regarding an experimental run as a series of log entries.
Definition: Run.h:38
TableRow represents a row in a TableWorkspace.
Definition: TableRow.h:39
A property class for workspaces.
void init() override
Initialise the properties.
Support for a property that holds an array of values.
Definition: ArrayProperty.h:28
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Validator to check that a property is not left empty.
Base class for properties.
Definition: Property.h:94
const std::string type() const
Returns the type of the property as a string.
Definition: Property.cpp:76
virtual std::string value() const =0
Returns the value of the property as a string.
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
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
StatisticType
Maps a "statistic" to a number.
Definition: Statistics.h:18
@ Output
An output workspace.
Definition: Property.h:54