///////////////////////////////////////////////////////////////////
// CalibrationDataInterfaceTool.h, (c) ATLAS Detector software
///////////////////////////////////////////////////////////////////

// 
// for some details on weighting event using the SF, see
// https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopCommonObjects#B_tagging
// http://indico.cern.ch/getFile.py/access?contribId=4&resId=0&materialId=slides&confId=106205
// http://cdsweb.cern.ch/record/1269912
// 

#ifndef ANALYSISCALIBRATIONDATAINTERFACEBASE_H
#define ANALYSISCALIBRATIONDATAINTERFACEBASE_H

#include "Rtypes.h"
#include "TMatrixDSym.h"
#include <vector>
#include <string>
#include <map>
#include <utility>
#include <algorithm>

class TF1;

namespace Analysis 
{

  const double CalibZERO = 1.e-6;
  const double dummyValue = -1.;
  typedef std::pair<double,double> CalibResult;
  // The following result is returned upon error
  const CalibResult dummyResult(dummyValue,dummyValue);
  //  const CalibResult dummyResult(std::make_pair(dummyValue,dummyValue));

  /** @class CalibrationDataInterfaceBase 

      This class provides some common functionality for other classes wishing to
      access Flavour Tagging performance estimates.

      @author  Frank Filthaut <F.Filthaut@science.ru.nl>
  */  

  class CalibrationDataInterfaceBase {
    public:
      CalibrationDataInterfaceBase();

       /** default destructor */
      virtual ~CalibrationDataInterfaceBase() = 0;
      
      /**
	 Main interface methods accessing the flavour tagging performance information.
	 Note that for both of the following, the label is assumed to adhere to the
	 TruthInfo conventions (see package PhysicsAnalysis/JetTagging/JetTagInfo).
      */

      const std::string& EffCalibrationName(const std::string& flavour) const;
      void setEffCalibrationNames(const std::map<std::string, std::string>& names);
      
      const std::string& SFCalibrationName(const std::string& flavour) const;
      void setSFCalibrationNames(const std::map<std::string, std::string>& names);
      
      /** @brief known variable types that can be used as function arguments */
      enum variableType { kEta, kAbsEta, kPt };

      /** @brief retrieve the variable types for the given object */
      const std::vector<int>& functionArguments(const std::string& object) const;

      /** @brief determine whether a given object has been 'registered'. Note that IOV
	  information is not available here (contrary to COOL access) and hence the only
	  thing that needs to be done is to carry out the computation of function arguments */
      bool existFunctionArguments(const std::string& object) const;

    private:

      /** @brief this maps to the possible function arguments below (avoid re-computation for each call) */
      mutable std::map<std::string, std::vector<int> > m_functionArguments;

      /** @brief this simply collects the per-flavour properties.
	  NB there ought to be no need for the 'mutable' qualifier here... */
      mutable std::map<std::string, std::string> m_calibrationEffNames;
      mutable std::map<std::string, std::string> m_calibrationSFNames;
      
      /** @brief utility function for computation of statistical uncertainty */
      double parametricVariance(TF1* fct, const TMatrixDSym* cov, const Double_t* x) const;

    protected:

      /** @brief auxiliary function for string concatenation */
      std::string getBasename (const std::string& OP, const std::string& flavour,
			       const std::string& extra = "", bool SF = true) const;

      /** @ brief common code computing final results from functions and variables */
      CalibResult getResults (const Double_t* x, const Double_t* xsyst,
			      TF1* fct, TF1* fctsys,
			      const TMatrixDSym* cov) const;

      /** @brief auxiliary function to determine function arguments from named object title */
      bool computeFunctionArguments(const std::string& object, const char* ctitle) const;

      /** @brief tagging algorithm name */
      std::string m_taggerName;

      /** @brief operating points: these need to be declared, so they have to be known a priori */
      std::vector<std::string> m_operatingPoints;

    }; 
} // end of namespace

#endif 
 CalibrationDataInterfaceBase.h:1
 CalibrationDataInterfaceBase.h:2
 CalibrationDataInterfaceBase.h:3
 CalibrationDataInterfaceBase.h:4
 CalibrationDataInterfaceBase.h:5
 CalibrationDataInterfaceBase.h:6
 CalibrationDataInterfaceBase.h:7
 CalibrationDataInterfaceBase.h:8
 CalibrationDataInterfaceBase.h:9
 CalibrationDataInterfaceBase.h:10
 CalibrationDataInterfaceBase.h:11
 CalibrationDataInterfaceBase.h:12
 CalibrationDataInterfaceBase.h:13
 CalibrationDataInterfaceBase.h:14
 CalibrationDataInterfaceBase.h:15
 CalibrationDataInterfaceBase.h:16
 CalibrationDataInterfaceBase.h:17
 CalibrationDataInterfaceBase.h:18
 CalibrationDataInterfaceBase.h:19
 CalibrationDataInterfaceBase.h:20
 CalibrationDataInterfaceBase.h:21
 CalibrationDataInterfaceBase.h:22
 CalibrationDataInterfaceBase.h:23
 CalibrationDataInterfaceBase.h:24
 CalibrationDataInterfaceBase.h:25
 CalibrationDataInterfaceBase.h:26
 CalibrationDataInterfaceBase.h:27
 CalibrationDataInterfaceBase.h:28
 CalibrationDataInterfaceBase.h:29
 CalibrationDataInterfaceBase.h:30
 CalibrationDataInterfaceBase.h:31
 CalibrationDataInterfaceBase.h:32
 CalibrationDataInterfaceBase.h:33
 CalibrationDataInterfaceBase.h:34
 CalibrationDataInterfaceBase.h:35
 CalibrationDataInterfaceBase.h:36
 CalibrationDataInterfaceBase.h:37
 CalibrationDataInterfaceBase.h:38
 CalibrationDataInterfaceBase.h:39
 CalibrationDataInterfaceBase.h:40
 CalibrationDataInterfaceBase.h:41
 CalibrationDataInterfaceBase.h:42
 CalibrationDataInterfaceBase.h:43
 CalibrationDataInterfaceBase.h:44
 CalibrationDataInterfaceBase.h:45
 CalibrationDataInterfaceBase.h:46
 CalibrationDataInterfaceBase.h:47
 CalibrationDataInterfaceBase.h:48
 CalibrationDataInterfaceBase.h:49
 CalibrationDataInterfaceBase.h:50
 CalibrationDataInterfaceBase.h:51
 CalibrationDataInterfaceBase.h:52
 CalibrationDataInterfaceBase.h:53
 CalibrationDataInterfaceBase.h:54
 CalibrationDataInterfaceBase.h:55
 CalibrationDataInterfaceBase.h:56
 CalibrationDataInterfaceBase.h:57
 CalibrationDataInterfaceBase.h:58
 CalibrationDataInterfaceBase.h:59
 CalibrationDataInterfaceBase.h:60
 CalibrationDataInterfaceBase.h:61
 CalibrationDataInterfaceBase.h:62
 CalibrationDataInterfaceBase.h:63
 CalibrationDataInterfaceBase.h:64
 CalibrationDataInterfaceBase.h:65
 CalibrationDataInterfaceBase.h:66
 CalibrationDataInterfaceBase.h:67
 CalibrationDataInterfaceBase.h:68
 CalibrationDataInterfaceBase.h:69
 CalibrationDataInterfaceBase.h:70
 CalibrationDataInterfaceBase.h:71
 CalibrationDataInterfaceBase.h:72
 CalibrationDataInterfaceBase.h:73
 CalibrationDataInterfaceBase.h:74
 CalibrationDataInterfaceBase.h:75
 CalibrationDataInterfaceBase.h:76
 CalibrationDataInterfaceBase.h:77
 CalibrationDataInterfaceBase.h:78
 CalibrationDataInterfaceBase.h:79
 CalibrationDataInterfaceBase.h:80
 CalibrationDataInterfaceBase.h:81
 CalibrationDataInterfaceBase.h:82
 CalibrationDataInterfaceBase.h:83
 CalibrationDataInterfaceBase.h:84
 CalibrationDataInterfaceBase.h:85
 CalibrationDataInterfaceBase.h:86
 CalibrationDataInterfaceBase.h:87
 CalibrationDataInterfaceBase.h:88
 CalibrationDataInterfaceBase.h:89
 CalibrationDataInterfaceBase.h:90
 CalibrationDataInterfaceBase.h:91
 CalibrationDataInterfaceBase.h:92
 CalibrationDataInterfaceBase.h:93
 CalibrationDataInterfaceBase.h:94
 CalibrationDataInterfaceBase.h:95
 CalibrationDataInterfaceBase.h:96
 CalibrationDataInterfaceBase.h:97
 CalibrationDataInterfaceBase.h:98
 CalibrationDataInterfaceBase.h:99
 CalibrationDataInterfaceBase.h:100
 CalibrationDataInterfaceBase.h:101
 CalibrationDataInterfaceBase.h:102
 CalibrationDataInterfaceBase.h:103
 CalibrationDataInterfaceBase.h:104
 CalibrationDataInterfaceBase.h:105
 CalibrationDataInterfaceBase.h:106
 CalibrationDataInterfaceBase.h:107
 CalibrationDataInterfaceBase.h:108
 CalibrationDataInterfaceBase.h:109