Newer
Older
Peterson, Peter
committed
#ifndef MANTID_API_ALGORITHM_H_
#define MANTID_API_ALGORITHM_H_
/* Used to register classes into the factory. creates a global object in an
Russell Taylor
committed
* anonymous namespace. The object itself does nothing, but the comma operator
* is used in the call to its constructor to effect a call to the factory's
* subscribe method.
*/
Peterson, Peter
committed
#define DECLARE_ALGORITHM(classname) \
Russell Taylor
committed
namespace { \
Mantid::Kernel::RegistrationHelper register_alg_##classname( \
((Mantid::API::AlgorithmFactory::Instance().subscribe<classname>()) \
, 0)); \
}
Peterson, Peter
committed
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/System.h"
#include "MantidAPI/AlgorithmFactory.h"
#include "MantidAPI/FrameworkManager.h"
Peterson, Peter
committed
#include "MantidAPI/IAlgorithm.h"
#include "MantidKernel/PropertyManagerOwner.h"
#include "MantidKernel/Property.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/FileValidator.h"
#include "MantidKernel/ListValidator.h"
#include "MantidKernel/MandatoryValidator.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/MultiThreaded.h"
#include "MantidAPI/WorkspaceGroup.h"
Peterson, Peter
committed
#include "MantidAPI/Progress.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidAPI/WorkspaceOpOverloads.h"
#include "MantidAPI/WorkspaceFactory.h"
#include <boost/shared_ptr.hpp>
#include <Poco/ActiveMethod.h>
#include <Poco/NotificationCenter.h>
#include <Poco/Notification.h>
Roman Tolchenov
committed
#include <Poco/NObserver.h>
Gigg, Martyn Anthony
committed
#include <Poco/Void.h>
Peterson, Peter
committed
#include <string>
#include <vector>
#include <map>
#include <cmath>
Peterson, Peter
committed
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
#endif
namespace Mantid
{
Russell Taylor
committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
namespace API
{
//----------------------------------------------------------------------
// Forward Declaration
//----------------------------------------------------------------------
class AlgorithmProxy;
/**
Base class from which all concrete algorithm classes should be derived.
In order for a concrete algorithm class to do anything
useful the methods init() & exec() should be overridden.
Further text from Gaudi file.......
The base class provides utility methods for accessing
standard services (event data service etc.); for declaring
properties which may be configured by the job options
service; and for creating sub algorithms.
The only base class functionality which may be used in the
constructor of a concrete algorithm is the declaration of
member variables as properties. All other functionality,
i.e. the use of services and the creation of sub-algorithms,
may be used only in initialise() and afterwards (see the
Gaudi user guide).
@author Russell Taylor, Tessella Support Services plc
@author Based on the Gaudi class of the same name (see http://proj-gaudi.web.cern.ch/proj-gaudi/)
@date 12/09/2007
Copyright © 2007-10 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport Algorithm : public IAlgorithm, public Kernel::PropertyManagerOwner
{
public:
/// Base class for algorithm notifications
class AlgorithmNotification: public Poco::Notification
{
public:
AlgorithmNotification(const Algorithm* const alg):Poco::Notification(),m_algorithm(alg){}///< Constructor
const IAlgorithm* algorithm() const {return m_algorithm;} ///< The algorithm
private:
const IAlgorithm* const m_algorithm;///< The algorithm
};
/// StartedNotification is sent when the algorithm begins execution.
class StartedNotification: public AlgorithmNotification
{
public:
StartedNotification(const Algorithm* const alg):AlgorithmNotification(alg){}///< Constructor
virtual std::string name() const{return "StartedNotification";}///< class name
};
/// FinishedNotification is sent after the algorithm finishes its execution
class FinishedNotification: public AlgorithmNotification
{
public:
FinishedNotification(const Algorithm* const alg, bool res):AlgorithmNotification(alg),success(res){}///< Constructor
virtual std::string name() const{return "FinishedNotification";}///< class name
bool success;///< true if the finished algorithm was successful or false if it failed.
};
/// An algorithm can report its progress by sending ProgressNotification. Use
/// Algorithm::progress(double) function to send a preogress notification.
class ProgressNotification: public AlgorithmNotification
{
public:
ProgressNotification(const Algorithm* const alg, double p,const std::string& msg):AlgorithmNotification(alg),progress(p),message(msg){}///< Constructor
virtual std::string name() const{return "ProgressNotification";}///< class name
double progress;///< Current progress. Value must be between 0 and 1.
std::string message;///< Message sent with notification
};
/// ErrorNotification is sent when an exception is caught during execution of the algorithm.
class ErrorNotification: public AlgorithmNotification
{
public:
/// Constructor
ErrorNotification(const Algorithm* const alg, const std::string& str):AlgorithmNotification(alg),what(str){}
virtual std::string name() const{return "ErrorNotification";}///< class name
std::string what;///< message string
};
/// CancelException is thrown to cancel execution of the algorithm. Use Algorithm::cancel() to
/// terminate an algorithm. The execution will only be stopped if Algorithm::exec() method calls
/// periodically Algorithm::interuption_point() which checks if Algorithm::cancel() has been called
/// and throws CancelException if needed.
class CancelException : public std::exception
{
public:
CancelException():outMessage("Algorithm terminated"){}
CancelException(const CancelException& A):outMessage(A.outMessage){}///< Copy constructor
/// Assignment operator
CancelException& operator=(const CancelException& A);
/// Destructor
~CancelException() throw() {}
/// Returns the message string.
const char* what() const throw()
{
return outMessage.c_str();
}
private:
/// The message returned by what()
std::string outMessage;
};
Algorithm();
virtual ~Algorithm();
/// function to return a name of the algorithm, must be overridden in all algorithms
virtual const std::string name() const = 0;
/// function to return a version of the algorithm, must be overridden in all algorithms
virtual int version() const = 0;
/// function to return a category of the algorithm. A default implementation is provided
virtual const std::string category() const {return "Misc";}
Campbell, Stuart
committed
/// function to return any aliases to the algorithm; A default implementation is provided
virtual const std::string alias() const {return "";}
Russell Taylor
committed
/// Algorithm ID. Unmanaged algorithms return 0 (or NULL?) values. Managed ones have non-zero.
AlgorithmID getAlgorithmID()const{return m_algorithmID;}
// IAlgorithm methods
void initialize();
bool execute();
virtual bool isInitialized() const;
virtual bool isExecuted() const;
// End of IAlgorithm methods
using Kernel::PropertyManagerOwner::getProperty;
/// To query whether algorithm is a child. Default to false
bool isChild() const;
void setChild(const bool isChild);
void setRethrows(const bool rethrow);
/// Asynchronous execution.
Poco::ActiveResult<bool> executeAsync();
Russell Taylor
committed
Lynch, Vickie
committed
/// Set the maximum number of cores from Properties files
void getOpenMPCores();
/// Execute as a sub-algorithm
void executeAsSubAlg();
Russell Taylor
committed
/// Add an observer for a notification
void addObserver(const Poco::AbstractObserver& observer)const;
/// Remove an observer
void removeObserver(const Poco::AbstractObserver& observer)const;
/// Raises the cancel flag. interuption_point() method if called inside exec() checks this flag
/// and if true terminates the algorithm.
void cancel()const;
/// True if the algorithm is running asynchronously.
bool isRunningAsync(){return m_runningAsync;}
/// True if the algorithm is running.
bool isRunning(){return m_running;}
///Logging can be disabled by passing a value of false
void setLogging(const bool value){g_log.setEnabled(value);}
///returns the status of logging, True = enabled
bool isLogging() const {return g_log.getEnabled();}
Janik Zikovsky
committed
/// Returns a reference to the logger.
Kernel::Logger& getLogger() const { return g_log; }
/// Returns the cancellation state
bool getCancel() const { return m_cancel; }
Russell Taylor
committed
Janik Zikovsky
committed
/// Sets documentation strings for this algorithm
virtual void initDocs() {};
Janik Zikovsky
committed
/// function returns an optional message that will be displayed in the default GUI, at the top.
const std::string getOptionalMessage() const { return m_OptionalMessage;}
/// Set an optional message that will be displayed in the default GUI, at the top.
void setOptionalMessage(const std::string optionalMessage) { m_OptionalMessage = optionalMessage;}
Janik Zikovsky
committed
/// Get a summary to be used in the wiki page.
const std::string getWikiSummary() const { return m_WikiSummary;}
/// Set a summary to be used in the wiki page. Normally, this is approx. the same as the optional message.
void setWikiSummary(const std::string WikiSummary) { m_WikiSummary = WikiSummary;}
Janik Zikovsky
committed
/// Get a description to be used in the wiki page.
const std::string getWikiDescription() const { return m_WikiDescription;}
/// Set a string to be used as the Description field in the wiki page.
void setWikiDescription(const std::string WikiDescription) { m_WikiDescription = WikiDescription;}
///setting the child start progress
void setChildStartProgress(const double startProgress)const{m_startChildProgress=startProgress;}
/// setting the child end progress
void setChildEndProgress(const double endProgress)const{m_endChildProgress=endProgress;}
Russell Taylor
committed
Gigg, Martyn Anthony
committed
/** @name Serialization functions */
//@{
/// Serialize an object to a string
Gigg, Martyn Anthony
committed
virtual std::string toString(bool withDefaultValues = false) const;
Gigg, Martyn Anthony
committed
/// De-serialize an object from a string
static IAlgorithm_sptr fromString(const std::string & input);
Gigg, Martyn Anthony
committed
/// Construct an object from a history entry
static IAlgorithm_sptr fromHistory(const AlgorithmHistory & history);
Gigg, Martyn Anthony
committed
//@}
Janik Zikovsky
committed
//creates a sub algorithm for use in this algorithm
boost::shared_ptr<Algorithm> createSubAlgorithm(const std::string& name, const double startProgress = -1.,
const double endProgress = -1., const bool enableLogging=true, const int& version = -1);
protected:
Russell Taylor
committed
// Equivalents of Gaudi's initialize & execute methods
/// Virtual method - must be overridden by concrete algorithm
virtual void init() = 0;
/// Virtual method - must be overridden by concrete algorithm
virtual void exec() = 0;
friend class AlgorithmProxy;
/// Initialize with properties from an algorithm proxy
void initializeFromProxy(const AlgorithmProxy&);
void setInitialized();
void setExecuted(bool state);
Janik Zikovsky
committed
// // Make PropertyManager's declareProperty methods protected in Algorithm
// using Kernel::PropertyManagerOwner::declareProperty;
Russell Taylor
committed
/// Sends notifications to observers. Observers can subscribe to notificationCenter
/// using Poco::NotificationCenter::addObserver(...);
mutable Poco::NotificationCenter m_notificationCenter;
friend class Progress;
/// Sends ProgressNotification. p must be between 0 (just started) and 1 (finished)
void progress(double p, const std::string& msg = "");
/// Interrupts algorithm execution if Algorithm::cancel() has been called.
/// Does nothing otherwise.
void interruption_point();
///Observation slot for child algorithm progress notification messages, these are scaled and then signalled for this algorithm.
void handleChildProgressNotification(const Poco::AutoPtr<ProgressNotification>& pNf);
///Child algorithm progress observer
Poco::NObserver<Algorithm, ProgressNotification> m_progressObserver;
Peterson, Peter
committed
///checks that the value was not set by users, uses the value in empty double/int.
template <typename NumT>
static bool isEmpty(const NumT toCheck);
Russell Taylor
committed
///checks the property is a workspace property
bool isWorkspaceProperty(const Kernel::Property* const prop) const;
/// checks the property is input workspace property
bool isInputWorkspaceProperty(const Kernel::Property* const prop) const;
/// checks the property is output workspace property
bool isOutputWorkspaceProperty(const Kernel::Property* const prop) const;
Sofia Antony
committed
/// This method checks the members workspaces are of similar names (example group_1,group_2) and returns true if they are.
bool isGroupWorkspacesofSimilarNames(const std::string&,const std::vector<std::string>& grpmembersNames);
Russell Taylor
committed
/// process workspace groups
Sofia Antony
committed
virtual bool processGroups(WorkspaceGroup_sptr ingrpws_sptr,const std::vector<Mantid::Kernel::Property*>&props);
Russell Taylor
committed
/// virtual method to set non workspace properties for an algorithm,it's useful for checking the period number when a member in a group workspace is executed
virtual void setOtherProperties(IAlgorithm* alg,const std::string & propertyName,const std::string &propertyValue,int perioidNum);
mutable bool m_cancel; ///< set to true to stop execution
bool m_parallelException; ///< Set if an exception is thrown, and not caught, within a parallel region
Kernel::Logger& g_log; ///< reference to the logger class
private:
Russell Taylor
committed
/// Private Copy constructor: NO COPY ALLOWED
Algorithm(const Algorithm&);
/// Private assignment operator: NO ASSIGNMENT ALLOWED
Algorithm& operator=(const Algorithm&);
Janik Zikovsky
committed
void store();
void fillHistory(Mantid::Kernel::DateAndTime, double,std::size_t);
Janik Zikovsky
committed
void findWorkspaceProperties(std::vector<Workspace_sptr>& inputWorkspaces,
std::vector<Workspace_sptr>& outputWorkspaces) const;
void algorithm_info() const;
/// setting the input properties for an algorithm - to handle workspace groups
bool setInputWSProperties(IAlgorithm* pAlg,Mantid::Kernel::Property* prop,const std::string& inMemberWSName );
/// setting the output properties for an algorithm -to handle workspace groups
bool setOutputWSProperties(IAlgorithm* pAlg,Mantid::Kernel::Property* prop,const int nPeriod,
const std::string& inmemberwsName,WorkspaceGroup_sptr& outwsgrp_sptr,bool bSimilarNames,bool bequal);
/// This method gets the input workspace name
void getInputGroupWorkspaceName(const std::vector<Mantid::Kernel::Property*>& props,std::string& ingroupwsName);
/// This method returns true if the input and output workspaces are same
bool isInputequaltoOutPut(const std::vector<Mantid::Kernel::Property*>&props);
Sofia Antony
committed
Russell Taylor
committed
/// Poco::ActiveMethod used to implement asynchronous execution.
Poco::ActiveMethod<bool, Poco::Void, Algorithm> m_executeAsync;
/** executeAsync() implementation.
Janik Zikovsky
committed
@param i :: Unused argument
Russell Taylor
committed
*/
bool executeAsyncImpl(const Poco::Void & i);
bool m_isInitialized; ///< Algorithm has been initialized flag
bool m_isExecuted; ///< Algorithm is executed flag
bool m_isChildAlgorithm; ///< Algorithm is a child algorithm
bool m_runningAsync; ///< Algorithm is running asynchronously
bool m_running; ///< Algorithm is running
bool m_rethrow; ///< Algorithm should rethrow exceptions while executing
mutable double m_startChildProgress; ///< Keeps value for algorithm's progress at start of an sub-algorithm
mutable double m_endChildProgress; ///< Keeps value for algorithm's progress at sub-algorithm's finish
Russell Taylor
committed
AlgorithmID m_algorithmID; ///< Algorithm ID for managed algorithms
Janik Zikovsky
committed
std::string m_OptionalMessage; ///< An optional message string to be displayed in the GUI.
std::string m_WikiSummary; ///< A summary line for the wiki page.
Janik Zikovsky
committed
std::string m_WikiDescription; ///< Description in the wiki page.
std::vector<IAlgorithm_wptr> m_ChildAlgorithms; ///< A list of weak pointers to any child algorithms created
Gigg, Martyn Anthony
committed
static size_t g_execCount; ///< Counter to keep track of algorithm execution order
Russell Taylor
committed
};
Peterson, Peter
committed
Russell Taylor
committed
///Typedef for a shared pointer to an Algorithm
typedef boost::shared_ptr<Algorithm> Algorithm_sptr;
Peterson, Peter
committed
Russell Taylor
committed
} // namespace API
Peterson, Peter
committed
} // namespace Mantid
#endif /*MANTID_API_ALGORITHM_H_*/