// @(#)root/roostats:$Id$

/*************************************************************************
 * Project: RooStats                                                     *
 * Package: RooFit/RooStats                                              *
 * Authors:                                                              *
 *   Danilo Piparo, Gregory Schott                                       *
 *************************************************************************
 * 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_HybridCalculatorOriginal
#define ROOSTATS_HybridCalculatorOriginal

#ifndef ROOSTATS_HypoTestCalculator
#include "RooStats/HypoTestCalculator.h"
#endif

#include <vector>


#ifndef ROOSTATS_HybridResult
#include "RooStats/HybridResult.h"
#endif

#ifndef ROOSTATS_ModelConfig
#include "RooStats/ModelConfig.h"
#endif

class TH1; 

namespace RooStats {

   class HybridResult; 

   class HybridCalculatorOriginal : public HypoTestCalculator , public TNamed {

   public:


      /// Dummy Constructor with only name 
      explicit HybridCalculatorOriginal(const char *name = 0);
      
      /// Constructor for HybridCalculator from pdf instances but without a data-set
      HybridCalculatorOriginal(RooAbsPdf& sb_model,
                       RooAbsPdf& b_model,
                       RooArgList& observables,
                       const RooArgSet* nuisance_parameters = 0,
                       RooAbsPdf* prior_pdf = 0,
                       bool GenerateBinned = false, int testStatistics = 1, int ntoys = 1000 );

      /// Constructor for HybridCalculator using  a data set and pdf instances
      HybridCalculatorOriginal(RooAbsData& data,
                       RooAbsPdf& sb_model,
                       RooAbsPdf& b_model,
                       const RooArgSet* nuisance_parameters = 0,
                       RooAbsPdf* prior_pdf = 0,
                       bool GenerateBinned = false, int testStatistics = 1, int ntoys = 1000 );


      /// Constructor passing a ModelConfig for the SBmodel and a ModelConfig for the B Model
      HybridCalculatorOriginal(RooAbsData& data,
                       const ModelConfig& sb_model, 
                       const ModelConfig& b_model,
                       bool GenerateBinned = false, int testStatistics = 1, int ntoys = 1000 );


   public: 

      /// Destructor of HybridCalculator
      virtual ~HybridCalculatorOriginal();

      /// inherited methods from HypoTestCalculator interface
      virtual HybridResult* GetHypoTest() const;

      // inherited setter methods from HypoTestCalculator


      // set the model for the null hypothesis (only B)
      virtual void SetNullModel(const ModelConfig & );
      // set the model for the alternate hypothesis  (S+B)
      virtual void SetAlternateModel(const ModelConfig & );


      // Set a common PDF for both the null and alternate
      virtual void SetCommonPdf(RooAbsPdf & pdf) { fSbModel = &pdf; }
      // Set the PDF for the null (only B)
      virtual void SetNullPdf(RooAbsPdf& pdf) { fBModel = &pdf; }
      // Set the PDF for the alternate hypothesis ( i.e. S+B)
      virtual void SetAlternatePdf(RooAbsPdf& pdf) { fSbModel = &pdf;  }

      // Set the DataSet
      virtual void SetData(RooAbsData& data) { fData = &data; }

      // set parameter values for the null if using a common PDF
      virtual void SetNullParameters(const RooArgSet& ) { } // not needed
      // set parameter values for the alternate if using a common PDF
      virtual void SetAlternateParameters(const RooArgSet&) {}  // not needed

      // additional methods specific for HybridCalculator
      // set a  prior pdf for the nuisance parameters 
      void SetNuisancePdf(RooAbsPdf & prior_pdf) {          
         fPriorPdf = &prior_pdf; 
         fUsePriorPdf = true; // if set by default turn it on
      } 
      
      // set the nuisance parameters to be marginalized
      void SetNuisanceParameters(const RooArgSet & params) { fNuisanceParameters = &params; }

      // set number of toy MC (Default is 1000)
      void SetNumberOfToys(unsigned int ntoys) { fNToys = ntoys; }

      // return number of toys used
      unsigned int GetNumberOfToys() const { return fNToys; }

      // control use of the pdf for the nuisance parameter and marginalize them
      void UseNuisance(bool on = true) { fUsePriorPdf = on; }

      // control to use bin data generation 
      void SetGenerateBinned(bool on = true) { fGenerateBinned = on; }

      /// set the desired test statistics:
      /// index=1 : 2 * log( L_sb / L_b )  (DEFAULT)
      /// index=2 : number of generated events
      /// index=3 : profiled likelihood ratio
      /// if the index is different to any of those values, the default is used
      void SetTestStatistic(int index);

      HybridResult* Calculate(TH1& data, unsigned int nToys, bool usePriors) const;
      HybridResult* Calculate(RooAbsData& data, unsigned int nToys, bool usePriors) const;
      HybridResult* Calculate(unsigned int nToys, bool usePriors) const;
      void PrintMore(const char* options) const;

      void PatchSetExtended(bool on = true) { fTmpDoExtended = on; std::cout << "extended patch set to " << on << std::endl; } // patch to test with RooPoisson (or other non-extended models)

   private:

      void RunToys(std::vector<double>& bVals, std::vector<double>& sbVals, unsigned int nToys, bool usePriors) const;

      // check input parameters before performing the calculation
      bool DoCheckInputs() const; 

      unsigned int fTestStatisticsIdx; // Index of the test statistics to use
      unsigned int fNToys;            // number of Toys MC
      RooAbsPdf* fSbModel; // The pdf of the signal+background model
      RooAbsPdf* fBModel; // The pdf of the background model
      mutable RooArgList* fObservables; // Collection of the observables of the model
      const RooArgSet* fNuisanceParameters;   // Collection of the nuisance parameters in the model
      RooAbsPdf* fPriorPdf;   // Prior PDF of the nuisance parameters
      RooAbsData * fData;     // pointer to the data sets 
      bool fGenerateBinned;   //Flag to control binned generation
      bool  fUsePriorPdf;               // use a prior for nuisance parameters  
      bool fTmpDoExtended;

//       TString fSbModelName;   // name of pdf of the signal+background model
//       TString fBModelName;   // name of pdf of the background model
//       TString fPriorPdfName;   // name of pdf of the background model
//       TString fDataName;      // name of the dataset in the workspace

   protected:
      ClassDef(HybridCalculatorOriginal,1)  // Hypothesis test calculator using a Bayesian-frequentist hybrid method
   };

}

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