////////////////////////////////////////////////////////////////////////////////
/// \class  RAT::Classifiers::Ext0NuTimeRes
///
/// \brief  Classifies events as 0nu or external background based on timing
///
/// \author Tereza Kroupa <tereza.kroupova@physics.ox.ac.uk>
///
/// REVISION HISTORY:
///     - 10/04/2018 : Tereza Kroupa - Implemented as RAT Classifier
///
/// \detail Calculates 0nu/external background discriminator based on event hit
///         time residuals given weights in RATDB table. Those can be likelihood
///         ratios or other. For further reference see DocDB 4903 or 3603. Based
///         on PSD studies by Ian Coulter and Jack Dunger.
///
////////////////////////////////////////////////////////////////////////////////

#ifndef __RAT_Classifiers_Ext0NuTimeRes_
#define __RAT_Classifiers_Ext0NuTimeRes_

#include <RAT/SeededClassifier.hh>
#include <RAT/DS/UniversalTime.hh>
#include <RAT/DU/TimeResidualCalculator.hh>

namespace RAT {
    namespace Classifiers {

        class Ext0NuTimeRes : public SeededClassifier {
            public:

                /// Static Method returning Classifier Name
                static inline std::string Name() { return "Ext0NuTimeRes";}

                /// Class Method returning Classifier Name
                virtual std::string GetName() const;

                /// Initialise fParam
                /// @param[param] String containing classifier parameters set in macro
                virtual void Initialise(const std::string& param);

                /// Load weights for 0Nu and External bkg
                /// Load fTimeFirst, fTimeLast and fTimeStep
                virtual void BeginOfRun(DS::Run& run);

                /// End Classifier call
                virtual void EndOfRun(DS::Run& run);

                /// Set fEventPos to zero vector and fEventTime to zero
                virtual void DefaultSeed();

                /// Set fEventTime and fEventPos from parameter seed
                /// @seed Seed (FitResult containing event time and position)
                virtual void SetSeed(const DS::FitResult& seed);

                /// Classify event as external bkg or signal
                /// @return ClassifierResult object containing the classification result
                virtual DS::ClassifierResult GetClassification();

            private:

                std::string fParam; ///< DB table name and index set in Initialise
                double fTimeFirst; ///< Lower boundary of the first time bin
                double fTimeLast; ///< Upper boundary of the last time bin
                double fTimeStep; ///< Binwidth
                          std::vector<double> fWeights; ///< Weights from bkg and signal pdfs
                          size_t fNormalisationFlag;
                          int fOffset; //Time residual to which all the residuals are offset

                DU::Point3D fEventPos; ///< Fitted event position
                double fEventTime; ///< Fitted event time

                double fDiscriminant; ///< Discriminant result

                DU::TimeResidualCalculator fTRCalc; // Time residual calculator for a given run
                size_t fPSUPSystemId; // coordinate system id for Point3D
        };

    } //::Classifiers
} //::RAT

#endif