Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
HypoTestCalculatorGeneric.cxx
Go to the documentation of this file.
1 // @(#)root/roostats:$Id$
2 // Author: Kyle Cranmer, Sven Kreiss 23/05/10
3 /*************************************************************************
4  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 /** \class RooStats::HypoTestCalculatorGeneric
12  \ingroup Roostats
13 
14 Common base class for the Hypothesis Test Calculators.
15 It is not designed to use directly but via its derived classes
16 
17 Same purpose as HybridCalculatorOriginal, but different implementation.
18 
19 This is the "generic" version that works with any TestStatSampler. The
20 HybridCalculator derives from this class but explicitly uses the
21 ToyMCSampler as its TestStatSampler.
22 
23 */
24 
26 #include "RooStats/ToyMCSampler.h"
30 
31 #include "RooAddPdf.h"
32 
33 #include "RooRandom.h"
34 
35 
36 ClassImp(RooStats::HypoTestCalculatorGeneric);
37 
38 using namespace RooStats;
39 using namespace std;
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /// Constructor. When test stat sampler is not provided
43 /// uses ToyMCSampler and RatioOfProfiledLikelihoodsTestStat
44 /// and nToys = 1000.
45 /// User can : GetTestStatSampler()->SetNToys( # )
46 
47 HypoTestCalculatorGeneric::HypoTestCalculatorGeneric(
48  const RooAbsData &data,
49  const ModelConfig &altModel,
50  const ModelConfig &nullModel,
51  TestStatSampler *sampler
52  ) :
53  fAltModel(&altModel),
54  fNullModel(&nullModel),
55  fData(&data),
56  fTestStatSampler(sampler),
57  fDefaultSampler(0),
58  fDefaultTestStat(0),
59  fAltToysSeed(0)
60 {
61  if(!sampler){
62  fDefaultTestStat
63  = new RatioOfProfiledLikelihoodsTestStat(*nullModel.GetPdf(),
64  *altModel.GetPdf(),
65  altModel.GetSnapshot());
66 
67  fDefaultSampler = new ToyMCSampler(*fDefaultTestStat, 1000);
68  fTestStatSampler = fDefaultSampler;
69  }
70 
71 
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 /// common setup for both models
76 
77 void HypoTestCalculatorGeneric::SetupSampler(const ModelConfig& model) const {
78  fNullModel->LoadSnapshot();
79  fTestStatSampler->SetObservables(*fNullModel->GetObservables());
80  fTestStatSampler->SetParametersForTestStat(*fNullModel->GetParametersOfInterest());
81 
82  // for this model
83  model.LoadSnapshot();
84  fTestStatSampler->SetSamplingDistName(model.GetName());
85  fTestStatSampler->SetPdf(*model.GetPdf());
86  fTestStatSampler->SetNuisanceParameters(*model.GetNuisanceParameters());
87  // global observables or nuisance pdf will be set by the derived classes
88  // (e.g. Frequentist or HybridCalculator)
89 }
90 
91 ////////////////////////////////////////////////////////////////////////////////
92 
93 HypoTestCalculatorGeneric::~HypoTestCalculatorGeneric() {
94  if(fDefaultSampler) delete fDefaultSampler;
95  if(fDefaultTestStat) delete fDefaultTestStat;
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// several possibilities:
100 /// no prior nuisance given and no nuisance parameters: ok
101 /// no prior nuisance given but nuisance parameters: error
102 /// prior nuisance given for some nuisance parameters:
103 /// - nuisance parameters are constant, so they don't float in test statistic
104 /// - nuisance parameters are floating, so they do float in test statistic
105 
106 HypoTestResult* HypoTestCalculatorGeneric::GetHypoTest() const {
107 
108  // initial setup
109  PreHook();
110  const_cast<ModelConfig*>(fNullModel)->GuessObsAndNuisance(*fData);
111  const_cast<ModelConfig*>(fAltModel)->GuessObsAndNuisance(*fData);
112 
113  const RooArgSet * nullSnapshot = fNullModel->GetSnapshot();
114  if(nullSnapshot == NULL) {
115  oocoutE((TObject*)0,Generation) << "Null model needs a snapshot. Set using modelconfig->SetSnapshot(poi)." << endl;
116  return 0;
117  }
118 
119  // CheckHook
120  if(CheckHook() != 0) {
121  oocoutE((TObject*)0,Generation) << "There was an error in CheckHook(). Stop." << endl;
122  return 0;
123  }
124 
125  if (!fTestStatSampler || !fTestStatSampler->GetTestStatistic() ) {
126  oocoutE((TObject*)0,InputArguments) << "Test Statistic Sampler or Test Statistics not defined. Stop." << endl;
127  return 0;
128  }
129 
130  // get a big list of all variables for convenient switching
131  RooArgSet *nullParams = fNullModel->GetPdf()->getParameters(*fData);
132  RooArgSet *altParams = fAltModel->GetPdf()->getParameters(*fData);
133  // save all parameters so we can set them back to what they were
134  RooArgSet *bothParams = fNullModel->GetPdf()->getParameters(*fData);
135  bothParams->add(*altParams,false);
136  RooArgSet *saveAll = (RooArgSet*) bothParams->snapshot();
137 
138  // check whether we have a ToyMCSampler and if so, keep a pointer to it
139  ToyMCSampler* toymcs = dynamic_cast<ToyMCSampler*>( fTestStatSampler );
140 
141 
142  // evaluate test statistic on data
143  RooArgSet nullP(*nullSnapshot);
144  double obsTestStat;
145 
146  RooArgList* allTS = NULL;
147  if( toymcs ) {
148  allTS = toymcs->EvaluateAllTestStatistics(*const_cast<RooAbsData*>(fData), nullP);
149  if (!allTS) return 0;
150  //oocoutP((TObject*)0,Generation) << "All Test Statistics on data: " << endl;
151  //allTS->Print("v");
152  RooRealVar* firstTS = (RooRealVar*)allTS->at(0);
153  obsTestStat = firstTS->getVal();
154  if (allTS->getSize()<=1) {
155  delete allTS;
156  allTS= 0; // don't save
157  }
158  }else{
159  obsTestStat = fTestStatSampler->EvaluateTestStatistic(*const_cast<RooAbsData*>(fData), nullP);
160  }
161  oocoutP((TObject*)0,Generation) << "Test Statistic on data: " << obsTestStat << endl;
162 
163  // set parameters back ... in case the evaluation of the test statistic
164  // modified something (e.g. a nuisance parameter that is not randomized
165  // must be set here)
166  *bothParams = *saveAll;
167 
168 
169 
170  // Generate sampling distribution for null
171  SetupSampler(*fNullModel);
172  RooArgSet paramPointNull(*fNullModel->GetParametersOfInterest());
173  if(PreNullHook(&paramPointNull, obsTestStat) != 0) {
174  oocoutE((TObject*)0,Generation) << "PreNullHook did not return 0." << endl;
175  }
176  SamplingDistribution* samp_null = NULL;
177  RooDataSet* detOut_null = NULL;
178  if(toymcs) {
179  detOut_null = toymcs->GetSamplingDistributions(paramPointNull);
180  if( detOut_null ) {
181  samp_null = new SamplingDistribution( detOut_null->GetName(), detOut_null->GetTitle(), *detOut_null );
182  if (detOut_null->get()->getSize()<=1) {
183  delete detOut_null;
184  detOut_null= 0;
185  }
186  }
187  }else samp_null = fTestStatSampler->GetSamplingDistribution(paramPointNull);
188 
189  // set parameters back
190  *bothParams = *saveAll;
191 
192  // Generate sampling distribution for alternate
193  SetupSampler(*fAltModel);
194  RooArgSet paramPointAlt(*fAltModel->GetParametersOfInterest());
195  if(PreAltHook(&paramPointAlt, obsTestStat) != 0) {
196  oocoutE((TObject*)0,Generation) << "PreAltHook did not return 0." << endl;
197  }
198  SamplingDistribution* samp_alt = NULL;
199  RooDataSet* detOut_alt = NULL;
200  if(toymcs) {
201 
202  // case of re-using same toys for every points
203  // set a given seed
204  unsigned int prevSeed = 0;
205  if (fAltToysSeed > 0) {
206  prevSeed = RooRandom::integer(std::numeric_limits<unsigned int>::max()-1)+1; // want to avoid zero value
207  RooRandom::randomGenerator()->SetSeed(fAltToysSeed);
208  }
209 
210  detOut_alt = toymcs->GetSamplingDistributions(paramPointAlt);
211  if( detOut_alt ) {
212  samp_alt = new SamplingDistribution( detOut_alt->GetName(), detOut_alt->GetTitle(), *detOut_alt );
213  if (detOut_alt->get()->getSize()<=1) {
214  delete detOut_alt;
215  detOut_alt= 0;
216  }
217  }
218 
219  // restore the seed
220  if (prevSeed > 0) {
221  RooRandom::randomGenerator()->SetSeed(prevSeed);
222  }
223 
224  }else samp_alt = fTestStatSampler->GetSamplingDistribution(paramPointAlt);
225 
226 
227  // create result
228  string resultname = "HypoTestCalculator_result";
229  HypoTestResult* res = new HypoTestResult(resultname.c_str());
230  res->SetPValueIsRightTail(fTestStatSampler->GetTestStatistic()->PValueIsRightTail());
231  res->SetTestStatisticData(obsTestStat);
232  res->SetAltDistribution(samp_alt);
233  res->SetNullDistribution(samp_null);
234  res->SetAltDetailedOutput( detOut_alt );
235  res->SetNullDetailedOutput( detOut_null );
236  res->SetAllTestStatisticsData( allTS );
237 
238  const RooArgSet *aset = GetFitInfo();
239  if (aset != NULL) {
240  RooDataSet *dset = new RooDataSet(NULL, NULL, *aset);
241  dset->add(*aset);
242  res->SetFitInfo( dset );
243  }
244 
245  *bothParams = *saveAll;
246  delete allTS;
247  delete bothParams;
248  delete saveAll;
249  delete altParams;
250  delete nullParams;
251  delete nullSnapshot;
252  PostHook();
253  return res;
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// to re-use same toys for alternate hypothesis
258 
259 void HypoTestCalculatorGeneric::UseSameAltToys() {
260  fAltToysSeed = RooRandom::integer(std::numeric_limits<unsigned int>::max()-1)+1;
261 }