// @(#)root/roostats:$Id$
// Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOSTATS_HypoTestInverter
#define ROOSTATS_HypoTestInverter



#ifndef ROOSTATS_IntervalCalculator
#include "RooStats/IntervalCalculator.h"
#endif


#ifndef  ROOSTATS_HypoTestInverterResult
#include "RooStats/HypoTestInverterResult.h"
#endif

class RooRealVar;
class TGraphErrors;

#include <memory>

namespace RooStats {

   //class HypoTestCalculator;
   class HybridCalculator;
   class FrequentistCalculator;
   class AsymptoticCalculator;
   class HypoTestCalculatorGeneric;
   class TestStatistic;

class HypoTestInverter : public IntervalCalculator {

public:

   enum ECalculatorType { kUndefined = 0, kHybrid = 1, kFrequentist = 2, kAsymptotic = 3};

   // default constructor (used only for I/O)
   HypoTestInverter();

   // constructor from generic hypotest calculator
   HypoTestInverter( HypoTestCalculatorGeneric & hc,
                     RooRealVar* scannedVariable =0, 
                     double size = 0.05) ;


   // constructor from hybrid calculator
   HypoTestInverter( HybridCalculator & hc,
                     RooRealVar* scannedVariable = 0, 
                     double size = 0.05) ;

   // constructor from frequentist calculator
   HypoTestInverter( FrequentistCalculator & hc,
                     RooRealVar* scannedVariable, 
                     double size = 0.05) ;

   // constructor from asymptotic calculator
   HypoTestInverter( AsymptoticCalculator & hc,
                     RooRealVar* scannedVariable, 
                     double size = 0.05) ;

   // constructor from two ModelConfigs (first sb (the null model) then b (the alt model)
   // creating a calculator inside
   HypoTestInverter( RooAbsData& data, ModelConfig &sb, ModelConfig &b,
		     RooRealVar * scannedVariable = 0,  ECalculatorType type = kFrequentist, 
		     double size = 0.05) ;


   virtual HypoTestInverterResult* GetInterval() const; 

   void Clear();

   // set for a fixed scan in nbins
   void SetFixedScan(int nBins, double xMin = 1, double xMax = -1, bool scanLog = false ) {
      fNBins = nBins; 
      fXmin = xMin; fXmax = xMax; 
      fScanLog = scanLog;
   }
     
   // set auto scan (default) 
   void SetAutoScan() { SetFixedScan(0); }

   bool RunFixedScan( int nBins, double xMin, double xMax, bool scanLog = false ) const;

   bool RunOnePoint( double thisX, bool adaptive = false, double clTarget = -1 ) const;

   //bool RunAutoScan( double xMin, double xMax, double target, double epsilon=0.005, unsigned int numAlgorithm=0 );

   bool RunLimit(double &limit, double &limitErr, double absTol = 0, double relTol = 0, const double *hint=0) const; 

   void UseCLs( bool on = true) { fUseCLs = on; if (fResults) fResults->UseCLs(on);   }

   virtual void  SetData(RooAbsData &);
     
   virtual void SetModel(const ModelConfig &) { } // not needed 

   // set the size of the test (rate of Type I error) ( Eg. 0.05 for a 95% Confidence Interval)
   virtual void SetTestSize(Double_t size) {fSize = size; if (fResults) fResults->SetTestSize(size); }
   // set the confidence level for the interval (eg. 0.95 for a 95% Confidence Interval)
   virtual void SetConfidenceLevel(Double_t cl) {fSize = 1.-cl;  if (fResults) fResults->SetConfidenceLevel(cl); }
   // Get the size of the test (eg. rate of Type I error)
   virtual Double_t Size() const {return fSize;}
   // Get the Confidence level for the test
   virtual Double_t ConfidenceLevel()  const {return 1.-fSize;}
 
   // destructor
   virtual ~HypoTestInverter() ;

   // retrieved a reference to the internally used HypoTestCalculator 
   // it might be invalid when the class is deleted
   HypoTestCalculatorGeneric * GetHypoTestCalculator() const { return fCalculator0; }

   // get the upper/lower limit distribution 
   SamplingDistribution * GetLowerLimitDistribution(bool rebuild=false, int nToys = 100);
   SamplingDistribution * GetUpperLimitDistribution(bool rebuild=false, int nToys = 100);

   // function to rebuild the distributions
   SamplingDistribution * RebuildDistributions(bool isUpper=true, int nToys = 100, 
                                               TList * clsDist = 0, TList *clsbDist= 0, TList * clbDist = 0, const char *  outputfile = "HypoTestInverterRebuiltDist.root");

   // get the test statistic
   TestStatistic * GetTestStatistic() const;

   // set the test statistic
   bool SetTestStatistic(TestStatistic& stat);

   // set verbose level (0,1,2)
   void SetVerbose(int level=1) { fVerbose = level; }

   // set maximum number of toys 
   void SetMaximumToys(int ntoys) { fMaxToys = ntoys;}

   // set numerical error in test statistic evaluation (default is zero)
   void SetNumErr(double err) { fNumErr = err; }

   // set flag to close proof for every new run
   static void SetCloseProof(Bool_t flag);

  
protected:

   // copy c-tor 
   HypoTestInverter(const HypoTestInverter & rhs);

   // assignment 
   HypoTestInverter & operator=(const HypoTestInverter & rhs);
    
   void CreateResults() const; 

   // run the hybrid at a single point
   HypoTestResult * Eval( HypoTestCalculatorGeneric &hc, bool adaptive , double clsTarget) const;

   // helper functions 
   static RooRealVar * GetVariableToScan(const HypoTestCalculatorGeneric &hc);    
   static void CheckInputModels(const HypoTestCalculatorGeneric &hc, const RooRealVar & scanVar);    

private:


   static unsigned int fgNToys;
   static double fgCLAccuracy;
   static double fgAbsAccuracy;
   static double fgRelAccuracy;
   static bool fgCloseProof;
   static std::string fgAlgo;

   // graph, used to compute the limit, not just for plotting!
   mutable std::unique_ptr<TGraphErrors> fLimitPlot;  //! plot of limits
    
    
   // performance counter: remember how many toys have been thrown
   mutable int fTotalToysRun;
   int fMaxToys;  // maximum number of toys to run 
    
   HypoTestCalculatorGeneric* fCalculator0;   // pointer to the calculator passed in the constructor
   std::unique_ptr<HypoTestCalculatorGeneric> fHC;  //! pointer to the generic hypotest calculator used
   RooRealVar* fScannedVariable;     // pointer to the constrained variable
   mutable HypoTestInverterResult* fResults; // pointer to the result 
     
   bool fUseCLs;
   bool fScanLog; 
   double fSize;
   int fVerbose;
   ECalculatorType fCalcType; 
   int fNBins;
   double fXmin; 
   double fXmax; 
   double fNumErr;

protected:

   ClassDef(HypoTestInverter,4)  // HypoTestInverter class

};

}

#endif
 HypoTestInverter.h:1
 HypoTestInverter.h:2
 HypoTestInverter.h:3
 HypoTestInverter.h:4
 HypoTestInverter.h:5
 HypoTestInverter.h:6
 HypoTestInverter.h:7
 HypoTestInverter.h:8
 HypoTestInverter.h:9
 HypoTestInverter.h:10
 HypoTestInverter.h:11
 HypoTestInverter.h:12
 HypoTestInverter.h:13
 HypoTestInverter.h:14
 HypoTestInverter.h:15
 HypoTestInverter.h:16
 HypoTestInverter.h:17
 HypoTestInverter.h:18
 HypoTestInverter.h:19
 HypoTestInverter.h:20
 HypoTestInverter.h:21
 HypoTestInverter.h:22
 HypoTestInverter.h:23
 HypoTestInverter.h:24
 HypoTestInverter.h:25
 HypoTestInverter.h:26
 HypoTestInverter.h:27
 HypoTestInverter.h:28
 HypoTestInverter.h:29
 HypoTestInverter.h:30
 HypoTestInverter.h:31
 HypoTestInverter.h:32
 HypoTestInverter.h:33
 HypoTestInverter.h:34
 HypoTestInverter.h:35
 HypoTestInverter.h:36
 HypoTestInverter.h:37
 HypoTestInverter.h:38
 HypoTestInverter.h:39
 HypoTestInverter.h:40
 HypoTestInverter.h:41
 HypoTestInverter.h:42
 HypoTestInverter.h:43
 HypoTestInverter.h:44
 HypoTestInverter.h:45
 HypoTestInverter.h:46
 HypoTestInverter.h:47
 HypoTestInverter.h:48
 HypoTestInverter.h:49
 HypoTestInverter.h:50
 HypoTestInverter.h:51
 HypoTestInverter.h:52
 HypoTestInverter.h:53
 HypoTestInverter.h:54
 HypoTestInverter.h:55
 HypoTestInverter.h:56
 HypoTestInverter.h:57
 HypoTestInverter.h:58
 HypoTestInverter.h:59
 HypoTestInverter.h:60
 HypoTestInverter.h:61
 HypoTestInverter.h:62
 HypoTestInverter.h:63
 HypoTestInverter.h:64
 HypoTestInverter.h:65
 HypoTestInverter.h:66
 HypoTestInverter.h:67
 HypoTestInverter.h:68
 HypoTestInverter.h:69
 HypoTestInverter.h:70
 HypoTestInverter.h:71
 HypoTestInverter.h:72
 HypoTestInverter.h:73
 HypoTestInverter.h:74
 HypoTestInverter.h:75
 HypoTestInverter.h:76
 HypoTestInverter.h:77
 HypoTestInverter.h:78
 HypoTestInverter.h:79
 HypoTestInverter.h:80
 HypoTestInverter.h:81
 HypoTestInverter.h:82
 HypoTestInverter.h:83
 HypoTestInverter.h:84
 HypoTestInverter.h:85
 HypoTestInverter.h:86
 HypoTestInverter.h:87
 HypoTestInverter.h:88
 HypoTestInverter.h:89
 HypoTestInverter.h:90
 HypoTestInverter.h:91
 HypoTestInverter.h:92
 HypoTestInverter.h:93
 HypoTestInverter.h:94
 HypoTestInverter.h:95
 HypoTestInverter.h:96
 HypoTestInverter.h:97
 HypoTestInverter.h:98
 HypoTestInverter.h:99
 HypoTestInverter.h:100
 HypoTestInverter.h:101
 HypoTestInverter.h:102
 HypoTestInverter.h:103
 HypoTestInverter.h:104
 HypoTestInverter.h:105
 HypoTestInverter.h:106
 HypoTestInverter.h:107
 HypoTestInverter.h:108
 HypoTestInverter.h:109
 HypoTestInverter.h:110
 HypoTestInverter.h:111
 HypoTestInverter.h:112
 HypoTestInverter.h:113
 HypoTestInverter.h:114
 HypoTestInverter.h:115
 HypoTestInverter.h:116
 HypoTestInverter.h:117
 HypoTestInverter.h:118
 HypoTestInverter.h:119
 HypoTestInverter.h:120
 HypoTestInverter.h:121
 HypoTestInverter.h:122
 HypoTestInverter.h:123
 HypoTestInverter.h:124
 HypoTestInverter.h:125
 HypoTestInverter.h:126
 HypoTestInverter.h:127
 HypoTestInverter.h:128
 HypoTestInverter.h:129
 HypoTestInverter.h:130
 HypoTestInverter.h:131
 HypoTestInverter.h:132
 HypoTestInverter.h:133
 HypoTestInverter.h:134
 HypoTestInverter.h:135
 HypoTestInverter.h:136
 HypoTestInverter.h:137
 HypoTestInverter.h:138
 HypoTestInverter.h:139
 HypoTestInverter.h:140
 HypoTestInverter.h:141
 HypoTestInverter.h:142
 HypoTestInverter.h:143
 HypoTestInverter.h:144
 HypoTestInverter.h:145
 HypoTestInverter.h:146
 HypoTestInverter.h:147
 HypoTestInverter.h:148
 HypoTestInverter.h:149
 HypoTestInverter.h:150
 HypoTestInverter.h:151
 HypoTestInverter.h:152
 HypoTestInverter.h:153
 HypoTestInverter.h:154
 HypoTestInverter.h:155
 HypoTestInverter.h:156
 HypoTestInverter.h:157
 HypoTestInverter.h:158
 HypoTestInverter.h:159
 HypoTestInverter.h:160
 HypoTestInverter.h:161
 HypoTestInverter.h:162
 HypoTestInverter.h:163
 HypoTestInverter.h:164
 HypoTestInverter.h:165
 HypoTestInverter.h:166
 HypoTestInverter.h:167
 HypoTestInverter.h:168
 HypoTestInverter.h:169
 HypoTestInverter.h:170
 HypoTestInverter.h:171
 HypoTestInverter.h:172
 HypoTestInverter.h:173
 HypoTestInverter.h:174
 HypoTestInverter.h:175
 HypoTestInverter.h:176
 HypoTestInverter.h:177
 HypoTestInverter.h:178
 HypoTestInverter.h:179
 HypoTestInverter.h:180
 HypoTestInverter.h:181
 HypoTestInverter.h:182
 HypoTestInverter.h:183
 HypoTestInverter.h:184
 HypoTestInverter.h:185
 HypoTestInverter.h:186
 HypoTestInverter.h:187
 HypoTestInverter.h:188
 HypoTestInverter.h:189
 HypoTestInverter.h:190
 HypoTestInverter.h:191
 HypoTestInverter.h:192
 HypoTestInverter.h:193
 HypoTestInverter.h:194
 HypoTestInverter.h:195
 HypoTestInverter.h:196
 HypoTestInverter.h:197
 HypoTestInverter.h:198
 HypoTestInverter.h:199
 HypoTestInverter.h:200
 HypoTestInverter.h:201
 HypoTestInverter.h:202
 HypoTestInverter.h:203
 HypoTestInverter.h:204
 HypoTestInverter.h:205