// @(#)root/roostats:$Id$
// Author: Sven Kreiss, Kyle Cranmer   Nov 2010
/*************************************************************************
 * 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_HybridCalculator
#define ROOSTATS_HybridCalculator





#ifndef ROOSTATS_HypoTestCalculatorGeneric
#include "RooStats/HypoTestCalculatorGeneric.h"
#endif

#ifndef ROOSTATS_ToyMCSampler
#include "RooStats/ToyMCSampler.h"
#endif



namespace RooStats {

   /**

This class implements the Hypothesis test calculation using an hybrid (frequentist/bayesian) procedure. 
A frequentist sampling of the test statistic distribution is obtained but with mariginalization of the nuisance parameters.
The toys are generated by sampling the nuisance parameters according to their prior distribution. 

The use of the of ToyMCSampler as the TestStatSampler is assumed.

\ingroup Roostats

*/


   class HybridCalculator : public HypoTestCalculatorGeneric {

   public:
      HybridCalculator(
                        const RooAbsData &data,
                        const ModelConfig &altModel,
                        const ModelConfig &nullModel,
                        TestStatSampler* sampler=0
      ) :
         HypoTestCalculatorGeneric(data, altModel, nullModel, sampler),
         fPriorNuisanceNull(MakeNuisancePdf(nullModel, "PriorNuisanceNull")),
         fPriorNuisanceAlt(MakeNuisancePdf(altModel, "PriorNuisanceAlt")),
         fPriorNuisanceNullExternal(false),
         fPriorNuisanceAltExternal(false),
         fNToysNull(-1),
         fNToysAlt(-1),
         fNToysNullTail(0),
         fNToysAltTail(0)
      {
      }

      ~HybridCalculator() {
         if(fPriorNuisanceNullExternal == false) delete fPriorNuisanceNull;   
         if(fPriorNuisanceAltExternal == false) delete fPriorNuisanceAlt;
      }


      /// Override the distribution used for marginalizing nuisance parameters that is inferred from ModelConfig
      virtual void ForcePriorNuisanceNull(RooAbsPdf& priorNuisance) { 
         if(fPriorNuisanceNullExternal == false) delete fPriorNuisanceNull;
         fPriorNuisanceNull = &priorNuisance; fPriorNuisanceNullExternal = true; 
      }
      virtual void ForcePriorNuisanceAlt(RooAbsPdf& priorNuisance) { 
         if(fPriorNuisanceAltExternal == false) delete fPriorNuisanceAlt;
         fPriorNuisanceAlt = &priorNuisance; fPriorNuisanceAltExternal = true; 
      }

      virtual void SetNullModel(const ModelConfig &nullModel) {
         fNullModel = &nullModel;
         if(fPriorNuisanceNullExternal == false) {
            delete fPriorNuisanceNull; 
            fPriorNuisanceNull = MakeNuisancePdf(nullModel, "PriorNuisanceNull");
         }
      }
   
      virtual void SetAlternateModel(const ModelConfig &altModel) {
         fAltModel = &altModel;
         if(fPriorNuisanceAltExternal == false) {
            delete fPriorNuisanceAlt; 
            fPriorNuisanceAlt = MakeNuisancePdf(altModel, "PriorNuisanceAlt");
         }
      }

      /// set number of toys
      void SetToys(int toysNull, int toysAlt) { fNToysNull = toysNull; fNToysAlt = toysAlt; }

      /// set least number of toys in tails
      void SetNToysInTails(int toysNull, int toysAlt) { fNToysNullTail = toysNull; fNToysAltTail = toysAlt; }

   protected:
      /// check whether all input is consistent
      int CheckHook(void) const;

      /// configure TestStatSampler for the Null run
      int PreNullHook(RooArgSet* /*parameterPoint*/, double obsTestStat) const;

      /// configure TestStatSampler for the Alt run
      int PreAltHook(RooArgSet* /*parameterPoint*/, double obsTestStat) const;

   protected:
      RooAbsPdf *fPriorNuisanceNull;
      RooAbsPdf *fPriorNuisanceAlt;

      // these flags tell us if the nuisance pdfs came from an external resource (via ForcePriorNuisance)
      // or were created internally and should be deleted
      Bool_t fPriorNuisanceNullExternal; 
      Bool_t fPriorNuisanceAltExternal;

      // different number of toys for null and alt
      int fNToysNull;
      int fNToysAlt;

      // adaptive sampling
      int fNToysNullTail;
      int fNToysAltTail;

   protected:
      ClassDef(HybridCalculator,2)
   };
}

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