//2d reweighting of rho and its sigma void reweight_rhosigma(TH1F* weight_rho, TH1F* weight_rhoo,TH2F*weight_rhon,TH2F*weight_rho2o,TH2F* weight_rhonr, TH2F* weight_rho2,TH2F*weight_sigman,TH2F*weight_sigma2o,TH2F* weight_sigmanr, TH2F* weight_sigma2,RooDataSet **dset, RooDataSet *dsetdestination, bool deleteold){ if (!(*dset)) return; // TH2F *hnum = new TH2F("hnum","hnum",n_rhobins_forreweighting,rhobins_forreweighting,n_sigmabins_forreweighting,sigmabins_forreweighting); // TH2F *hden = new TH2F("hden","hden",n_rhobins_forreweighting,rhobins_forreweighting,n_sigmabins_forreweighting,sigmabins_forreweighting); TH2F *hnum = new TH2F("hnum","hnum",100,0,100,20,0,20); TH2F *hden = new TH2F("hden","hden",100,0,100,20,0,20); hnum->Sumw2(); hden->Sumw2(); for (int i=0; i<(*dset)->numEntries(); i++){ hden->Fill(fabs((*dset)->get(i)->getRealValue("roorho")),fabs((*dset)->get(i)->getRealValue("roosigma")),(*dset)->store()->weight(i)); } for (int i=0; i<dsetdestination->numEntries(); i++){ hnum->Fill(fabs(dsetdestination->get(i)->getRealValue("roorho")),fabs(dsetdestination->get(i)->getRealValue("roosigma")),dsetdestination->store()->weight(i)); } hnum->Scale(1.0/hnum->Integral()); hden->Scale(1.0/hden->Integral()); //data/MC hnum->Divide(hden); TH2F *h = hnum; RooDataSet *newdset = new RooDataSet(**dset,Form("%s_rhosigmarew",(*dset)->GetName())); newdset->reset(); for (int i=0; i<(*dset)->numEntries(); i++){ RooArgSet args = *((*dset)->get(i)); float oldw = (*dset)->store()->weight(i); float rho = args.getRealValue("roorho"); float sigma = args.getRealValue("roosigma"); float neww = oldw*h->GetBinContent(h->FindBin(rho,sigma)); if(debug){ weight_rho->Fill(neww); weight_rhoo->Fill(oldw); weight_rho2o->Fill(h->GetXaxis()->FindBin(rho),oldw); weight_rhon->Fill(h->GetXaxis()->FindBin(rho),neww); if(oldw!=0)weight_rhonr->Fill(h->GetXaxis()->FindBin(rho),oldw/neww); else {weight_rhonr->Fill(-10,1);}//cout << "dipho weight old 0" << endl;} if(oldw!=0)weight_rho2->Fill(rho,oldw/neww); weight_sigma2o->Fill(h->GetYaxis()->FindBin(sigma),oldw); weight_sigman->Fill(h->GetYaxis()->FindBin(sigma),neww); if(oldw!=0)weight_sigmanr->Fill(h->GetYaxis()->FindBin(sigma),oldw/neww); else {weight_sigmanr->Fill(-10,1);}//cout << "dipho weight old 0" << endl;} if(oldw!=0)weight_sigma2->Fill(sigma,oldw/neww); } newdset->add(args,neww); } newdset->SetName((*dset)->GetName()); newdset->SetTitle((*dset)->GetTitle()); delete hnum; delete hden; RooDataSet *old_dset = *dset; *dset=newdset; std::cout << "RhoSigma2D rew: norm from " << old_dset->sumEntries() << " to " << newdset->sumEntries() << std::endl; if (deleteold) delete old_dset; };
void reweight_eta_1d(TH1F* weight_eta,TH1F* weight_etao,TH2F*weight_etan,TH2F* weight_eta2o,TH2F* weight_etanr,TH2F*weight_eta2,RooDataSet **dset, RooDataSet *dsetdestination, int numvar){ if (!(*dset)) return; TH1F *hnum = new TH1F("hnum","hnum",n_etabins_forreweighting,etabins_forreweighting); TH1F *hden = new TH1F("hden","hden",n_etabins_forreweighting,etabins_forreweighting); // TH1F *hnum = new TH1F("hnum","hnum",25,0.,2.5); // TH1F *hden = new TH1F("hden","hden",25,0.,2.5); hnum->Sumw2(); hden->Sumw2(); const char* etaname=Form("rooeta%d",numvar); for (int i=0; i<(*dset)->numEntries(); i++){ hden->Fill(fabs((*dset)->get(i)->getRealValue(etaname)),(*dset)->store()->weight(i)); } for (int i=0; i<dsetdestination->numEntries(); i++){ hnum->Fill(fabs(dsetdestination->get(i)->getRealValue(etaname)),dsetdestination->store()->weight(i)); } hnum->Scale(1.0/hnum->Integral()); hden->Scale(1.0/hden->Integral()); hnum->Divide(hden); TH1F *h = hnum; RooDataSet *newdset = new RooDataSet(**dset,Form("%s_etarew",(*dset)->GetName())); newdset->reset(); for (int i=0; i<(*dset)->numEntries(); i++){ RooArgSet args = *((*dset)->get(i)); float oldw = (*dset)->store()->weight(i); float eta = args.getRealValue(etaname); float neww = oldw*h->GetBinContent(h->FindBin(fabs(eta))); if(debug){ weight_eta->Fill(neww); weight_etao->Fill(oldw); weight_etan->Fill(h->FindBin(fabs(eta)),neww); weight_eta2o->Fill(h->FindBin(fabs(eta)),oldw); if(oldw!=0 && neww!=0)weight_etanr->Fill(h->FindBin(fabs(eta)),oldw/neww); else {weight_etanr->Fill(-10,1);} // weight_pt2->Fill(pt,neww/oldw); if(oldw!=0 && neww!=0)weight_eta2->Fill(fabs(eta),oldw/neww); else {weight_eta2->Fill(-10,1);} } newdset->add(args,neww); } newdset->SetName((*dset)->GetName()); newdset->SetTitle((*dset)->GetTitle()); delete hnum; delete hden; RooDataSet *old_dset = *dset; *dset=newdset; std::cout << "Eta 1d rew: norm from " << old_dset->sumEntries() << " to " << newdset->sumEntries() << std::endl; delete old_dset; };
void reweight_pt_1d(TH1F* weight_pt, TH1F* weight_pto,TH2F*weight_ptn,TH2F*weight_pt2o,TH2F* weight_ptnr, TH2F* weight_pt2,RooDataSet **dset, RooDataSet *dsetdestination, int numvar){ if (!(*dset)) return; ///numerator and denominator TH1F *hnum = new TH1F("hnum","hnum",n_ptbins_forreweighting,ptbins_forreweighting); TH1F *hden = new TH1F("hden","hden",n_ptbins_forreweighting,ptbins_forreweighting); hnum->Sumw2(); hden->Sumw2(); const char* ptname=Form("roopt%d",numvar); // RooAbsData->get*() Load a given row of data //getRealValue Get value of a RooAbsReal stored in set with given name. If none is found, value of defVal is returned. for (int i=0; i<(*dset)->numEntries(); i++){ hden->Fill(fabs((*dset)->get(i)->getRealValue(ptname)),(*dset)->store()->weight(i)); } for (int i=0; i<dsetdestination->numEntries(); i++){ hnum->Fill(fabs(dsetdestination->get(i)->getRealValue(ptname)),dsetdestination->store()->weight(i)); } //normalize to one hnum->Scale(1.0/hnum->Integral()); hden->Scale(1.0/hden->Integral()); hnum->Divide(hden); TH1F *h = hnum; RooDataSet *newdset = new RooDataSet(**dset,Form("%s_ptrew",(*dset)->GetName())); newdset->reset(); for (int i=0; i<(*dset)->numEntries(); i++){ RooArgSet args = *((*dset)->get(i)); float oldw = (*dset)->store()->weight(i); float pt = args.getRealValue(ptname); float neww = oldw*h->GetBinContent(h->FindBin(fabs(pt))); if(debug){ weight_pt->Fill(neww); weight_pto->Fill(oldw); weight_pt2o->Fill(h->FindBin(fabs(pt)),oldw); weight_ptn->Fill(h->FindBin(fabs(pt)),neww); if(oldw!=0 && neww!=0)weight_ptnr->Fill(h->FindBin(fabs(pt)),oldw/neww); else {weight_ptnr->Fill(-10,1);} if(oldw!=0 && neww!=0)weight_pt2->Fill(pt,oldw/neww); else {weight_pt2->Fill(-10,1);} } newdset->add(args,neww); } newdset->SetName((*dset)->GetName()); newdset->SetTitle((*dset)->GetTitle()); delete hnum; delete hden; RooDataSet *old_dset = *dset; *dset=newdset; std::cout << "Pt 1d rew: norm from " << old_dset->sumEntries() << " to " << newdset->sumEntries() << std::endl; delete old_dset; };
// The actual job void backgroundFits_qqzz_1Dw(int channel, int sqrts, int VBFtag) { if(sqrts==7)return; TString schannel; if (channel == 1) schannel = "4mu"; else if (channel == 2) schannel = "4e"; else if (channel == 3) schannel = "2e2mu"; else cout << "Not a valid channel: " << schannel << endl; TString ssqrts = (long) sqrts + TString("TeV"); cout << "schannel = " << schannel << " sqrts = " << sqrts << " VBFtag = " << VBFtag << endl; TString outfile; if(VBFtag<2) outfile = "CardFragments/qqzzBackgroundFit_" + ssqrts + "_" + schannel + "_" + Form("%d",int(VBFtag)) + ".txt"; if(VBFtag==2) outfile = "CardFragments/qqzzBackgroundFit_" + ssqrts + "_" + schannel + ".txt"; ofstream of(outfile,ios_base::out); of << "### background functions ###" << endl; gSystem->AddIncludePath("-I$ROOFITSYS/include"); gROOT->ProcessLine(".L ../CreateDatacards/include/tdrstyle.cc"); setTDRStyle(false); gStyle->SetPadLeftMargin(0.16); TString filepath; if (sqrts==7) { filepath = filePath7TeV; } else if (sqrts==8) { filepath = filePath8TeV; } TChain* tree = new TChain("SelectedTree"); tree->Add( filepath+ "/" + (schannel=="2e2mu"?"2mu2e":schannel) + "/HZZ4lTree_ZZTo*.root"); RooRealVar* MC_weight = new RooRealVar("MC_weight","MC_weight",0.,2.) ; RooRealVar* ZZMass = new RooRealVar("ZZMass","ZZMass",100.,1000.); RooRealVar* NJets30 = new RooRealVar("NJets30","NJets30",0.,100.); RooArgSet ntupleVarSet(*ZZMass,*NJets30,*MC_weight); RooDataSet *set = new RooDataSet("set","set",ntupleVarSet,WeightVar("MC_weight")); Float_t myMC,myMass; Short_t myNJets; int nentries = tree->GetEntries(); tree->SetBranchAddress("ZZMass",&myMass); tree->SetBranchAddress("MC_weight",&myMC); tree->SetBranchAddress("NJets30",&myNJets); for(int i =0;i<nentries;i++) { tree->GetEntry(i); if(VBFtag==1 && myNJets<2)continue; if(VBFtag==0 && myNJets>1)continue; ntupleVarSet.setRealValue("ZZMass",myMass); ntupleVarSet.setRealValue("MC_weight",myMC); ntupleVarSet.setRealValue("NJets30",(double)myNJets); set->add(ntupleVarSet, myMC); } double totalweight = 0.; double totalweight_z = 0.; for (int i=0 ; i<set->numEntries() ; i++) { //set->get(i) ; RooArgSet* row = set->get(i) ; //row->Print("v"); totalweight += set->weight(); if (row->getRealValue("ZZMass") < 200) totalweight_z += set->weight(); } cout << "nEntries: " << set->numEntries() << ", totalweight: " << totalweight << ", totalweight_z: " << totalweight_z << endl; gSystem->Load("libHiggsAnalysisCombinedLimit.so"); //// --------------------------------------- //Background RooRealVar CMS_qqzzbkg_a0("CMS_qqzzbkg_a0","CMS_qqzzbkg_a0",115.3,0.,200.); RooRealVar CMS_qqzzbkg_a1("CMS_qqzzbkg_a1","CMS_qqzzbkg_a1",21.96,0.,200.); RooRealVar CMS_qqzzbkg_a2("CMS_qqzzbkg_a2","CMS_qqzzbkg_a2",122.8,0.,200.); RooRealVar CMS_qqzzbkg_a3("CMS_qqzzbkg_a3","CMS_qqzzbkg_a3",0.03479,0.,1.); RooRealVar CMS_qqzzbkg_a4("CMS_qqzzbkg_a4","CMS_qqzzbkg_a4",185.5,0.,200.); RooRealVar CMS_qqzzbkg_a5("CMS_qqzzbkg_a5","CMS_qqzzbkg_a5",12.67,0.,200.); RooRealVar CMS_qqzzbkg_a6("CMS_qqzzbkg_a6","CMS_qqzzbkg_a6",34.81,0.,100.); RooRealVar CMS_qqzzbkg_a7("CMS_qqzzbkg_a7","CMS_qqzzbkg_a7",0.1393,0.,1.); RooRealVar CMS_qqzzbkg_a8("CMS_qqzzbkg_a8","CMS_qqzzbkg_a8",66.,0.,200.); RooRealVar CMS_qqzzbkg_a9("CMS_qqzzbkg_a9","CMS_qqzzbkg_a9",0.07191,0.,1.); RooRealVar CMS_qqzzbkg_a10("CMS_qqzzbkg_a10","CMS_qqzzbkg_a10",94.11,0.,200.); RooRealVar CMS_qqzzbkg_a11("CMS_qqzzbkg_a11","CMS_qqzzbkg_a11",-5.111,-100.,100.); RooRealVar CMS_qqzzbkg_a12("CMS_qqzzbkg_a12","CMS_qqzzbkg_a12",4834,0.,10000.); RooRealVar CMS_qqzzbkg_a13("CMS_qqzzbkg_a13","CMS_qqzzbkg_a13",0.2543,0.,1.); if (channel == 1){ ///* 4mu CMS_qqzzbkg_a0.setVal(103.854); CMS_qqzzbkg_a1.setVal(10.0718); CMS_qqzzbkg_a2.setVal(117.551); CMS_qqzzbkg_a3.setVal(0.0450287); CMS_qqzzbkg_a4.setVal(185.262); CMS_qqzzbkg_a5.setVal(7.99428); CMS_qqzzbkg_a6.setVal(39.7813); CMS_qqzzbkg_a7.setVal(0.0986891); CMS_qqzzbkg_a8.setVal(49.1325); CMS_qqzzbkg_a9.setVal(0.0389984); CMS_qqzzbkg_a10.setVal(98.6645); CMS_qqzzbkg_a11.setVal(-7.02043); CMS_qqzzbkg_a12.setVal(5694.66); CMS_qqzzbkg_a13.setVal(0.0774525); //*/ } else if (channel == 2){ ///* 4e CMS_qqzzbkg_a0.setVal(111.165); CMS_qqzzbkg_a1.setVal(19.8178); CMS_qqzzbkg_a2.setVal(120.89); CMS_qqzzbkg_a3.setVal(0.0546639); CMS_qqzzbkg_a4.setVal(184.878); CMS_qqzzbkg_a5.setVal(11.7041); CMS_qqzzbkg_a6.setVal(33.2659); CMS_qqzzbkg_a7.setVal(0.140858); CMS_qqzzbkg_a8.setVal(56.1226); CMS_qqzzbkg_a9.setVal(0.0957699); CMS_qqzzbkg_a10.setVal(98.3662); CMS_qqzzbkg_a11.setVal(-6.98701); CMS_qqzzbkg_a12.setVal(10.0536); CMS_qqzzbkg_a13.setVal(0.110576); //*/ } else if (channel == 3){ ///* 2e2mu CMS_qqzzbkg_a0.setVal(110.293); CMS_qqzzbkg_a1.setVal(11.8334); CMS_qqzzbkg_a2.setVal(116.91); CMS_qqzzbkg_a3.setVal(0.0433151); CMS_qqzzbkg_a4.setVal(185.817); CMS_qqzzbkg_a5.setVal(10.5945); CMS_qqzzbkg_a6.setVal(29.6208); CMS_qqzzbkg_a7.setVal(0.0826); CMS_qqzzbkg_a8.setVal(53.1346); CMS_qqzzbkg_a9.setVal(0.0882081); CMS_qqzzbkg_a10.setVal(85.3776); CMS_qqzzbkg_a11.setVal(-13.3836); CMS_qqzzbkg_a12.setVal(7587.95); CMS_qqzzbkg_a13.setVal(0.325621); //*/ } else { cout << "disaster" << endl; } RooqqZZPdf_v2* bkg_qqzz = new RooqqZZPdf_v2("bkg_qqzz","bkg_qqzz",*ZZMass, CMS_qqzzbkg_a0,CMS_qqzzbkg_a1,CMS_qqzzbkg_a2,CMS_qqzzbkg_a3,CMS_qqzzbkg_a4, CMS_qqzzbkg_a5,CMS_qqzzbkg_a6,CMS_qqzzbkg_a7,CMS_qqzzbkg_a8, CMS_qqzzbkg_a9,CMS_qqzzbkg_a10,CMS_qqzzbkg_a11,CMS_qqzzbkg_a12,CMS_qqzzbkg_a13); RooArgSet myASet(*ZZMass, CMS_qqzzbkg_a0,CMS_qqzzbkg_a1,CMS_qqzzbkg_a2,CMS_qqzzbkg_a3,CMS_qqzzbkg_a4, CMS_qqzzbkg_a5,CMS_qqzzbkg_a6,CMS_qqzzbkg_a7); myASet.add(CMS_qqzzbkg_a8); myASet.add(CMS_qqzzbkg_a9); myASet.add(CMS_qqzzbkg_a10); myASet.add(CMS_qqzzbkg_a11); myASet.add(CMS_qqzzbkg_a12); myASet.add(CMS_qqzzbkg_a13); RooFitResult *r1 = bkg_qqzz->fitTo( *set, Save(kTRUE), SumW2Error(kTRUE) );//, Save(kTRUE), SumW2Error(kTRUE)) ; cout << endl; cout << "------- Parameters for " << schannel << " sqrts=" << sqrts << endl; cout << " a0_bkgd = " << CMS_qqzzbkg_a0.getVal() << endl; cout << " a1_bkgd = " << CMS_qqzzbkg_a1.getVal() << endl; cout << " a2_bkgd = " << CMS_qqzzbkg_a2.getVal() << endl; cout << " a3_bkgd = " << CMS_qqzzbkg_a3.getVal() << endl; cout << " a4_bkgd = " << CMS_qqzzbkg_a4.getVal() << endl; cout << " a5_bkgd = " << CMS_qqzzbkg_a5.getVal() << endl; cout << " a6_bkgd = " << CMS_qqzzbkg_a6.getVal() << endl; cout << " a7_bkgd = " << CMS_qqzzbkg_a7.getVal() << endl; cout << " a8_bkgd = " << CMS_qqzzbkg_a8.getVal() << endl; cout << " a9_bkgd = " << CMS_qqzzbkg_a9.getVal() << endl; cout << " a10_bkgd = " << CMS_qqzzbkg_a10.getVal() << endl; cout << " a11_bkgd = " << CMS_qqzzbkg_a11.getVal() << endl; cout << " a12_bkgd = " << CMS_qqzzbkg_a12.getVal() << endl; cout << " a13_bkgd = " << CMS_qqzzbkg_a13.getVal() << endl; cout << "}" << endl; cout << "---------------------------" << endl; of << "qqZZshape a0_bkgd " << CMS_qqzzbkg_a0.getVal() << endl; of << "qqZZshape a1_bkgd " << CMS_qqzzbkg_a1.getVal() << endl; of << "qqZZshape a2_bkgd " << CMS_qqzzbkg_a2.getVal() << endl; of << "qqZZshape a3_bkgd " << CMS_qqzzbkg_a3.getVal() << endl; of << "qqZZshape a4_bkgd " << CMS_qqzzbkg_a4.getVal() << endl; of << "qqZZshape a5_bkgd " << CMS_qqzzbkg_a5.getVal() << endl; of << "qqZZshape a6_bkgd " << CMS_qqzzbkg_a6.getVal() << endl; of << "qqZZshape a7_bkgd " << CMS_qqzzbkg_a7.getVal() << endl; of << "qqZZshape a8_bkgd " << CMS_qqzzbkg_a8.getVal() << endl; of << "qqZZshape a9_bkgd " << CMS_qqzzbkg_a9.getVal() << endl; of << "qqZZshape a10_bkgd " << CMS_qqzzbkg_a10.getVal() << endl; of << "qqZZshape a11_bkgd " << CMS_qqzzbkg_a11.getVal() << endl; of << "qqZZshape a12_bkgd " << CMS_qqzzbkg_a12.getVal() << endl; of << "qqZZshape a13_bkgd " << CMS_qqzzbkg_a13.getVal() << endl; of << endl << endl; of.close(); cout << endl << "Output written to: " << outfile << endl; double qqzznorm; if (channel == 1) qqzznorm = 20.5836; else if (channel == 2) qqzznorm = 13.8871; else if (channel == 3) qqzznorm = 32.9883; else { cout << "disaster!" << endl; } ZZMass->setRange("fullrange",100.,1000.); ZZMass->setRange("largerange",100.,600.); ZZMass->setRange("zoomrange",100.,200.); double rescale = qqzznorm/totalweight; double rescale_z = qqzznorm/totalweight_z; cout << "rescale: " << rescale << ", rescale_z: " << rescale_z << endl; // Plot m4l and RooPlot* frameM4l = ZZMass->frame(Title("M4L"),Range(100,600),Bins(250)) ; set->plotOn(frameM4l, MarkerStyle(20), Rescale(rescale)) ; //set->plotOn(frameM4l) ; RooPlot* frameM4lz = ZZMass->frame(Title("M4L"),Range(100,200),Bins(100)) ; set->plotOn(frameM4lz, MarkerStyle(20), Rescale(rescale)) ; int iLineColor = 1; string lab = "blah"; if (channel == 1) { iLineColor = 2; lab = "4#mu"; } if (channel == 3) { iLineColor = 4; lab = "2e2#mu"; } if (channel == 2) { iLineColor = 6; lab = "4e"; } bkg_qqzz->plotOn(frameM4l,LineColor(iLineColor),NormRange("largerange")) ; bkg_qqzz->plotOn(frameM4lz,LineColor(iLineColor),NormRange("zoomrange")) ; //second shape to compare with (if previous comparison code unceommented) //bkg_qqzz_bkgd->plotOn(frameM4l,LineColor(1),NormRange("largerange")) ; //bkg_qqzz_bkgd->plotOn(frameM4lz,LineColor(1),NormRange("zoomrange")) ; double normalizationBackground_qqzz = bkg_qqzz->createIntegral( RooArgSet(*ZZMass), Range("fullrange") )->getVal(); cout << "Norm all = " << normalizationBackground_qqzz << endl; frameM4l->GetXaxis()->SetTitle("m_{4l} [GeV]"); frameM4l->GetYaxis()->SetTitle("a.u."); frameM4lz->GetXaxis()->SetTitle("m_{4l} [GeV]"); frameM4lz->GetYaxis()->SetTitle("a.u."); char lname[192]; sprintf(lname,"qq #rightarrow ZZ #rightarrow %s", lab.c_str() ); char lname2[192]; sprintf(lname2,"Shape Model, %s", lab.c_str() ); // dummy! TF1* dummyF = new TF1("dummyF","1",0.,1.); TH1F* dummyH = new TH1F("dummyH","",1, 0.,1.); dummyF->SetLineColor( iLineColor ); dummyF->SetLineWidth( 2 ); dummyH->SetLineColor( kBlue ); TLegend * box2 = new TLegend(0.4,0.70,0.80,0.90); box2->SetFillColor(0); box2->SetBorderSize(0); box2->AddEntry(dummyH,"Simulation (POWHEG+Pythia) ","pe"); box2->AddEntry(dummyH,lname,""); box2->AddEntry(dummyH,"",""); box2->AddEntry(dummyF,lname2,"l"); TPaveText *pt = new TPaveText(0.15,0.955,0.4,0.99,"NDC"); pt->SetFillColor(0); pt->SetBorderSize(0); pt->AddText("CMS Preliminary 2012"); TPaveText *pt2 = new TPaveText(0.84,0.955,0.99,0.99,"NDC"); pt2->SetFillColor(0); pt2->SetBorderSize(0); TString entag;entag.Form("#sqrt{s} = %d TeV",sqrts); pt2->AddText(entag.Data()); TCanvas *c = new TCanvas("c","c",800,600); c->cd(); frameM4l->Draw(); frameM4l->GetYaxis()->SetRangeUser(0,0.4); if(channel == 3)frameM4l->GetYaxis()->SetRangeUser(0,0.7); box2->Draw(); pt->Draw(); pt2->Draw(); TString outputPath = "bkgFigs"; outputPath = outputPath+ (long) sqrts + "TeV/"; TString outputName; if(VBFtag<2) outputName = outputPath + "bkgqqzz_" + schannel + "_" + Form("%d",int(VBFtag)); if(VBFtag==2) outputName = outputPath + "bkgqqzz_" + schannel; c->SaveAs(outputName + ".eps"); c->SaveAs(outputName + ".png"); TCanvas *c2 = new TCanvas("c2","c2",1000,500); c2->Divide(2,1); c2->cd(1); frameM4l->Draw(); box2->Draw("same"); c2->cd(2); frameM4lz->Draw(); box2->Draw("same"); if (VBFtag<2) outputName = outputPath + "bkgqqzz_" + schannel + "_z" + "_" + Form("%d",int(VBFtag)); if (VBFtag==2) outputName = outputPath + "bkgqqzz_" + schannel + "_z"; c2->SaveAs(outputName + ".eps"); c2->SaveAs(outputName + ".png"); /* TO make the ratio btw 2 shapes, if needed for compairson TCanvas *c3 = new TCanvas("c3","c3",1000,500); if(sqrts==7) sprintf(outputName, "bkgFigs7TeV/bkgqqzz_%s_ratio.eps",schannel.c_str()); else if(sqrts==8) sprintf(outputName, "bkgFigs8TeV/bkgqqzz_%s_ratio.eps",schannel.c_str()); const int nPoints = 501.; double masses[nPoints] ; int j=0; for (int i=100; i<601; i++){ masses[j] = i; j++; } cout<<j<<endl; double effDiff[nPoints]; for (int i = 0; i < nPoints; i++){ ZZMass->setVal(masses[i]); double eval = (bkg_qqzz_bkgd->getVal(otherASet)-bkg_qqzz->getVal(myASet))/(bkg_qqzz->getVal(myASet)); //cout<<bkg_qqzz_bkgd->getVal(otherASet)<<" "<<bkg_qqzz->getVal(myASet)<<" "<<eval<<endl; effDiff[i]=eval; } TGraph* grEffDiff = new TGraph( nPoints, masses, effDiff ); grEffDiff->SetMarkerStyle(20); grEffDiff->Draw("AL"); //c3->SaveAs(outputName); */ if (VBFtag<2) outputName = outputPath + "bkgqqzz_" + schannel + "_z" + "_" + Form("%d",int(VBFtag)) + ".root"; if (VBFtag==2) outputName = outputPath + "bkgqqzz_" + schannel + "_z" + ".root"; TFile* outF = new TFile(outputName,"RECREATE"); outF->cd(); c2->Write(); frameM4l->Write(); frameM4lz->Write(); outF->Close(); delete c; delete c2; }
void StandardFeldmanCousinsDemo(const char* infile = "", const char* workspaceName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData"){ // ------------------------------------------------------- // First part is just to access a user-defined file // or create the standard example file if it doesn't exist const char* filename = ""; if (!strcmp(infile,"")) { filename = "results/example_combined_GaussExample_model.root"; bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code // if file does not exists generate with histfactory if (!fileExist) { #ifdef _WIN32 cout << "HistFactory file cannot be generated on Windows - exit" << endl; return; #endif // Normally this would be run on the command line cout <<"will run standard hist2workspace example"<<endl; gROOT->ProcessLine(".! prepareHistFactory ."); gROOT->ProcessLine(".! hist2workspace config/example.xml"); cout <<"\n\n---------------------"<<endl; cout <<"Done creating example input"<<endl; cout <<"---------------------\n\n"<<endl; } } else filename = infile; // Try to open the file TFile *file = TFile::Open(filename); // if input file was specified byt not found, quit if(!file ){ cout <<"StandardRooStatsDemoMacro: Input file " << filename << " is not found" << endl; return; } // ------------------------------------------------------- // Tutorial starts here // ------------------------------------------------------- // get the workspace out of the file RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName); if(!w){ cout <<"workspace not found" << endl; return; } // get the modelConfig out of the file ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName); // get the modelConfig out of the file RooAbsData* data = w->data(dataName); // make sure ingredients are found if(!data || !mc){ w->Print(); cout << "data or ModelConfig was not found" <<endl; return; } // ------------------------------------------------------- // create and use the FeldmanCousins tool // to find and plot the 95% confidence interval // on the parameter of interest as specified // in the model config FeldmanCousins fc(*data,*mc); fc.SetConfidenceLevel(0.95); // 95% interval //fc.AdditionalNToysFactor(0.1); // to speed up the result fc.UseAdaptiveSampling(true); // speed it up a bit fc.SetNBins(10); // set how many points per parameter of interest to scan fc.CreateConfBelt(true); // save the information in the belt for plotting // Since this tool needs to throw toy MC the PDF needs to be // extended or the tool needs to know how many entries in a dataset // per pseudo experiment. // In the 'number counting form' where the entries in the dataset // are counts, and not values of discriminating variables, the // datasets typically only have one entry and the PDF is not // extended. if(!mc->GetPdf()->canBeExtended()){ if(data->numEntries()==1) fc.FluctuateNumDataEntries(false); else cout <<"Not sure what to do about this model" <<endl; } // We can use PROOF to speed things along in parallel // ProofConfig pc(*w, 1, "workers=4", kFALSE); // ToyMCSampler* toymcsampler = (ToyMCSampler*) fc.GetTestStatSampler(); // toymcsampler->SetProofConfig(&pc); // enable proof // Now get the interval PointSetInterval* interval = fc.GetInterval(); ConfidenceBelt* belt = fc.GetConfidenceBelt(); // print out the iterval on the first Parameter of Interest RooRealVar* firstPOI = (RooRealVar*) mc->GetParametersOfInterest()->first(); cout << "\n95% interval on " <<firstPOI->GetName()<<" is : ["<< interval->LowerLimit(*firstPOI) << ", "<< interval->UpperLimit(*firstPOI) <<"] "<<endl; // --------------------------------------------- // No nice plots yet, so plot the belt by hand // Ask the calculator which points were scanned RooDataSet* parameterScan = (RooDataSet*) fc.GetPointsToScan(); RooArgSet* tmpPoint; // make a histogram of parameter vs. threshold TH1F* histOfThresholds = new TH1F("histOfThresholds","", parameterScan->numEntries(), firstPOI->getMin(), firstPOI->getMax()); // loop through the points that were tested and ask confidence belt // what the upper/lower thresholds were. // For FeldmanCousins, the lower cut off is always 0 for(Int_t i=0; i<parameterScan->numEntries(); ++i){ tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp"); double arMax = belt->GetAcceptanceRegionMax(*tmpPoint); double arMin = belt->GetAcceptanceRegionMax(*tmpPoint); double poiVal = tmpPoint->getRealValue(firstPOI->GetName()) ; histOfThresholds->Fill(poiVal,arMax); } histOfThresholds->SetMinimum(0); histOfThresholds->Draw(); }
void OneSidedFrequentistUpperLimitWithBands(const char* infile = "", const char* workspaceName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData") { double confidenceLevel=0.95; int nPointsToScan = 20; int nToyMC = 200; // ------------------------------------------------------- // First part is just to access a user-defined file // or create the standard example file if it doesn't exist const char* filename = ""; if (!strcmp(infile,"")) { filename = "results/example_combined_GaussExample_model.root"; bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code // if file does not exists generate with histfactory if (!fileExist) { #ifdef _WIN32 cout << "HistFactory file cannot be generated on Windows - exit" << endl; return; #endif // Normally this would be run on the command line cout <<"will run standard hist2workspace example"<<endl; gROOT->ProcessLine(".! prepareHistFactory ."); gROOT->ProcessLine(".! hist2workspace config/example.xml"); cout <<"\n\n---------------------"<<endl; cout <<"Done creating example input"<<endl; cout <<"---------------------\n\n"<<endl; } } else filename = infile; // Try to open the file TFile *file = TFile::Open(filename); // if input file was specified byt not found, quit if(!file ){ cout <<"StandardRooStatsDemoMacro: Input file " << filename << " is not found" << endl; return; } // ------------------------------------------------------- // Now get the data and workspace // get the workspace out of the file RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName); if(!w){ cout <<"workspace not found" << endl; return; } // get the modelConfig out of the file ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName); // get the modelConfig out of the file RooAbsData* data = w->data(dataName); // make sure ingredients are found if(!data || !mc){ w->Print(); cout << "data or ModelConfig was not found" <<endl; return; } // ------------------------------------------------------- // Now get the POI for convenience // you may want to adjust the range of your POI RooRealVar* firstPOI = (RooRealVar*) mc->GetParametersOfInterest()->first(); /* firstPOI->setMin(0);*/ /* firstPOI->setMax(10);*/ // -------------------------------------------- // Create and use the FeldmanCousins tool // to find and plot the 95% confidence interval // on the parameter of interest as specified // in the model config // REMEMBER, we will change the test statistic // so this is NOT a Feldman-Cousins interval FeldmanCousins fc(*data,*mc); fc.SetConfidenceLevel(confidenceLevel); /* fc.AdditionalNToysFactor(0.25); // degrade/improve sampling that defines confidence belt*/ /* fc.UseAdaptiveSampling(true); // speed it up a bit, don't use for expected limits*/ fc.SetNBins(nPointsToScan); // set how many points per parameter of interest to scan fc.CreateConfBelt(true); // save the information in the belt for plotting // ------------------------------------------------------- // Feldman-Cousins is a unified limit by definition // but the tool takes care of a few things for us like which values // of the nuisance parameters should be used to generate toys. // so let's just change the test statistic and realize this is // no longer "Feldman-Cousins" but is a fully frequentist Neyman-Construction. /* ProfileLikelihoodTestStatModified onesided(*mc->GetPdf());*/ /* fc.GetTestStatSampler()->SetTestStatistic(&onesided);*/ /* ((ToyMCSampler*) fc.GetTestStatSampler())->SetGenerateBinned(true); */ ToyMCSampler* toymcsampler = (ToyMCSampler*) fc.GetTestStatSampler(); ProfileLikelihoodTestStat* testStat = dynamic_cast<ProfileLikelihoodTestStat*>(toymcsampler->GetTestStatistic()); testStat->SetOneSided(true); // Since this tool needs to throw toy MC the PDF needs to be // extended or the tool needs to know how many entries in a dataset // per pseudo experiment. // In the 'number counting form' where the entries in the dataset // are counts, and not values of discriminating variables, the // datasets typically only have one entry and the PDF is not // extended. if(!mc->GetPdf()->canBeExtended()){ if(data->numEntries()==1) fc.FluctuateNumDataEntries(false); else cout <<"Not sure what to do about this model" <<endl; } // We can use PROOF to speed things along in parallel // However, the test statistic has to be installed on the workers // so either turn off PROOF or include the modified test statistic // in your `$ROOTSYS/roofit/roostats/inc` directory, // add the additional line to the LinkDef.h file, // and recompile root. if (useProof) { ProofConfig pc(*w, nworkers, "", false); toymcsampler->SetProofConfig(&pc); // enable proof } if(mc->GetGlobalObservables()){ cout << "will use global observables for unconditional ensemble"<<endl; mc->GetGlobalObservables()->Print(); toymcsampler->SetGlobalObservables(*mc->GetGlobalObservables()); } // Now get the interval PointSetInterval* interval = fc.GetInterval(); ConfidenceBelt* belt = fc.GetConfidenceBelt(); // print out the interval on the first Parameter of Interest cout << "\n95% interval on " <<firstPOI->GetName()<<" is : ["<< interval->LowerLimit(*firstPOI) << ", "<< interval->UpperLimit(*firstPOI) <<"] "<<endl; // get observed UL and value of test statistic evaluated there RooArgSet tmpPOI(*firstPOI); double observedUL = interval->UpperLimit(*firstPOI); firstPOI->setVal(observedUL); double obsTSatObsUL = fc.GetTestStatSampler()->EvaluateTestStatistic(*data,tmpPOI); // Ask the calculator which points were scanned RooDataSet* parameterScan = (RooDataSet*) fc.GetPointsToScan(); RooArgSet* tmpPoint; // make a histogram of parameter vs. threshold TH1F* histOfThresholds = new TH1F("histOfThresholds","", parameterScan->numEntries(), firstPOI->getMin(), firstPOI->getMax()); histOfThresholds->GetXaxis()->SetTitle(firstPOI->GetName()); histOfThresholds->GetYaxis()->SetTitle("Threshold"); // loop through the points that were tested and ask confidence belt // what the upper/lower thresholds were. // For FeldmanCousins, the lower cut off is always 0 for(Int_t i=0; i<parameterScan->numEntries(); ++i){ tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp"); //cout <<"get threshold"<<endl; double arMax = belt->GetAcceptanceRegionMax(*tmpPoint); double poiVal = tmpPoint->getRealValue(firstPOI->GetName()) ; histOfThresholds->Fill(poiVal,arMax); } TCanvas* c1 = new TCanvas(); c1->Divide(2); c1->cd(1); histOfThresholds->SetMinimum(0); histOfThresholds->Draw(); c1->cd(2); // ------------------------------------------------------- // Now we generate the expected bands and power-constraint // First: find parameter point for mu=0, with conditional MLEs for nuisance parameters RooAbsReal* nll = mc->GetPdf()->createNLL(*data); RooAbsReal* profile = nll->createProfile(*mc->GetParametersOfInterest()); firstPOI->setVal(0.); profile->getVal(); // this will do fit and set nuisance parameters to profiled values RooArgSet* poiAndNuisance = new RooArgSet(); if(mc->GetNuisanceParameters()) poiAndNuisance->add(*mc->GetNuisanceParameters()); poiAndNuisance->add(*mc->GetParametersOfInterest()); w->saveSnapshot("paramsToGenerateData",*poiAndNuisance); RooArgSet* paramsToGenerateData = (RooArgSet*) poiAndNuisance->snapshot(); cout << "\nWill use these parameter points to generate pseudo data for bkg only" << endl; paramsToGenerateData->Print("v"); RooArgSet unconditionalObs; unconditionalObs.add(*mc->GetObservables()); unconditionalObs.add(*mc->GetGlobalObservables()); // comment this out for the original conditional ensemble double CLb=0; double CLbinclusive=0; // Now we generate background only and find distribution of upper limits TH1F* histOfUL = new TH1F("histOfUL","",100,0,firstPOI->getMax()); histOfUL->GetXaxis()->SetTitle("Upper Limit (background only)"); histOfUL->GetYaxis()->SetTitle("Entries"); for(int imc=0; imc<nToyMC; ++imc){ // set parameters back to values for generating pseudo data // cout << "\n get current nuis, set vals, print again" << endl; w->loadSnapshot("paramsToGenerateData"); // poiAndNuisance->Print("v"); RooDataSet* toyData = 0; // now generate a toy dataset if(!mc->GetPdf()->canBeExtended()){ if(data->numEntries()==1) toyData = mc->GetPdf()->generate(*mc->GetObservables(),1); else cout <<"Not sure what to do about this model" <<endl; } else{ // cout << "generating extended dataset"<<endl; toyData = mc->GetPdf()->generate(*mc->GetObservables(),Extended()); } // generate global observables // need to be careful for simpdf // RooDataSet* globalData = mc->GetPdf()->generate(*mc->GetGlobalObservables(),1); RooSimultaneous* simPdf = dynamic_cast<RooSimultaneous*>(mc->GetPdf()); if(!simPdf){ RooDataSet *one = mc->GetPdf()->generate(*mc->GetGlobalObservables(), 1); const RooArgSet *values = one->get(); RooArgSet *allVars = mc->GetPdf()->getVariables(); *allVars = *values; delete allVars; delete values; delete one; } else { //try fix for sim pdf TIterator* iter = simPdf->indexCat().typeIterator() ; RooCatType* tt = NULL; while((tt=(RooCatType*) iter->Next())) { // Get pdf associated with state from simpdf RooAbsPdf* pdftmp = simPdf->getPdf(tt->GetName()) ; // Generate only global variables defined by the pdf associated with this state RooArgSet* globtmp = pdftmp->getObservables(*mc->GetGlobalObservables()) ; RooDataSet* tmp = pdftmp->generate(*globtmp,1) ; // Transfer values to output placeholder *globtmp = *tmp->get(0) ; // Cleanup delete globtmp ; delete tmp ; } } // globalData->Print("v"); // unconditionalObs = *globalData->get(); // mc->GetGlobalObservables()->Print("v"); // delete globalData; // cout << "toy data = " << endl; // toyData->get()->Print("v"); // get test stat at observed UL in observed data firstPOI->setVal(observedUL); double toyTSatObsUL = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI); // toyData->get()->Print("v"); // cout <<"obsTSatObsUL " <<obsTSatObsUL << "toyTS " << toyTSatObsUL << endl; if(obsTSatObsUL < toyTSatObsUL) // not sure about <= part yet CLb+= (1.)/nToyMC; if(obsTSatObsUL <= toyTSatObsUL) // not sure about <= part yet CLbinclusive+= (1.)/nToyMC; // loop over points in belt to find upper limit for this toy data double thisUL = 0; for(Int_t i=0; i<parameterScan->numEntries(); ++i){ tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp"); double arMax = belt->GetAcceptanceRegionMax(*tmpPoint); firstPOI->setVal( tmpPoint->getRealValue(firstPOI->GetName()) ); // double thisTS = profile->getVal(); double thisTS = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI); // cout << "poi = " << firstPOI->getVal() // << " max is " << arMax << " this profile = " << thisTS << endl; // cout << "thisTS = " << thisTS<<endl; if(thisTS<=arMax){ thisUL = firstPOI->getVal(); } else{ break; } } /* // loop over points in belt to find upper limit for this toy data double thisUL = 0; for(Int_t i=0; i<histOfThresholds->GetNbinsX(); ++i){ tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp"); cout <<"---------------- "<<i<<endl; tmpPoint->Print("v"); cout << "from hist " << histOfThresholds->GetBinCenter(i+1) <<endl; double arMax = histOfThresholds->GetBinContent(i+1); // cout << " threhold from Hist = aMax " << arMax<<endl; // double arMax2 = belt->GetAcceptanceRegionMax(*tmpPoint); // cout << "from scan arMax2 = "<< arMax2 << endl; // not the same due to TH1F not TH1D // cout << "scan - hist" << arMax2-arMax << endl; firstPOI->setVal( histOfThresholds->GetBinCenter(i+1)); // double thisTS = profile->getVal(); double thisTS = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI); // cout << "poi = " << firstPOI->getVal() // << " max is " << arMax << " this profile = " << thisTS << endl; // cout << "thisTS = " << thisTS<<endl; // NOTE: need to add a small epsilon term for single precision vs. double precision if(thisTS<=arMax + 1e-7){ thisUL = firstPOI->getVal(); } else{ break; } } */ histOfUL->Fill(thisUL); // for few events, data is often the same, and UL is often the same // cout << "thisUL = " << thisUL<<endl; delete toyData; } histOfUL->Draw(); c1->SaveAs("one-sided_upper_limit_output.pdf"); // if you want to see a plot of the sampling distribution for a particular scan point: /* SamplingDistPlot sampPlot; int indexInScan = 0; tmpPoint = (RooArgSet*) parameterScan->get(indexInScan)->clone("temp"); firstPOI->setVal( tmpPoint->getRealValue(firstPOI->GetName()) ); toymcsampler->SetParametersForTestStat(tmpPOI); SamplingDistribution* samp = toymcsampler->GetSamplingDistribution(*tmpPoint); sampPlot.AddSamplingDistribution(samp); sampPlot.Draw(); */ // Now find bands and power constraint Double_t* bins = histOfUL->GetIntegral(); TH1F* cumulative = (TH1F*) histOfUL->Clone("cumulative"); cumulative->SetContent(bins); double band2sigDown, band1sigDown, bandMedian, band1sigUp,band2sigUp; for(int i=1; i<=cumulative->GetNbinsX(); ++i){ if(bins[i]<RooStats::SignificanceToPValue(2)) band2sigDown=cumulative->GetBinCenter(i); if(bins[i]<RooStats::SignificanceToPValue(1)) band1sigDown=cumulative->GetBinCenter(i); if(bins[i]<0.5) bandMedian=cumulative->GetBinCenter(i); if(bins[i]<RooStats::SignificanceToPValue(-1)) band1sigUp=cumulative->GetBinCenter(i); if(bins[i]<RooStats::SignificanceToPValue(-2)) band2sigUp=cumulative->GetBinCenter(i); } cout << "-2 sigma band " << band2sigDown << endl; cout << "-1 sigma band " << band1sigDown << " [Power Constraint)]" << endl; cout << "median of band " << bandMedian << endl; cout << "+1 sigma band " << band1sigUp << endl; cout << "+2 sigma band " << band2sigUp << endl; // print out the interval on the first Parameter of Interest cout << "\nobserved 95% upper-limit "<< interval->UpperLimit(*firstPOI) <<endl; cout << "CLb strict [P(toy>obs|0)] for observed 95% upper-limit "<< CLb <<endl; cout << "CLb inclusive [P(toy>=obs|0)] for observed 95% upper-limit "<< CLbinclusive <<endl; delete profile; delete nll; }
void OneSidedFrequentistUpperLimitWithBands_intermediate(const char* infile = "", const char* workspaceName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData"){ double confidenceLevel=0.95; // degrade/improve number of pseudo-experiments used to define the confidence belt. // value of 1 corresponds to default number of toys in the tail, which is 50/(1-confidenceLevel) double additionalToysFac = 1.; int nPointsToScan = 30; // number of steps in the parameter of interest int nToyMC = 100; // number of toys used to define the expected limit and band TStopwatch t; t.Start(); ///////////////////////////////////////////////////////////// // First part is just to access a user-defined file // or create the standard example file if it doesn't exist //////////////////////////////////////////////////////////// const char* filename = ""; if (!strcmp(infile,"")) filename = "results/example_combined_GaussExample_model.root"; else filename = infile; // Check if example input file exists TFile *file = TFile::Open(filename); // if input file was specified byt not found, quit if(!file && strcmp(infile,"")){ cout <<"file not found" << endl; return; } // if default file not found, try to create it if(!file ){ // Normally this would be run on the command line cout <<"will run standard hist2workspace example"<<endl; gROOT->ProcessLine(".! prepareHistFactory ."); gROOT->ProcessLine(".! hist2workspace config/example.xml"); cout <<"\n\n---------------------"<<endl; cout <<"Done creating example input"<<endl; cout <<"---------------------\n\n"<<endl; } // now try to access the file again file = TFile::Open(filename); if(!file){ // if it is still not there, then we can't continue cout << "Not able to run hist2workspace to create example input" <<endl; return; } ///////////////////////////////////////////////////////////// // Now get the data and workspace //////////////////////////////////////////////////////////// // get the workspace out of the file RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName); if(!w){ cout <<"workspace not found" << endl; return; } // get the modelConfig out of the file ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName); // get the modelConfig out of the file RooAbsData* data = w->data(dataName); // make sure ingredients are found if(!data || !mc){ w->Print(); cout << "data or ModelConfig was not found" <<endl; return; } cout << "Found data and ModelConfig:" <<endl; mc->Print(); ///////////////////////////////////////////////////////////// // Now get the POI for convenience // you may want to adjust the range of your POI //////////////////////////////////////////////////////////// RooRealVar* firstPOI = (RooRealVar*) mc->GetParametersOfInterest()->first(); // firstPOI->setMin(0); // firstPOI->setMax(10); ///////////////////////////////////////////// // create and use the FeldmanCousins tool // to find and plot the 95% confidence interval // on the parameter of interest as specified // in the model config // REMEMBER, we will change the test statistic // so this is NOT a Feldman-Cousins interval FeldmanCousins fc(*data,*mc); fc.SetConfidenceLevel(confidenceLevel); fc.AdditionalNToysFactor(additionalToysFac); // improve sampling that defines confidence belt // fc.UseAdaptiveSampling(true); // speed it up a bit, but don't use for expectd limits fc.SetNBins(nPointsToScan); // set how many points per parameter of interest to scan fc.CreateConfBelt(true); // save the information in the belt for plotting ///////////////////////////////////////////// // Feldman-Cousins is a unified limit by definition // but the tool takes care of a few things for us like which values // of the nuisance parameters should be used to generate toys. // so let's just change the test statistic and realize this is // no longer "Feldman-Cousins" but is a fully frequentist Neyman-Construction. // ProfileLikelihoodTestStatModified onesided(*mc->GetPdf()); // fc.GetTestStatSampler()->SetTestStatistic(&onesided); // ((ToyMCSampler*) fc.GetTestStatSampler())->SetGenerateBinned(true); ToyMCSampler* toymcsampler = (ToyMCSampler*) fc.GetTestStatSampler(); ProfileLikelihoodTestStat* testStat = dynamic_cast<ProfileLikelihoodTestStat*>(toymcsampler->GetTestStatistic()); testStat->SetOneSided(true); // test speedups: testStat->SetReuseNLL(true); // toymcsampler->setUseMultiGen(true); // not fully validated // Since this tool needs to throw toy MC the PDF needs to be // extended or the tool needs to know how many entries in a dataset // per pseudo experiment. // In the 'number counting form' where the entries in the dataset // are counts, and not values of discriminating variables, the // datasets typically only have one entry and the PDF is not // extended. if(!mc->GetPdf()->canBeExtended()){ if(data->numEntries()==1) fc.FluctuateNumDataEntries(false); else cout <<"Not sure what to do about this model" <<endl; } // We can use PROOF to speed things along in parallel ProofConfig pc(*w, 4, "",false); if(mc->GetGlobalObservables()){ cout << "will use global observables for unconditional ensemble"<<endl; mc->GetGlobalObservables()->Print(); toymcsampler->SetGlobalObservables(*mc->GetGlobalObservables()); } toymcsampler->SetProofConfig(&pc); // enable proof // Now get the interval PointSetInterval* interval = fc.GetInterval(); ConfidenceBelt* belt = fc.GetConfidenceBelt(); // print out the iterval on the first Parameter of Interest cout << "\n95% interval on " <<firstPOI->GetName()<<" is : ["<< interval->LowerLimit(*firstPOI) << ", "<< interval->UpperLimit(*firstPOI) <<"] "<<endl; // get observed UL and value of test statistic evaluated there RooArgSet tmpPOI(*firstPOI); double observedUL = interval->UpperLimit(*firstPOI); firstPOI->setVal(observedUL); double obsTSatObsUL = fc.GetTestStatSampler()->EvaluateTestStatistic(*data,tmpPOI); // Ask the calculator which points were scanned RooDataSet* parameterScan = (RooDataSet*) fc.GetPointsToScan(); RooArgSet* tmpPoint; // make a histogram of parameter vs. threshold TH1F* histOfThresholds = new TH1F("histOfThresholds","", parameterScan->numEntries(), firstPOI->getMin(), firstPOI->getMax()); histOfThresholds->GetXaxis()->SetTitle(firstPOI->GetName()); histOfThresholds->GetYaxis()->SetTitle("Threshold"); // loop through the points that were tested and ask confidence belt // what the upper/lower thresholds were. // For FeldmanCousins, the lower cut off is always 0 for(Int_t i=0; i<parameterScan->numEntries(); ++i){ tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp"); double arMax = belt->GetAcceptanceRegionMax(*tmpPoint); double poiVal = tmpPoint->getRealValue(firstPOI->GetName()) ; histOfThresholds->Fill(poiVal,arMax); } TCanvas* c1 = new TCanvas(); c1->Divide(2); c1->cd(1); histOfThresholds->SetMinimum(0); histOfThresholds->Draw(); c1->cd(2); ///////////////////////////////////////////////////////////// // Now we generate the expected bands and power-constriant //////////////////////////////////////////////////////////// // First: find parameter point for mu=0, with conditional MLEs for nuisance parameters RooAbsReal* nll = mc->GetPdf()->createNLL(*data); RooAbsReal* profile = nll->createProfile(*mc->GetParametersOfInterest()); firstPOI->setVal(0.); profile->getVal(); // this will do fit and set nuisance parameters to profiled values RooArgSet* poiAndNuisance = new RooArgSet(); if(mc->GetNuisanceParameters()) poiAndNuisance->add(*mc->GetNuisanceParameters()); poiAndNuisance->add(*mc->GetParametersOfInterest()); w->saveSnapshot("paramsToGenerateData",*poiAndNuisance); RooArgSet* paramsToGenerateData = (RooArgSet*) poiAndNuisance->snapshot(); cout << "\nWill use these parameter points to generate pseudo data for bkg only" << endl; paramsToGenerateData->Print("v"); double CLb=0; double CLbinclusive=0; // Now we generate background only and find distribution of upper limits TH1F* histOfUL = new TH1F("histOfUL","",100,0,firstPOI->getMax()); histOfUL->GetXaxis()->SetTitle("Upper Limit (background only)"); histOfUL->GetYaxis()->SetTitle("Entries"); for(int imc=0; imc<nToyMC; ++imc){ // set parameters back to values for generating pseudo data w->loadSnapshot("paramsToGenerateData"); // in 5.30 there is a nicer way to generate toy data & randomize global obs RooAbsData* toyData = toymcsampler->GenerateToyData(*paramsToGenerateData); // get test stat at observed UL in observed data firstPOI->setVal(observedUL); double toyTSatObsUL = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI); // toyData->get()->Print("v"); // cout <<"obsTSatObsUL " <<obsTSatObsUL << "toyTS " << toyTSatObsUL << endl; if(obsTSatObsUL < toyTSatObsUL) // (should be checked) CLb+= (1.)/nToyMC; if(obsTSatObsUL <= toyTSatObsUL) // (should be checked) CLbinclusive+= (1.)/nToyMC; // loop over points in belt to find upper limit for this toy data double thisUL = 0; for(Int_t i=0; i<parameterScan->numEntries(); ++i){ tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp"); double arMax = belt->GetAcceptanceRegionMax(*tmpPoint); firstPOI->setVal( tmpPoint->getRealValue(firstPOI->GetName()) ); double thisTS = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI); if(thisTS<=arMax){ thisUL = firstPOI->getVal(); } else{ break; } } histOfUL->Fill(thisUL); delete toyData; } histOfUL->Draw(); c1->SaveAs("one-sided_upper_limit_output.pdf"); // if you want to see a plot of the sampling distribution for a particular scan point: // Now find bands and power constraint Double_t* bins = histOfUL->GetIntegral(); TH1F* cumulative = (TH1F*) histOfUL->Clone("cumulative"); cumulative->SetContent(bins); double band2sigDown=0, band1sigDown=0, bandMedian=0, band1sigUp=0,band2sigUp=0; for(int i=1; i<=cumulative->GetNbinsX(); ++i){ if(bins[i]<RooStats::SignificanceToPValue(2)) band2sigDown=cumulative->GetBinCenter(i); if(bins[i]<RooStats::SignificanceToPValue(1)) band1sigDown=cumulative->GetBinCenter(i); if(bins[i]<0.5) bandMedian=cumulative->GetBinCenter(i); if(bins[i]<RooStats::SignificanceToPValue(-1)) band1sigUp=cumulative->GetBinCenter(i); if(bins[i]<RooStats::SignificanceToPValue(-2)) band2sigUp=cumulative->GetBinCenter(i); } t.Stop(); t.Print(); cout << "-2 sigma band " << band2sigDown << endl; cout << "-1 sigma band " << band1sigDown << endl; cout << "median of band " << bandMedian << " [Power Constriant)]" << endl; cout << "+1 sigma band " << band1sigUp << endl; cout << "+2 sigma band " << band2sigUp << endl; // print out the iterval on the first Parameter of Interest cout << "\nobserved 95% upper-limit "<< interval->UpperLimit(*firstPOI) <<endl; cout << "CLb strict [P(toy>obs|0)] for observed 95% upper-limit "<< CLb <<endl; cout << "CLb inclusive [P(toy>=obs|0)] for observed 95% upper-limit "<< CLbinclusive <<endl; delete profile; delete nll; }