// @(#)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;

   /**

      
HybridCalculatorOriginal class. This class is depracated and it is replaced by the HybridCalculator.
This is a fresh rewrite in RooStats of
	RooStatsCms/LimitCalculator developped by D. Piparo and G. Schott
Authors: D. Piparo, G. Schott - Universitaet Karlsruhe

The class is born from the need to have an implementation of the CLs 
method that could take advantage from the RooFit Package.
The basic idea is the following: 
- Instantiate an object specifying a signal+background model, a background model and a dataset.
- Perform toy MC experiments to know the distributions of -2lnQ 
- Calculate the CLsb and CLs values as "integrals" of these distributions.

The class allows the user to input models as RooAbsPdf ( TH1 object could be used 
by using the RooHistPdf class)
The pdfs must be "extended": for more information please refer to 
http://roofit.sourceforge.net). The dataset can be entered as a 
RooAbsData objects.  

Unlike the TLimit Class a complete MC generation is performed at each step 
and not a simple Poisson fluctuation of the contents of the bins.
Another innovation is the treatment of the nuisance parameters. The user 
can input in the constructor nuisance parameters.
To include the information that we have about the nuisance parameters a prior
PDF (RooAbsPdf) should be specified

Different test statistic can be used (likelihood ratio, number of events or 
profile likelihood ratio. The default is the likelihood ratio. 
See the method SetTestStatistic.

The number of toys to be generated is controlled by SetNumberOfToys(n).

The result of the calculations is returned as a HybridResult object pointer.

see also the following interesting references:
- Alex Read, "Presentation of search results: the CLs technique",
  Journal of Physics G: Nucl. Part. Phys. 28 2693-2704 (2002).
  see http://www.iop.org/EJ/abstract/0954-3899/28/10/313/

- Alex Read, "Modified Frequentist Analysis of Search Results (The CLs Method)" CERN 2000-005 (30 May 2000)

- V. Bartsch, G.Quast, "Expected signal observability at future experiments" CMS NOTE 2005/004

- http://root.cern.ch/root/html/src/TLimit.html
*/


   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
 HybridCalculatorOriginal.h:171
 HybridCalculatorOriginal.h:172
 HybridCalculatorOriginal.h:173
 HybridCalculatorOriginal.h:174
 HybridCalculatorOriginal.h:175
 HybridCalculatorOriginal.h:176
 HybridCalculatorOriginal.h:177
 HybridCalculatorOriginal.h:178
 HybridCalculatorOriginal.h:179
 HybridCalculatorOriginal.h:180
 HybridCalculatorOriginal.h:181
 HybridCalculatorOriginal.h:182
 HybridCalculatorOriginal.h:183
 HybridCalculatorOriginal.h:184
 HybridCalculatorOriginal.h:185
 HybridCalculatorOriginal.h:186
 HybridCalculatorOriginal.h:187
 HybridCalculatorOriginal.h:188
 HybridCalculatorOriginal.h:189
 HybridCalculatorOriginal.h:190
 HybridCalculatorOriginal.h:191
 HybridCalculatorOriginal.h:192
 HybridCalculatorOriginal.h:193
 HybridCalculatorOriginal.h:194
 HybridCalculatorOriginal.h:195
 HybridCalculatorOriginal.h:196
 HybridCalculatorOriginal.h:197
 HybridCalculatorOriginal.h:198
 HybridCalculatorOriginal.h:199
 HybridCalculatorOriginal.h:200
 HybridCalculatorOriginal.h:201
 HybridCalculatorOriginal.h:202
 HybridCalculatorOriginal.h:203
 HybridCalculatorOriginal.h:204
 HybridCalculatorOriginal.h:205
 HybridCalculatorOriginal.h:206
 HybridCalculatorOriginal.h:207
 HybridCalculatorOriginal.h:208
 HybridCalculatorOriginal.h:209
 HybridCalculatorOriginal.h:210
 HybridCalculatorOriginal.h:211
 HybridCalculatorOriginal.h:212
 HybridCalculatorOriginal.h:213
 HybridCalculatorOriginal.h:214
 HybridCalculatorOriginal.h:215
 HybridCalculatorOriginal.h:216
 HybridCalculatorOriginal.h:217
 HybridCalculatorOriginal.h:218
 HybridCalculatorOriginal.h:219