// @(#)root/roostats:$Id$
// Author: Kyle Cranmer   28/07/2008

/*************************************************************************
 * 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.             *
 *************************************************************************/

/////////////////////////////////////////
// RooStats
//
// namespace for classes and functions of the RooStats package
/////////////////////////////////////////
#include "Rtypes.h"

#if !defined(R__ALPHA) && !defined(R__SOLARIS) && !defined(R__ACC) && !defined(R__FBSD)
NamespaceImp(RooStats)
#endif

#include "TTree.h"

#include "RooUniform.h"
#include "RooProdPdf.h"
#include "RooExtendPdf.h"
#include "RooSimultaneous.h"
#include "RooStats/ModelConfig.h"
#include "RooStats/RooStatsUtils.h"
#include <typeinfo>

using namespace std;

// this file is only for the documentation of RooStats namespace

namespace RooStats {

   bool gUseOffset = false;
   
   void UseNLLOffset(bool on) { 
      // use offset in NLL calculations
      gUseOffset = on;
   }

   bool IsNLLOffset() {
      return gUseOffset; 
   }      

   void FactorizePdf(const RooArgSet &observables, RooAbsPdf &pdf, RooArgList &obsTerms, RooArgList &constraints) {
   // utility function to factorize constraint terms from a pdf 
   // (from G. Petrucciani)
      const std::type_info & id = typeid(pdf);
      if (id == typeid(RooProdPdf)) {
         RooProdPdf *prod = dynamic_cast<RooProdPdf *>(&pdf);
         RooArgList list(prod->pdfList());
         for (int i = 0, n = list.getSize(); i < n; ++i) {
            RooAbsPdf *pdfi = (RooAbsPdf *) list.at(i);
            FactorizePdf(observables, *pdfi, obsTerms, constraints);
         }
      } else if (id == typeid(RooExtendPdf)) {
         TIterator *iter = pdf.serverIterator(); 
         // extract underlying pdf which is extended; first server is the pdf; second server is the number of events variable
         RooAbsPdf *updf = dynamic_cast<RooAbsPdf *>(iter->Next());
         assert(updf != 0);
         delete iter;
         FactorizePdf(observables, *updf, obsTerms, constraints);
      } else if (id == typeid(RooSimultaneous)) {    //|| id == typeid(RooSimultaneousOpt)) {
         RooSimultaneous *sim  = dynamic_cast<RooSimultaneous *>(&pdf);
         assert(sim != 0);
         RooAbsCategoryLValue *cat = (RooAbsCategoryLValue *) sim->indexCat().clone(sim->indexCat().GetName());
         for (int ic = 0, nc = cat->numBins((const char *)0); ic < nc; ++ic) {
            cat->setBin(ic);
            RooAbsPdf* catPdf = sim->getPdf(cat->getLabel());
            // it is possible that a pdf is not defined for every category
            if (catPdf != 0) FactorizePdf(observables, *catPdf, obsTerms, constraints);
         }
         delete cat;
      } else if (pdf.dependsOn(observables)) {
         if (!obsTerms.contains(pdf)) obsTerms.add(pdf);
      } else {
         if (!constraints.contains(pdf)) constraints.add(pdf);
      }
   }


   void FactorizePdf(RooStats::ModelConfig &model, RooAbsPdf &pdf, RooArgList &obsTerms, RooArgList &constraints) {
      // utility function to factorize constraint terms from a pdf 
      // (from G. Petrucciani)
      if (!model.GetObservables() ) { 
         oocoutE((TObject*)0,InputArguments) << "RooStatsUtils::FactorizePdf - invalid input model: missing observables" << endl;
         return;
      }
      return FactorizePdf(*model.GetObservables(), pdf, obsTerms, constraints);
   }


   RooAbsPdf * MakeNuisancePdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name) { 
      // make a nuisance pdf by factorizing out all constraint terms in a common pdf 
      RooArgList obsTerms, constraints;
      FactorizePdf(observables, pdf, obsTerms, constraints);
      if(constraints.getSize() == 0) {
         oocoutW((TObject *)0, Eval) << "RooStatsUtils::MakeNuisancePdf - no constraints found on nuisance parameters in the input model" << endl;
         return 0;
      } else if(constraints.getSize() == 1) {
         return dynamic_cast<RooAbsPdf *>(constraints.first()->clone(name));
      }
      return new RooProdPdf(name,"", constraints);
   }

   RooAbsPdf * MakeNuisancePdf(const RooStats::ModelConfig &model, const char *name) { 
      // make a nuisance pdf by factorizing out all constraint terms in a common pdf
      if (!model.GetPdf() || !model.GetObservables() ) { 
         oocoutE((TObject*)0, InputArguments) << "RooStatsUtils::MakeNuisancePdf - invalid input model: missing pdf and/or observables" << endl;
         return 0;
      }
      return MakeNuisancePdf(*model.GetPdf(), *model.GetObservables(), name);
   }

   RooAbsPdf * StripConstraints(RooAbsPdf &pdf, const RooArgSet &observables) { 
      const std::type_info & id = typeid(pdf);

      if (id == typeid(RooProdPdf)) {

         RooProdPdf *prod = dynamic_cast<RooProdPdf *>(&pdf);
         RooArgList list(prod->pdfList()); RooArgList newList;

         for (int i = 0, n = list.getSize(); i < n; ++i) {
            RooAbsPdf *pdfi = (RooAbsPdf *) list.at(i);
            RooAbsPdf *newPdfi = StripConstraints(*pdfi, observables);
            if(newPdfi != NULL) newList.add(*newPdfi);
         }

         if(newList.getSize() == 0) return NULL; // only constraints in product
         // return single component (no longer a product)
         else if(newList.getSize() == 1) return dynamic_cast<RooAbsPdf *>(newList.at(0)->clone(TString::Format("%s_unconstrained", 
                                                                                                               newList.at(0)->GetName()))); 
         else return new RooProdPdf(TString::Format("%s_unconstrained", prod->GetName()).Data(),
            TString::Format("%s without constraints", prod->GetTitle()).Data(), newList);

      } else if (id == typeid(RooExtendPdf)) {

         TIterator *iter = pdf.serverIterator(); 
         // extract underlying pdf which is extended; first server is the pdf; second server is the number of events variable
         RooAbsPdf *uPdf = dynamic_cast<RooAbsPdf *>(iter->Next());
         RooAbsReal *extended_term = dynamic_cast<RooAbsReal *>(iter->Next());
         assert(uPdf != NULL); assert(extended_term != NULL); assert(iter->Next() == NULL);
         delete iter;
         
         RooAbsPdf *newUPdf = StripConstraints(*uPdf, observables);
         if(newUPdf == NULL) return NULL; // only constraints in underlying pdf
         else return new RooExtendPdf(TString::Format("%s_unconstrained", pdf.GetName()).Data(),
            TString::Format("%s without constraints", pdf.GetTitle()).Data(), *newUPdf, *extended_term);
         
      } else if (id == typeid(RooSimultaneous)) {    //|| id == typeid(RooSimultaneousOpt)) {

         RooSimultaneous *sim  = dynamic_cast<RooSimultaneous *>(&pdf); assert(sim != NULL);
         RooAbsCategoryLValue *cat = (RooAbsCategoryLValue *) sim->indexCat().Clone(); assert(cat != NULL);
         RooArgList pdfList;

         for (int ic = 0, nc = cat->numBins((const char *)NULL); ic < nc; ++ic) {
            cat->setBin(ic);
            RooAbsPdf* catPdf = sim->getPdf(cat->getLabel());
            RooAbsPdf* newPdf = NULL;
            // it is possible that a pdf is not defined for every category
            if (catPdf != NULL) newPdf = StripConstraints(*catPdf, observables);
            if (newPdf == NULL) { delete cat; return NULL; } // all channels must have observables
            pdfList.add(*newPdf);
         }

         return new RooSimultaneous(TString::Format("%s_unconstrained", sim->GetName()).Data(), 
            TString::Format("%s without constraints", sim->GetTitle()).Data(), pdfList, *cat); 

      } else if (pdf.dependsOn(observables)) {  
         return (RooAbsPdf *) pdf.clone(TString::Format("%s_unconstrained", pdf.GetName()).Data());
      }

      return NULL; // just  a constraint term
   }

   RooAbsPdf * MakeUnconstrainedPdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name) { 
      // make a clone pdf without all constraint terms in a common pdf
      RooAbsPdf * unconstrainedPdf = StripConstraints(pdf, observables);
      if(!unconstrainedPdf) {
         oocoutE((TObject *)NULL, InputArguments) << "RooStats::MakeUnconstrainedPdf - invalid observable list passed (observables not found in original pdf) or invalid pdf passed (without observables)" << endl;
         return NULL;
      }
      if(name != NULL) unconstrainedPdf->SetName(name);
      return unconstrainedPdf;   
   }

   RooAbsPdf * MakeUnconstrainedPdf(const RooStats::ModelConfig &model, const char *name) { 
      // make a clone pdf without all constraint terms in a common pdf 
      if(!model.GetPdf() || !model.GetObservables()) {
         oocoutE((TObject *)NULL, InputArguments) << "RooStatsUtils::MakeUnconstrainedPdf - invalid input model: missing pdf and/or observables" << endl;
         return NULL;
      }
      return MakeUnconstrainedPdf(*model.GetPdf(), *model.GetObservables(), name);
   }

   // Helper class for GetAsTTree
   class BranchStore {
      public:
         std::map<TString, Double_t> fVarVals;
         double fInval;
         TTree *fTree;

         BranchStore(const vector <TString> &params = vector <TString>(), double _inval = -999.) : fTree(0) {
            fInval = _inval;
            for(unsigned int i = 0;i<params.size();i++)
               fVarVals[params[i]] = _inval;
         }

         ~BranchStore() {
            if (fTree) {
               for(std::map<TString, Double_t>::iterator it = fVarVals.begin();it!=fVarVals.end();it++) {
                  TBranch *br = fTree->GetBranch( it->first );
                  if (br) br->ResetAddress();
               }
            }
         }

         void AssignToTTree(TTree &myTree) {
            fTree = &myTree;
            for(std::map<TString, Double_t>::iterator it = fVarVals.begin();it!=fVarVals.end();it++) {
               const TString& name = it->first;
               myTree.Branch( name, &fVarVals[name], TString::Format("%s/D", name.Data()));
            }
         }
         void ResetValues() {
            for(std::map<TString, Double_t>::iterator it = fVarVals.begin();it!=fVarVals.end();it++) {
               const TString& name = it->first;
               fVarVals[name] = fInval;
            }
         }
   };

   BranchStore* CreateBranchStore(const RooDataSet& data) {
      if (data.numEntries() == 0) {
         return new BranchStore;
      }
      vector <TString> V;
      const RooArgSet* aset = data.get(0);
      RooAbsArg *arg(0);
      TIterator *it = aset->createIterator();
      for(;(arg = dynamic_cast<RooAbsArg*>(it->Next()));) {
         RooRealVar *rvar = dynamic_cast<RooRealVar*>(arg);
         if (rvar == NULL)
            continue;
         V.push_back(rvar->GetName());
         if (rvar->hasAsymError()) {
            V.push_back(TString::Format("%s_errlo", rvar->GetName()));
            V.push_back(TString::Format("%s_errhi", rvar->GetName()));
         }
         else if (rvar->hasError()) {
            V.push_back(TString::Format("%s_err", rvar->GetName()));
         }
      }
      delete it;
      return new BranchStore(V);
   }

   void FillTree(TTree &myTree, const RooDataSet &data) {
      BranchStore *bs = CreateBranchStore(data);
      bs->AssignToTTree(myTree);

      for(int entry = 0;entry<data.numEntries();entry++) {
         bs->ResetValues();
         const RooArgSet* aset = data.get(entry);
         RooAbsArg *arg(0);
         RooLinkedListIter it = aset->iterator();
         for(;(arg = dynamic_cast<RooAbsArg*>(it.Next()));) {
            RooRealVar *rvar = dynamic_cast<RooRealVar*>(arg);
            if (rvar == NULL)
               continue;
            bs->fVarVals[rvar->GetName()] = rvar->getValV();
            if (rvar->hasAsymError()) {
               bs->fVarVals[TString::Format("%s_errlo", rvar->GetName())] = rvar->getAsymErrorLo();
               bs->fVarVals[TString::Format("%s_errhi", rvar->GetName())] = rvar->getAsymErrorHi();
            }
            else if (rvar->hasError()) {
               bs->fVarVals[TString::Format("%s_err", rvar->GetName())] = rvar->getError();
            }
         }
         myTree.Fill();
      }

      delete bs;
   }

   TTree * GetAsTTree(TString name, TString desc, const RooDataSet& data) {
      TTree* myTree = new TTree(name, desc);
      FillTree(*myTree, data);
      return myTree;
   }


   // useful function to print in one line the content of a set with their values 
   void PrintListContent(const RooArgList & l, std::ostream & os ) { 
      bool first = true;
      os << "( "; 
      for (int i = 0; i< l.getSize(); ++i) { 
         if (first) {
            first=kFALSE ;
         } else {
            os << ", " ;
         }
         l[i].printName(os); 
         os << " = "; 
         l[i].printValue(os); 
      }
      os << ")\n"; 
   }
}
 RooStatsUtils.cxx:1
 RooStatsUtils.cxx:2
 RooStatsUtils.cxx:3
 RooStatsUtils.cxx:4
 RooStatsUtils.cxx:5
 RooStatsUtils.cxx:6
 RooStatsUtils.cxx:7
 RooStatsUtils.cxx:8
 RooStatsUtils.cxx:9
 RooStatsUtils.cxx:10
 RooStatsUtils.cxx:11
 RooStatsUtils.cxx:12
 RooStatsUtils.cxx:13
 RooStatsUtils.cxx:14
 RooStatsUtils.cxx:15
 RooStatsUtils.cxx:16
 RooStatsUtils.cxx:17
 RooStatsUtils.cxx:18
 RooStatsUtils.cxx:19
 RooStatsUtils.cxx:20
 RooStatsUtils.cxx:21
 RooStatsUtils.cxx:22
 RooStatsUtils.cxx:23
 RooStatsUtils.cxx:24
 RooStatsUtils.cxx:25
 RooStatsUtils.cxx:26
 RooStatsUtils.cxx:27
 RooStatsUtils.cxx:28
 RooStatsUtils.cxx:29
 RooStatsUtils.cxx:30
 RooStatsUtils.cxx:31
 RooStatsUtils.cxx:32
 RooStatsUtils.cxx:33
 RooStatsUtils.cxx:34
 RooStatsUtils.cxx:35
 RooStatsUtils.cxx:36
 RooStatsUtils.cxx:37
 RooStatsUtils.cxx:38
 RooStatsUtils.cxx:39
 RooStatsUtils.cxx:40
 RooStatsUtils.cxx:41
 RooStatsUtils.cxx:42
 RooStatsUtils.cxx:43
 RooStatsUtils.cxx:44
 RooStatsUtils.cxx:45
 RooStatsUtils.cxx:46
 RooStatsUtils.cxx:47
 RooStatsUtils.cxx:48
 RooStatsUtils.cxx:49
 RooStatsUtils.cxx:50
 RooStatsUtils.cxx:51
 RooStatsUtils.cxx:52
 RooStatsUtils.cxx:53
 RooStatsUtils.cxx:54
 RooStatsUtils.cxx:55
 RooStatsUtils.cxx:56
 RooStatsUtils.cxx:57
 RooStatsUtils.cxx:58
 RooStatsUtils.cxx:59
 RooStatsUtils.cxx:60
 RooStatsUtils.cxx:61
 RooStatsUtils.cxx:62
 RooStatsUtils.cxx:63
 RooStatsUtils.cxx:64
 RooStatsUtils.cxx:65
 RooStatsUtils.cxx:66
 RooStatsUtils.cxx:67
 RooStatsUtils.cxx:68
 RooStatsUtils.cxx:69
 RooStatsUtils.cxx:70
 RooStatsUtils.cxx:71
 RooStatsUtils.cxx:72
 RooStatsUtils.cxx:73
 RooStatsUtils.cxx:74
 RooStatsUtils.cxx:75
 RooStatsUtils.cxx:76
 RooStatsUtils.cxx:77
 RooStatsUtils.cxx:78
 RooStatsUtils.cxx:79
 RooStatsUtils.cxx:80
 RooStatsUtils.cxx:81
 RooStatsUtils.cxx:82
 RooStatsUtils.cxx:83
 RooStatsUtils.cxx:84
 RooStatsUtils.cxx:85
 RooStatsUtils.cxx:86
 RooStatsUtils.cxx:87
 RooStatsUtils.cxx:88
 RooStatsUtils.cxx:89
 RooStatsUtils.cxx:90
 RooStatsUtils.cxx:91
 RooStatsUtils.cxx:92
 RooStatsUtils.cxx:93
 RooStatsUtils.cxx:94
 RooStatsUtils.cxx:95
 RooStatsUtils.cxx:96
 RooStatsUtils.cxx:97
 RooStatsUtils.cxx:98
 RooStatsUtils.cxx:99
 RooStatsUtils.cxx:100
 RooStatsUtils.cxx:101
 RooStatsUtils.cxx:102
 RooStatsUtils.cxx:103
 RooStatsUtils.cxx:104
 RooStatsUtils.cxx:105
 RooStatsUtils.cxx:106
 RooStatsUtils.cxx:107
 RooStatsUtils.cxx:108
 RooStatsUtils.cxx:109
 RooStatsUtils.cxx:110
 RooStatsUtils.cxx:111
 RooStatsUtils.cxx:112
 RooStatsUtils.cxx:113
 RooStatsUtils.cxx:114
 RooStatsUtils.cxx:115
 RooStatsUtils.cxx:116
 RooStatsUtils.cxx:117
 RooStatsUtils.cxx:118
 RooStatsUtils.cxx:119
 RooStatsUtils.cxx:120
 RooStatsUtils.cxx:121
 RooStatsUtils.cxx:122
 RooStatsUtils.cxx:123
 RooStatsUtils.cxx:124
 RooStatsUtils.cxx:125
 RooStatsUtils.cxx:126
 RooStatsUtils.cxx:127
 RooStatsUtils.cxx:128
 RooStatsUtils.cxx:129
 RooStatsUtils.cxx:130
 RooStatsUtils.cxx:131
 RooStatsUtils.cxx:132
 RooStatsUtils.cxx:133
 RooStatsUtils.cxx:134
 RooStatsUtils.cxx:135
 RooStatsUtils.cxx:136
 RooStatsUtils.cxx:137
 RooStatsUtils.cxx:138
 RooStatsUtils.cxx:139
 RooStatsUtils.cxx:140
 RooStatsUtils.cxx:141
 RooStatsUtils.cxx:142
 RooStatsUtils.cxx:143
 RooStatsUtils.cxx:144
 RooStatsUtils.cxx:145
 RooStatsUtils.cxx:146
 RooStatsUtils.cxx:147
 RooStatsUtils.cxx:148
 RooStatsUtils.cxx:149
 RooStatsUtils.cxx:150
 RooStatsUtils.cxx:151
 RooStatsUtils.cxx:152
 RooStatsUtils.cxx:153
 RooStatsUtils.cxx:154
 RooStatsUtils.cxx:155
 RooStatsUtils.cxx:156
 RooStatsUtils.cxx:157
 RooStatsUtils.cxx:158
 RooStatsUtils.cxx:159
 RooStatsUtils.cxx:160
 RooStatsUtils.cxx:161
 RooStatsUtils.cxx:162
 RooStatsUtils.cxx:163
 RooStatsUtils.cxx:164
 RooStatsUtils.cxx:165
 RooStatsUtils.cxx:166
 RooStatsUtils.cxx:167
 RooStatsUtils.cxx:168
 RooStatsUtils.cxx:169
 RooStatsUtils.cxx:170
 RooStatsUtils.cxx:171
 RooStatsUtils.cxx:172
 RooStatsUtils.cxx:173
 RooStatsUtils.cxx:174
 RooStatsUtils.cxx:175
 RooStatsUtils.cxx:176
 RooStatsUtils.cxx:177
 RooStatsUtils.cxx:178
 RooStatsUtils.cxx:179
 RooStatsUtils.cxx:180
 RooStatsUtils.cxx:181
 RooStatsUtils.cxx:182
 RooStatsUtils.cxx:183
 RooStatsUtils.cxx:184
 RooStatsUtils.cxx:185
 RooStatsUtils.cxx:186
 RooStatsUtils.cxx:187
 RooStatsUtils.cxx:188
 RooStatsUtils.cxx:189
 RooStatsUtils.cxx:190
 RooStatsUtils.cxx:191
 RooStatsUtils.cxx:192
 RooStatsUtils.cxx:193
 RooStatsUtils.cxx:194
 RooStatsUtils.cxx:195
 RooStatsUtils.cxx:196
 RooStatsUtils.cxx:197
 RooStatsUtils.cxx:198
 RooStatsUtils.cxx:199
 RooStatsUtils.cxx:200
 RooStatsUtils.cxx:201
 RooStatsUtils.cxx:202
 RooStatsUtils.cxx:203
 RooStatsUtils.cxx:204
 RooStatsUtils.cxx:205
 RooStatsUtils.cxx:206
 RooStatsUtils.cxx:207
 RooStatsUtils.cxx:208
 RooStatsUtils.cxx:209
 RooStatsUtils.cxx:210
 RooStatsUtils.cxx:211
 RooStatsUtils.cxx:212
 RooStatsUtils.cxx:213
 RooStatsUtils.cxx:214
 RooStatsUtils.cxx:215
 RooStatsUtils.cxx:216
 RooStatsUtils.cxx:217
 RooStatsUtils.cxx:218
 RooStatsUtils.cxx:219
 RooStatsUtils.cxx:220
 RooStatsUtils.cxx:221
 RooStatsUtils.cxx:222
 RooStatsUtils.cxx:223
 RooStatsUtils.cxx:224
 RooStatsUtils.cxx:225
 RooStatsUtils.cxx:226
 RooStatsUtils.cxx:227
 RooStatsUtils.cxx:228
 RooStatsUtils.cxx:229
 RooStatsUtils.cxx:230
 RooStatsUtils.cxx:231
 RooStatsUtils.cxx:232
 RooStatsUtils.cxx:233
 RooStatsUtils.cxx:234
 RooStatsUtils.cxx:235
 RooStatsUtils.cxx:236
 RooStatsUtils.cxx:237
 RooStatsUtils.cxx:238
 RooStatsUtils.cxx:239
 RooStatsUtils.cxx:240
 RooStatsUtils.cxx:241
 RooStatsUtils.cxx:242
 RooStatsUtils.cxx:243
 RooStatsUtils.cxx:244
 RooStatsUtils.cxx:245
 RooStatsUtils.cxx:246
 RooStatsUtils.cxx:247
 RooStatsUtils.cxx:248
 RooStatsUtils.cxx:249
 RooStatsUtils.cxx:250
 RooStatsUtils.cxx:251
 RooStatsUtils.cxx:252
 RooStatsUtils.cxx:253
 RooStatsUtils.cxx:254
 RooStatsUtils.cxx:255
 RooStatsUtils.cxx:256
 RooStatsUtils.cxx:257
 RooStatsUtils.cxx:258
 RooStatsUtils.cxx:259
 RooStatsUtils.cxx:260
 RooStatsUtils.cxx:261
 RooStatsUtils.cxx:262
 RooStatsUtils.cxx:263
 RooStatsUtils.cxx:264
 RooStatsUtils.cxx:265
 RooStatsUtils.cxx:266
 RooStatsUtils.cxx:267
 RooStatsUtils.cxx:268
 RooStatsUtils.cxx:269
 RooStatsUtils.cxx:270
 RooStatsUtils.cxx:271
 RooStatsUtils.cxx:272
 RooStatsUtils.cxx:273
 RooStatsUtils.cxx:274
 RooStatsUtils.cxx:275
 RooStatsUtils.cxx:276
 RooStatsUtils.cxx:277
 RooStatsUtils.cxx:278
 RooStatsUtils.cxx:279
 RooStatsUtils.cxx:280
 RooStatsUtils.cxx:281
 RooStatsUtils.cxx:282
 RooStatsUtils.cxx:283
 RooStatsUtils.cxx:284
 RooStatsUtils.cxx:285
 RooStatsUtils.cxx:286
 RooStatsUtils.cxx:287
 RooStatsUtils.cxx:288
 RooStatsUtils.cxx:289
 RooStatsUtils.cxx:290
 RooStatsUtils.cxx:291
 RooStatsUtils.cxx:292
 RooStatsUtils.cxx:293
 RooStatsUtils.cxx:294
 RooStatsUtils.cxx:295
 RooStatsUtils.cxx:296
 RooStatsUtils.cxx:297
 RooStatsUtils.cxx:298
 RooStatsUtils.cxx:299
 RooStatsUtils.cxx:300
 RooStatsUtils.cxx:301
 RooStatsUtils.cxx:302
 RooStatsUtils.cxx:303
 RooStatsUtils.cxx:304
 RooStatsUtils.cxx:305
 RooStatsUtils.cxx:306
 RooStatsUtils.cxx:307
 RooStatsUtils.cxx:308
 RooStatsUtils.cxx:309
 RooStatsUtils.cxx:310
 RooStatsUtils.cxx:311
 RooStatsUtils.cxx:312
 RooStatsUtils.cxx:313
 RooStatsUtils.cxx:314