ROOT  6.06/09
Reference Guide
RooStatsUtils.cxx
Go to the documentation of this file.
1 // @(#)root/roostats:$Id$
2 // Author: Kyle Cranmer 28/07/2008
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /////////////////////////////////////////
13 // RooStats
14 //
15 // namespace for classes and functions of the RooStats package
16 /////////////////////////////////////////
17 #include "Rtypes.h"
18 
19 #if !defined(R__ALPHA) && !defined(R__SOLARIS) && !defined(R__ACC) && !defined(R__FBSD)
21 #endif
22 
23 #include "TTree.h"
24 
25 #include "RooUniform.h"
26 #include "RooProdPdf.h"
27 #include "RooExtendPdf.h"
28 #include "RooSimultaneous.h"
29 #include "RooStats/ModelConfig.h"
30 #include "RooStats/RooStatsUtils.h"
31 #include <typeinfo>
32 
33 using namespace std;
34 
35 // this file is only for the documentation of RooStats namespace
36 
37 namespace RooStats {
38 
39  bool gUseOffset = false;
40 
41  void UseNLLOffset(bool on) {
42  // use offset in NLL calculations
43  gUseOffset = on;
44  }
45 
46  bool IsNLLOffset() {
47  return gUseOffset;
48  }
49 
50  void FactorizePdf(const RooArgSet &observables, RooAbsPdf &pdf, RooArgList &obsTerms, RooArgList &constraints) {
51  // utility function to factorize constraint terms from a pdf
52  // (from G. Petrucciani)
53  const std::type_info & id = typeid(pdf);
54  if (id == typeid(RooProdPdf)) {
55  RooProdPdf *prod = dynamic_cast<RooProdPdf *>(&pdf);
56  RooArgList list(prod->pdfList());
57  for (int i = 0, n = list.getSize(); i < n; ++i) {
58  RooAbsPdf *pdfi = (RooAbsPdf *) list.at(i);
59  FactorizePdf(observables, *pdfi, obsTerms, constraints);
60  }
61  } else if (id == typeid(RooExtendPdf)) {
62  TIterator *iter = pdf.serverIterator();
63  // extract underlying pdf which is extended; first server is the pdf; second server is the number of events variable
64  RooAbsPdf *updf = dynamic_cast<RooAbsPdf *>(iter->Next());
65  assert(updf != 0);
66  delete iter;
67  FactorizePdf(observables, *updf, obsTerms, constraints);
68  } else if (id == typeid(RooSimultaneous)) { //|| id == typeid(RooSimultaneousOpt)) {
69  RooSimultaneous *sim = dynamic_cast<RooSimultaneous *>(&pdf);
70  assert(sim != 0);
72  for (int ic = 0, nc = cat->numBins((const char *)0); ic < nc; ++ic) {
73  cat->setBin(ic);
74  RooAbsPdf* catPdf = sim->getPdf(cat->getLabel());
75  // it is possible that a pdf is not defined for every category
76  if (catPdf != 0) FactorizePdf(observables, *catPdf, obsTerms, constraints);
77  }
78  delete cat;
79  } else if (pdf.dependsOn(observables)) {
80  if (!obsTerms.contains(pdf)) obsTerms.add(pdf);
81  } else {
82  if (!constraints.contains(pdf)) constraints.add(pdf);
83  }
84  }
85 
86 
87  void FactorizePdf(RooStats::ModelConfig &model, RooAbsPdf &pdf, RooArgList &obsTerms, RooArgList &constraints) {
88  // utility function to factorize constraint terms from a pdf
89  // (from G. Petrucciani)
90  if (!model.GetObservables() ) {
91  oocoutE((TObject*)0,InputArguments) << "RooStatsUtils::FactorizePdf - invalid input model: missing observables" << endl;
92  return;
93  }
94  return FactorizePdf(*model.GetObservables(), pdf, obsTerms, constraints);
95  }
96 
97 
98  RooAbsPdf * MakeNuisancePdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name) {
99  // make a nuisance pdf by factorizing out all constraint terms in a common pdf
100  RooArgList obsTerms, constraints;
101  FactorizePdf(observables, pdf, obsTerms, constraints);
102  if(constraints.getSize() == 0) {
103  oocoutW((TObject *)0, Eval) << "RooStatsUtils::MakeNuisancePdf - no constraints found on nuisance parameters in the input model" << endl;
104  return 0;
105  } else if(constraints.getSize() == 1) {
106  return dynamic_cast<RooAbsPdf *>(constraints.first()->clone(name));
107  }
108  return new RooProdPdf(name,"", constraints);
109  }
110 
111  RooAbsPdf * MakeNuisancePdf(const RooStats::ModelConfig &model, const char *name) {
112  // make a nuisance pdf by factorizing out all constraint terms in a common pdf
113  if (!model.GetPdf() || !model.GetObservables() ) {
114  oocoutE((TObject*)0, InputArguments) << "RooStatsUtils::MakeNuisancePdf - invalid input model: missing pdf and/or observables" << endl;
115  return 0;
116  }
117  return MakeNuisancePdf(*model.GetPdf(), *model.GetObservables(), name);
118  }
119 
120  RooAbsPdf * StripConstraints(RooAbsPdf &pdf, const RooArgSet &observables) {
121  const std::type_info & id = typeid(pdf);
122 
123  if (id == typeid(RooProdPdf)) {
124 
125  RooProdPdf *prod = dynamic_cast<RooProdPdf *>(&pdf);
126  RooArgList list(prod->pdfList()); RooArgList newList;
127 
128  for (int i = 0, n = list.getSize(); i < n; ++i) {
129  RooAbsPdf *pdfi = (RooAbsPdf *) list.at(i);
130  RooAbsPdf *newPdfi = StripConstraints(*pdfi, observables);
131  if(newPdfi != NULL) newList.add(*newPdfi);
132  }
133 
134  if(newList.getSize() == 0) return NULL; // only constraints in product
135  // return single component (no longer a product)
136  else if(newList.getSize() == 1) return dynamic_cast<RooAbsPdf *>(newList.at(0)->clone(TString::Format("%s_unconstrained",
137  newList.at(0)->GetName())));
138  else return new RooProdPdf(TString::Format("%s_unconstrained", prod->GetName()).Data(),
139  TString::Format("%s without constraints", prod->GetTitle()).Data(), newList);
140 
141  } else if (id == typeid(RooExtendPdf)) {
142 
143  TIterator *iter = pdf.serverIterator();
144  // extract underlying pdf which is extended; first server is the pdf; second server is the number of events variable
145  RooAbsPdf *uPdf = dynamic_cast<RooAbsPdf *>(iter->Next());
146  RooAbsReal *extended_term = dynamic_cast<RooAbsReal *>(iter->Next());
147  assert(uPdf != NULL); assert(extended_term != NULL); assert(iter->Next() == NULL);
148  delete iter;
149 
150  RooAbsPdf *newUPdf = StripConstraints(*uPdf, observables);
151  if(newUPdf == NULL) return NULL; // only constraints in underlying pdf
152  else return new RooExtendPdf(TString::Format("%s_unconstrained", pdf.GetName()).Data(),
153  TString::Format("%s without constraints", pdf.GetTitle()).Data(), *newUPdf, *extended_term);
154 
155  } else if (id == typeid(RooSimultaneous)) { //|| id == typeid(RooSimultaneousOpt)) {
156 
157  RooSimultaneous *sim = dynamic_cast<RooSimultaneous *>(&pdf); assert(sim != NULL);
158  RooAbsCategoryLValue *cat = (RooAbsCategoryLValue *) sim->indexCat().Clone(); assert(cat != NULL);
159  RooArgList pdfList;
160 
161  for (int ic = 0, nc = cat->numBins((const char *)NULL); ic < nc; ++ic) {
162  cat->setBin(ic);
163  RooAbsPdf* catPdf = sim->getPdf(cat->getLabel());
164  RooAbsPdf* newPdf = NULL;
165  // it is possible that a pdf is not defined for every category
166  if (catPdf != NULL) newPdf = StripConstraints(*catPdf, observables);
167  if (newPdf == NULL) { delete cat; return NULL; } // all channels must have observables
168  pdfList.add(*newPdf);
169  }
170 
171  return new RooSimultaneous(TString::Format("%s_unconstrained", sim->GetName()).Data(),
172  TString::Format("%s without constraints", sim->GetTitle()).Data(), pdfList, *cat);
173 
174  } else if (pdf.dependsOn(observables)) {
175  return (RooAbsPdf *) pdf.clone(TString::Format("%s_unconstrained", pdf.GetName()).Data());
176  }
177 
178  return NULL; // just a constraint term
179  }
180 
181  RooAbsPdf * MakeUnconstrainedPdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name) {
182  // make a clone pdf without all constraint terms in a common pdf
183  RooAbsPdf * unconstrainedPdf = StripConstraints(pdf, observables);
184  if(!unconstrainedPdf) {
185  oocoutE((TObject *)NULL, InputArguments) << "RooStats::MakeUnconstrainedPdf - invalid observable list passed (observables not found in original pdf) or invalid pdf passed (without observables)" << endl;
186  return NULL;
187  }
188  if(name != NULL) unconstrainedPdf->SetName(name);
189  return unconstrainedPdf;
190  }
191 
192  RooAbsPdf * MakeUnconstrainedPdf(const RooStats::ModelConfig &model, const char *name) {
193  // make a clone pdf without all constraint terms in a common pdf
194  if(!model.GetPdf() || !model.GetObservables()) {
195  oocoutE((TObject *)NULL, InputArguments) << "RooStatsUtils::MakeUnconstrainedPdf - invalid input model: missing pdf and/or observables" << endl;
196  return NULL;
197  }
198  return MakeUnconstrainedPdf(*model.GetPdf(), *model.GetObservables(), name);
199  }
200 
201  // Helper class for GetAsTTree
202  class BranchStore {
203  public:
204  std::map<TString, Double_t> fVarVals;
205  double fInval;
206  TTree *fTree;
207 
208  BranchStore(const vector <TString> &params = vector <TString>(), double _inval = -999.) : fTree(0) {
209  fInval = _inval;
210  for(unsigned int i = 0;i<params.size();i++)
211  fVarVals[params[i]] = _inval;
212  }
213 
214  ~BranchStore() {
215  if (fTree) {
216  for(std::map<TString, Double_t>::iterator it = fVarVals.begin();it!=fVarVals.end();it++) {
217  TBranch *br = fTree->GetBranch( it->first );
218  if (br) br->ResetAddress();
219  }
220  }
221  }
222 
223  void AssignToTTree(TTree &myTree) {
224  fTree = &myTree;
225  for(std::map<TString, Double_t>::iterator it = fVarVals.begin();it!=fVarVals.end();it++) {
226  const TString& name = it->first;
227  myTree.Branch( name, &fVarVals[name], TString::Format("%s/D", name.Data()));
228  }
229  }
230  void ResetValues() {
231  for(std::map<TString, Double_t>::iterator it = fVarVals.begin();it!=fVarVals.end();it++) {
232  const TString& name = it->first;
233  fVarVals[name] = fInval;
234  }
235  }
236  };
237 
238  BranchStore* CreateBranchStore(const RooDataSet& data) {
239  if (data.numEntries() == 0) {
240  return new BranchStore;
241  }
242  vector <TString> V;
243  const RooArgSet* aset = data.get(0);
244  RooAbsArg *arg(0);
245  TIterator *it = aset->createIterator();
246  for(;(arg = dynamic_cast<RooAbsArg*>(it->Next()));) {
247  RooRealVar *rvar = dynamic_cast<RooRealVar*>(arg);
248  if (rvar == NULL)
249  continue;
250  V.push_back(rvar->GetName());
251  if (rvar->hasAsymError()) {
252  V.push_back(TString::Format("%s_errlo", rvar->GetName()));
253  V.push_back(TString::Format("%s_errhi", rvar->GetName()));
254  }
255  else if (rvar->hasError()) {
256  V.push_back(TString::Format("%s_err", rvar->GetName()));
257  }
258  }
259  delete it;
260  return new BranchStore(V);
261  }
262 
263  void FillTree(TTree &myTree, const RooDataSet &data) {
264  BranchStore *bs = CreateBranchStore(data);
265  bs->AssignToTTree(myTree);
266 
267  for(int entry = 0;entry<data.numEntries();entry++) {
268  bs->ResetValues();
269  const RooArgSet* aset = data.get(entry);
270  RooAbsArg *arg(0);
271  RooLinkedListIter it = aset->iterator();
272  for(;(arg = dynamic_cast<RooAbsArg*>(it.Next()));) {
273  RooRealVar *rvar = dynamic_cast<RooRealVar*>(arg);
274  if (rvar == NULL)
275  continue;
276  bs->fVarVals[rvar->GetName()] = rvar->getValV();
277  if (rvar->hasAsymError()) {
278  bs->fVarVals[TString::Format("%s_errlo", rvar->GetName())] = rvar->getAsymErrorLo();
279  bs->fVarVals[TString::Format("%s_errhi", rvar->GetName())] = rvar->getAsymErrorHi();
280  }
281  else if (rvar->hasError()) {
282  bs->fVarVals[TString::Format("%s_err", rvar->GetName())] = rvar->getError();
283  }
284  }
285  myTree.Fill();
286  }
287 
288  delete bs;
289  }
290 
291  TTree * GetAsTTree(TString name, TString desc, const RooDataSet& data) {
292  TTree* myTree = new TTree(name, desc);
293  FillTree(*myTree, data);
294  return myTree;
295  }
296 
297 
298  // useful function to print in one line the content of a set with their values
299  void PrintListContent(const RooArgList & l, std::ostream & os ) {
300  bool first = true;
301  os << "( ";
302  for (int i = 0; i< l.getSize(); ++i) {
303  if (first) {
304  first=kFALSE ;
305  } else {
306  os << ", " ;
307  }
308  l[i].printName(os);
309  os << " = ";
310  l[i].printValue(os);
311  }
312  os << ")\n";
313  }
314 }
virtual TObject * clone(const char *newname=0) const =0
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
ModelConfig is a simple class that holds configuration information specifying how a model should be u...
Definition: ModelConfig.h:52
RooAbsPdf * GetPdf() const
get model PDF (return NULL if pdf has not been specified or does not exist)
Definition: ModelConfig.h:244
TIterator * serverIterator() const
Definition: RooAbsArg.h:112
Bool_t hasError(Bool_t allowZero=kTRUE) const
Definition: RooRealVar.h:55
RooAbsPdf * MakeNuisancePdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name)
#define assert(cond)
Definition: unittest.h:542
virtual Int_t Fill()
Fill all branches.
Definition: TTree.cxx:4328
const RooAbsCategoryLValue & indexCat() const
Bool_t contains(const RooAbsArg &var) const
Basic string class.
Definition: TString.h:137
const Bool_t kFALSE
Definition: Rtypes.h:92
STL namespace.
TTree * GetAsTTree(TString name, TString desc, const RooDataSet &data)
RooAbsPdf * getPdf(const char *catName) const
Return the p.d.f associated with the given index category name.
Iterator abstract base class.
Definition: TIterator.h:32
void FactorizePdf(const RooArgSet &observables, RooAbsPdf &pdf, RooArgList &obsTerms, RooArgList &constraints)
RooAbsArg * first() const
RooAbsPdf * StripConstraints(RooAbsPdf &pdf, const RooArgSet &observables)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2334
#define oocoutE(o, a)
Definition: RooMsgService.h:48
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
TIterator * createIterator(Bool_t dir=kIterForward) const
std::vector< std::vector< double > > Data
virtual TObject * Next()
NamespaceImp(RooStats) using namespace std
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition: TTree.cxx:4822
RooAbsPdf * MakeUnconstrainedPdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name=NULL)
Bool_t hasAsymError(Bool_t allowZero=kTRUE) const
Definition: RooRealVar.h:60
virtual Int_t numBins(const char *rangeName) const
Returm the number of fit bins ( = number of types )
virtual Int_t numEntries() const
Definition: RooAbsData.cxx:291
BranchStore * CreateBranchStore(const RooDataSet &data)
void SetName(const char *name)
Change (i.e.
Definition: RooAbsArg.cxx:2389
void PrintListContent(const RooArgList &l, std::ostream &os=std::cout)
TLine * l
Definition: textangle.C:4
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
Long64_t entry
Double_t getAsymErrorHi() const
Definition: RooRealVar.h:59
void UseNLLOffset(bool on)
const RooArgSet * GetObservables() const
get RooArgSet for observables (return NULL if not existing)
Definition: ModelConfig.h:259
Namespace for the RooStats classes.
Definition: Asimov.h:20
virtual void ResetAddress()
Reset the address of the branch.
Definition: TBranch.cxx:2017
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
virtual TObject * Clone(const char *newname=0) const
Make a clone of an object using the Streamer facility.
Definition: RooAbsArg.h:75
bool gUseOffset
virtual void printName(std::ostream &os) const
Return collection name.
bool IsNLLOffset()
#define name(a, b)
Definition: linkTestLib0.cpp:5
#define oocoutW(o, a)
Definition: RooMsgService.h:47
Mother of all ROOT objects.
Definition: TObject.h:58
virtual Int_t Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="")
Create one branch for each element in the collection.
Definition: TTree.cxx:1624
Double_t getAsymErrorLo() const
Definition: RooRealVar.h:58
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
void FillTree(TTree &myTree, const RooDataSet &data)
virtual void setBin(Int_t ibin, const char *rangeName=0)
Set category to i-th fit bin, which is the i-th registered state.
virtual TObject * Next()=0
Bool_t dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=0, Bool_t valueOnly=kFALSE) const
Test whether we depend on (ie, are served by) any object in the specified collection.
Definition: RooAbsArg.cxx:743
#define NULL
Definition: Rtypes.h:82
virtual const char * getLabel() const
Return label string of current state.
A TTree object has a header with a name and a title.
Definition: TTree.h:94
RooLinkedListIter iterator(Bool_t dir=kIterForward) const
Int_t getSize() const
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
const RooArgList & pdfList() const
Definition: RooProdPdf.h:69
A TTree is a list of TBranches.
Definition: TBranch.h:58
virtual const RooArgSet * get(Int_t index) const
Return RooArgSet with coordinates of event 'index'.
const Int_t n
Definition: legend1.C:16
virtual void printValue(std::ostream &os) const
Print value of collection, i.e.
Double_t getError() const
Definition: RooRealVar.h:54
virtual Double_t getValV(const RooArgSet *nset=0) const
Return value of variable.
Definition: RooRealVar.cxx:191