CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/HiggsAnalysis/CombinedLimit/src/AsimovUtils.cc

Go to the documentation of this file.
00001 #include "../interface/AsimovUtils.h"
00002 
00003 #include <memory>
00004 #include <stdexcept>
00005 #include <TIterator.h>
00006 #include <RooAbsData.h>
00007 #include <RooArgSet.h>
00008 #include <RooProdPdf.h>
00009 #include <RooUniform.h>
00010 #include "../interface/utils.h"
00011 #include "../interface/ToyMCSamplerOpt.h"
00012 #include "../interface/CloseCoutSentry.h"
00013 #include "../interface/CascadeMinimizer.h"
00014 
00015 RooAbsData *asimovutils::asimovDatasetNominal(RooStats::ModelConfig *mc, double poiValue, int verbose) {
00016         RooArgSet  poi(*mc->GetParametersOfInterest());
00017         RooRealVar *r = dynamic_cast<RooRealVar *>(poi.first());
00018         r->setConstant(true); r->setVal(poiValue);
00019         toymcoptutils::SimPdfGenInfo newToyMC(*mc->GetPdf(), *mc->GetObservables(), false); 
00020         RooRealVar *weightVar = 0;
00021         RooAbsData *asimov = newToyMC.generateAsimov(weightVar); 
00022         delete weightVar;
00023         return asimov;
00024 }
00025 
00026 RooAbsData *asimovutils::asimovDatasetWithFit(RooStats::ModelConfig *mc, RooAbsData &realdata, RooAbsCollection &snapshot, double poiValue, int verbose) {
00027         RooArgSet  poi(*mc->GetParametersOfInterest());
00028         RooRealVar *r = dynamic_cast<RooRealVar *>(poi.first());
00029         r->setConstant(true); r->setVal(poiValue);
00030         {
00031             CloseCoutSentry sentry(verbose < 3);
00032             bool needsFit = false; 
00033             if (mc->GetNuisanceParameters()) {
00034                 needsFit = true;
00035             } else {
00036                 // Do we have free parameters anyway that need fitting?
00037                 std::auto_ptr<RooArgSet> params(mc->GetPdf()->getParameters(realdata));
00038                 std::auto_ptr<TIterator> iter(params->createIterator());
00039                 for (RooAbsArg *a = (RooAbsArg *) iter->Next(); a != 0; a = (RooAbsArg *) iter->Next()) {
00040                     RooRealVar *rrv = dynamic_cast<RooRealVar *>(a);
00041                     if ( rrv != 0 && rrv->isConstant() == false ) { needsFit = true; break; }
00042                 } 
00043             }
00044             if (needsFit) {
00045                 //mc->GetPdf()->fitTo(realdata, RooFit::Minimizer("Minuit2","minimize"), RooFit::Strategy(1), RooFit::Constrain(*mc->GetNuisanceParameters()));
00046                 const RooCmdArg &constrain = (mc->GetNuisanceParameters() ? RooFit::Constrain(*mc->GetNuisanceParameters()) : RooCmdArg());
00047                 std::auto_ptr<RooAbsReal> nll(mc->GetPdf()->createNLL(realdata, constrain, RooFit::Extended(mc->GetPdf()->canBeExtended())));
00048                 CascadeMinimizer minim(*nll, CascadeMinimizer::Constrained);
00049                 minim.setStrategy(1);
00050                 minim.minimize(verbose-1);
00051             }
00052         }
00053         if (mc->GetNuisanceParameters() && verbose > 1) {
00054             std::cout << "Nuisance parameters after fit for asimov dataset: " << std::endl;
00055             mc->GetNuisanceParameters()->Print("V");
00056         }
00057         toymcoptutils::SimPdfGenInfo newToyMC(*mc->GetPdf(), *mc->GetObservables(), false); 
00058         RooRealVar *weightVar = 0;
00059         RooAbsData *asimov = newToyMC.generateAsimov(weightVar); 
00060         delete weightVar;
00061 
00062         // NOW SNAPSHOT THE GLOBAL OBSERVABLES
00063         if (mc->GetGlobalObservables() && mc->GetGlobalObservables()->getSize() > 0) {
00064             RooArgSet gobs(*mc->GetGlobalObservables());
00065 
00066             // snapshot data global observables
00067             RooArgSet snapGlobalObsData;
00068             utils::setAllConstant(gobs, true);
00069             gobs.snapshot(snapGlobalObsData);
00070 
00071             RooArgSet nuis(*mc->GetNuisanceParameters());
00072             std::auto_ptr<RooAbsPdf> nuispdf(utils::makeNuisancePdf(*mc));
00073             RooProdPdf *prod = dynamic_cast<RooProdPdf *>(nuispdf.get());
00074             if (prod == 0) throw std::runtime_error("AsimovUtils: the nuisance pdf is not a RooProdPdf!");
00075             std::auto_ptr<TIterator> iter(prod->pdfList().createIterator());
00076             for (RooAbsArg *a = (RooAbsArg *) iter->Next(); a != 0; a = (RooAbsArg *) iter->Next()) {
00077                 RooAbsPdf *cterm = dynamic_cast<RooAbsPdf *>(a); 
00078                 if (!cterm) throw std::logic_error("AsimovUtils: a factor of the nuisance pdf is not a Pdf!");
00079                 if (!cterm->dependsOn(nuis)) continue; // dummy constraints
00080                 if (typeid(*cterm) == typeid(RooUniform)) continue;
00081                 std::auto_ptr<RooArgSet> cpars(cterm->getParameters(&gobs));
00082                 std::auto_ptr<RooArgSet> cgobs(cterm->getObservables(&gobs));
00083                 if (cgobs->getSize() != 1) {
00084                     throw std::runtime_error(Form("AsimovUtils: constraint term %s has multiple global observables", cterm->GetName()));
00085                 }
00086                 RooRealVar &rrv = dynamic_cast<RooRealVar &>(*cgobs->first());
00087 
00088                 RooAbsReal *match = 0;
00089                 if (cpars->getSize() == 1) {
00090                     match = dynamic_cast<RooAbsReal *>(cpars->first());
00091                 } else {
00092                     std::auto_ptr<TIterator> iter2(cpars->createIterator());
00093                     for (RooAbsArg *a2 = (RooAbsArg *) iter2->Next(); a2 != 0; a2 = (RooAbsArg *) iter2->Next()) {
00094                         RooRealVar *rrv2 = dynamic_cast<RooRealVar *>(a2); 
00095                         if (rrv2 != 0 && !rrv2->isConstant()) {
00096                             if (match != 0) throw std::runtime_error(Form("AsimovUtils: constraint term %s has multiple floating params", cterm->GetName()));
00097                             match = rrv2;
00098                         }
00099                     }
00100                 }
00101                 if (match == 0) {   
00102                     std::cerr << "ERROR: AsimovUtils: can't find nuisance for constraint term " << cterm->GetName() << std::endl;
00103                     std::cerr << "Parameters: " << std::endl;
00104                     cpars->Print("V");
00105                     std::cerr << "Observables: " << std::endl;
00106                     cgobs->Print("V");
00107                     throw std::runtime_error(Form("AsimovUtils: can't find nuisance for constraint term %s", cterm->GetName()));
00108                 }
00109                 std::string pdfName(cterm->ClassName());
00110                 if (pdfName == "RooGaussian" || pdfName == "RooPoisson") {
00111                     // this is easy
00112                     rrv.setVal(match->getVal());
00113                 } else if (pdfName == "RooGamma") {
00114                     // notation as in http://en.wikipedia.org/wiki/Gamma_distribution
00115                     //     nuisance = x
00116                     //     global obs = kappa ( = observed sideband events + 1)
00117                     //     scaling    = theta ( = extrapolation from sideband to signal)
00118                     // we want to set the global obs to a value for which the current value 
00119                     // of the nuisance is the best fit one.
00120                     // best fit x = (k-1)*theta    ---->  k = x/theta + 1
00121                     RooArgList leaves; cterm->leafNodeServerList(&leaves);
00122                     std::auto_ptr<TIterator> iter2(leaves.createIterator());
00123                     RooAbsReal *match2 = 0;
00124                     for (RooAbsArg *a2 = (RooAbsArg *) iter2->Next(); a2 != 0; a2 = (RooAbsArg *) iter2->Next()) {
00125                         RooAbsReal *rar = dynamic_cast<RooAbsReal *>(a2);
00126                         if (rar == 0 || rar == match || rar == &rrv) continue;
00127                         if (!rar->isConstant()) throw std::runtime_error(Form("AsimovUtils: extra floating parameter %s of RooGamma %s.", rar->GetName(), cterm->GetName()));
00128                         if (rar->getVal() == 0) continue; // this could be mu
00129                         if (match2 != 0) throw std::runtime_error(Form("AsimovUtils: extra constant non-zero parameter %s of RooGamma %s.", rar->GetName(), cterm->GetName()));
00130                         match2 = rar;
00131                     } 
00132                     if (match2 == 0) throw std::runtime_error(Form("AsimovUtils: could not find the scaling term for  RooGamma %s.", cterm->GetName()));
00133                     //std::cout << " nuisance "   << match->GetName() << " = x = " << match->getVal() << std::endl;
00134                     //std::cout << " scaling param "   << match2->GetName() << " = theta = " << match2->getVal() << std::endl;
00135                     //std::cout << " global obs " << rrv.GetName() << " = kappa = " << rrv.getVal() << std::endl;
00136                     //std::cout << " new value for global obs " << rrv.GetName() << " = x/theta+1 = " << (match->getVal()/match2->getVal() + 1) << std::endl;
00137                     rrv.setVal(match->getVal()/match2->getVal() + 1.);
00138                 } else {
00139                     throw std::runtime_error(Form("AsimovUtils: can't handle constraint term %s of type %s", cterm->GetName(), cterm->ClassName()));
00140                 }
00141             }
00142 
00143             // snapshot
00144             snapshot.removeAll();
00145             utils::setAllConstant(gobs, true);
00146             gobs.snapshot(snapshot);
00147 
00148             // revert things to normal
00149             gobs = snapGlobalObsData;
00150     
00151             if (verbose > 1) {
00152                 std::cout << "Global observables for data: " << std::endl;
00153                 snapGlobalObsData.Print("V");
00154                 std::cout << "Global observables for asimov: " << std::endl;
00155                 snapshot.Print("V");
00156             }
00157         }
00158 
00159         return asimov;
00160 }