Skip to content
Snippets Groups Projects
Algorithm.h 10.3 KiB
Newer Older
#ifndef MANTID_KERNEL_ALGORITHM_H_
#define MANTID_KERNEL_ALGORITHM_H_
/* Used to register classes into the factory. creates a global object in an
Dickon Champion's avatar
Dickon Champion 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
Dickon Champion's avatar
Dickon Champion committed
* subscribe method.
*/

#define DECLARE_ALGORITHM(classname) \
	namespace { \
	Mantid::Kernel::RegistrationHelper register_alg_##classname( \
	((Mantid::API::AlgorithmFactory::Instance().subscribe<classname>()) \
	, 0)); \
  }

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/System.h"
#include "MantidAPI/IAlgorithm.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidAPI/WorkspaceOpOverloads.h"
#include "MantidKernel/PropertyManager.h"
#include "MantidKernel/Property.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidKernel/Logger.h"
#include <Poco/ActiveMethod.h>
#include <Poco/NotificationCenter.h>
#include <Poco/Notification.h>
#define PACKAGE_VERSION "unknown"
Nick Draper's avatar
Nick Draper committed
namespace API
/** @class Algorithm Algorithm.h Kernel/Algorithm.h

 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

 @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 &copy; 2007-8 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/>.
 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::PropertyManager
    /// Base class for algorithm notifications
    class AlgorithmNotification: public Poco::Notification
        AlgorithmNotification(Algorithm* alg):Poco::Notification(),m_algorithm(alg){}///< Constructor
        const Algorithm *algorithm()const{return m_algorithm;}                       ///< The algorithm
    /// StartedNotification is sent when the algorithm begins execution.
    class StartedNotification: public AlgorithmNotification
    {
    public:
        StartedNotification(Algorithm* 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
        FinishedNotification(Algorithm* 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
        ProgressNotification(Algorithm* alg, double p):AlgorithmNotification(alg),progress(p){}///< Constructor
        virtual std::string name() const{return "ProgressNotification";}///< class name
        double progress;///< Current progress. Value must be between 0 and 1.
    /// ErrorNotification is sent when an exception is caught during execution of the algorithm.
    class ErrorNotification: public AlgorithmNotification
        ErrorNotification(Algorithm* 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();
Dickon Champion's avatar
Dickon Champion committed
  /// function to return a name of the algorithm, must be overridden in all algorithms
Dickon Champion's avatar
Dickon Champion committed
  virtual const std::string name() const {throw Kernel::Exception::AbsObjMethod("Algorithm");}
Nick Draper's avatar
Nick Draper committed
  /// function to return a version of the algorithm, must be overridden in all algorithms
Nick Draper's avatar
Nick Draper committed
  virtual const int version() const {throw Kernel::Exception::AbsObjMethod("Algorithm");}
Nick Draper's avatar
Nick Draper committed
  /// function to return a category of the algorithm. A default implementation is provided
Nick Draper's avatar
Nick Draper committed
  virtual const std::string category() const {return "Misc";}
  virtual bool isInitialized() const; // Protected in Gaudi version
  virtual bool isExecuted() const;
Dickon Champion's avatar
Dickon Champion committed
  virtual void setPropertyOrdinal(const int &index, const std::string &value);
  virtual void setPropertyValue(const std::string &name, const std::string &value);
  virtual void setProperties(const std::string& propertiesArray);
  virtual std::string getPropertyValue(const std::string &name) const;
  using Kernel::PropertyManager::getProperty;
Nick Draper's avatar
Nick Draper committed

Nick Draper's avatar
Nick Draper committed
  /// To query whether algorithm is a child. Default to false
  bool isChild() const;
  void setChild(const bool isChild);

  /// Asynchronous execution.
  /// Usage: Poco::ActiveResult<bool> res = alg->executeAsync();
  Poco::ActiveResult<bool> executeAsync(){return _executeAsync(0);}
  /// Sends notifications to observers. Observers can subscribe to notificationCenter
  /// using Poco::NotificationCenter::addObserver(...);
  Poco::NotificationCenter notificationCenter;
  /// Raises the cancel flag. interuption_point() method if called inside exec() checks this flag
  /// and if true terminates the algorithm.
  // 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;

Nick Draper's avatar
Nick Draper committed
  //creates a sub algorithm for use in this algorithm
  Algorithm_sptr createSubAlgorithm(const std::string& name);

  void setInitialized();
  void setExecuted(bool state);
Nick Draper's avatar
Nick Draper committed

  // Make PropertyManager's declareProperty methods protected in Algorithm
  using Kernel::PropertyManager::declareProperty;

  /// Sends ProgressNotification. p must be between 0 (just started) and 1 (finished)
  void progress(double p);
  /// Interrupts algorithm execution if Algorithm::cancel() has been called. 
  /// Does nothing otherwise.
  /// Poco::ActiveMethod is used to implement asynchronous execution.
  Poco::ActiveMethod<bool, int, Algorithm> _executeAsync;
  /// Private Copy constructor: NO COPY ALLOWED
Russell Taylor's avatar
Russell Taylor committed
  /// Private assignment operator: NO ASSIGNMENT ALLOWED
  void fillHistory(AlgorithmHistory::dateAndTime, double);
  void findWorkspaceProperties(std::vector<Workspace_sptr>& inputWorkspaces,
                               std::vector<Workspace_sptr>& outputWorkspaces) const;
  void algorithm_info() const;

  /// 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

Russell Taylor's avatar
Russell Taylor committed
  bool m_isChildAlgorithm; ///< Algorithm is a child algorithm
  bool executeAsyncImpl(const int&);///< executeAsync implementation.
  bool m_cancel; ///< set to true to stop execution
  bool m_runningAsync; ///< Algorithm is running asynchronously
  /// Pointers to child algorithms used in this algorithm.
  std::vector< boost::shared_ptr<Algorithm> > m_children;
///Typedef for a shared pointer to an Algorithm
typedef boost::shared_ptr<Algorithm> Algorithm_sptr;

Nick Draper's avatar
Nick Draper committed
} // namespace API