////////////////////////////////////////////////////////////////////////
/// \class RAT::ClassifierProcessor
///
/// \brief   RAT Processor which invokes classifiers
///
/// \author  Phil Jones <p.g.jones@qmul.ac.uk> \n
/// \author Matt Mottram < m.mottram@qmul.ac.uk> -- contact person
///
/// REVISION HISTORY:\n
///   - 27/04/2011 : P.Jones - First Revision, new file.
///   - 2014-03-29 : P G Jones - Updated lifetime, added BeginOfRun method
///   - 2015-03-23 : M Mottram - added ability to seed from previous passes
///
/// \details  Assembles the classifier components then invokes a classifier,
/// based on command inputs
///
////////////////////////////////////////////////////////////////////////

#ifndef __RAT_ClassifierProcessor__
#define __RAT_ClassifierProcessor__

#include <RAT/Processor.hh>

#include <vector>

namespace RAT
{

namespace Classifiers
{
  class Classifier;
}

namespace PDFs
{
  class PDF;
}

namespace Optimisers
{
  class Optimiser;
}

namespace PMTSelectors
{
  class PMTSelector;
}

class ClassifierProcessor : public Processor
{
public:
  /// Constructor, gets Factory instances
  ClassifierProcessor();
  /// Destructor deletes the components
  virtual ~ClassifierProcessor();

  /// Called at the start of a run
  virtual void BeginOfRun( DS::Run& run );

  /// Called to invoke the ClassifierProcessor
  virtual Processor::Result DSEvent( DS::Run& run,
                                     DS::Entry& ds );

  /// Called at the end of a run
  virtual void EndOfRun( DS::Run& run );

  /// Set a int command
  ///
  /// @param[in] param is classifier, optimiser, pdf, seed or selector or something to be passed to the component
  /// @param[in] value is any value (component will check validity)
  virtual void SetI( const std::string& param,
                     const int value );

  /// Set a double command
  ///
  /// @param[in] param is classifier, optimiser, pdf, seed or selector or something to be passed to the component
  /// @param[in] value is any value (component will check validity)
  virtual void SetD( const std::string& param,
                     const double value );

  /// Set a string command
  ///
  /// @param[in] param is classifier, optimiser, pdf, seed or selector or something to be passed to the component
  /// @param[in] value is any value (component will check validity)
  virtual void SetS( const std::string& param,
                     const std::string& value );

protected:
  std::vector< std::string > fSeeds; ///< Name of seeds must be full fit result name, optional
  std::vector< int > fSeedPass; ///< Pass number of seeds, defaults to current pass
  std::string fNickName; ///< Optional alternative name for the classifier

  Classifiers::Classifier* fClassifier; ///< The classifier
  PDFs::PDF* fPDF; ///< The PDF (optional)
  Optimisers::Optimiser* fOptimiser; ///< The optimiser (optional)
  PMTSelectors::PMTSelector* fSelector; ///< The selector (optional)
  PMTSelectors::PMTSelector* fPMTCalSelector;
};

} // ::RAT

#endif