Newer
Older
#ifndef MANTID_API_ALGORITHM_H_
#define MANTID_API_ALGORITHM_H_
Russell Taylor
committed
Russell Taylor
committed
/* Used to register classes into the factory. creates a global object in an
* anonymous namespace. The object itself does nothing, but the comma operator
Russell Taylor
committed
* is used in the call to its constructor to effect a call to the factory's
* subscribe method.
*/
#define DECLARE_ALGORITHM(classname) \
namespace { \
Mantid::Kernel::RegistrationHelper register_alg_##classname( \
((Mantid::API::AlgorithmFactory::Instance().subscribe<classname>()) \
, 0)); \
}
Russell Taylor
committed
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
Nick Draper
committed
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidAPI/WorkspaceOpOverloads.h"
#include "MantidKernel/PropertyManagerOwner.h"
#include "MantidKernel/Property.h"
Nick Draper
committed
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidKernel/Logger.h"
Russell Taylor
committed
#include "MantidKernel/Exception.h"
Roman Tolchenov
committed
#include "MantidAPI/Progress.h"
Russell Taylor
committed
Russell Taylor
committed
#include <boost/shared_ptr.hpp>
Roman Tolchenov
committed
#include <Poco/ActiveMethod.h>
#include <Poco/NotificationCenter.h>
#include <Poco/Notification.h>
Roman Tolchenov
committed
#include <Poco/NObserver.h>
Russell Taylor
committed
#include <vector>
#include <map>
Russell Taylor
committed
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
Russell Taylor
committed
#endif
namespace Mantid
{
Russell Taylor
committed
{
//----------------------------------------------------------------------
// Forward Declaration
//----------------------------------------------------------------------
class AlgorithmProxy;
Russell Taylor
committed
Russell Taylor
committed
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.
Russell Taylor
committed
Further text from Gaudi file.......
Russell Taylor
committed
The base class provides utility methods for accessing
standard services (event data service etc.); for declaring
Russell Taylor
committed
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
Russell Taylor
committed
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,
Russell Taylor
committed
may be used only in initialise() and afterwards (see the
Russell Taylor
committed
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
Russell Taylor
committed
Copyright © 2007-9 STFC Rutherford Appleton 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/>.
Russell Taylor
committed
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
Russell Taylor
committed
Roman Tolchenov
committed
/// Base class for algorithm notifications
Roman Tolchenov
committed
class AlgorithmNotification: public Poco::Notification
Roman Tolchenov
committed
{
public:
AlgorithmNotification(const Algorithm* const alg):Poco::Notification(),m_algorithm(alg){}///< Constructor
const IAlgorithm* algorithm() const {return m_algorithm;} ///< The algorithm
Roman Tolchenov
committed
private:
const IAlgorithm* const m_algorithm;///< The algorithm
Roman Tolchenov
committed
};
Roman Tolchenov
committed
/// StartedNotification is sent when the algorithm begins execution.
Roman Tolchenov
committed
class StartedNotification: public AlgorithmNotification
{
public:
StartedNotification(const Algorithm* const alg):AlgorithmNotification(alg){}///< Constructor
Roman Tolchenov
committed
virtual std::string name() const{return "StartedNotification";}///< class name
Roman Tolchenov
committed
};
Roman Tolchenov
committed
/// FinishedNotification is sent after the algorithm finishes its execution
Roman Tolchenov
committed
class FinishedNotification: public AlgorithmNotification
Roman Tolchenov
committed
{
public:
FinishedNotification(const Algorithm* const alg, bool res):AlgorithmNotification(alg),success(res){}///< Constructor
Roman Tolchenov
committed
virtual std::string name() const{return "FinishedNotification";}///< class name
bool success;///< true if the finished algorithm was successful or false if it failed.
Roman Tolchenov
committed
};
Russell Taylor
committed
/// An algorithm can report its progress by sending ProgressNotification. Use
Roman Tolchenov
committed
/// Algorithm::progress(double) function to send a preogress notification.
Roman Tolchenov
committed
class ProgressNotification: public AlgorithmNotification
Roman Tolchenov
committed
{
public:
ProgressNotification(const Algorithm* const alg, double p,const std::string& msg):AlgorithmNotification(alg),progress(p),message(msg){}///< Constructor
Roman Tolchenov
committed
virtual std::string name() const{return "ProgressNotification";}///< class name
double progress;///< Current progress. Value must be between 0 and 1.
Roman Tolchenov
committed
std::string message;///< Message sent with notification
Roman Tolchenov
committed
};
Roman Tolchenov
committed
/// ErrorNotification is sent when an exception is caught during execution of the algorithm.
Roman Tolchenov
committed
class ErrorNotification: public AlgorithmNotification
Roman Tolchenov
committed
{
public:
Roman Tolchenov
committed
/// Constructor
ErrorNotification(const Algorithm* const alg, const std::string& str):AlgorithmNotification(alg),what(str){}
Roman Tolchenov
committed
virtual std::string name() const{return "ErrorNotification";}///< class name
std::string what;///< message string
Roman Tolchenov
committed
};
Roman Tolchenov
committed
/// 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 {throw Kernel::Exception::AbsObjMethod("Algorithm");}
/// function to return a version of the algorithm, must be overridden in all algorithms
virtual const int version() const {throw Kernel::Exception::AbsObjMethod("Algorithm");}
/// function to return a category of the algorithm. A default implementation is provided
/// Algorithm ID. Unmanaged algorithms return 0 (or NULL?) values. Managed ones have non-zero.
AlgorithmID getAlgorithmID()const{return m_algorithmID;}
Russell Taylor
committed
// IAlgorithm methods
Anders Markvardsen
committed
bool execute();
virtual bool isInitialized() const; // Protected in Gaudi version
virtual bool isExecuted() const;
Russell Taylor
committed
// 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);
Roman Tolchenov
committed
/// Asynchronous execution.
Poco::ActiveResult<bool> executeAsync(){return m_executeAsync(0);}
/// Add an observer for a notification
void addObserver(const Poco::AbstractObserver& observer)const;
/// Remove an observer
void removeObserver(const Poco::AbstractObserver& observer)const;
Roman Tolchenov
committed
/// Raises the cancel flag. interuption_point() method if called inside exec() checks this flag
/// and if true terminates the algorithm.
Roman Tolchenov
committed
void cancel()const;
Roman Tolchenov
committed
/// True if the algorithm is running asynchronously.
Russell Taylor
committed
bool isRunningAsync(){return m_runningAsync;}
Roman Tolchenov
committed
/// True if the algorithm is running.
Russell Taylor
committed
bool isRunning(){return m_running;}
// 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&);
IAlgorithm_sptr createSubAlgorithm(const std::string& name, double startProgress = -1., double endProgress = -1.);
void setInitialized();
void setExecuted(bool state);
Russell Taylor
committed
// Make PropertyManager's declareProperty methods protected in Algorithm
using Kernel::PropertyManagerOwner::declareProperty;
/// Sends notifications to observers. Observers can subscribe to notificationCenter
/// using Poco::NotificationCenter::addObserver(...);
mutable Poco::NotificationCenter m_notificationCenter;
Russell Taylor
committed
Roman Tolchenov
committed
friend class Progress;
Roman Tolchenov
committed
/// Sends ProgressNotification. p must be between 0 (just started) and 1 (finished)
Roman Tolchenov
committed
void progress(double p, const std::string& msg = "");
Russell Taylor
committed
/// Interrupts algorithm execution if Algorithm::cancel() has been called.
Roman Tolchenov
committed
/// Does nothing otherwise.
Roman Tolchenov
committed
void interruption_point();
///Observation slot for child algorithm progress notification messages, these are scaled and then signalled for this algorithm.
Roman Tolchenov
committed
void handleChildProgressNotification(const Poco::AutoPtr<ProgressNotification>& pNf);
///Child algorithm progress observer
Poco::NObserver<Algorithm, ProgressNotification> m_progressObserver;
Roman Tolchenov
committed
private:
/// Private Copy constructor: NO COPY ALLOWED
Russell Taylor
committed
Algorithm(const Algorithm&);
/// Private assignment operator: NO ASSIGNMENT ALLOWED
Russell Taylor
committed
Algorithm& operator=(const Algorithm&);
void fillHistory(AlgorithmHistory::dateAndTime, double,unsigned int);
Russell Taylor
committed
void findWorkspaceProperties(std::vector<Workspace_sptr>& inputWorkspaces,
std::vector<Workspace_sptr>& outputWorkspaces) const;
void algorithm_info() const;
Roman Tolchenov
committed
/// Poco::ActiveMethod used to implement asynchronous execution.
Poco::ActiveMethod<bool, int, Algorithm> m_executeAsync;
Roman Tolchenov
committed
/** executeAsync() implementation.
@param i Unused argument
*/
bool executeAsyncImpl(const int& i);
/// Static refenence to the logger class
static Kernel::Logger& g_log;
bool m_isInitialized; ///< Algorithm has been initialized flag
bool m_isExecuted; ///< Algorithm is executed flag
bool m_isChildAlgorithm; ///< Algorithm is a child algorithm
Roman Tolchenov
committed
Roman Tolchenov
committed
mutable bool m_cancel; ///< set to true to stop execution
bool m_runningAsync; ///< Algorithm is running asynchronously
Roman Tolchenov
committed
bool m_running; ///< Algorithm is running
Roman Tolchenov
committed
double m_startChildProgress; ///< Keeps value for algorithm's progress at start of an sub-algorithm
double m_endChildProgress; ///< Keeps value for algorithm's progress at sub-algorithm's finish
AlgorithmID m_algorithmID; ///< Algorithm ID for managed algorithms
static unsigned int g_execCount;
Russell Taylor
committed
///Typedef for a shared pointer to an Algorithm
typedef boost::shared_ptr<Algorithm> Algorithm_sptr;
} // namespace Mantid
Russell Taylor
committed
#endif /*MANTID_API_ALGORITHM_H_*/