//this file looks like plain C, but it's actually -*- c++ -*-
#ifndef __TQ_SIGNIFICANCEEVALUTATOR__
#define __TQ_SIGNIFICANCEEVALUTATOR__

#include "TString.h"
#include "TNamed.h"
#include "QFramework/TQTaggable.h"
#include "TH1.h"
#include "THnBase.h"

#include <functional>

class TQSampleDataReader;
class TQGridScanner;
class TQSampleFolder;

class TQSignificanceEvaluator : public TQTaggable, public TNamed {
protected:
  TClass* initialization; //!
  bool isSimpleEvaluator; //!
  TQSampleDataReader* reader; //!
  TQGridScanner* scanner; //!
  double luminosity;
  double luminosityScale;
  TString fileIdentifier; //!
  bool verbose; //!
  std::vector<TString> m_regions; //!
  std::vector<TString> autoNFs; //!

  std::vector< std::function<double (double, double)> > m_functionsFOM ; //!
  std::vector< std::function<double (double, double, double)> > m_functionsFOMWithBkgUnc ; //!
  std::vector< std::function<double (double, double, double, double)> > m_functionsFOMWithUnc ; //!
  std::vector <TString> m_FOMDefinitions; //!
  std::vector<THnBase*> m_bkgHists; //!
  std::vector<THnBase*> m_signalHists; //!
  std::vector<THnBase*> m_multiDimHists; //! only used for cl evaluator mode!
  
public:
  TString info;
  bool m_multipleFOMsCompatible = false;
  std::vector<TString> FOMDefinitions() {return m_FOMDefinitions;};
  std::vector<TString> regions() {return m_regions;};
  bool isSimple() {return isSimpleEvaluator;};
  
  std::vector<THnBase*> multiDimHists() {return m_multiDimHists;};
  std::vector<THnBase*> bkgHists() {return m_bkgHists;};
  std::vector<THnBase*> signalHists() {return m_signalHists;};
  
  virtual double getLuminosity(TString folderName="info",TString tagName="luminosity");
  virtual bool scaleLuminosity(double lumi = 1000);
  virtual void setFileIdentifier(TString s);
  virtual void setVerbose(bool v = true);
  virtual bool setRangeAxis(int axis, double low, double up);
  virtual bool updateHists(std::vector<int> axisToScan, TQGridScanner* scanner, int axisToEvaluate);
  TQSampleDataReader* getReader();

  virtual void bookNF(const TString& path);
  virtual void addRegion(const TString& cutname);

  virtual bool hasNativeRegionSetHandling();
  virtual bool prepareNextRegionSet(const TString& suffix = "");
  virtual bool isPrepared();

  virtual double evaluate() = 0;
  virtual std::vector<double> evaluateMultiple() = 0;
  TQSignificanceEvaluator(const TString& name = "");
  TQSignificanceEvaluator(const TString& name, TQSampleFolder* sf);
  virtual bool initialize(TQGridScanner* scanner) = 0;

  virtual int exportWorkspace(const TString& outFileName) = 0; // only used in TSCLSignificanceEvaluator
  
  virtual double getSignificance(size_t iregion) = 0;
  virtual double getSignificance2(size_t iregion) = 0;

  virtual bool addFunctionsFOM(std::vector<TString> fomDefinitions, std::vector<double>* parameter = nullptr);
  virtual std::vector<double> getFOMs(size_t iregion);

  double signal(size_t iregion);
  std::pair<double, double> signalAndError(size_t iregion);
  double bkg(size_t iregion);
  std::pair<double, double> bkgAndError(size_t iregion);

  ClassDefOverride(TQSignificanceEvaluator,1) // base class for singificance estimation
};

class TQSignificanceEvaluatorBase : public TQSignificanceEvaluator {
protected:
  TString signalPath; //! 
  TString backgroundPath; //!

  TH1F* bkgproj;
  TH1F* sigproj;
  virtual double getSignificance(size_t iregion) override;
  virtual double getSignificance2(size_t iregion) override;
  virtual double significance(size_t iregion, const std::function<double (double, double)>& signifFunc);

public:
  virtual double evaluate() override;
  virtual std::vector<double> evaluateMultiple() override;
  virtual bool initialize(TQGridScanner* scanner) override;
  virtual int exportWorkspace(const TString& outFileName) override;
  virtual void printHistogramAxes();
  virtual bool setRangeAxis(int axis, double low, double up) override;
  virtual bool updateHists(std::vector<int> axisToScan, TQGridScanner* scanner, int axisToEvaluate) override;
  TQSignificanceEvaluatorBase(TQSampleFolder* sf=NULL, TString signal="sig", TString background="bkg", TString name="s/sqrt(b)");

  ClassDefOverride(TQSignificanceEvaluatorBase,1) // basic class for significance estimation
};

class TQSimpleSignificanceEvaluator : public TQSignificanceEvaluatorBase {
protected:
  virtual double getSignificance(size_t iregion) override;
public:
  TQSimpleSignificanceEvaluator(TQSampleFolder* sf=NULL, TString signal="sig", TString background="bkg", TString name="s/sqrt(b)");

  ClassDefOverride(TQSimpleSignificanceEvaluator,1) // simple s/sqrt(s+b) significance evaluator
};

class TQSimpleSignificanceEvaluator2 : public TQSignificanceEvaluatorBase {
protected:
  virtual double getSignificance(size_t iregion) override;
public:
  TQSimpleSignificanceEvaluator2(TQSampleFolder* sf=NULL, TString signal="sig", TString background="bkg", TString name="s/sqrt(s+b)");

  ClassDefOverride(TQSimpleSignificanceEvaluator2,1) // simple s/sqrt(s+b) significance evaluator
};

class TQSimpleSignificanceEvaluator3 : public TQSignificanceEvaluatorBase {
protected:
  virtual double getSignificance(size_t iregion) override;
public:
  TQSimpleSignificanceEvaluator3(TQSampleFolder* sf=NULL, TString signal="sig", TString background="bkg", TString name="s/b");

  ClassDefOverride(TQSimpleSignificanceEvaluator3,1) // simple s/b significance evaluator
};

class TQPoissonSignificanceEvaluator : public TQSignificanceEvaluatorBase {
protected:
  virtual double getSignificance(size_t iregion) override;
public:
  TQPoissonSignificanceEvaluator(TQSampleFolder* sf=NULL, TString signal="sig", TString background="bkg", TString name="poisson");

  ClassDefOverride(TQPoissonSignificanceEvaluator,1) // simple poisson significance evaluator
};

#endif
 TQSignificanceEvaluator.h:1
 TQSignificanceEvaluator.h:2
 TQSignificanceEvaluator.h:3
 TQSignificanceEvaluator.h:4
 TQSignificanceEvaluator.h:5
 TQSignificanceEvaluator.h:6
 TQSignificanceEvaluator.h:7
 TQSignificanceEvaluator.h:8
 TQSignificanceEvaluator.h:9
 TQSignificanceEvaluator.h:10
 TQSignificanceEvaluator.h:11
 TQSignificanceEvaluator.h:12
 TQSignificanceEvaluator.h:13
 TQSignificanceEvaluator.h:14
 TQSignificanceEvaluator.h:15
 TQSignificanceEvaluator.h:16
 TQSignificanceEvaluator.h:17
 TQSignificanceEvaluator.h:18
 TQSignificanceEvaluator.h:19
 TQSignificanceEvaluator.h:20
 TQSignificanceEvaluator.h:21
 TQSignificanceEvaluator.h:22
 TQSignificanceEvaluator.h:23
 TQSignificanceEvaluator.h:24
 TQSignificanceEvaluator.h:25
 TQSignificanceEvaluator.h:26
 TQSignificanceEvaluator.h:27
 TQSignificanceEvaluator.h:28
 TQSignificanceEvaluator.h:29
 TQSignificanceEvaluator.h:30
 TQSignificanceEvaluator.h:31
 TQSignificanceEvaluator.h:32
 TQSignificanceEvaluator.h:33
 TQSignificanceEvaluator.h:34
 TQSignificanceEvaluator.h:35
 TQSignificanceEvaluator.h:36
 TQSignificanceEvaluator.h:37
 TQSignificanceEvaluator.h:38
 TQSignificanceEvaluator.h:39
 TQSignificanceEvaluator.h:40
 TQSignificanceEvaluator.h:41
 TQSignificanceEvaluator.h:42
 TQSignificanceEvaluator.h:43
 TQSignificanceEvaluator.h:44
 TQSignificanceEvaluator.h:45
 TQSignificanceEvaluator.h:46
 TQSignificanceEvaluator.h:47
 TQSignificanceEvaluator.h:48
 TQSignificanceEvaluator.h:49
 TQSignificanceEvaluator.h:50
 TQSignificanceEvaluator.h:51
 TQSignificanceEvaluator.h:52
 TQSignificanceEvaluator.h:53
 TQSignificanceEvaluator.h:54
 TQSignificanceEvaluator.h:55
 TQSignificanceEvaluator.h:56
 TQSignificanceEvaluator.h:57
 TQSignificanceEvaluator.h:58
 TQSignificanceEvaluator.h:59
 TQSignificanceEvaluator.h:60
 TQSignificanceEvaluator.h:61
 TQSignificanceEvaluator.h:62
 TQSignificanceEvaluator.h:63
 TQSignificanceEvaluator.h:64
 TQSignificanceEvaluator.h:65
 TQSignificanceEvaluator.h:66
 TQSignificanceEvaluator.h:67
 TQSignificanceEvaluator.h:68
 TQSignificanceEvaluator.h:69
 TQSignificanceEvaluator.h:70
 TQSignificanceEvaluator.h:71
 TQSignificanceEvaluator.h:72
 TQSignificanceEvaluator.h:73
 TQSignificanceEvaluator.h:74
 TQSignificanceEvaluator.h:75
 TQSignificanceEvaluator.h:76
 TQSignificanceEvaluator.h:77
 TQSignificanceEvaluator.h:78
 TQSignificanceEvaluator.h:79
 TQSignificanceEvaluator.h:80
 TQSignificanceEvaluator.h:81
 TQSignificanceEvaluator.h:82
 TQSignificanceEvaluator.h:83
 TQSignificanceEvaluator.h:84
 TQSignificanceEvaluator.h:85
 TQSignificanceEvaluator.h:86
 TQSignificanceEvaluator.h:87
 TQSignificanceEvaluator.h:88
 TQSignificanceEvaluator.h:89
 TQSignificanceEvaluator.h:90
 TQSignificanceEvaluator.h:91
 TQSignificanceEvaluator.h:92
 TQSignificanceEvaluator.h:93
 TQSignificanceEvaluator.h:94
 TQSignificanceEvaluator.h:95
 TQSignificanceEvaluator.h:96
 TQSignificanceEvaluator.h:97
 TQSignificanceEvaluator.h:98
 TQSignificanceEvaluator.h:99
 TQSignificanceEvaluator.h:100
 TQSignificanceEvaluator.h:101
 TQSignificanceEvaluator.h:102
 TQSignificanceEvaluator.h:103
 TQSignificanceEvaluator.h:104
 TQSignificanceEvaluator.h:105
 TQSignificanceEvaluator.h:106
 TQSignificanceEvaluator.h:107
 TQSignificanceEvaluator.h:108
 TQSignificanceEvaluator.h:109
 TQSignificanceEvaluator.h:110
 TQSignificanceEvaluator.h:111
 TQSignificanceEvaluator.h:112
 TQSignificanceEvaluator.h:113
 TQSignificanceEvaluator.h:114
 TQSignificanceEvaluator.h:115
 TQSignificanceEvaluator.h:116
 TQSignificanceEvaluator.h:117
 TQSignificanceEvaluator.h:118
 TQSignificanceEvaluator.h:119
 TQSignificanceEvaluator.h:120
 TQSignificanceEvaluator.h:121
 TQSignificanceEvaluator.h:122
 TQSignificanceEvaluator.h:123
 TQSignificanceEvaluator.h:124
 TQSignificanceEvaluator.h:125
 TQSignificanceEvaluator.h:126
 TQSignificanceEvaluator.h:127
 TQSignificanceEvaluator.h:128
 TQSignificanceEvaluator.h:129
 TQSignificanceEvaluator.h:130
 TQSignificanceEvaluator.h:131
 TQSignificanceEvaluator.h:132
 TQSignificanceEvaluator.h:133
 TQSignificanceEvaluator.h:134
 TQSignificanceEvaluator.h:135
 TQSignificanceEvaluator.h:136
 TQSignificanceEvaluator.h:137
 TQSignificanceEvaluator.h:138
 TQSignificanceEvaluator.h:139
 TQSignificanceEvaluator.h:140
 TQSignificanceEvaluator.h:141
 TQSignificanceEvaluator.h:142
 TQSignificanceEvaluator.h:143
 TQSignificanceEvaluator.h:144
 TQSignificanceEvaluator.h:145
 TQSignificanceEvaluator.h:146