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

//_________________________________________________
/*
BEGIN_HTML
<p>
This class extends the HybridCalculator with Importance Sampling. The use
of ToyMCSampler as the TestStatSampler is assumed.
</p>
END_HTML
*/
//



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

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

namespace 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