int main (int argc, char *argv[]){ gROOT->SetBatch(); OptionParser(argc,argv); TFile *outFile = new TFile(outfilename_.c_str(),"RECREATE"); RooRealVar *intLumi = new RooRealVar("IntLumi","IntLumi",lumi_*1000,0.,10.e5); WSTFileWrapper * inWS = new WSTFileWrapper(infilename_,"wsig_13TeV"); RooWorkspace *saveWS = new RooWorkspace(); RooWorkspace *tmpWS = new RooWorkspace(); //saveWS->import((inWS->allVars()),RecycleConflictNodes()); //saveWS->import((inWS->allFunctions()),RecycleConflictNodes()); for (int i=0 ; i < inWS->getWsList().size() ; i++){ inWS->getWsList()[i]->Print(); if (i==0) tmpWS = (RooWorkspace*) inWS->getWsList()[i]->Clone(); if (!tmpWS){ std::cout << "EXIT" << std::endl; exit(1);} if (i !=0) { //tmpWS->merge(*(inWS->getWsList()[i])); tmpWS->import(inWS->getWsList()[i]->allVars(),RecycleConflictNodes()); tmpWS->import(inWS->getWsList()[i]->allFunctions(),RecycleConflictNodes()); inWS->getWsList()[i]->allFunctions().Print(); tmpWS->import(inWS->getWsList()[i]->allPdfs(),RecycleConflictNodes()); inWS->getWsList()[i]->allPdfs().Print(); std::list<RooAbsData*> data = (inWS->getWsList()[i]->allData()) ; for (std::list<RooAbsData*>::const_iterator iterator = data.begin(), end = data.end(); iterator != end; ++iterator ) { tmpWS->import(**iterator); } std::list<TObject*> stuff = (inWS->getWsList()[i]->allGenericObjects()) ; for (std::list<TObject*>::const_iterator iterator = stuff.begin(), end = stuff.end(); iterator != end; ++iterator ) { tmpWS->import(**iterator); } }; } WSTFileWrapper *mergedWS = new WSTFileWrapper(tmpWS); saveWS->SetName("wsig_13TeV"); ncats_= flashggCats_.size(); cout << "[INFO] Starting to combine fits..." << endl; // this guy packages everything up RooWorkspace *mergeWS = 0; Packager packager(mergedWS, saveWS ,procs_,ncats_,mhLow_,mhHigh_,skipMasses_,/*sqrts*/13,/*skipPlots_*/false,plotDir_,mergeWS,cats_,flashggCats_); cout << "[INFO] Finished initalising packager." << endl; packager.packageOutput(/*split*/ false); cout << "[INFO] Combination complete." << endl; cout << "[INFO] cd to output file" << endl; outFile->cd(); cout << "[INFO] write saveWS " << endl; saveWS->Write(); cout << "[INFO] close output file " << endl; outFile->Close(); return 0; }
void buildModel(int sel_i, TFile *fin, TDirectory *fout){ // Define outputs RooWorkspace *wout = new RooWorkspace(); wout->SetName(Form("normalization_cat%d",sel_i)); fout->cd(); // Input to this is TTrees // Setup the "x" variable and weights RooRealVar mvamet("metRaw","metRaw",200,1200); //RooRealVar mvamet("jet1mprune","jet1mprune",0,200); //RooRealVar mvamet("jet1tau2o1","jet1tau2o1",0,1); wout->import(mvamet); // TH1F Base Style std::string lName = "basehist"; //const int numberofBins = 18; //double myBins[numberofBins+1] = {200,210,220,230,240,250,260,270,280,290,300,310,320,330,350,380,430,500,1200}; //TH1F *lMet = new TH1F(lName.c_str(),lName.c_str(),numberofBins,myBins); TH1F *lMet = new TH1F(lName.c_str(),lName.c_str(),20,200,1200); //TH1F *lMet = new TH1F(lName.c_str(),lName.c_str(),20,0,1); // Make Datasets makeAndImportDataSets(fin,wout,mvamet); // ========================================================================================================== const int nProcs = 27; std::string procnames[nProcs]; procnames[0] = "DY"; procnames[1] = "RDY"; procnames[2] = "W"; procnames[3] = "WHT"; procnames[4] = "TT"; procnames[5] = "T"; procnames[6] = "ZZ"; procnames[7] = "WW"; procnames[8] = "WZ"; procnames[9] = "WH0"; procnames[10] = "ZH0"; procnames[11] = "GGH0"; procnames[12] = "VBFH0"; //procnames[12] = "DY_control_bkg_mc"; procnames[13] = "Zvv_control_mc"; procnames[14] = "T_control_bkg_mc"; procnames[15] = "TT_control_bkg_mc"; procnames[16] = "WW_control_bkg_mc"; procnames[17] = "WZ_control_bkg_mc"; procnames[18] = "ZZ_control_bkg_mc"; procnames[19] = "Wlv_control_mc_1"; procnames[20] = "Wlv_control_mc_2"; procnames[21] = "T_sl_control_bkg_mc"; procnames[22] = "TT_sl_control_bkg_mc"; procnames[23] = "WW_sl_control_bkg_mc"; procnames[24] = "WZ_sl_control_bkg_mc"; procnames[25] = "ZZ_sl_control_bkg_mc"; procnames[26] = "DY_sl_control_bkg_mc"; // Fill TF1s which do not need corrections for (int p0=0;p0<nProcs;p0++){ std::cout << "Filling hist for " << procnames[p0] << std::endl;; TH1F *hist_ = (TH1F*)generateTemplate(lMet, (TTree*)fin->Get(procnames[p0].c_str()), mvamet.GetName(), "weight",cutstring); // standard processes are TTrees hist_->Write(); } std::cout << "Filling hist for " << "data_obs" << std::endl;; TH1F *hist_ = (TH1F*)generateTemplate(lMet, (TTree*)fin->Get("data_obs"), mvamet.GetName(), "",cutstring); // standard processes are TTrees hist_->Write(); std::cout << "Filling hist for " << "Zvv_control" << std::endl;; hist_ = (TH1F*)generateTemplate(lMet, (TTree*)fin->Get("Zvv_control"), mvamet.GetName(), "",cutstring); // standard processes are TTrees hist_->Write(); std::cout << "Filling hist for " << "Wlv_control" << std::endl;; hist_ = (TH1F*)generateTemplate(lMet, (TTree*)fin->Get("Wlv_control"), mvamet.GetName(), "",cutstring); // standard processes are TTrees hist_->Write(); // ========================================================================================================== // Fit backgrounds to produce fit model #ifdef RUN_CORRECTION buildAndFitModels(fout,wout,mvamet,"Zvv"); buildAndFitModels(fout,wout,mvamet,"Wlv"); double mcyield = wout->data("DY")->sumEntries(); double datayield = wout->var("num_Zvv")->getVal(); // post fit number of data Z->mumu in control std::cout << "sfactor" << brscaleFactorZvv*datayield/mcyield << std::endl; TH1F *hist_zvv = (TH1F*)generateTemplate(lMet, (RooFormulaVar*)wout->function("ratio_Zvv") , *(wout->var(mvamet.GetName())), (RooDataSet*) wout->data("DY") //TH1F *hist_zvv = (TH1F*)generateTemplate(lMet, (RooFormulaVar*)wout->function("") , *(wout->var(mvamet.GetName())), (RooDataSet*) wout->data("DY") , 1 /*run correction*/ , 1 /*brscaleFactorZvv*datayield/mcyield*/ /*additional weight*/); hist_zvv->Write(); std::cout << " DataCardInfo ---------------- " << std::endl; std::cout << Form(" Zvv_norm gmN %d %g ",(int)datayield,hist_zvv->Integral()/datayield) << std::endl; std::cout << " ----------------------------- " << std::endl; // Also correct normalization data why not? hist_zvv = (TH1F*)generateTemplate(lMet, (RooFormulaVar*)wout->function("ratio_Zvv") , *(wout->var(mvamet.GetName())), (RooDataSet*) wout->data("Zvv_control_mc") , 1 /*run correction*/ , 1. /*additional weight*/); hist_zvv->Write(); // Single muon mcyield = wout->data("W")->sumEntries(); datayield = wout->var("num_Wlv")->getVal(); // post fit number of data W->munu in control std::cout << "sfactor" << brscaleFactorWlv*datayield/mcyield << std::endl; TH1F *hist_wlv = (TH1F*)generateTemplate(lMet, (RooFormulaVar*)wout->function("ratio_Wlv") , *(wout->var(mvamet.GetName())), (RooDataSet*) wout->data("W") , 1 /*run correction*/ , 1./*brscaleFactorWlv*datayield/mcyield*/ /*additional weight*/); hist_wlv->Write(); std::cout << " DataCardInfo ---------------- " << std::endl; std::cout << Form(" Wlv_norm gmN %d %g ",(int)datayield,hist_wlv->Integral()/datayield) << std::endl; std::cout << " ----------------------------- " << std::endl; // Also correct normalization data why not? hist_wlv = (TH1F*)generateTemplate(lMet, (RooFormulaVar*)wout->function("ratio_Wlv") , *(wout->var(mvamet.GetName())), (RooDataSet*) wout->data("Wlv_control_mc") , 1 /*run correction*/ , 1. /*additional weight*/); hist_wlv->Write(); //buildAndFitModels(fout,wout,mvamet,"Wlv"); //TH1F *hist_wlv = (TH1F*)generateTemplate(lMet, (RooFormulaVar*)wout->function("ratio_Wlv"), &mvamet, (RooDataSet*) wout->data("")); //hist_wlv->Write(); #endif // Since the W came in 2 parts, we can make the histogram based on the dataset (called uncorrected) TH1F *hist_wlv_uc = (TH1F*)generateTemplate(lMet, (RooFormulaVar*)wout->function("") , *(wout->var(mvamet.GetName())), (RooDataSet*) wout->data("W") , 1 /*run correction forwards*/ , 1./*brscaleFactorWlv*datayield/mcyield*/ /*additional weight*/); hist_wlv_uc->Write(); #ifdef RUN_BKGSYS // Load and run systematics from fit model std::vector<TH1F> v_th1f_Z; generateVariations(lMet,(RooFitResult*)fout->Get("fitResult_Zvv_control"),(RooFormulaVar*)wout->function("ratio_Zvv"),wout->var(mvamet.GetName()),v_th1f_Z,wout,"DY"); std::vector<TH1F> v_th1f_W; generateVariations(lMet,(RooFitResult*)fout->Get("fitResult_Wlv_control"),(RooFormulaVar*)wout->function("ratio_Wlv"),wout->var(mvamet.GetName()),v_th1f_W,wout,"W"); // Nice plots hist_zvv = (TH1F*)fout->Get("th1f_corrected_DY"); hist_wlv = (TH1F*)fout->Get("th1f_corrected_W"); double norm = hist_zvv->Integral(); int colit=2, styleit=1; TCanvas *can_zvv_systs = new TCanvas("can_zvv_systs","can_zvv_systs",800,600); TLegend *leg = new TLegend(0.6,0.4,0.89,0.89); leg->SetFillColor(0); leg->SetTextFont(42); hist_zvv->SetLineColor(1);hist_zvv->SetLineWidth(3); hist_zvv->Draw(); for (std::vector<TH1F>::iterator hit=v_th1f_Z.begin();hit!=v_th1f_Z.end();hit++){ hit->SetLineColor(colit); hit->SetLineWidth(3); hit->SetLineStyle(styleit%2+1); leg->AddEntry(&(*hit),hit->GetName(),"L"); hit->Scale(norm/hit->Integral()); hit->Draw("same"); hit->Write(); styleit++; if (styleit%2==1) colit++; } leg->Draw(); can_zvv_systs->Write(); norm = hist_wlv->Integral(); styleit=1; colit=2; TCanvas *can_wlv_systs = new TCanvas("can_wlv_systs","can_wlv_systs",800,600); TLegend *leg_2 = new TLegend(0.6,0.4,0.89,0.89); leg_2->SetFillColor(0); leg_2->SetTextFont(42); hist_wlv->SetLineColor(1);hist_wlv->SetLineWidth(3); hist_wlv->Draw(); for (std::vector<TH1F>::iterator hit=v_th1f_W.begin();hit!=v_th1f_W.end();hit++){ hit->SetLineColor(colit); hit->SetLineWidth(3); hit->SetLineStyle(styleit%2+1); leg_2->AddEntry(&(*hit),hit->GetName(),"L"); hit->Scale(norm/hit->Integral()); hit->Draw("same"); hit->Write(); styleit++; if (styleit%2==1) colit++; } leg_2->Draw(); can_wlv_systs->Write(); #endif // Save the work fout->cd(); wout->Write(); // Done! }
void rs101_limitexample() { // -------------------------------------- // An example of setting a limit in a number counting experiment with uncertainty on background and signal // to time the macro TStopwatch t; t.Start(); // -------------------------------------- // The Model building stage // -------------------------------------- RooWorkspace* wspace = new RooWorkspace(); wspace->factory("Poisson::countingModel(obs[150,0,300], sum(s[50,0,120]*ratioSigEff[1.,0,3.],b[100]*ratioBkgEff[1.,0.,3.]))"); // counting model // wspace->factory("Gaussian::sigConstraint(ratioSigEff,1,0.05)"); // 5% signal efficiency uncertainty // wspace->factory("Gaussian::bkgConstraint(ratioBkgEff,1,0.1)"); // 10% background efficiency uncertainty wspace->factory("Gaussian::sigConstraint(gSigEff[1,0,3],ratioSigEff,0.05)"); // 5% signal efficiency uncertainty wspace->factory("Gaussian::bkgConstraint(gSigBkg[1,0,3],ratioBkgEff,0.2)"); // 10% background efficiency uncertainty wspace->factory("PROD::modelWithConstraints(countingModel,sigConstraint,bkgConstraint)"); // product of terms wspace->Print(); RooAbsPdf* modelWithConstraints = wspace->pdf("modelWithConstraints"); // get the model RooRealVar* obs = wspace->var("obs"); // get the observable RooRealVar* s = wspace->var("s"); // get the signal we care about RooRealVar* b = wspace->var("b"); // get the background and set it to a constant. Uncertainty included in ratioBkgEff b->setConstant(); RooRealVar* ratioSigEff = wspace->var("ratioSigEff"); // get uncertain parameter to constrain RooRealVar* ratioBkgEff = wspace->var("ratioBkgEff"); // get uncertain parameter to constrain RooArgSet constrainedParams(*ratioSigEff, *ratioBkgEff); // need to constrain these in the fit (should change default behavior) RooRealVar * gSigEff = wspace->var("gSigEff"); // global observables for signal efficiency RooRealVar * gSigBkg = wspace->var("gSigBkg"); // global obs for background efficiency gSigEff->setConstant(); gSigBkg->setConstant(); // Create an example dataset with 160 observed events obs->setVal(160.); RooDataSet* data = new RooDataSet("exampleData", "exampleData", RooArgSet(*obs)); data->add(*obs); RooArgSet all(*s, *ratioBkgEff, *ratioSigEff); // not necessary modelWithConstraints->fitTo(*data, RooFit::Constrain(RooArgSet(*ratioSigEff, *ratioBkgEff))); // Now let's make some confidence intervals for s, our parameter of interest RooArgSet paramOfInterest(*s); ModelConfig modelConfig(wspace); modelConfig.SetPdf(*modelWithConstraints); modelConfig.SetParametersOfInterest(paramOfInterest); modelConfig.SetNuisanceParameters(constrainedParams); modelConfig.SetObservables(*obs); modelConfig.SetGlobalObservables( RooArgSet(*gSigEff,*gSigBkg)); modelConfig.SetName("ModelConfig"); wspace->import(modelConfig); wspace->import(*data); wspace->SetName("w"); wspace->writeToFile("rs101_ws.root"); // First, let's use a Calculator based on the Profile Likelihood Ratio //ProfileLikelihoodCalculator plc(*data, *modelWithConstraints, paramOfInterest); ProfileLikelihoodCalculator plc(*data, modelConfig); plc.SetTestSize(.05); ConfInterval* lrinterval = plc.GetInterval(); // that was easy. // Let's make a plot TCanvas* dataCanvas = new TCanvas("dataCanvas"); dataCanvas->Divide(2,1); dataCanvas->cd(1); LikelihoodIntervalPlot plotInt((LikelihoodInterval*)lrinterval); plotInt.SetTitle("Profile Likelihood Ratio and Posterior for S"); plotInt.Draw(); // Second, use a Calculator based on the Feldman Cousins technique FeldmanCousins fc(*data, modelConfig); fc.UseAdaptiveSampling(true); fc.FluctuateNumDataEntries(false); // number counting analysis: dataset always has 1 entry with N events observed fc.SetNBins(100); // number of points to test per parameter fc.SetTestSize(.05); // fc.SaveBeltToFile(true); // optional ConfInterval* fcint = NULL; fcint = fc.GetInterval(); // that was easy. RooFitResult* fit = modelWithConstraints->fitTo(*data, Save(true)); // Third, use a Calculator based on Markov Chain monte carlo // Before configuring the calculator, let's make a ProposalFunction // that will achieve a high acceptance rate ProposalHelper ph; ph.SetVariables((RooArgSet&)fit->floatParsFinal()); ph.SetCovMatrix(fit->covarianceMatrix()); ph.SetUpdateProposalParameters(true); ph.SetCacheSize(100); ProposalFunction* pdfProp = ph.GetProposalFunction(); // that was easy MCMCCalculator mc(*data, modelConfig); mc.SetNumIters(20000); // steps to propose in the chain mc.SetTestSize(.05); // 95% CL mc.SetNumBurnInSteps(40); // ignore first N steps in chain as "burn in" mc.SetProposalFunction(*pdfProp); mc.SetLeftSideTailFraction(0.5); // find a "central" interval MCMCInterval* mcInt = (MCMCInterval*)mc.GetInterval(); // that was easy // Get Lower and Upper limits from Profile Calculator cout << "Profile lower limit on s = " << ((LikelihoodInterval*) lrinterval)->LowerLimit(*s) << endl; cout << "Profile upper limit on s = " << ((LikelihoodInterval*) lrinterval)->UpperLimit(*s) << endl; // Get Lower and Upper limits from FeldmanCousins with profile construction if (fcint != NULL) { double fcul = ((PointSetInterval*) fcint)->UpperLimit(*s); double fcll = ((PointSetInterval*) fcint)->LowerLimit(*s); cout << "FC lower limit on s = " << fcll << endl; cout << "FC upper limit on s = " << fcul << endl; TLine* fcllLine = new TLine(fcll, 0, fcll, 1); TLine* fculLine = new TLine(fcul, 0, fcul, 1); fcllLine->SetLineColor(kRed); fculLine->SetLineColor(kRed); fcllLine->Draw("same"); fculLine->Draw("same"); dataCanvas->Update(); } // Plot MCMC interval and print some statistics MCMCIntervalPlot mcPlot(*mcInt); mcPlot.SetLineColor(kMagenta); mcPlot.SetLineWidth(2); mcPlot.Draw("same"); double mcul = mcInt->UpperLimit(*s); double mcll = mcInt->LowerLimit(*s); cout << "MCMC lower limit on s = " << mcll << endl; cout << "MCMC upper limit on s = " << mcul << endl; cout << "MCMC Actual confidence level: " << mcInt->GetActualConfidenceLevel() << endl; // 3-d plot of the parameter points dataCanvas->cd(2); // also plot the points in the markov chain RooDataSet * chainData = mcInt->GetChainAsDataSet(); assert(chainData); std::cout << "plotting the chain data - nentries = " << chainData->numEntries() << std::endl; TTree* chain = RooStats::GetAsTTree("chainTreeData","chainTreeData",*chainData); assert(chain); chain->SetMarkerStyle(6); chain->SetMarkerColor(kRed); chain->Draw("s:ratioSigEff:ratioBkgEff","nll_MarkovChain_local_","box"); // 3-d box proportional to posterior // the points used in the profile construction RooDataSet * parScanData = (RooDataSet*) fc.GetPointsToScan(); assert(parScanData); std::cout << "plotting the scanned points used in the frequentist construction - npoints = " << parScanData->numEntries() << std::endl; // getting the tree and drawing it -crashes (very strange....); // TTree* parameterScan = RooStats::GetAsTTree("parScanTreeData","parScanTreeData",*parScanData); // assert(parameterScan); // parameterScan->Draw("s:ratioSigEff:ratioBkgEff","","goff"); TGraph2D *gr = new TGraph2D(parScanData->numEntries()); for (int ievt = 0; ievt < parScanData->numEntries(); ++ievt) { const RooArgSet * evt = parScanData->get(ievt); double x = evt->getRealValue("ratioBkgEff"); double y = evt->getRealValue("ratioSigEff"); double z = evt->getRealValue("s"); gr->SetPoint(ievt, x,y,z); // std::cout << ievt << " " << x << " " << y << " " << z << std::endl; } gr->SetMarkerStyle(24); gr->Draw("P SAME"); delete wspace; delete lrinterval; delete mcInt; delete fcint; delete data; // print timing info t.Stop(); t.Print(); }