Mantid
Loading...
Searching...
No Matches
DataProcessorAlgorithm.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 +
19#include "Poco/Path.h"
20#include <stdexcept>
21#include <utility>
22
23using namespace Mantid::Kernel;
24using namespace Mantid::API;
25
26namespace Mantid::API {
27
28//----------------------------------------------------------------------------------------------
31template <class Base>
33 : m_loadAlg("Load"), m_accumulateAlg("Plus"), m_loadAlgFileProp("Filename"),
34 m_propertyManagerPropertyName("ReductionProperties") {
35 Base::enableHistoryRecordingForChild(true);
36}
37
38//---------------------------------------------------------------------------------------------
59template <class Base>
60std::shared_ptr<Algorithm>
61GenericDataProcessorAlgorithm<Base>::createChildAlgorithm(const std::string &name, const double startProgress,
62 const double endProgress, const bool enableLogging,
63 const int &version) {
64 // call parent method to create the child algorithm
65 auto alg = Algorithm::createChildAlgorithm(name, startProgress, endProgress, enableLogging, version);
66 alg->enableHistoryRecordingForChild(this->isRecordingHistoryForChild());
67 if (this->isRecordingHistoryForChild()) {
68 // pass pointer to the history object created in Algorithm to the child
69 alg->trackAlgorithmHistory(Base::m_history);
70 }
71 return alg;
72}
73
74template <class Base> void GenericDataProcessorAlgorithm<Base>::setLoadAlg(const std::string &alg) {
75 if (alg.empty())
76 throw std::invalid_argument("Cannot set load algorithm to empty string");
77 m_loadAlg = alg;
78}
79
80template <class Base> void GenericDataProcessorAlgorithm<Base>::setLoadAlgFileProp(const std::string &filePropName) {
81 if (filePropName.empty()) {
82 throw std::invalid_argument("Cannot set the load algorithm file property name");
83 }
84 m_loadAlgFileProp = filePropName;
85}
86
87template <class Base> void GenericDataProcessorAlgorithm<Base>::setAccumAlg(const std::string &alg) {
88 if (alg.empty())
89 throw std::invalid_argument("Cannot set accumulate algorithm to empty string");
90 m_accumulateAlg = alg;
91}
92
93template <class Base> void GenericDataProcessorAlgorithm<Base>::setPropManagerPropName(const std::string &propName) {
94 m_propertyManagerPropertyName = propName;
95}
96
105template <class Base>
107 const std::string &nameInPropManager) {
108 m_nameToPMName[nameInProp] = nameInPropManager;
109}
110
122template <class Base>
124 if (!alg->existsProperty(name)) {
125 std::stringstream msg;
126 msg << "Algorithm \"" << alg->name() << "\" does not have property \"" << name << "\"";
127 throw std::runtime_error(msg.str());
128 }
129
130 auto prop = alg->getPointerToProperty(name);
131 Base::declareProperty(std::unique_ptr<Property>(prop->clone()), prop->documentation());
132}
133
142template <class Base> std::string GenericDataProcessorAlgorithm<Base>::getPropertyValue(const std::string &name) const {
143 // explicitly specifying a property wins
144 if (!Base::isDefault(name)) {
146 }
147
148 // return it if it is in the held property manager
149 auto mapping = m_nameToPMName.find(name);
150 if (mapping != m_nameToPMName.end()) {
151 auto pm = this->getProcessProperties();
152 if (pm->existsProperty(mapping->second)) {
153 return pm->getPropertyValue(mapping->second);
154 }
155 }
156
157 // let the parent class version win
159}
160
168template <class Base>
170 // explicitely specifying a property wins
171 if (!Base::isDefault(name)) {
172 return Base::getProperty(name);
173 }
174
175 // return it if it is in the held property manager
176 auto mapping = m_nameToPMName.find(name);
177 if (mapping != m_nameToPMName.end()) {
178 auto pm = this->getProcessProperties();
179 if (pm->existsProperty(mapping->second)) {
180 return pm->getProperty(mapping->second);
181 }
182 }
183
184 // let the parent class version win
186}
187
188template <class Base>
190 UNUSED_ARG(filename);
191
192 throw std::runtime_error("DataProcessorAlgorithm::determineChunk is not implemented");
193}
194
195template <class Base> MatrixWorkspace_sptr GenericDataProcessorAlgorithm<Base>::loadChunk(const size_t rowIndex) {
196 UNUSED_ARG(rowIndex);
197
198 throw std::runtime_error("DataProcessorAlgorithm::loadChunk is not implemented");
199}
200
207template <class Base>
208void GenericDataProcessorAlgorithm<Base>::saveNexus(const std::string &outputWSName, const std::string &outputFile) {
209 if (!outputFile.empty()) {
210 auto saveAlg = createChildAlgorithm("SaveNexus");
211 saveAlg->setPropertyValue("Filename", outputFile);
212 saveAlg->setPropertyValue("InputWorkspace", outputWSName);
213 saveAlg->execute();
214 }
215}
216
222template <class Base>
223Workspace_sptr GenericDataProcessorAlgorithm<Base>::load(const std::string &inputData, const bool loadQuiet) {
224 Workspace_sptr inputWS;
225
226 // First, check whether we have the name of an existing workspace
227 if (AnalysisDataService::Instance().doesExist(inputData)) {
228 inputWS = AnalysisDataService::Instance().retrieve(inputData);
229 } else {
230 std::string foundFile = FileFinder::Instance().getFullPath(inputData);
231 if (foundFile.empty()) {
232 // Get facility extensions
233 FacilityInfo facilityInfo = ConfigService::Instance().getFacility();
234 const std::vector<std::string> facilityExts = facilityInfo.extensions();
235 foundFile = FileFinder::Instance().findRun(inputData, facilityExts).result();
236 }
237
238 if (!foundFile.empty()) {
239 Poco::Path p(foundFile);
240 const std::string outputWSName = p.getBaseName();
241
242 auto loadAlg = createChildAlgorithm(m_loadAlg);
243 loadAlg->setProperty(m_loadAlgFileProp, foundFile);
244 if (!loadQuiet) {
245 loadAlg->setAlwaysStoreInADS(true);
246 }
247
248 loadAlg->execute();
249
250 if (loadQuiet) {
251 inputWS = loadAlg->getProperty("OutputWorkspace");
252 } else {
253 inputWS = AnalysisDataService::Instance().retrieve(outputWSName);
254 }
255 } else
256 throw std::runtime_error("DataProcessorAlgorithm::load could process any data");
257 }
258 return inputWS;
259}
260
269template <class Base>
270std::shared_ptr<PropertyManager>
271GenericDataProcessorAlgorithm<Base>::getProcessProperties(const std::string &propertyManager) const {
272 std::string propertyManagerName(propertyManager);
273 if (propertyManager.empty() && (!m_propertyManagerPropertyName.empty())) {
274 if (!Base::existsProperty(m_propertyManagerPropertyName)) {
275 std::stringstream msg;
276 msg << "Failed to find property \"" << m_propertyManagerPropertyName << "\"";
277 throw Exception::NotFoundError(msg.str(), this->name());
278 }
279 propertyManagerName = this->getPropertyValue(m_propertyManagerPropertyName);
280 }
281
282 std::shared_ptr<PropertyManager> processProperties;
283 if (PropertyManagerDataService::Instance().doesExist(propertyManagerName)) {
284 processProperties = PropertyManagerDataService::Instance().retrieve(propertyManagerName);
285 } else {
286 Base::getLogger().notice() << "Could not find property manager\n";
287 processProperties = std::make_shared<PropertyManager>();
288 PropertyManagerDataService::Instance().addOrReplace(propertyManagerName, processProperties);
289 }
290 return processProperties;
291}
292
293template <class Base>
294std::vector<std::string> GenericDataProcessorAlgorithm<Base>::splitInput(const std::string &input) {
295 UNUSED_ARG(input);
296 throw std::runtime_error("DataProcessorAlgorithm::splitInput is not implemented");
297}
298
300 throw std::runtime_error("DataProcessorAlgorithm::forwardProperties is not implemented");
301}
302
303//------------------------------------------------------------------------------------------
304// Binary opration implementations for DPA so it can record history
305//------------------------------------------------------------------------------------------
306
313template <class Base>
316 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>("Divide", lhs,
317 rhs);
318}
319
326template <class Base>
328 const double &rhsValue) {
329 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>(
330 "Divide", lhs, createWorkspaceSingleValue(rhsValue));
331}
332
341template <class Base>
344 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>("Divide", lhs,
345 rhs);
346}
347
356template <class Base>
358 const double &rhsValue) {
359 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>(
360 "Multiply", lhs, createWorkspaceSingleValue(rhsValue));
361}
362
369template <class Base>
372 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>("Plus", lhs,
373 rhs);
374}
375
382template <class Base>
384 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>(
385 "Plus", lhs, createWorkspaceSingleValue(rhsValue));
386}
387
394template <class Base>
397 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>("Minus", lhs,
398 rhs);
399}
400
408template <class Base>
410 const double &rhsValue) {
411 return this->executeBinaryAlgorithm<MatrixWorkspace_sptr, MatrixWorkspace_sptr, MatrixWorkspace_sptr>(
412 "Minus", lhs, createWorkspaceSingleValue(rhsValue));
413}
414
420template <class Base>
422 MatrixWorkspace_sptr retVal = WorkspaceFactory::Instance().create("WorkspaceSingleValue", 1, 1, 1);
423 retVal->dataY(0)[0] = rhsValue;
424
425 return retVal;
426}
427
429
431
433
434} // namespace Mantid::API
std::string name
Definition Run.cpp:60
const std::vector< double > & rhs
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual 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)
Create a Child Algorithm.
Data processor algorithm to be used as a parent to workflow algorithms.
std::shared_ptr< Kernel::PropertyManager > getProcessProperties(const std::string &propertyManager=std::string()) const
Get the property manager object of a given name from the property manager data service,...
MatrixWorkspace_sptr createWorkspaceSingleValue(const double &rhsValue)
Create a matrix workspace from a single number.
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.
virtual ITableWorkspace_sptr determineChunk(const std::string &filename)
void saveNexus(const std::string &outputWSName, const std::string &outputFile)
Save a workspace as a nexus file, with check for which thread we are executing in.
void copyProperty(const API::Algorithm_sptr &alg, const std::string &name)
Copy a property from an existing algorithm.
Kernel::IPropertyManager::TypedValue getProperty(const std::string &name) const override
Get the property held by this object.
std::vector< std::string > splitInput(const std::string &input)
std::string getPropertyValue(const std::string &name) const override
Get the property held by this object.
void setLoadAlgFileProp(const std::string &filePropName)
MatrixWorkspace_sptr plus(const MatrixWorkspace_sptr lhs, const MatrixWorkspace_sptr rhs)
Add a matrix workspace to another matrix workspace.
MatrixWorkspace_sptr minus(const MatrixWorkspace_sptr lhs, const MatrixWorkspace_sptr rhs)
Subract a matrix workspace by another matrix workspace.
MatrixWorkspace_sptr multiply(const MatrixWorkspace_sptr lhs, const MatrixWorkspace_sptr rhs)
Multiply a matrix workspace by another matrix workspace.
virtual MatrixWorkspace_sptr loadChunk(const size_t rowIndex)
void setPropManagerPropName(const std::string &propName)
Workspace_sptr load(const std::string &inputData, const bool loadQuiet=false)
Determine what kind of input data we have and load it.
void mapPropertyName(const std::string &nameInProp, const std::string &nameInPropManager)
Declare mapping of property name to name in the PropertyManager.
MatrixWorkspace_sptr divide(const MatrixWorkspace_sptr lhs, const MatrixWorkspace_sptr rhs)
Divide a matrix workspace by another matrix workspace.
Exception for when an item is not found in a collection.
Definition Exception.h:145
A class that holds information about a facility.
const std::vector< std::string > & extensions() const
Returns a list of file extensions.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
Definition Algorithm.h:52
static MatrixWorkspace_sptr createWorkspaceSingleValue(const double &rhsValue)
Creates a temporary single value workspace the error is set to zero.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
Utility class that enables the getProperty() method to effectively be templated on the return type.