void ComputeUpperLimit(RooAbsData *data, RooStats::ModelConfig *model, float &UpperLimit, float &signif, RooRealVar *mu, RooArgSet *nullParams,RooWorkspace *ws,REGION region,const char* tag) { bool StoreEverything=false; // activate if you want to store frames and all RooStats::ProfileLikelihoodCalculator *plc = new RooStats::ProfileLikelihoodCalculator(*data, *model); plc->SetParameters(*mu); plc->SetNullParameters(*nullParams); plc->SetTestSize(0.05); RooStats::LikelihoodInterval *interval = plc->GetInterval(); bool ComputationSuccessful=false; UpperLimit = interval->UpperLimit(*mu,ComputationSuccessful); signif = 0.0; // plc->GetHypoTest()->Significance(); // deactivated significance (to make algorithm faster) if(!ComputationSuccessful) { cout << "There seems to have been a problem. Returned upper limit is " << UpperLimit << " but it will be set to -999" << endl; UpperLimit=-999; signif=-999; } if(StoreEverything) { // Store it all RooRealVar* minv = (RooRealVar*)model->GetObservables()->first(); minv->setBins(static_cast<int>((minv->getMax()-minv->getMin())/5.)); RooPlot* frameEE = minv->frame(RooFit::Title("ee sample")); frameEE->GetXaxis()->CenterTitle(1); frameEE->GetYaxis()->CenterTitle(1); RooPlot* frameMM = minv->frame(RooFit::Title("mm sample")); frameMM->GetXaxis()->CenterTitle(1); frameMM->GetYaxis()->CenterTitle(1); RooPlot* frameOF = minv->frame(RooFit::Title("OF sample")); frameOF->GetXaxis()->CenterTitle(1); frameOF->GetYaxis()->CenterTitle(1); data->plotOn(frameMM,RooFit::Cut("catCentral==catCentral::MMCentral")); model->GetPdf()->plotOn(frameMM,RooFit::Slice(*ws->cat("catCentral"), "MMCentral"),RooFit::ProjWData(*data)); data->plotOn(frameEE,RooFit::Cut("catCentral==catCentral::EECentral")); model->GetPdf()->plotOn(frameEE,RooFit::Slice(*ws->cat("catCentral"), "EECentral"),RooFit::ProjWData(*data)); data->plotOn(frameOF,RooFit::Cut("catCentral==catCentral::OFOSCentral")); model->GetPdf()->plotOn(frameOF,RooFit::Slice(*ws->cat("catCentral"), "OFOSCentral"),RooFit::ProjWData(*data)); TFile *fout = new TFile("fout.root","UPDATE"); frameMM->Write(Concatenate(Concatenate(data->GetName(),"_MM"),tag),TObject::kOverwrite); frameEE->Write(Concatenate(Concatenate(data->GetName(),"_EE"),tag),TObject::kOverwrite); frameOF->Write(Concatenate(Concatenate(data->GetName(),"_OF"),tag),TObject::kOverwrite); fout->Close(); } delete plc; plc=0; }
void THSEventsPDF::adjustBinning(Int_t* offset1) const { RooRealVar* xvar = fx_off ; if (!dynamic_cast<RooRealVar*>(xvar)) { coutE(InputArguments) << "RooDataHist::adjustBinning(" << GetName() << ") ERROR: dimension " << xvar->GetName() << " must be real" << endl ; assert(0) ; } Double_t xlo = xvar->getMin() ; Double_t xhi = xvar->getMax() ; //adjust bin range limits with new scale parameter //cout<<scale<<" "<<fMean<<" "<<xlo<<" "<<xhi<<endl; xlo=(xlo-fMean)/scale+fMean; xhi=(xhi-fMean)/scale+fMean; if(xvar->getBinning().lowBound()==xlo&&xvar->getBinning().highBound()==xhi) return; xvar->setRange(xlo,xhi) ; // Int_t xmin(0) ; // cout<<"THSEventsPDF::adjustBinning( "<<xlo <<" "<<xhi<<endl; //now adjust fitting range to bin limits??Possibly not if (fRHist->GetXaxis()->GetXbins()->GetArray()) { RooBinning xbins(fRHist->GetNbinsX(),fRHist->GetXaxis()->GetXbins()->GetArray()) ; Double_t tolerance = 1e-6*xbins.averageBinWidth() ; // Adjust xlo/xhi to nearest boundary Double_t xloAdj = xbins.binLow(xbins.binNumber(xlo+tolerance)) ; Double_t xhiAdj = xbins.binHigh(xbins.binNumber(xhi-tolerance)) ; xbins.setRange(xloAdj,xhiAdj) ; xvar->setBinning(xbins) ; if (fabs(xloAdj-xlo)>tolerance||fabs(xhiAdj-xhi)<tolerance) { coutI(DataHandling) << "RooDataHist::adjustBinning(" << GetName() << "): fit range of variable " << xvar->GetName() << " expanded to nearest bin boundaries: [" << xlo << "," << xhi << "] --> [" << xloAdj << "," << xhiAdj << "]" << endl ; } } else { RooBinning xbins(fRHist->GetXaxis()->GetXmin(),fRHist->GetXaxis()->GetXmax()) ; xbins.addUniform(fRHist->GetNbinsX(),fRHist->GetXaxis()->GetXmin(),fRHist->GetXaxis()->GetXmax()) ; Double_t tolerance = 1e-6*xbins.averageBinWidth() ; // Adjust xlo/xhi to nearest boundary Double_t xloAdj = xbins.binLow(xbins.binNumber(xlo+tolerance)) ; Double_t xhiAdj = xbins.binHigh(xbins.binNumber(xhi-tolerance)) ; xbins.setRange(xloAdj,xhiAdj) ; xvar->setRange(xloAdj,xhiAdj) ; //xvar->setRange(xlo,xhi) ; } return; }
double getChisq(RooAbsData &dat, RooAbsPdf &pdf, RooRealVar &var, bool prt=false) { // Find total number of events double nEvt; double nTot=0.0; for(int j=0; j<dat.numEntries(); j++) { dat.get(j); nEvt=dat.weight(); nTot+=nEvt; } // Find chi-squared equivalent 2NLL //RooRealVar *var=(RooRealVar*)(pdf.getParameters(*dat)->find("CMS_hgg_mass")); double totNLL=0.0; double prbSum=0.0; for(int j=0; j<dat.numEntries(); j++) { double m=dat.get(j)->getRealValue(var.GetName()); if ( m < var.getMin() || m > var.getMax()) continue; // Find probability density and hence probability var.setVal(m); double prb = var.getBinWidth(0)*pdf.getVal(var); prbSum+=prb; dat.get(j); nEvt=dat.weight(); double mubin=nTot*prb; double contrib(0.); if (nEvt < 1) contrib = mubin; else contrib=mubin-nEvt+nEvt*log(nEvt/mubin); totNLL+=contrib; if(prt) cout << "Bin " << j << " prob = " << prb << " nEvt = " << nEvt << ", mu = " << mubin << " contribution " << contrib << endl; } totNLL*=2.0; if(prt) cout << pdf.GetName() << " nTot = " << nTot << " 2NLL constant = " << totNLL << endl; return totNLL; }
void createWorkspace(const std::string &infilename, int nState, bool correctCtau, bool drawRapPt2D) { gROOT->SetStyle("Plain"); gStyle->SetTitleBorderSize(0); delete gRandom; gRandom = new TRandom3(23101987); // Set some strings const std::string workspacename = "ws_masslifetime", treename = "selectedData"; // Get the tree from the data file TFile *f = TFile::Open(infilename.c_str()); TTree *tree = (TTree*)f->Get(treename.c_str()); // Set branch addresses in tree to be able to import tree to roofit TLorentzVector* chic = new TLorentzVector; tree->SetBranchAddress("chic",&chic); TLorentzVector* chic_rf = new TLorentzVector; tree->SetBranchAddress("chic_rf",&chic_rf); TLorentzVector* jpsi = new TLorentzVector; tree->SetBranchAddress("jpsi",&jpsi); double lifetime = 0; tree->SetBranchAddress("Jpsict",&lifetime); double lifetimeErr = 0; tree->SetBranchAddress("JpsictErr",&lifetimeErr); char lifetimeTitle[200]; sprintf(lifetimeTitle,"l^{#psi} [mm]"); if(correctCtau) sprintf(lifetimeTitle,"l^{#chi} [mm]"); // define variables necessary for J/Psi(Psi(2S)) mass,lifetime fit RooRealVar* JpsiMass = new RooRealVar("JpsiMass", "M^{#psi} [GeV]", onia::massMin, onia::massMax); RooRealVar* JpsiPt = new RooRealVar("JpsiPt", "p^{#psi}_{T} [GeV]", 0. ,1000.); RooRealVar* JpsiRap = new RooRealVar("JpsiRap", "y^{#psi}", -2., 2.); RooRealVar* chicMass = new RooRealVar("chicMass", "M^{#chi} [GeV]", onia::chimassMin, onia::chimassMax); RooRealVar* chicRap = new RooRealVar("chicRap", "y^{#chi}", -onia::chirap, onia::chirap); RooRealVar* chicPt = new RooRealVar("chicPt", "p^{#chi}_{T} [GeV]", 0. ,100.); RooRealVar* Jpsict = new RooRealVar("Jpsict", lifetimeTitle, onia::ctVarMin, onia::ctVarMax); RooRealVar* JpsictErr = new RooRealVar("JpsictErr", Form("Error on %s",lifetimeTitle), 0.0001, 1.); // Set bins Jpsict->setBins(10000,"cache"); JpsiMass->setBins(10000,"cache"); JpsiPt->setBins(100); JpsiRap->setBins(10000,"cache"); chicMass->setBins(10000,"cache"); //JpsictErr->setBins(100); JpsictErr->setBins(10000,"cache"); // The list of data variables RooArgList dataVars(*JpsiMass,*JpsiPt,*JpsiRap,*chicMass,*chicRap,*chicPt,*Jpsict,*JpsictErr); // construct dataset to contain events RooDataSet* fullData = new RooDataSet("fullData","The Full Data From the Input ROOT Trees",dataVars); int entries = tree->GetEntries(); cout << "entries " << entries << endl; int numEntriesTotal=0; int numEntriesInAnalysis=0; int numEntriesNotInAnalysis=0; /* /// Read in 2011 data ctauErr-histos char saveDir[200]; char PlotID[200]; char savename[200]; sprintf(saveDir,"/afs/hephy.at/scratch/k/knuenz/ChicPol/macros/polFit/Figures/CtauErrModel"); gSystem->mkdir(saveDir); sprintf(PlotID,"2014May26_MoreLbins"); sprintf(saveDir,"%s/%s",saveDir,PlotID); gSystem->mkdir(saveDir); sprintf(savename,"%s/CtauErrModel_histograms.root",saveDir); TFile *infile = new TFile(savename,"READ"); cout<<"opened file"<<endl; const int nPT=5; const int nRAP=2; const int nL=15; const double bordersPT[nPT+1] = {0., 12., 16., 20., 30., 100.}; const double bordersRAP[nRAP+1] = {0., 0.6, 2.}; const double bordersL[nL+1] = {onia::ctVarMin, -0.05, -0.03, -0.02, -0.015, -0.01, -0.005, 0., 0.005, 0.01, 0.015, 0.02, 0.03, 0.05, 0.1, onia::ctVarMax}; TH1D* h_ctauerr_2011[nRAP+1][nPT+1][nL+1]; TH1D* h_ctauerr_2012[nRAP+1][nPT+1][nL+1]; for(int iRAP = 0; iRAP < nRAP+1; iRAP++){ for(int iPT = 0; iPT < nPT+1; iPT++){ for(int iL = 0; iL < nL+1; iL++){ h_ctauerr_2011[iRAP][iPT][iL] = (TH1D*)infile->Get(Form("h_ctauerr_2011_rap%d_pt%d_l%d",iRAP, iPT, iL)); h_ctauerr_2012[iRAP][iPT][iL] = (TH1D*)infile->Get(Form("h_ctauerr_2012_rap%d_pt%d_l%d",iRAP, iPT, iL)); } } } cout<<"opened hists"<<endl; /// Finished reading in 2011 data ctauErr-histos */ // loop through events in tree and save them to dataset for (int ientries = 0; ientries < entries; ientries++) { numEntriesTotal++; if (ientries%10000==0) std::cout << "event " << ientries << " of " << entries << std::endl; tree->GetEntry(ientries); double M_jpsi =jpsi->M(); double pt_jpsi =jpsi->Pt(); double y_jpsi =jpsi->Rapidity(); double M =chic_rf->M(); //double M =chic->M()-jpsi->M()+onia::MpsiPDG; double y=chic->Rapidity(); double pt=chic->Pt(); //if (ientries%3==0){ // M_jpsi = gRandom->Uniform(JpsiMass->getMin(), JpsiMass->getMax()); //} //double JpsictErrRand = h_JpsictErr->GetRandom(); //double JpsictErrRand2 = h_JpsictErr->GetRandom(); //double JpsictMeanRand=0.; ////double pTcorrection=(pt-20.)*0.002; // ////JpsictErrRand-=pTcorrection; //if(JpsictErrRand<0) JpsictErrRand=0.001; ////JpsictErrRand2-=pTcorrection; //if(JpsictErrRand2<0) JpsictErrRand2=0.001; // //if (ientries%1000000==0){ // double exponent=0.4; // JpsictMeanRand=gRandom->Exp(exponent); //} // // //lifetime = gRandom->Gaus(JpsictMeanRand,0.8*JpsictErrRand); //lifetimeErr = JpsictErrRand2; //if (ientries%3==0){ // lifetime = gRandom->Gaus(JpsictMeanRand,1.5*JpsictErrRand); //} // //double resCorrFactor=1.08; //if(lifetime<0) // lifetimeErr/=resCorrFactor; /* int iRAPindex=0; int iPTindex=0; int iLindex=0; for(int iRAP = 1; iRAP < nRAP+1; iRAP++){ for(int iPT = 1; iPT < nPT+1; iPT++){ for(int iL = 1; iL < nL+1; iL++){ Double_t ptMin = bordersPT[iPT-1];; Double_t ptMax = bordersPT[iPT];; Double_t rapMin = bordersRAP[iRAP-1];; Double_t rapMax = bordersRAP[iRAP]; ; Double_t lMin = bordersL[iL-1];; Double_t lMax = bordersL[iL]; ; if(pt_jpsi>ptMin && pt_jpsi<ptMax && TMath::Abs(y_jpsi)>rapMin && TMath::Abs(y_jpsi)<rapMax && lifetime>lMin && lifetime<lMax){ iRAPindex=iRAP; iPTindex=iPT; iLindex=iL; } } } } double lifetimeErrRand = h_ctauerr_2011[iRAPindex][iPTindex][iLindex]->GetRandom(); lifetimeErr = lifetimeErrRand; if (ientries%10000==0){ std::cout << "Test output: lifetimeErr " << lifetimeErr << " randomly drawn from from " << h_ctauerr_2011[iRAPindex][iPTindex][iLindex]->GetName() << std::endl; } */ if ( M > chicMass->getMin() && M < chicMass->getMax() && pt > chicPt->getMin() && pt < chicPt->getMax() && y > chicRap->getMin() && y < chicRap->getMax() && M_jpsi > JpsiMass->getMin() && M_jpsi < JpsiMass->getMax() && pt_jpsi > JpsiPt->getMin() && pt_jpsi < JpsiPt->getMax() && y_jpsi > JpsiRap->getMin() && y_jpsi < JpsiRap->getMax() && lifetime > Jpsict->getMin() && lifetime < Jpsict->getMax() && lifetimeErr > JpsictErr->getMin() && lifetimeErr < JpsictErr->getMax() ) { chicPt ->setVal(pt); chicRap ->setVal(y); chicMass ->setVal(M); JpsiMass ->setVal(M_jpsi); JpsiPt ->setVal(pt_jpsi); JpsiRap ->setVal(y_jpsi); Jpsict ->setVal(lifetime); JpsictErr ->setVal(lifetimeErr); //cout<<"JpsiRap->getVal() "<<JpsiRap->getVal()<<endl; fullData->add(dataVars); numEntriesInAnalysis++; } else { numEntriesNotInAnalysis++; //if (M < chicMass->getMin() || M > chicMass->getMax()) cout << "M " << M << endl; //if (pt < chicPt->getMin() || pt > chicPt->getMax()) cout << "pt " << pt << endl; //if (y < chicRap->getMin() || y > chicRap->getMax()) cout << "y " << y << endl; //if (lifetime < Jpsict->getMin() || lifetime > Jpsict->getMax()) cout << "lifetime " << lifetime << endl; //if (lifetimeErr < JpsictErr->getMin() || lifetimeErr > JpsictErr->getMax()) cout << "lifetimeErr " << lifetimeErr << endl; //cout << "M " << M << endl; //cout << "pt " << pt << endl; //cout << "y " << y << endl; //cout << "lifetime " << lifetime << endl; //cout << "lifetimeErr " << lifetimeErr << endl; //cout << " " << endl; } }//ientries //infile->Close(); cout << "entries entering all bins " << fullData->sumEntries() << endl; cout << "numEntriesTotal " << numEntriesTotal << endl; cout << "numEntriesInAnalysis " << numEntriesInAnalysis << endl; cout << "numEntriesNotInAnalysis " << numEntriesNotInAnalysis << endl; //------------------------------------------------------------------------------------------------------------------ // Define workspace and import datasets ////Get datasets binned in pT an y for(int iRap = 0; iRap <= onia::kNbRapForPTBins; iRap++) { Double_t yMin; Double_t yMax; if(iRap==0) { yMin = onia::rapForPTRange[0]; yMax = onia::rapForPTRange[onia::kNbRapForPTBins]; } else { yMin = onia::rapForPTRange[iRap-1]; yMax = onia::rapForPTRange[iRap]; } for(int iPT = 0; iPT <= onia::kNbPTBins[iRap]; iPT++) { //for(int iPT = 0; iPT <= 0; iPT++) Double_t ptMin; Double_t ptMax; if(iPT==0) { ptMin = onia::pTRange[iRap][0]; ptMax = onia::pTRange[iRap][onia::kNbPTBins[0]]; } else { ptMin = onia::pTRange[iRap][iPT-1]; ptMax = onia::pTRange[iRap][iPT]; } // output file name and workspace std::stringstream outfilename; outfilename << "tmpFiles/backupWorkSpace/ws_createWorkspace_Chi_rap" << iRap << "_pt" << iPT << ".root"; RooWorkspace* ws = new RooWorkspace(workspacename.c_str()); // define pt and y cuts on dataset std::stringstream cutString; if(onia::KinParticleChi && !onia::KinParticleChiButJpsiRap) { cutString << "(chicPt >= " << ptMin << " && chicPt < "<< ptMax << ") && " << "(TMath::Abs(chicRap) >= " << yMin << " && TMath::Abs(chicRap) < " << yMax << ")"; } if(!onia::KinParticleChi) { cutString << "(JpsiPt >= " << ptMin << " && JpsiPt < "<< ptMax << ") && " << "(TMath::Abs(JpsiRap) >= " << yMin << " && TMath::Abs(JpsiRap) < " << yMax << ")"; } if(onia::KinParticleChi && onia::KinParticleChiButJpsiRap) { cutString << "(chicPt >= " << ptMin << " && chicPt < "<< ptMax << ") && " << "(TMath::Abs(JpsiRap) >= " << yMin << " && TMath::Abs(JpsiRap) < " << yMax << ")"; } cout << "cutString: " << cutString.str().c_str() << endl; // get the dataset for the fit RooDataSet* binData = (RooDataSet*)fullData->reduce(cutString.str().c_str()); std::stringstream name; name << "jpsi_data_rap" << iRap << "_pt" << iPT; binData->SetNameTitle(name.str().c_str(), "Data For Fitting"); cout << "numEvents = " << binData->sumEntries() << endl; double chicMeanPt = binData->mean(*chicPt); RooRealVar var_chicMeanPt("var_chicMeanPt","var_chicMeanPt",chicMeanPt); if(!ws->var("var_chicMeanPt")) ws->import(var_chicMeanPt); else ws->var("var_chicMeanPt")->setVal(chicMeanPt); cout << "chicMeanPt = " << chicMeanPt << endl; double jpsiMeanPt = binData->mean(*JpsiPt); RooRealVar var_jpsiMeanPt("var_jpsiMeanPt","var_jpsiMeanPt",jpsiMeanPt); if(!ws->var("var_jpsiMeanPt")) ws->import(var_jpsiMeanPt); else ws->var("var_jpsiMeanPt")->setVal(jpsiMeanPt); cout << "jpsiMeanPt = " << jpsiMeanPt << endl; std::stringstream cutStringPosRapChic; cutStringPosRapChic << "chicRap > 0"; RooDataSet* binDataPosRapChic = (RooDataSet*)binData->reduce(cutStringPosRapChic.str().c_str()); double chicMeanAbsRap = binDataPosRapChic->mean(*chicRap); cout << "chicMeanAbsRap = " << chicMeanAbsRap << endl; RooRealVar var_chicMeanAbsRap("var_chicMeanAbsRap","var_chicMeanAbsRap",chicMeanAbsRap); if(!ws->var("var_chicMeanAbsRap")) ws->import(var_chicMeanAbsRap); else ws->var("var_chicMeanAbsRap")->setVal(chicMeanAbsRap); std::stringstream cutStringPosRapJpsi; cutStringPosRapJpsi << "JpsiRap > 0"; RooDataSet* binDataPosRapJpsi = (RooDataSet*)binData->reduce(cutStringPosRapJpsi.str().c_str()); double jpsiMeanAbsRap = binDataPosRapJpsi->mean(*JpsiRap); cout << "jpsiMeanAbsRap = " << jpsiMeanAbsRap << endl; RooRealVar var_jpsiMeanAbsRap("var_jpsiMeanAbsRap","var_jpsiMeanAbsRap",jpsiMeanAbsRap); if(!ws->var("var_jpsiMeanAbsRap")) ws->import(var_jpsiMeanAbsRap); else ws->var("var_jpsiMeanAbsRap")->setVal(jpsiMeanAbsRap); // Import variables to workspace ws->import(*binData); ws->writeToFile(outfilename.str().c_str()); }//iPT }//iRap ////--------------------------------------------------------------- ////--Integrating rapidity and pt bins, in +/- 3*sigma mass window ////--------------------------------------------------------------- if(drawRapPt2D) { double yMin = onia::rapForPTRange[0]; double yMax = 1.6;//onia::rapForPTRange[onia::kNbRapForPTBins]; double ptMin = onia::pTRange[0][0]; double ptMax = onia::pTRange[0][onia::kNbPTBins[0]]; std::stringstream cutRapPt; cutRapPt << "(chicPt > " << ptMin << " && chicPt < "<< ptMax << ") && " << "(TMath::Abs(chicRap) > " << yMin << " && TMath::Abs(chicRap) < " << yMax << ")"; cout<<"cutRapPt: "<<cutRapPt.str().c_str()<<endl; RooDataSet* rapPtData = (RooDataSet*)fullData->reduce(cutRapPt.str().c_str()); std::stringstream nameRapPt; nameRapPt << "data_rap0_pt0"; rapPtData->SetNameTitle(nameRapPt.str().c_str(), "Data For full rap and pt"); // output file name and workspace std::stringstream outfilename; outfilename << "tmpFiles/backupWorkSpace/ws_createWorkspace_Chi_rap0_pt0.root"; RooWorkspace* ws_RapPt = new RooWorkspace(workspacename.c_str()); //Import variables to workspace ws_RapPt->import(*rapPtData); ws_RapPt->writeToFile(outfilename.str().c_str()); TH2D* rapPt; TH1D* rap1p2; double MassMin; double MassMax; rap1p2 = new TH1D("rap1p2","rap1p2",30,1.2, 1.8); if(nState==4) { rapPt = new TH2D( "rapPt", "rapPt", 52,-1.3,1.3,144,0,72); MassMin=3.011;//massPsi1S-onia::nSigMass*sigma1S; MassMax=3.174;//massPsi1S+onia::nSigMass*sigma1S; // sigma 27.2 MeV // mean 3.093 GeV } if(nState==5) { rapPt = new TH2D( "rapPt", "rapPt", 64,-1.6,1.6,144,0,72); // rap<1.5 //rapPt = new TH2D( "rapPt", "rapPt", 52,-1.3,1.3,144,0,72); // rap<1.2 MassMin=3.576;//massPsi2S-onia::nSigMass*sigma2S; MassMax=3.786;//massPsi2S+onia::nSigMass*sigma2S; // sigma 34.9 MeV // pT > 7 // sigma 34.3 MeV // pT > 10 // mean 3.681 GeV } cout<<"Plotting rap-Pt for Psi"<<nState-3<<"S"<<endl; cout<<"MassMin for rap-Pt plot = "<<MassMin<<endl; cout<<"MassMax for rap-Pt plot = "<<MassMax<<endl; TTree *rapPtTree = (TTree*)rapPtData->tree(); std::stringstream cutMass; cutMass<<"(chicMass > " << MassMin << " && chicMass < "<< MassMax << ")"; //following two methods can only be used in root_v30, 34 does not work rapPtTree->Draw("chicPt:chicRap>>rapPt",cutMass.str().c_str(),"colz"); cout<<"debug"<<endl; rapPtTree->Draw("TMath::Abs(chicRap)>>rap1p2",cutMass.str().c_str()); TCanvas* c2 = new TCanvas("c2","c2",1200,1500); rapPt->SetYTitle("p_{T}(#mu#mu) [GeV]"); rapPt->SetXTitle("y(#mu#mu)"); gStyle->SetPalette(1); gPad->SetFillColor(kWhite); rapPt->SetTitle(0); rapPt->SetStats(0); gPad->SetLeftMargin(0.15); gPad->SetRightMargin(0.17); rapPt->GetYaxis()->SetTitleOffset(1.5); rapPt->Draw("colz"); TLine* rapPtLine; for(int iRap=0; iRap<onia::kNbRapForPTBins+1; iRap++) { rapPtLine= new TLine( -onia::rapForPTRange[iRap], onia::pTRange[0][0], -onia::rapForPTRange[iRap], onia::pTRange[0][onia::kNbPTBins[iRap]] ); rapPtLine->SetLineWidth( 2 ); rapPtLine->SetLineStyle( 1 ); rapPtLine->SetLineColor( kWhite ); rapPtLine->Draw(); rapPtLine= new TLine( onia::rapForPTRange[iRap], onia::pTRange[0][0], onia::rapForPTRange[iRap], onia::pTRange[0][onia::kNbPTBins[iRap]] ); rapPtLine->SetLineWidth( 2 ); rapPtLine->SetLineStyle( 1 ); rapPtLine->SetLineColor( kWhite ); rapPtLine->Draw(); int pTBegin = 0; if(nState==5) pTBegin = 1; for(int iPt=pTBegin; iPt<onia::kNbPTBins[iRap+1]+1; iPt++) { rapPtLine= new TLine( -onia::rapForPTRange[onia::kNbRapForPTBins], onia::pTRange[0][iPt], onia::rapForPTRange[onia::kNbRapForPTBins], onia::pTRange[0][iPt] ); rapPtLine->SetLineWidth( 2 ); rapPtLine->SetLineStyle( 1 ); rapPtLine->SetLineColor( kWhite ); rapPtLine->Draw(); } } char savename[200]; sprintf(savename,"Figures/rapPt_Chi.pdf"); c2->SaveAs(savename); TCanvas* c3 = new TCanvas("c3","c3",1500,1200); rap1p2->SetYTitle("Events"); rap1p2->SetXTitle("y(#mu#mu)"); rap1p2->SetTitle(0); rap1p2->SetStats(0); rap1p2->GetYaxis()->SetTitleOffset(1.2); rap1p2->Draw(); sprintf(savename,"Figures/rap_Chi_1p2.pdf"); c3->SaveAs(savename); } f->Close(); }
// internal routine to run the inverter HypoTestInverterResult * RunInverter(RooWorkspace * w, const char * modelSBName, const char * modelBName, const char * dataName, int type, int testStatType, int npoints, double poimin, double poimax, int ntoys, bool useCls ) { std::cout << "Running HypoTestInverter on the workspace " << w->GetName() << std::endl; w->Print(); RooAbsData * data = w->data(dataName); if (!data) { Error("RA2bHypoTestDemo","Not existing data %s",dataName); return 0; } else std::cout << "Using data set " << dataName << std::endl; // get models from WS // get the modelConfig out of the file ModelConfig* bModel = (ModelConfig*) w->obj(modelBName); ModelConfig* sbModel = (ModelConfig*) w->obj(modelSBName); if (!sbModel) { Error("RA2bHypoTestDemo","Not existing ModelConfig %s",modelSBName); return 0; } // check the model if (!sbModel->GetPdf()) { Error("RA2bHypoTestDemo","Model %s has no pdf ",modelSBName); return 0; } if (!sbModel->GetParametersOfInterest()) { Error("RA2bHypoTestDemo","Model %s has no poi ",modelSBName); return 0; } if (!sbModel->GetParametersOfInterest()) { Error("RA2bHypoTestInvDemo","Model %s has no poi ",modelSBName); return 0; } if (!sbModel->GetSnapshot() ) { Info("RA2bHypoTestInvDemo","Model %s has no snapshot - make one using model poi",modelSBName); sbModel->SetSnapshot( *sbModel->GetParametersOfInterest() ); } if (!bModel || bModel == sbModel) { Info("RA2bHypoTestInvDemo","The background model %s does not exist",modelBName); Info("RA2bHypoTestInvDemo","Copy it from ModelConfig %s and set POI to zero",modelSBName); bModel = (ModelConfig*) sbModel->Clone(); bModel->SetName(TString(modelSBName)+TString("_with_poi_0")); RooRealVar * var = dynamic_cast<RooRealVar*>(bModel->GetParametersOfInterest()->first()); if (!var) return 0; double oldval = var->getVal(); var->setVal(0); bModel->SetSnapshot( RooArgSet(*var) ); var->setVal(oldval); } else { if (!bModel->GetSnapshot() ) { Info("RA2bHypoTestInvDemo","Model %s has no snapshot - make one using model poi and 0 values ",modelBName); RooRealVar * var = dynamic_cast<RooRealVar*>(bModel->GetParametersOfInterest()->first()); if (var) { double oldval = var->getVal(); var->setVal(0); bModel->SetSnapshot( RooArgSet(*var) ); var->setVal(oldval); } else { Error("RA2bHypoTestInvDemo","Model %s has no valid poi",modelBName); return 0; } } } SimpleLikelihoodRatioTestStat slrts(*sbModel->GetPdf(),*bModel->GetPdf()); if (sbModel->GetSnapshot()) slrts.SetNullParameters(*sbModel->GetSnapshot()); if (bModel->GetSnapshot()) slrts.SetAltParameters(*bModel->GetSnapshot()); // ratio of profile likelihood - need to pass snapshot for the alt RatioOfProfiledLikelihoodsTestStat ropl(*sbModel->GetPdf(), *bModel->GetPdf(), bModel->GetSnapshot()); ropl.SetSubtractMLE(false); //MyProfileLikelihoodTestStat profll(*sbModel->GetPdf()); ProfileLikelihoodTestStat profll(*sbModel->GetPdf()); if (testStatType == 3) profll.SetOneSided(1); if (optimize) profll.SetReuseNLL(true); TestStatistic * testStat = &slrts; if (testStatType == 1) testStat = &ropl; if (testStatType == 2 || testStatType == 3) testStat = &profll; HypoTestCalculatorGeneric * hc = 0; if (type == 0) hc = new FrequentistCalculator(*data, *bModel, *sbModel); else hc = new HybridCalculator(*data, *bModel, *sbModel); ToyMCSampler *toymcs = (ToyMCSampler*)hc->GetTestStatSampler(); //=== DEBUG ///// toymcs->SetWS( w ) ; //=== DEBUG toymcs->SetNEventsPerToy(1); toymcs->SetTestStatistic(testStat); if (optimize) toymcs->SetUseMultiGen(true); if (type == 1) { HybridCalculator *hhc = (HybridCalculator*) hc; hhc->SetToys(ntoys,ntoys); // check for nuisance prior pdf if (bModel->GetPriorPdf() && sbModel->GetPriorPdf() ) { hhc->ForcePriorNuisanceAlt(*bModel->GetPriorPdf()); hhc->ForcePriorNuisanceNull(*sbModel->GetPriorPdf()); } else { if (bModel->GetNuisanceParameters() || sbModel->GetNuisanceParameters() ) { Error("RA2bHypoTestInvDemo","Cannnot run Hybrid calculator because no prior on the nuisance parameter is specified"); return 0; } } } else ((FrequentistCalculator*) hc)->SetToys(ntoys,ntoys); // Get the result RooMsgService::instance().getStream(1).removeTopic(RooFit::NumIntegration); TStopwatch tw; tw.Start(); const RooArgSet * poiSet = sbModel->GetParametersOfInterest(); RooRealVar *poi = (RooRealVar*)poiSet->first(); // fit the data first sbModel->GetPdf()->fitTo(*data); double poihat = poi->getVal(); HypoTestInverter calc(*hc); calc.SetConfidenceLevel(0.95); calc.UseCLs(useCls); calc.SetVerbose(true); // can speed up using proof-lite if (useProof && nworkers > 1) { ProofConfig pc(*w, nworkers, "", kFALSE); toymcs->SetProofConfig(&pc); // enable proof } printf(" npoints = %d, poimin = %7.2f, poimax = %7.2f\n\n", npoints, poimin, poimax ) ; cout << flush ; if ( npoints==1 ) { std::cout << "Evaluating one point : " << poimax << std::endl; calc.RunOnePoint(poimax); } else if (npoints > 0) { if (poimin >= poimax) { // if no min/max given scan between MLE and +4 sigma poimin = int(poihat); poimax = int(poihat + 4 * poi->getError()); } std::cout << "Doing a fixed scan in interval : " << poimin << " , " << poimax << std::endl; calc.SetFixedScan(npoints,poimin,poimax); } else { //poi->setMax(10*int( (poihat+ 10 *poi->getError() )/10 ) ); std::cout << "Doing an automatic scan in interval : " << poi->getMin() << " , " << poi->getMax() << std::endl; } cout << "\n\n right before calc.GetInterval(), ntoys = " << ntoys << " \n\n" << flush ; HypoTestInverterResult * r = calc.GetInterval(); return r; }
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; }
void fitPtOverMCJLST(int mass = 125, int LHCsqrts = 7, int whichtype = 1, bool correctErrors = false, /* string changeParName = "", */ bool showErrorPDFs = false, string systString = "Default") // whichtype // 0 - gg Signal // 1 - VBF Signal // 2 - ZZ // 3 - ZX // 4 - ggZZ // 5 - WH // 6 - ZH // 7 - ttH { string changeParName = ""; if (systString == "Default") changeParName = "up"; string nameSample[8] = {"gg","vbf","zz","zx","ggzz","wh","zh","tth"}; float maxType[8] = {2.4,3.2,1.6,1.6,1.6,3.2,3.2,3.2}; float rebinType[8] = {1,2,1,1,4,10,10,40}; for (int t = 0; t < 8; t++) { if (mass > 150) maxType[t] = int(117.90*maxType[t]/sqrt(mass-10.91))/10.; } char fileToOpen[200]; sprintf(fileToOpen,"selRootFiles/PToverM_%s%d_SEL_%dTeV.root",nameSample[whichtype].c_str(),mass,LHCsqrts); // if (whichtype == 3) sprintf(fileToOpen,"PTOVERM_%s_SEL_allTeV.root",nameSample[whichtype].c_str()); RooRealVar* ptoverm = new RooRealVar("ptoverm","p_{T}/M^{4l}",0.,maxType[whichtype],"GeV/c"); TFile input(fileToOpen); // if (systString == "Mass" || systString == "Mela") { // sprintf(fileToOpen,"ptovermH_%sUp",systString.c_str()); // } else { sprintf(fileToOpen,"ptovermH_%s",systString.c_str()); //} TH1F* ptovermH = (TH1F*)input.Get(fileToOpen); if (rebinType[whichtype] > 1) ptovermH->Rebin(rebinType[whichtype]); if (maxType[whichtype] < ptovermH->GetBinLowEdge(ptovermH->GetNbinsX() + 1) - ptovermH->GetBinWidth(1)) { int theBin = ptovermH->FindBin(maxType[whichtype]); ptovermH->GetXaxis()->SetRange(1,theBin-1); } gROOT->ProcessLine(".L mytdrstyle.C"); gROOT->ProcessLine("setTDRStyle()"); // cout << endl << "Signal " << endl; ptoverm->setBins(ptovermH->GetNbinsX()); RooDataHist* rdh = new RooDataHist("rdh","Some dataset",RooArgList(*ptoverm),Import(*ptovermH,kFALSE)); // fit definitions // RooWorkspace *ws = new RooWorkspace("ws"); RooRealVar m("m","emme", 1.,0.01, 40.); RooRealVar n("n","enne", 0.93, 0.05, 15.); RooRealVar n2("n2","enne2", 0.75, 0.5, 15.); RooRealVar bb("bb","bibi",0.02, 0.000005, 20.0); RooRealVar T("T","tti",0.2,0.00000005,1.); RooRealVar bb2("bb2","bibi2",0.02, 0.0005, 10.0); RooRealVar fexp("fexp","f_exp",0.02, 0.0, 1.0); if (whichtype == 0) { if (LHCsqrts == 8) { m.setVal(3.319); // m.setConstant(kTRUE); n.setVal(0.7606); if (systString != "Default" || mass != 125) n.setConstant(kTRUE); n2.setVal(0.8061); n2.setConstant(kTRUE); bb.setVal(3.728); // bb.setConstant(kTRUE); T.setVal(0.00333); // T.setConstant(kTRUE); bb2.setVal(1.7172); // bb2.setConstant(kTRUE); fexp.setVal(0.002144); if (systString != "Default" || mass != 125) fexp.setConstant(kTRUE); } else { m.setVal(0.061); // m.setConstant(kTRUE); n.setVal(1.6141); if (systString == "Resummation" || systString == "TopMass") n.setConstant(kTRUE); n2.setVal(1.3294); n2.setConstant(kTRUE); bb.setVal(4.2761); // bb.setConstant(kTRUE); T.setVal(0.0361); // T.setConstant(kTRUE); bb2.setVal(1.6643); bb2.setConstant(kTRUE); fexp.setVal(0.0004); // fexp.setConstant(kTRUE); } } else if (whichtype == 1) { m.setVal(1.006); // m.setConstant(kTRUE); n.setVal(10.939); n.setConstant(kTRUE); n2.setVal(1.1448); n2.setConstant(kTRUE); bb.setVal(0.02048); bb.setConstant(kTRUE); T.setVal(0.16115); if (systString.find("Mela") != string::npos) T.setConstant(kTRUE); // T.setConstant(kTRUE); bb2.setVal(1.0024); bb2.setConstant(kTRUE); fexp.setVal(0.005); fexp.setConstant(kTRUE); if (mass > 300) { fexp.setVal(0.0); fexp.setConstant(kFALSE); } if (mass > 500) { bb2.setVal(5.0); // bb2.setConstant(kFALSE); } if (mass > 500) { bb.setVal(15.0); // bb.setConstant(kFALSE); } } else if (whichtype == 2) { if (LHCsqrts == 8) { m.setVal(1.0476); // m.setConstant(kTRUE); bb.setVal(3.3088); // if (mass != 140) bb.setConstant(kTRUE); n2.setVal(0.7146); n2.setConstant(kTRUE); n.setVal(0.9518); n.setConstant(kTRUE); bb2.setVal(100000.); bb2.setConstant(kTRUE); T.setVal(0.0021889); if (systString.find("Mela") != string::npos || mass != 140) T.setConstant(kTRUE); fexp.setVal(0.0); fexp.setConstant(kTRUE); } else { m.setVal(1.028); // m.setConstant(kTRUE); bb.setVal(2.91); // bb.setConstant(kTRUE); n2.setVal(0.7146); n2.setConstant(kTRUE); n.setVal(0.9518); n.setConstant(kTRUE); bb2.setVal(100000.); bb2.setConstant(kTRUE); T.setVal(0.002248); if (systString.find("Mela") != string::npos) T.setConstant(kTRUE); fexp.setVal(0.0); fexp.setConstant(kTRUE); } } else if (whichtype == 3) { m.setVal(1.411); // m.setConstant(kTRUE); n.setVal(3.4523); n.setConstant(kTRUE); n2.setVal(0.6910); n2.setConstant(kTRUE); bb.setVal(0.00039); // bb.setConstant(kTRUE); T.setVal(0.118); // T.setConstant(kTRUE); bb2.setVal(0.0224); bb2.setConstant(kTRUE); fexp.setVal(0.0); fexp.setConstant(kTRUE); } else if (whichtype == 4) { m.setVal(1.411); // m.setConstant(kTRUE); n.setVal(5.756); // n.setConstant(kTRUE); n2.setVal(0.8738); // n2.setConstant(kTRUE); bb.setVal(0.00039); // bb.setConstant(kTRUE); T.setVal(0.118); // T.setConstant(kTRUE); bb2.setVal(0.0224); bb2.setConstant(kTRUE); fexp.setVal(0.0); fexp.setConstant(kTRUE); } else if (whichtype == 5 && LHCsqrts == 8) { m.setVal(1.006); // m.setConstant(kTRUE); n.setVal(10.939); n.setConstant(kTRUE); n2.setVal(1.1448); n2.setConstant(kTRUE); bb.setVal(3.897); bb.setConstant(kTRUE); T.setVal(0.1009); // T.setConstant(kTRUE); bb2.setVal(1.0224); bb2.setConstant(kTRUE); fexp.setVal(0.01); fexp.setConstant(kTRUE); } else { // cout << "Entro qui" << endl; m.setVal(1.006); // m.setConstant(kTRUE); n.setVal(10.939); n.setConstant(kTRUE); n2.setVal(1.1448); n2.setConstant(kTRUE); bb.setVal(0.0129); bb.setConstant(kTRUE); T.setVal(0.1009); // T.setConstant(kTRUE); bb2.setVal(1.0224); bb2.setConstant(kTRUE); fexp.setVal(0.01); fexp.setConstant(kTRUE); } RooModifTsallis* rt3 = new RooModifTsallis("rt3","rt3",*ptoverm,m,n,n2,bb,bb2,T,fexp); // ws->import(*rt3); // fit RooFitResult* fit = rt3->fitTo(*rdh,Minos(0),Save(1),SumW2Error(kTRUE),NumCPU(1)); float mVal = m.getVal(); float nVal = n.getVal(); float n2Val = n2.getVal(); float bbVal = bb.getVal(); float bb2Val = bb2.getVal(); float fexpVal = fexp.getVal(); float TVal = T.getVal(); if (correctErrors) { // Tsallis errors not reliable, use toy MC TH1F* mHist = new TH1F("mHist","m",21,-0.5*mVal,0.5*mVal); TH1F* nHist = new TH1F("nHist","n",21,-0.2*nVal,0.2*nVal); TH1F* n2Hist = new TH1F("n2Hist","n2",21,-0.2*n2Val,0.2*n2Val); TH1F* bbHist = new TH1F("bbHist","bb",21,-0.2*bbVal,0.2*bbVal); TH1F* bb2Hist = new TH1F("bb2Hist","bb2",21,-0.2*bb2Val,0.2*bb2Val); TH1F* fexpHist = new TH1F("fexpHist","fexp",21,-0.2*fexpVal-0.000001,0.2*fexpVal+0.000001); TH1F* THist = new TH1F("THist","T",21,-0.5*TVal,0.5*TVal); mHist->GetXaxis()->SetTitle("m-m_{gen}"); nHist->GetXaxis()->SetTitle("n-n_{gen}"); n2Hist->GetXaxis()->SetTitle("n2-n2_{gen}"); bbHist->GetXaxis()->SetTitle("bb-bb_{gen}"); bb2Hist->GetXaxis()->SetTitle("bb2-bb2_{gen}"); THist->GetXaxis()->SetTitle("T-T_{gen}"); fexpHist->GetXaxis()->SetTitle("fexp-fexp_{gen}"); for (unsigned int iToy = 0; iToy < 200; iToy++) { cout << endl << "####" << endl; cout << "Generating toy experiment n. " << iToy+1 << endl; m.setVal(mVal); n.setVal(nVal); n2.setVal(n2Val); bb.setVal(bbVal); bb2.setVal(bb2Val); fexp.setVal(fexpVal); T.setVal(TVal); TDatime *now = new TDatime(); Int_t seed = now->GetDate() + now->GetTime(); cout << "RooFit Generation Seed = " << seed+iToy << endl; RooRandom::randomGenerator()->SetSeed(seed+iToy); cout << "####" << endl << endl; RooDataSet *dataToy = rt3->generate(RooArgSet(*ptoverm),ptovermH->GetEntries()); RooDataHist *dataToyH = new RooDataHist("dataToyH","toy",RooArgSet(*ptoverm),*dataToy); rt3->fitTo(*dataToyH,Minos(0),SumW2Error(kTRUE),NumCPU(1)); if (fit->floatParsFinal().find("m")) mHist->Fill(m.getVal()-mVal); if (fit->floatParsFinal().find("n")) nHist->Fill(n.getVal()-nVal); if (fit->floatParsFinal().find("n2")) n2Hist->Fill(n2.getVal()-n2Val); if (fit->floatParsFinal().find("bb")) bbHist->Fill(bb.getVal()-bbVal); if (fit->floatParsFinal().find("bb2")) bb2Hist->Fill(bb2.getVal()-bb2Val); if (fit->floatParsFinal().find("fexp")) fexpHist->Fill(fexp.getVal()-fexpVal); if (fit->floatParsFinal().find("T")) THist->Fill(T.getVal()-TVal); } TCanvas cant("cant","Test canvas",5.,5.,900.,500.); cant.Divide(4,2); cant.cd(1); mHist->Draw(); cant.cd(2); nHist->Draw(); cant.cd(3); n2Hist->Draw(); cant.cd(4); bbHist->Draw(); cant.cd(5); bb2Hist->Draw(); cant.cd(6); fexpHist->Draw(); cant.cd(7); THist->Draw(); // cant.SaveAs("figs/testToys.pdf"); cant.SaveAs("newfigs/testToys.pdf"); if (fit->floatParsFinal().find("m")) m.setError(mHist->GetRMS()); if (fit->floatParsFinal().find("n")) n.setError(nHist->GetRMS()); if (fit->floatParsFinal().find("n2")) n2.setError(n2Hist->GetRMS()); if (fit->floatParsFinal().find("bb")) bb.setError(bbHist->GetRMS()); if (fit->floatParsFinal().find("bb2")) bb2.setError(bb2Hist->GetRMS()); if (fit->floatParsFinal().find("fexp")) fexp.setError(fexpHist->GetRMS()); if (fit->floatParsFinal().find("T")) T.setError(THist->GetRMS()); } m.setVal(mVal); n.setVal(nVal); n2.setVal(n2Val); bb.setVal(bbVal); bb2.setVal(bb2Val); fexp.setVal(fexpVal); T.setVal(TVal); char fileToSave[200]; // if (changeParName != "") // sprintf(fileToSave,"text/paramsPTOverMCJLST_%s_%dTeV_%s_%s.txt",nameSample[whichtype].c_str(),LHCsqrts,systString.c_str(),changeParName.c_str()); // else sprintf(fileToSave,"text/paramsPTOverMCJLST_%s%d_%dTeV_%s.txt",nameSample[whichtype].c_str(),mass,LHCsqrts,systString.c_str()); ofstream os1(fileToSave); if (changeParName != "") { sprintf(fileToSave,"m%s",changeParName.c_str()); m.SetName(fileToSave); sprintf(fileToSave,"n%s",changeParName.c_str()); n.SetName(fileToSave); sprintf(fileToSave,"n2%s",changeParName.c_str()); n2.SetName(fileToSave); sprintf(fileToSave,"bb%s",changeParName.c_str()); bb.SetName(fileToSave); sprintf(fileToSave,"bb2%s",changeParName.c_str()); bb2.SetName(fileToSave); sprintf(fileToSave,"fexp%s",changeParName.c_str()); fexp.SetName(fileToSave); sprintf(fileToSave,"T%s",changeParName.c_str()); T.SetName(fileToSave); } (RooArgSet(m,n,n2,bb,bb2,fexp,T)).writeToStream(os1,false); os1.close(); RooRealVar mup("mup","emme", 1.,0.01, 30.); RooRealVar nup("nup","enne", 0.93, 0.5, 15.); RooRealVar n2up("n2up","enne2", 0.75, 0.5, 15.); RooRealVar bbup("bbup","bibi",0.02, 0.00005, 20.0); RooRealVar Tup("Tup","tti",0.2,0.00000005,1.); RooRealVar bb2up("bb2up","bibi2",0.02, 0.0005, 10.0); RooRealVar fexpup("fexpup","f_exp",0.02, 0.0, 1.0); RooModifTsallis* rt3up = new RooModifTsallis("rt3up","rt3up",*ptoverm,mup,nup,n2up,bbup,bb2up,Tup,fexpup); // ws->import(*rt3up); RooRealVar mdown("mdown","emme", 1.,0.01, 30.); RooRealVar ndown("ndown","enne", 0.93, 0.5, 15.); RooRealVar n2down("n2down","enne2", 0.75, 0.5, 15.); RooRealVar bbdown("bbdown","bibi",0.02, 0.00005, 20.0); RooRealVar Tdown("Tdown","tti",0.2,0.00000005,1.); RooRealVar bb2down("bb2down","bibi2",0.02, 0.0005, 10.0); RooRealVar fexpdown("fexpdown","f_exp",0.02, 0.0, 1.0); RooModifTsallis* rt3down = new RooModifTsallis("rt3down","rt3down",*ptoverm,mdown,ndown,n2down,bbdown,bb2down,Tdown,fexpdown); // ws->import(*rt3down); RooPlot *frame = ptoverm->frame(); char reducestr[300]; sprintf(reducestr,"ptoverm > %f && ptoverm < %f",ptoverm->getMin(),ptoverm->getMax()); rdh->plotOn(frame,DataError(RooAbsData::SumW2),Cut(reducestr)); static RooHist *hpull; float chi2 = 0.; if (changeParName == "") { sprintf(fileToSave,"text/paramsPTOverMCJLST_%s%d_%dTeV_Default.txt",nameSample[whichtype].c_str(),mass,LHCsqrts); ifstream is1(fileToSave); (RooArgSet(mup,nup,n2up,bbup,bb2up,fexpup,Tup)).readFromStream(is1,false); mdown.setVal(fabs(3*mup.getVal() - 2*m.getVal())); ndown.setVal(fabs(3*nup.getVal() - 2*n.getVal())); n2down.setVal(fabs(3*n2up.getVal() - 2*n2.getVal())); bbdown.setVal(fabs(3*bbup.getVal() - 2*bb.getVal())); Tdown.setVal(fabs(3*Tup.getVal() - 2*T.getVal())); bb2down.setVal(fabs(3*bb2up.getVal() - 2*bb2.getVal())); fexpdown.setVal(fabs(3*fexpup.getVal() - 2*fexp.getVal())); if (showErrorPDFs) { rt3->plotOn(frame,LineColor(kRed),LineStyle(kDashed),Normalization(rdh->sumEntries(),RooAbsReal::NumEvent)); hpull = frame->pullHist(); rt3up->plotOn(frame,LineColor(kBlue),Normalization(rdh->sumEntries(),RooAbsReal::NumEvent)); if (systString.find("Mela") == string::npos) rt3down->plotOn(frame,LineColor(kRed),LineStyle(kDashed),Normalization(rdh->sumEntries(),RooAbsReal::NumEvent)); } else { rt3->plotOn(frame,LineColor(kBlue),Normalization(rdh->sumEntries(),RooAbsReal::NumEvent)); hpull = frame->pullHist(); } } else { mup.setVal(m.getVal() + m.getError()); cout << "mup = " << mup.getVal() << endl; nup.setVal(n.getVal() + n.getError()); n2up.setVal(n2.getVal() + n2.getError()); bbup.setVal(bb.getVal() + bb.getError()); Tup.setVal(T.getVal() + T.getError()); bb2up.setVal(bb2.getVal() + bb2.getError()); fexpup.setVal(fexp.getVal() + fexp.getError()); mdown.setVal(m.getVal() - m.getError()); cout << "mdown = " << mdown.getVal() << endl; ndown.setVal(n.getVal() - n.getError()); n2down.setVal(n2.getVal() - n2.getError()); bbdown.setVal(bb.getVal() - bb.getError()); Tdown.setVal(T.getVal() - T.getError()); bb2down.setVal(bb2.getVal() - bb2.getError()); fexpdown.setVal(fexp.getVal() - fexp.getError()); rt3->plotOn(frame,LineColor(kBlue),Normalization(rdh->sumEntries(),RooAbsReal::NumEvent)); hpull = frame->pullHist(); if (showErrorPDFs) { rt3up->plotOn(frame,LineColor(kRed),LineStyle(kDashed),Normalization(rdh->sumEntries(),RooAbsReal::NumEvent)); rt3down->plotOn(frame,LineColor(kRed),LineStyle(kDashed),Normalization(rdh->sumEntries(),RooAbsReal::NumEvent)); } } double *ypulls = hpull->GetY(); unsigned int nBins = rdh->numEntries(); unsigned int nFullBins = 0; for (unsigned int i = 0; i < nBins; i++) { cout << "Pull of bin " << i << " = " << ypulls[i] << endl; if (fabs(ypulls[i]) < 5.0) chi2 += ypulls[i]*ypulls[i]; cout << "Partial chi2 = " << chi2 << endl; if (fabs(ypulls[i]) > 0.0001 && fabs(ypulls[i]) < 5.0) nFullBins++; } for (unsigned int i = 0; i < nBins; i++) { if (fabs(ypulls[i]) < 0.0001) ypulls[i] = 999.; hpull->SetPointError(i,0.,0.,0.,0.); } int nFitPar = fit->floatParsFinal().getSize() - 1; TCanvas can("can","The canvas",5.,5.,500.,900.); can.Divide(1,3); TLatex *t = new TLatex(); t->SetNDC(); t->SetTextAlign(22); t->SetTextSize(0.06); can.cd(1); gPad->SetBottomMargin(0.0); frame->Draw(); // gPad->SetLogy(); // Htest->Draw(); sprintf(fileToSave,"%s %d GeV at %d TeV",nameSample[whichtype].c_str(),mass,LHCsqrts); t->DrawLatex(0.6,0.8,fileToSave); can.cd(2); gPad->SetLogy(); gPad->SetTopMargin(0.0); frame->Draw(); RooPlot* pull = ptoverm->frame(Title("Pull Distribution")) ; pull->GetYaxis()->SetTitle("Pull"); /* pull->SetLabelSize(0.08,"XYZ"); pull->SetTitleSize(0.08,"XYZ"); pull->SetTitleOffset(0.6,"Y"); pull->SetTitleOffset(1.0,"X"); */ pull->addPlotable(hpull,"P") ; pull->SetMinimum(-6.); pull->SetMaximum(6.); can.cd(3); gPad->SetGridy(); pull->Draw(); sprintf(fileToSave,"#chi^{2}/n_{DoF} = %4.1f/%d",chi2,nFullBins - nFitPar); if (chi2 < 1000.) t->DrawLatex(0.80,0.86,fileToSave); // sprintf(fileToSave,"figs/fitPTOverMCJLST_%s%d_%dTeV_%s.pdf",nameSample[whichtype].c_str(),mass,LHCsqrts,systString.c_str()); sprintf(fileToSave,"newfigs/fitPTOverMCJLST_%s%d_%dTeV_%s.pdf",nameSample[whichtype].c_str(),mass,LHCsqrts,systString.c_str()); can.SaveAs(fileToSave); }
// internal routine to run the inverter HypoTestInverterResult * RooStats::HypoTestInvTool::RunInverter(RooWorkspace * w, const char * modelSBName, const char * modelBName, const char * dataName, int type, int testStatType, bool useCLs, int npoints, double poimin, double poimax, int ntoys, bool useNumberCounting, const char * nuisPriorName ){ std::cout << "Running HypoTestInverter on the workspace " << w->GetName() << std::endl; w->Print(); RooAbsData * data = w->data(dataName); if (!data) { Error("StandardHypoTestDemo","Not existing data %s",dataName); return 0; } else std::cout << "Using data set " << dataName << std::endl; if (mUseVectorStore) { RooAbsData::setDefaultStorageType(RooAbsData::Vector); data->convertToVectorStore() ; } // get models from WS // get the modelConfig out of the file ModelConfig* bModel = (ModelConfig*) w->obj(modelBName); ModelConfig* sbModel = (ModelConfig*) w->obj(modelSBName); if (!sbModel) { Error("StandardHypoTestDemo","Not existing ModelConfig %s",modelSBName); return 0; } // check the model if (!sbModel->GetPdf()) { Error("StandardHypoTestDemo","Model %s has no pdf ",modelSBName); return 0; } if (!sbModel->GetParametersOfInterest()) { Error("StandardHypoTestDemo","Model %s has no poi ",modelSBName); return 0; } if (!sbModel->GetObservables()) { Error("StandardHypoTestInvDemo","Model %s has no observables ",modelSBName); return 0; } if (!sbModel->GetSnapshot() ) { Info("StandardHypoTestInvDemo","Model %s has no snapshot - make one using model poi",modelSBName); sbModel->SetSnapshot( *sbModel->GetParametersOfInterest() ); } // case of no systematics // remove nuisance parameters from model if (noSystematics) { const RooArgSet * nuisPar = sbModel->GetNuisanceParameters(); if (nuisPar && nuisPar->getSize() > 0) { std::cout << "StandardHypoTestInvDemo" << " - Switch off all systematics by setting them constant to their initial values" << std::endl; RooStats::SetAllConstant(*nuisPar); } if (bModel) { const RooArgSet * bnuisPar = bModel->GetNuisanceParameters(); if (bnuisPar) RooStats::SetAllConstant(*bnuisPar); } } if (!bModel || bModel == sbModel) { Info("StandardHypoTestInvDemo","The background model %s does not exist",modelBName); Info("StandardHypoTestInvDemo","Copy it from ModelConfig %s and set POI to zero",modelSBName); bModel = (ModelConfig*) sbModel->Clone(); bModel->SetName(TString(modelSBName)+TString("_with_poi_0")); RooRealVar * var = dynamic_cast<RooRealVar*>(bModel->GetParametersOfInterest()->first()); if (!var) return 0; double oldval = var->getVal(); var->setVal(0); bModel->SetSnapshot( RooArgSet(*var) ); var->setVal(oldval); } else { if (!bModel->GetSnapshot() ) { Info("StandardHypoTestInvDemo","Model %s has no snapshot - make one using model poi and 0 values ",modelBName); RooRealVar * var = dynamic_cast<RooRealVar*>(bModel->GetParametersOfInterest()->first()); if (var) { double oldval = var->getVal(); var->setVal(0); bModel->SetSnapshot( RooArgSet(*var) ); var->setVal(oldval); } else { Error("StandardHypoTestInvDemo","Model %s has no valid poi",modelBName); return 0; } } } // check model has global observables when there are nuisance pdf // for the hybrid case the globobs are not needed if (type != 1 ) { bool hasNuisParam = (sbModel->GetNuisanceParameters() && sbModel->GetNuisanceParameters()->getSize() > 0); bool hasGlobalObs = (sbModel->GetGlobalObservables() && sbModel->GetGlobalObservables()->getSize() > 0); if (hasNuisParam && !hasGlobalObs ) { // try to see if model has nuisance parameters first RooAbsPdf * constrPdf = RooStats::MakeNuisancePdf(*sbModel,"nuisanceConstraintPdf_sbmodel"); if (constrPdf) { Warning("StandardHypoTestInvDemo","Model %s has nuisance parameters but no global observables associated",sbModel->GetName()); Warning("StandardHypoTestInvDemo","\tThe effect of the nuisance parameters will not be treated correctly "); } } } // run first a data fit const RooArgSet * poiSet = sbModel->GetParametersOfInterest(); RooRealVar *poi = (RooRealVar*)poiSet->first(); std::cout << "StandardHypoTestInvDemo : POI initial value: " << poi->GetName() << " = " << poi->getVal() << std::endl; // fit the data first (need to use constraint ) TStopwatch tw; bool doFit = initialFit; if (testStatType == 0 && initialFit == -1) doFit = false; // case of LEP test statistic if (type == 3 && initialFit == -1) doFit = false; // case of Asymptoticcalculator with nominal Asimov double poihat = 0; if (minimizerType.size()==0) minimizerType = ROOT::Math::MinimizerOptions::DefaultMinimizerType(); else ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerType.c_str()); Info("StandardHypoTestInvDemo","Using %s as minimizer for computing the test statistic", ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str() ); if (doFit) { // do the fit : By doing a fit the POI snapshot (for S+B) is set to the fit value // and the nuisance parameters nominal values will be set to the fit value. // This is relevant when using LEP test statistics Info( "StandardHypoTestInvDemo"," Doing a first fit to the observed data "); RooArgSet constrainParams; if (sbModel->GetNuisanceParameters() ) constrainParams.add(*sbModel->GetNuisanceParameters()); RooStats::RemoveConstantParameters(&constrainParams); tw.Start(); RooFitResult * fitres = sbModel->GetPdf()->fitTo(*data,InitialHesse(false), Hesse(false), Minimizer(minimizerType.c_str(),"Migrad"), Strategy(0), PrintLevel(mPrintLevel), Constrain(constrainParams), Save(true) ); if (fitres->status() != 0) { Warning("StandardHypoTestInvDemo","Fit to the model failed - try with strategy 1 and perform first an Hesse computation"); fitres = sbModel->GetPdf()->fitTo(*data,InitialHesse(true), Hesse(false),Minimizer(minimizerType.c_str(),"Migrad"), Strategy(1), PrintLevel(mPrintLevel+1), Constrain(constrainParams), Save(true) ); } if (fitres->status() != 0) Warning("StandardHypoTestInvDemo"," Fit still failed - continue anyway....."); poihat = poi->getVal(); std::cout << "StandardHypoTestInvDemo - Best Fit value : " << poi->GetName() << " = " << poihat << " +/- " << poi->getError() << std::endl; std::cout << "Time for fitting : "; tw.Print(); //save best fit value in the poi snapshot sbModel->SetSnapshot(*sbModel->GetParametersOfInterest()); std::cout << "StandardHypoTestInvo: snapshot of S+B Model " << sbModel->GetName() << " is set to the best fit value" << std::endl; } // print a message in case of LEP test statistics because it affects result by doing or not doing a fit if (testStatType == 0) { if (!doFit) Info("StandardHypoTestInvDemo","Using LEP test statistic - an initial fit is not done and the TS will use the nuisances at the model value"); else Info("StandardHypoTestInvDemo","Using LEP test statistic - an initial fit has been done and the TS will use the nuisances at the best fit value"); } // build test statistics and hypotest calculators for running the inverter SimpleLikelihoodRatioTestStat slrts(*sbModel->GetPdf(),*bModel->GetPdf()); // null parameters must includes snapshot of poi plus the nuisance values RooArgSet nullParams(*sbModel->GetSnapshot()); if (sbModel->GetNuisanceParameters()) nullParams.add(*sbModel->GetNuisanceParameters()); if (sbModel->GetSnapshot()) slrts.SetNullParameters(nullParams); RooArgSet altParams(*bModel->GetSnapshot()); if (bModel->GetNuisanceParameters()) altParams.add(*bModel->GetNuisanceParameters()); if (bModel->GetSnapshot()) slrts.SetAltParameters(altParams); // ratio of profile likelihood - need to pass snapshot for the alt RatioOfProfiledLikelihoodsTestStat ropl(*sbModel->GetPdf(), *bModel->GetPdf(), bModel->GetSnapshot()); ropl.SetSubtractMLE(false); if (testStatType == 11) ropl.SetSubtractMLE(true); ropl.SetPrintLevel(mPrintLevel); ropl.SetMinimizer(minimizerType.c_str()); ProfileLikelihoodTestStat profll(*sbModel->GetPdf()); if (testStatType == 3) profll.SetOneSided(true); if (testStatType == 4) profll.SetSigned(true); profll.SetMinimizer(minimizerType.c_str()); profll.SetPrintLevel(mPrintLevel); profll.SetReuseNLL(mOptimize); slrts.SetReuseNLL(mOptimize); ropl.SetReuseNLL(mOptimize); if (mOptimize) { profll.SetStrategy(0); ropl.SetStrategy(0); ROOT::Math::MinimizerOptions::SetDefaultStrategy(0); } if (mMaxPoi > 0) poi->setMax(mMaxPoi); // increase limit MaxLikelihoodEstimateTestStat maxll(*sbModel->GetPdf(),*poi); NumEventsTestStat nevtts; AsymptoticCalculator::SetPrintLevel(mPrintLevel); // create the HypoTest calculator class HypoTestCalculatorGeneric * hc = 0; if (type == 0) hc = new FrequentistCalculator(*data, *bModel, *sbModel); else if (type == 1) hc = new HybridCalculator(*data, *bModel, *sbModel); // else if (type == 2 ) hc = new AsymptoticCalculator(*data, *bModel, *sbModel, false, mAsimovBins); // else if (type == 3 ) hc = new AsymptoticCalculator(*data, *bModel, *sbModel, true, mAsimovBins); // for using Asimov data generated with nominal values else if (type == 2 ) hc = new AsymptoticCalculator(*data, *bModel, *sbModel, false ); else if (type == 3 ) hc = new AsymptoticCalculator(*data, *bModel, *sbModel, true ); // for using Asimov data generated with nominal values else { Error("StandardHypoTestInvDemo","Invalid - calculator type = %d supported values are only :\n\t\t\t 0 (Frequentist) , 1 (Hybrid) , 2 (Asymptotic) ",type); return 0; } // set the test statistic TestStatistic * testStat = 0; if (testStatType == 0) testStat = &slrts; if (testStatType == 1 || testStatType == 11) testStat = &ropl; if (testStatType == 2 || testStatType == 3 || testStatType == 4) testStat = &profll; if (testStatType == 5) testStat = &maxll; if (testStatType == 6) testStat = &nevtts; if (testStat == 0) { Error("StandardHypoTestInvDemo","Invalid - test statistic type = %d supported values are only :\n\t\t\t 0 (SLR) , 1 (Tevatron) , 2 (PLR), 3 (PLR1), 4(MLE)",testStatType); return 0; } ToyMCSampler *toymcs = (ToyMCSampler*)hc->GetTestStatSampler(); if (toymcs && (type == 0 || type == 1) ) { // look if pdf is number counting or extended if (sbModel->GetPdf()->canBeExtended() ) { if (useNumberCounting) Warning("StandardHypoTestInvDemo","Pdf is extended: but number counting flag is set: ignore it "); } else { // for not extended pdf if (!useNumberCounting ) { int nEvents = data->numEntries(); Info("StandardHypoTestInvDemo","Pdf is not extended: number of events to generate taken from observed data set is %d",nEvents); toymcs->SetNEventsPerToy(nEvents); } else { Info("StandardHypoTestInvDemo","using a number counting pdf"); toymcs->SetNEventsPerToy(1); } } toymcs->SetTestStatistic(testStat); if (data->isWeighted() && !mGenerateBinned) { Info("StandardHypoTestInvDemo","Data set is weighted, nentries = %d and sum of weights = %8.1f but toy generation is unbinned - it would be faster to set mGenerateBinned to true\n",data->numEntries(), data->sumEntries()); } toymcs->SetGenerateBinned(mGenerateBinned); toymcs->SetUseMultiGen(mOptimize); if (mGenerateBinned && sbModel->GetObservables()->getSize() > 2) { Warning("StandardHypoTestInvDemo","generate binned is activated but the number of ovservable is %d. Too much memory could be needed for allocating all the bins",sbModel->GetObservables()->getSize() ); } // set the random seed if needed if (mRandomSeed >= 0) RooRandom::randomGenerator()->SetSeed(mRandomSeed); } // specify if need to re-use same toys if (reuseAltToys) { hc->UseSameAltToys(); } if (type == 1) { HybridCalculator *hhc = dynamic_cast<HybridCalculator*> (hc); assert(hhc); hhc->SetToys(ntoys,ntoys/mNToysRatio); // can use less ntoys for b hypothesis // remove global observables from ModelConfig (this is probably not needed anymore in 5.32) bModel->SetGlobalObservables(RooArgSet() ); sbModel->SetGlobalObservables(RooArgSet() ); // check for nuisance prior pdf in case of nuisance parameters if (bModel->GetNuisanceParameters() || sbModel->GetNuisanceParameters() ) { // fix for using multigen (does not work in this case) toymcs->SetUseMultiGen(false); ToyMCSampler::SetAlwaysUseMultiGen(false); RooAbsPdf * nuisPdf = 0; if (nuisPriorName) nuisPdf = w->pdf(nuisPriorName); // use prior defined first in bModel (then in SbModel) if (!nuisPdf) { Info("StandardHypoTestInvDemo","No nuisance pdf given for the HybridCalculator - try to deduce pdf from the model"); if (bModel->GetPdf() && bModel->GetObservables() ) nuisPdf = RooStats::MakeNuisancePdf(*bModel,"nuisancePdf_bmodel"); else nuisPdf = RooStats::MakeNuisancePdf(*sbModel,"nuisancePdf_sbmodel"); } if (!nuisPdf ) { if (bModel->GetPriorPdf()) { nuisPdf = bModel->GetPriorPdf(); Info("StandardHypoTestInvDemo","No nuisance pdf given - try to use %s that is defined as a prior pdf in the B model",nuisPdf->GetName()); } else { Error("StandardHypoTestInvDemo","Cannnot run Hybrid calculator because no prior on the nuisance parameter is specified or can be derived"); return 0; } } assert(nuisPdf); Info("StandardHypoTestInvDemo","Using as nuisance Pdf ... " ); nuisPdf->Print(); const RooArgSet * nuisParams = (bModel->GetNuisanceParameters() ) ? bModel->GetNuisanceParameters() : sbModel->GetNuisanceParameters(); RooArgSet * np = nuisPdf->getObservables(*nuisParams); if (np->getSize() == 0) { Warning("StandardHypoTestInvDemo","Prior nuisance does not depend on nuisance parameters. They will be smeared in their full range"); } delete np; hhc->ForcePriorNuisanceAlt(*nuisPdf); hhc->ForcePriorNuisanceNull(*nuisPdf); } } else if (type == 2 || type == 3) { if (testStatType == 3) ((AsymptoticCalculator*) hc)->SetOneSided(true); if (testStatType != 2 && testStatType != 3) Warning("StandardHypoTestInvDemo","Only the PL test statistic can be used with AsymptoticCalculator - use by default a two-sided PL"); } else if (type == 0 || type == 1) ((FrequentistCalculator*) hc)->SetToys(ntoys,ntoys/mNToysRatio); // Get the result RooMsgService::instance().getStream(1).removeTopic(RooFit::NumIntegration); HypoTestInverter calc(*hc); calc.SetConfidenceLevel(0.95); calc.UseCLs(useCLs); calc.SetVerbose(true); // can speed up using proof-lite if (mUseProof && mNWorkers > 1) { ProofConfig pc(*w, mNWorkers, "", kFALSE); toymcs->SetProofConfig(&pc); // enable proof } if (npoints > 0) { if (poimin > poimax) { // if no min/max given scan between MLE and +4 sigma poimin = int(poihat); poimax = int(poihat + 4 * poi->getError()); } std::cout << "Doing a fixed scan in interval : " << poimin << " , " << poimax << std::endl; calc.SetFixedScan(npoints,poimin,poimax); } else { //poi->setMax(10*int( (poihat+ 10 *poi->getError() )/10 ) ); std::cout << "Doing an automatic scan in interval : " << poi->getMin() << " , " << poi->getMax() << std::endl; } tw.Start(); HypoTestInverterResult * r = calc.GetInterval(); std::cout << "Time to perform limit scan \n"; tw.Print(); if (mRebuild) { calc.SetCloseProof(1); tw.Start(); SamplingDistribution * limDist = calc.GetUpperLimitDistribution(true,mNToyToRebuild); std::cout << "Time to rebuild distributions " << std::endl; tw.Print(); if (limDist) { std::cout << "expected up limit " << limDist->InverseCDF(0.5) << " +/- " << limDist->InverseCDF(0.16) << " " << limDist->InverseCDF(0.84) << "\n"; //update r to a new updated result object containing the rebuilt expected p-values distributions // (it will not recompute the expected limit) if (r) delete r; // need to delete previous object since GetInterval will return a cloned copy r = calc.GetInterval(); } else std::cout << "ERROR : failed to re-build distributions " << std::endl; } return r; }
int DiagnosisMacro(int Nbins = 10, int Nsigma = 10, int CPUused = 1, TString Filename = "FIT_DATA_Psi2SJpsi_PPPrompt_Bkg_SecondOrderChebychev_pt65300_rap016_cent0200_262620_263757.root", TString Outputdir = "./") //Nbins: Number of points for which to calculate profile likelihood. Time required is about (1/CPU) minutes per point per parameter. 0 means do plain likelihood only //Nsigma: The range in which the scan is performed (value-Nsigma*sigma, value+Nsigma*sigma) //CPUused: anything larger than 1 causes weird fit results on my laptop, runs fine on lxplus with more (16) { // R e a d w o r k s p a c e f r o m f i l e // ----------------------------------------------- // Open input file with workspace //Filename = "FIT_DATA_Psi2SJpsi_PP_Jpsi_DoubleCrystalBall_Psi2S_DoubleCrystalBall_Bkg_Chebychev2_pt6590_rap016_cent0200.root"; //Filename = "FIT_DATA_Psi2SJpsi_PbPb_Jpsi_DoubleCrystalBall_Psi2S_DoubleCrystalBall_Bkg_Chebychev1_pt6590_rap016_cent0200.root"; TFile *f = new TFile(Filename); // Retrieve workspace from file RooWorkspace* w = (RooWorkspace*)f->Get("workspace"); // Retrieve x,model and data from workspace RooRealVar* x = w->var("invMass"); RooAbsPdf* model = w->pdf("simPdf_syst"); if (model == 0) { model = w->pdf("simPdf"); } if (model == 0) { model = w->pdf("pdfMASS_Tot_PP"); } if (model == 0) { model = w->pdf("pdfMASS_Tot_PbPb"); } if (model == 0) { cout << "[ERROR] pdf failed to load from the workspace" << endl; return false; } RooAbsData* data = w->data("dOS_DATA"); if (data == 0) { data = w->data("dOS_DATA_PP"); } if (data == 0) { data = w->data("dOS_DATA_PbPb"); } if (data == 0) { cout << "[ERROR] data failed to load from the workspace" << endl; return false; } // Print structure of composite p.d.f. model->Print("t"); /* // P l o t m o d e l // --------------------------------------------------------- // Plot data and PDF overlaid RooPlot* xframe = x->frame(Title("J/psi Model and Data")); data->plotOn(xframe); model->plotOn(xframe); // Draw the frame on the canvas TCanvas* c2 = new TCanvas("PlotModel", "PlotModel", 1000, 1000); gPad->SetLeftMargin(0.15); xframe->GetYaxis()->SetTitleOffset(2.0); xframe->Draw();//*/ ///// Check parameters RooArgSet* paramSet1 = model->getDependents(data); paramSet1->Print("v"); // Just check RooArgSet* paramSet2 = model->getParameters(data); paramSet2->Print("v"); int Nparams = paramSet2->getSize(); cout << "Number of parameters: " << Nparams<<endl<<endl; // C o n s t r u c t p l a i n l i k e l i h o o d // --------------------------------------------------- // Construct unbinned likelihood RooAbsReal* nll = model->createNLL(*data, NumCPU(CPUused)); // Minimize likelihood w.r.t all parameters before making plots RooMinuit(*nll).migrad(); ////////////////////////////////////////////////////// /////////////////// L O O P O V E R P A R A M E T E R S ///////////////////////////////////////////////////// /// Set up loop over parameters TString ParamName; double ParamValue; double ParamError; double ParamLimitLow; double ParamLimitHigh; double FitRangeLow; double FitRangeHigh; RooRealVar* vParam; int counter = 0; // Loop start TIterator* iter = paramSet2->createIterator(); TObject* var = iter->Next(); while (var != 0) { counter++; ParamName = var->GetName(); vParam = w->var(ParamName); ParamValue = vParam->getVal(); ParamError = vParam->getError(); ParamLimitLow = vParam->getMin(); ParamLimitHigh = vParam->getMax(); cout << ParamName << " has value " << ParamValue << " with error: " << ParamError << " and limits: " << ParamLimitLow << " to " << ParamLimitHigh << endl << endl; if (ParamError == 0) { //Skipping fixed parameters cout << "Parameter was fixed, skipping its fitting" << endl; cout << endl << "DONE WITH " << counter << " PARAMETER OUT OF " << Nparams << endl << endl; var = iter->Next(); continue; } // determining fit range: Nsigma sigma on each side unless it would be outside of parameter limits if ((ParamValue - Nsigma * ParamError) > ParamLimitLow) { FitRangeLow = (ParamValue - Nsigma * ParamError); } else { FitRangeLow = ParamLimitLow; } if ((ParamValue + Nsigma * ParamError) < ParamLimitHigh) { FitRangeHigh = (ParamValue + Nsigma * ParamError); } else { FitRangeHigh = ParamLimitHigh; } // P l o t p l a i n l i k e l i h o o d a n d C o n s t r u c t p r o f i l e l i k e l i h o o d // --------------------------------------------------- RooPlot* frame1; RooAbsReal* pll=NULL; if (Nbins != 0) { frame1 = vParam->frame(Bins(Nbins), Range(FitRangeLow, FitRangeHigh), Title(TString::Format("LL and profileLL in %s", ParamName.Data()))); nll->plotOn(frame1, ShiftToZero()); pll = nll->createProfile(*vParam); // Plot the profile likelihood pll->plotOn(frame1, LineColor(kRed), RooFit::Precision(-1)); } else { //Skip profile likelihood frame1 = vParam->frame(Bins(10), Range(FitRangeLow, FitRangeHigh), Title(TString::Format("LL and profileLL in %s", ParamName.Data()))); nll->plotOn(frame1, ShiftToZero()); } // D r a w a n d s a v e p l o t s // ----------------------------------------------------------------------- // Adjust frame maximum for visual clarity frame1->SetMinimum(0); frame1->SetMaximum(20); TCanvas* c = new TCanvas("CLikelihoodResult", "CLikelihoodResult", 800, 600); c->cd(1); gPad->SetLeftMargin(0.15); frame1->GetYaxis()->SetTitleOffset(1.4); frame1->Draw(); TLegend* leg = new TLegend(0.70, 0.70, 0.95, 0.88, ""); leg->SetFillColor(kWhite); leg->SetBorderSize(0); leg->SetTextSize(0.035); TLegendEntry *le1 = leg->AddEntry(nll, "Plain likelihood", "l"); le1->SetLineColor(kBlue); le1->SetLineWidth(3); TLegendEntry *le2 = leg->AddEntry(pll, "Profile likelihood", "l"); le2->SetLineColor(kRed); le2->SetLineWidth(3); leg->Draw("same"); //Save plot TString StrippedName = TString(Filename(Filename.Last('/')+1,Filename.Length())); StrippedName = StrippedName.ReplaceAll(".root",""); cout << StrippedName << endl; gSystem->mkdir(Form("%s/root/%s", Outputdir.Data(), StrippedName.Data()), kTRUE); c->SaveAs(Form("%s/root/%s/Likelihood_scan_%s.root", Outputdir.Data(), StrippedName.Data(), ParamName.Data())); gSystem->mkdir(Form("%s/pdf/%s", Outputdir.Data(), StrippedName.Data()), kTRUE); c->SaveAs(Form("%s/pdf/%s/Likelihood_scan_%s.pdf", Outputdir.Data(), StrippedName.Data(), ParamName.Data())); gSystem->mkdir(Form("%s/png/%s", Outputdir.Data(), StrippedName.Data()), kTRUE); c->SaveAs(Form("%s/png/%s/Likelihood_scan_%s.png", Outputdir.Data(), StrippedName.Data(), ParamName.Data())); delete c; delete frame1; if (pll) delete pll; cout << endl << "DONE WITH " << counter << " PARAMETER OUT OF " << Nparams << endl << endl; //if (counter == 2){ break; } //Exit - for testing var = iter->Next(); } // End of the loop return true; }
void test_counting_experiment() { ////////////////////// MODEL BUILDING ///////////////////////////////// /////////////////////////////////////////////////////////////////////////// /* N_s = N_tot_theory(Mass,Xsec) * Acceptance_SR * Eff_AmBe_bin_i * mu N_b = N_Co_SR_bin_i * Norm_factor Xesec: considered 10^-40 cm^2 Norm_factor = N_Data_CR / N_Co_CR --> assuming no difference between Co and Data in CR and SR. N_tot_theory(Mass,Xsec): for 225 livedays, 45kg and considering Xsec. It is a constant, no uncertainty at the moment. ---Costraint Signal nuissance parameter = Acceptance_SR, Eff_AmBe_bin_i Gauss(Acceptance_SR_obs | Acceptance_SR, err.) Poisson(S0_i | S_tot_SR * Eff_AmBe_bin_i) ---Costraint Bkg nuissance parameter = N_Co_SR_bin_i, Norm_factor Gauss(Norm_factor_obs | Norm_factor, err) Poisson(B0_i | N_Co_SR_bin_i) ---- WARNING:: convergence problems: mu_hat should always be >> 1, too small values have problem in finding minimum because mu is set >0. ---> Try to fix Xsec in order to have mu_hat ~ 10 */ RooWorkspace w("w"); //gROOT->ProcessLine(".L retrieve_input_from_histo_NoSys.C+"); gROOT->ProcessLine(".L retrieve_input_from_histo.C+"); retrieve_input_from_histo(w); // Building the model ModelConfig mc("ModelConfig",&w); mc.SetPdf(*w.pdf("model")); mc.SetParametersOfInterest(*w.var("mu")); // Setting nuissance parameter mc.SetNuisanceParameters(*w.set("nuissance_parameter")); // need now to set the global observable mc.SetGlobalObservables(*w.set("g_observables")); mc.SetObservables(*w.set("observables")); // this is needed for the hypothesis tests mc.SetSnapshot(*w.var("mu")); // make data set with the number of observed events RooDataSet data("data","", *w.set("observables")); data.add(*w.set("observables")); // import data set in workspace and save it in a file w.import(data); // import model in the workspace w.import(mc); w.writeToFile("CountingModel.root", true); w.Print(); data.Print(); /* cout << w.var("S_i")->getValV() << endl;//<< " " << w.var("S_i_exp")->getValV() << endl; /////////////////////////////////////////////////////////////////////// ProfileLikelihoodCalculator pl(data,mc); pl.SetConfidenceLevel(0.95); LikelihoodInterval* interval = pl.GetInterval(); // find the iterval on the first Parameter of Interest RooRealVar* firstPOI = (RooRealVar*) mc.GetParametersOfInterest()->first(); double lowerLimit = interval->LowerLimit(*firstPOI); double upperLimit = interval->UpperLimit(*firstPOI); cout << "\n95% interval on " <<firstPOI->GetName()<<" is : ["<< lowerLimit << ", "<< upperLimit <<"] "<<endl; LikelihoodIntervalPlot * plot = new LikelihoodIntervalPlot(interval); // plot->SetRange(0,50); // possible eventually to change ranges //plot->SetNPoints(50); // do not use too many points, it could become very slow for some models plot->Draw(""); // use option TF1 if too slow (plot.Draw("tf1") */ ////////////////////////// hypo test // get the modelConfig (S+B) out of the file // and create the B model from the S+B model ModelConfig * sbModel = (ModelConfig*) mc.Clone(); sbModel->SetName("S+B Model"); RooRealVar* poi = (RooRealVar*) sbModel->GetParametersOfInterest()->first(); poi->setVal(1); // set POI snapshot in S+B model for expected significance sbModel->SetSnapshot(*poi); ModelConfig * bModel = (ModelConfig*) mc.Clone(); bModel->SetName("B Model"); RooRealVar* poi2 = (RooRealVar*) bModel->GetParametersOfInterest()->first(); poi2->setVal(0); bModel->SetSnapshot( *poi2 ); //------------------Limit calculation for N_th event expected = 10 AsymptoticCalculator ac(data, *bModel, *sbModel); //ac.SetOneSidedDiscovery(true); // for one-side discovery test // ac.SetOneSided(true); // for one-side tests (limits) ac.SetQTilde(true); ac.SetPrintLevel(2); // to suppress print level // create hypotest inverter // passing the desired calculator HypoTestInverter *calc = new HypoTestInverter(ac); // for asymptotic //HypoTestInverter calc(fc); // for frequentist calc->SetConfidenceLevel(0.90); //calc->UseCLs(false); calc->UseCLs(true); int npoints = 500; // number of points to scan //int npoints = 1000; // number of points to scan default 1000 // min and max (better to choose smaller intervals) double poimin = poi->getMin(); double poimax = poi->getMax(); //poimin = 0; poimax=10; std::cout << "Doing a fixed scan in interval : " << poimin << " , " << poimax << std::endl; calc->SetFixedScan(npoints,poimin,poimax); calc->SetVerbose(2); HypoTestInverterResult * r = calc->GetInterval(); double upperLimit = r->UpperLimit(); std::cout << "The computed Expected upper limit is: " << r->GetExpectedUpperLimit(0) << std::endl; //------------ Getting the interval as function of m --------------// /* ifstream in; in.open("integral_mass.dat"); vector <double> masses_v; vector <double> observed_v; vector <double> expected_v; vector <double> expected_gaud_v; vector <double> expected_S1_up_v; vector <double> expected_S1_dw_v; vector <double> expected_S2_up_v; vector <double> expected_S2_dw_v; double mass_itr =0.; double Nev_exp_th_itr =0.; double xsec_modifier = 10.; double N_tot_theory = w.var("N_tot_theory")->getValV(); while(mass_itr <1000.){ in >> mass_itr; in >> Nev_exp_th_itr; xsec_modifier = Nev_exp_th_itr * 225.009 * 34.; //225.009 livedays and 34 kg and 10^-40 cm2 Xsec. masses_v.push_back(mass_itr); observed_v.push_back( 1.e-40 * N_tot_theory / xsec_modifier * upperLimit ); expected_v.push_back( 1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(0) ); expected_gaud_v.push_back(7e-38 * 1.37590955945e-05 / Nev_exp_th_itr ); expected_S1_up_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(1)); expected_S2_up_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(2)); expected_S2_dw_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(-2)); expected_S1_dw_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(-1)); cout << "Expected median limit for mass " << mass_itr << " GeV = " << 1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(0) << " cm^2 " << endl; // observed_v.push_back( w.var("Xsec")->getValV() * w.var("K_m")->getValV()* upperLimit ); // expected_v.push_back( w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(0) ); // expected_S1_up_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(1)); // expected_S2_up_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(2)); // expected_S2_dw_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(-2)); // expected_S1_dw_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(-1)); } in.close(); const int n = masses_v.size(); double xe[n]; double mA[n]; double observed[n]; double expected[n]; double expected_gaudenz[n]; double exSigma1_l[n]; double exSigma1_u[n]; double exSigma2_l[n]; double exSigma2_u[n]; for(int k=0; k< n; k++){ mA[k] = masses_v[k]; observed[k] = observed_v[k]; expected[k] = expected_v[k]; expected_gaudenz[k] = expected_gaud_v[k]; exSigma1_l[k] =expected_v[k] - expected_S1_dw_v[k] ; exSigma1_u[k] = expected_S1_up_v[k] - expected_v[k]; exSigma2_l[k] = expected_v[k] - expected_S2_dw_v[k]; exSigma2_u[k] = expected_S2_up_v[k] - expected_v[k] ; } TGraphErrors *obs_limits = new TGraphErrors(n, mA, observed); TGraphErrors *Exp_limits = new TGraphErrors(n, mA, expected ); TGraphAsymmErrors *Exp_limitsS1 = new TGraphAsymmErrors(n, mA, expected ,xe, xe, exSigma1_l, exSigma1_u ); TGraphAsymmErrors *Exp_limitsS2 = new TGraphAsymmErrors(n, mA, expected ,xe, xe, exSigma2_l, exSigma2_u); TGraphErrors *Exp_limits_gaudenz = new TGraphErrors( n, mA, expected_gaudenz); //double expected_xmass[15] = {8e-36,7e-37, 2e-37, 1e-37, 8e-38, 6e-38, 5.5e-38, 5e-38, 4.3e-38, 5e-38, 6e-38, 7e-38, 9e-38, 1.2e-37, 1.5e-37}; //double m_xmass[15] = { 20, 30., 40., 50., 60., 70., 80., 90., 100., 200., 300., 400, 500.,700., 1000.}; TGraphErrors *Exp_limits_xmass = new TGraphErrors(16); Exp_limits_xmass->SetPoint(0,20,8e-36); Exp_limits_xmass->SetPointError(0,0,0); Exp_limits_xmass->SetPoint(1,29.8071,7.162923e-37); Exp_limits_xmass->SetPointError(1,0,0); Exp_limits_xmass->SetPoint(2,39.90202,2.027528e-37); Exp_limits_xmass->SetPointError(2,0,0); Exp_limits_xmass->SetPoint(3,53.41583,9.91722e-38); Exp_limits_xmass->SetPointError(3,0,0); Exp_limits_xmass->SetPoint(4,62.16429,7.461589e-38); Exp_limits_xmass->SetPointError(4,0,0); Exp_limits_xmass->SetPoint(5,69.85718,6.3506e-38); Exp_limits_xmass->SetPointError(5,0,0); Exp_limits_xmass->SetPoint(6,83.21777,5.354015e-38); Exp_limits_xmass->SetPointError(6,0,0); Exp_limits_xmass->SetPoint(7,90,5e-38); Exp_limits_xmass->SetPointError(7,0,0); Exp_limits_xmass->SetPoint(8,105.0887,4.600252e-38); Exp_limits_xmass->SetPointError(8,0,0); Exp_limits_xmass->SetPoint(9,200,5e-38); Exp_limits_xmass->SetPointError(9,0,0); Exp_limits_xmass->SetPoint(10,300,6e-38); Exp_limits_xmass->SetPointError(10,0,0); Exp_limits_xmass->SetPoint(11,388.2045,7.252295e-38); Exp_limits_xmass->SetPointError(11,0,0); Exp_limits_xmass->SetPoint(12,590.8438,9.823615e-38); Exp_limits_xmass->SetPointError(12,0,0); Exp_limits_xmass->SetPoint(13,746.1269,1.210266e-37); Exp_limits_xmass->SetPointError(13,0,0); Exp_limits_xmass->SetPoint(14,1000,1.5e-37); Exp_limits_xmass->SetPointError(14,0,0); Exp_limits_xmass->SetPoint(15,4244.204,4.354065e-37); Exp_limits_xmass->SetPointError(15,0,0); TCanvas *c1 = new TCanvas("limits", "limit", 600, 600); Exp_limitsS1->SetFillColor(3); Exp_limitsS1->SetLineColor(3); Exp_limitsS1->SetMarkerColor(3); Exp_limitsS1->SetMarkerSize(0); Exp_limitsS2->SetFillColor(5); Exp_limitsS2->SetLineColor(5); Exp_limitsS2->SetMarkerColor(5); Exp_limitsS2->SetMarkerSize(0); obs_limits->SetFillColor(0); obs_limits->SetLineWidth(3); obs_limits->SetMarkerSize(0); Exp_limits->SetFillColor(0); Exp_limits->SetMarkerSize(0); Exp_limits->SetLineStyle(7); Exp_limits->SetLineWidth(3); Exp_limits_gaudenz->SetFillColor(0); Exp_limits_gaudenz->SetMarkerSize(0); Exp_limits_gaudenz->SetLineWidth(3); Exp_limits_gaudenz->SetLineColor(4); Exp_limits_xmass->SetFillColor(0); Exp_limits_xmass->SetMarkerSize(0); Exp_limits_xmass->SetLineWidth(3); Exp_limits_xmass->SetLineColor(2); //Exp_limitsS2->GetYaxis()->SetTitle("#sigma#timesBR( #phi #rightarrow #tau#tau ) [pb]"); Exp_limitsS2->GetYaxis()->SetTitle("#sigma"); Exp_limitsS2->GetXaxis()->SetTitle("M [GeV]"); Exp_limitsS2->GetXaxis()->SetLimits(9.,1000.); Exp_limitsS2->GetYaxis()->SetRangeUser(1E-38,1E-30); Exp_limits->GetXaxis()->SetLimits(9.,1000.); Exp_limits->GetYaxis()->SetRangeUser(1E-38,1E-30); Exp_limitsS2->Draw("Al3"); Exp_limitsS1->Draw("sameL3"); Exp_limits->Draw("PL"); Exp_limits_gaudenz->Draw("PC"); Exp_limits_xmass->Draw("PC"); //obs_limits->Draw("PL"); TLegend* lego = new TLegend(0.2,0.9,0.5,0.7); lego->SetTextSize(0.033); lego->SetFillColor(0); lego->SetBorderSize(0); lego->AddEntry(obs_limits,"Observed 90\% CLs limit"); lego->AddEntry(Exp_limits_gaudenz, "Expected 90\% Gaudenz"); lego->AddEntry(Exp_limits_xmass, "Expected 90\% XMASS"); lego->AddEntry(Exp_limits, "Expected 90\% CLs limit"); lego->AddEntry(Exp_limitsS1,"1 #sigma","f"); lego->AddEntry(Exp_limitsS2,"2 #sigma","f"); lego->Draw(); gPad->SetLogy(); gPad->SetLogx(); gPad->RedrawAxis("g"); myText(0.4,0.86,2,"Test"); */ // now use the profile inspector ProfileInspector p; TList* list = p.GetListOfProfilePlots(data,&mc); // now make plots TCanvas* c1 = new TCanvas("c1","ProfileInspectorDemo",800,200); if(list->GetSize()>4){ double n = list->GetSize(); int nx = (int)sqrt(n) ; int ny = TMath::CeilNint(n/nx); nx = TMath::CeilNint( sqrt(n) ); c1->Divide(ny,nx); } else c1->Divide(list->GetSize()); for(int i=0; i<list->GetSize(); ++i){ c1->cd(i+1); list->At(i)->Draw("al"); } cout << endl; /* // plot now the result of the scan HypoTestInverterPlot *plot = new HypoTestInverterPlot("HTI_Result_Plot","HypoTest Scan Result",r); // plot in a new canvas with style TCanvas * c1 = new TCanvas("HypoTestInverter Scan"); c1->SetLogy(false); plot->Draw("2CL"); // plot also CLb and CLs+b //plot->Draw("OBS"); // plot only observed p-value */ // plot also in a new canvas the test statistics distributions // plot test statistics distributions for the two hypothesis /* // when distribution is generated (case of FrequentistCalculators) const int n = r->ArraySize(); if (n> 0 && r->GetResult(0)->GetNullDistribution() ) { TCanvas * c2 = new TCanvas("Test Statistic Distributions","",2); if (n > 1) { int ny = TMath::CeilNint( sqrt(n) ); int nx = TMath::CeilNint(double(n)/ny); c2->Divide( nx,ny); } for (int i=0; i<n; i++) { if (n > 1) c2->cd(i+1); SamplingDistPlot * pl = plot->MakeTestStatPlot(i); pl->SetLogYaxis(true); pl->Draw(); } } */ }
/// /// Perform the 1d Prob scan. /// Saves chi2 values and the prob-Scan p-values in a root tree /// For the datasets stuff, we do not yet have a MethodDatasetsProbScan class, so we do it all in /// MethodDatasetsProbScan /// \param nRun Part of the root tree file name to facilitate parallel production. /// int MethodDatasetsProbScan::scan1d(bool fast, bool reverse) { if (fast) return 0; // tmp if ( arg->debug ) cout << "MethodDatasetsProbScan::scan1d() : starting ... " << endl; // Set limit to all parameters. this->loadParameterLimits(); /// Default is "free", if not changed by cmd-line parameter // Define scan parameter and scan range. RooRealVar *parameterToScan = w->var(scanVar1); float parameterToScan_min = hCL->GetXaxis()->GetXmin(); float parameterToScan_max = hCL->GetXaxis()->GetXmax(); // do a free fit RooFitResult *result = this->loadAndFit(this->pdf); // fit on data assert(result); RooSlimFitResult *slimresult = new RooSlimFitResult(result,true); slimresult->setConfirmed(true); solutions.push_back(slimresult); double freeDataFitValue = w->var(scanVar1)->getVal(); // Define outputfile system("mkdir -p root"); TString probResName = Form("root/scan1dDatasetsProb_" + this->pdf->getName() + "_%ip" + "_" + scanVar1 + ".root", arg->npoints1d); TFile* outputFile = new TFile(probResName, "RECREATE"); // Set up toy root tree this->probScanTree = new ToyTree(this->pdf, arg); this->probScanTree->init(); this->probScanTree->nrun = -999; //\todo: why does this branch even exist in the output tree of the prob scan? // Save parameter values that were active at function // call. We'll reset them at the end to be transparent // to the outside. RooDataSet* parsFunctionCall = new RooDataSet("parsFunctionCall", "parsFunctionCall", *w->set(pdf->getParName())); parsFunctionCall->add(*w->set(pdf->getParName())); // start scan cout << "MethodDatasetsProbScan::scan1d_prob() : starting ... with " << nPoints1d << " scanpoints..." << endl; ProgressBar progressBar(arg, nPoints1d); for ( int i = 0; i < nPoints1d; i++ ) { progressBar.progress(); // scanpoint is calculated using min, max, which are the hCL x-Axis limits set in this->initScan() // this uses the "scan" range, as expected // don't add half the bin size. try to solve this within plotting method float scanpoint = parameterToScan_min + (parameterToScan_max - parameterToScan_min) * (double)i / ((double)nPoints1d - 1); if (arg->debug) cout << "DEBUG in MethodDatasetsProbScan::scan1d_prob() " << scanpoint << " " << parameterToScan_min << " " << parameterToScan_max << endl; this->probScanTree->scanpoint = scanpoint; if (arg->debug) cout << "DEBUG in MethodDatasetsProbScan::scan1d_prob() - scanpoint in step " << i << " : " << scanpoint << endl; // don't scan in unphysical region // by default this means checking against "free" range if ( scanpoint < parameterToScan->getMin() || scanpoint > parameterToScan->getMax() + 2e-13 ) { cout << "it seems we are scanning in an unphysical region: " << scanpoint << " < " << parameterToScan->getMin() << " or " << scanpoint << " > " << parameterToScan->getMax() + 2e-13 << endl; exit(EXIT_FAILURE); } // FIT TO REAL DATA WITH FIXED HYPOTHESIS(=SCANPOINT). // THIS GIVES THE NUMERATOR FOR THE PROFILE LIKELIHOOD AT THE GIVEN HYPOTHESIS // THE RESULTING NUISANCE PARAMETERS TOGETHER WITH THE GIVEN HYPOTHESIS ARE ALSO // USED WHEN SIMULATING THE TOY DATA FOR THE FELDMAN-COUSINS METHOD FOR THIS HYPOTHESIS(=SCANPOINT) // Here the scanvar has to be fixed -> this is done once per scanpoint // and provides the scanner with the DeltaChi2 for the data as reference // additionally the nuisances are set to the resulting fit values parameterToScan->setVal(scanpoint); parameterToScan->setConstant(true); RooFitResult *result = this->loadAndFit(this->pdf); // fit on data assert(result); if (arg->debug) { cout << "DEBUG in MethodDatasetsProbScan::scan1d_prob() - minNll data scan at scan point " << scanpoint << " : " << 2 * result->minNll() << ": "<< 2 * pdf->getMinNll() << endl; } this->probScanTree->statusScanData = result->status(); // set chi2 of fixed fit: scan fit on data // CAVEAT: chi2min from fitresult gives incompatible results to chi2min from pdf // this->probScanTree->chi2min = 2 * result->minNll(); this->probScanTree->chi2min = 2 * pdf->getMinNll(); this->probScanTree->covQualScanData = result->covQual(); this->probScanTree->scanbest = freeDataFitValue; // After doing the fit with the parameter of interest constrained to the scanpoint, // we are now saving the fit values of the nuisance parameters. These values will be // used to generate toys according to the PLUGIN method. this->probScanTree->storeParsScan(); // \todo : figure out which one of these is semantically the right one this->pdf->deleteNLL(); // also save the chi2 of the free data fit to the tree: this->probScanTree->chi2minGlobal = this->getChi2minGlobal(); this->probScanTree->chi2minBkg = this->getChi2minBkg(); this->probScanTree->genericProbPValue = this->getPValueTTestStatistic(this->probScanTree->chi2min - this->probScanTree->chi2minGlobal); this->probScanTree->fill(); if(arg->debug && pdf->getBkgPdf()) { float pval_cls = this->getPValueTTestStatistic(this->probScanTree->chi2min - this->probScanTree->chi2minBkg, true); cout << "DEBUG in MethodDatasetsProbScan::scan1d() - p value CLs: " << pval_cls << endl; } // reset setParameters(w, pdf->getParName(), parsFunctionCall->get(0)); //setParameters(w, pdf->getObsName(), obsDataset->get(0)); } // End of npoints loop probScanTree->writeToFile(); if (bkgOnlyFitResult) bkgOnlyFitResult->Write(); if (dataFreeFitResult) dataFreeFitResult->Write(); outputFile->Close(); std::cout << "Wrote ToyTree to file" << std::endl; delete parsFunctionCall; // This is kind of a hack. The effect is supposed to be the same as callincg // this->sethCLFromProbScanTree(); here, but the latter gives a segfault somehow.... // \todo: use this->sethCLFromProbScanTree() directly after figuring out the cause of the segfault. this->loadScanFromFile(); return 0; }
void createWorkspace(const std::string &infilename, int nState, bool correctCtau, bool drawRapPt2D, bool drawPtCPM2D){ gROOT->SetStyle("Plain"); gStyle->SetTitleBorderSize(0); // Set some strings const std::string workspacename = "ws_masslifetime", treename = "selectedData"; // Get the tree from the data file TFile *f = TFile::Open(infilename.c_str()); TTree *tree = (TTree*)f->Get(treename.c_str()); // Set branch addresses in tree to be able to import tree to roofit TLorentzVector* jpsi = new TLorentzVector; tree->SetBranchAddress("JpsiP",&jpsi); double CPMval = 0; tree->SetBranchAddress("CPM",&CPMval); double massErr = 0; tree->SetBranchAddress("JpsiMassErr",&massErr); double Vprob = 0; tree->SetBranchAddress("JpsiVprob",&Vprob); double lifetime = 0; tree->SetBranchAddress("Jpsict",&lifetime); double lifetimeErr = 0; tree->SetBranchAddress("JpsictErr",&lifetimeErr); // define variables necessary for J/Psi(Psi(2S)) mass,lifetime fit RooRealVar* JpsiMass = new RooRealVar("JpsiMass", "M [GeV]", onia::massMin, onia::massMax); RooRealVar* JpsiMassErr = new RooRealVar("JpsiMassErr", "#delta M [GeV]", 0, 5); RooRealVar* JpsiRap = new RooRealVar("JpsiRap", "y", -onia::rap, onia::rap); RooRealVar* JpsiPt = new RooRealVar("JpsiPt", "p_{T} [GeV]", 0. ,100.); RooRealVar* JpsiCPM = new RooRealVar("JpsiCPM", "N_{ch}", 0. ,100.); RooRealVar* Jpsict = new RooRealVar("Jpsict", "lifetime [mm]", -1., 2.5); RooRealVar* JpsictErr = new RooRealVar("JpsictErr", "Error on lifetime [mm]", 0.0001, 1); RooRealVar* JpsiVprob = new RooRealVar("JpsiVprob", "", 0.01, 1.); // Set bins Jpsict->setBins(10000,"cache"); Jpsict->setBins(100); JpsiMass->setBins(100); JpsictErr->setBins(100); // The list of data variables RooArgList dataVars(*JpsiMass,*JpsiMassErr,*JpsiRap,*JpsiPt,*JpsiCPM,*Jpsict,*JpsictErr,*JpsiVprob); // construct dataset to contain events RooDataSet* fullData = new RooDataSet("fullData","The Full Data From the Input ROOT Trees",dataVars); int entries = tree->GetEntries(); cout << "entries " << entries << endl; // loop through events in tree and save them to dataset for (int ientries = 0; ientries < entries; ientries++) { if (ientries%100000==0) std::cout << "event " << ientries << " of " << entries << std::endl; tree->GetEntry(ientries); double M =jpsi->M(); double y=jpsi->Rapidity(); double pt=jpsi->Pt(); double cpm=CPMval; if (M > JpsiMass->getMin() && M < JpsiMass->getMax() && massErr > JpsiMassErr->getMin() && massErr < JpsiMassErr->getMax() && pt > JpsiPt->getMin() && pt < JpsiPt->getMax() && cpm > JpsiCPM->getMin() && cpm < JpsiCPM->getMax() && y > JpsiRap->getMin() && y < JpsiRap->getMax() && lifetime > Jpsict->getMin() && lifetime < Jpsict->getMax() && lifetimeErr > JpsictErr->getMin() && lifetimeErr < JpsictErr->getMax() && Vprob > JpsiVprob->getMin() && Vprob < JpsiVprob->getMax() ){ JpsiPt ->setVal(pt); JpsiCPM ->setVal(cpm); JpsiRap ->setVal(y); JpsiMass ->setVal(M); JpsiMassErr ->setVal(massErr); JpsiVprob ->setVal(Vprob); //cout<<"before lifetime correction \n" // <<"Jpsict: "<<lifetime<<" JpsictErr: "<<lifetimeErr<<endl; if(correctCtau){ lifetime = lifetime * onia::MpsiPDG / M ; lifetimeErr = lifetimeErr * onia::MpsiPDG / M ; Jpsict ->setVal(lifetime); JpsictErr ->setVal(lifetimeErr); //cout<<"MpsiPDG: "<<onia::MpsiPDG<<endl; //cout<<"after lifetime correction \n" // <<"Jpsict: "<<lifetime<<" JpsictErr: "<<lifetimeErr<<endl; } else{ Jpsict ->setVal(lifetime); JpsictErr ->setVal(lifetimeErr); } fullData->add(dataVars); } }//ientries //------------------------------------------------------------------------------------------------------------------ // Define workspace and import datasets ////Get datasets binned in pT, cpm, and y for(int iRap = 1; iRap <= onia::kNbRapForPTBins; iRap++){ Double_t yMin; Double_t yMax; if(iRap==0){ yMin = onia::rapForPTRange[0]; yMax = onia::rapForPTRange[onia::kNbRapForPTBins]; } else{ yMin = onia::rapForPTRange[iRap-1]; yMax = onia::rapForPTRange[iRap]; } for(int iPT = 1; iPT <= onia::kNbPTBins[iRap]; iPT++){ //for(int iPT = 0; iPT <= 0; iPT++) Double_t ptMin; Double_t ptMax; if(iPT==0){ ptMin = onia::pTRange[iRap][0]; ptMax = onia::pTRange[iRap][onia::kNbPTBins[0]]; } else{ ptMin = onia::pTRange[iRap][iPT-1]; ptMax = onia::pTRange[iRap][iPT]; } for(int iCPM = 1; iCPM <= onia::NchBins; iCPM++){ Double_t cpmMin; Double_t cpmMax; if(iCPM==0){ cpmMin = onia::cpmRange[0]; cpmMax = onia::cpmRange[onia::NchBins]; } else{ cpmMin = onia::cpmRange[iCPM-1]; cpmMax = onia::cpmRange[iCPM]; } // output file name and workspace std::stringstream outfilename; outfilename << "tmpFiles/backupWorkSpace/fit_Psi" << nState-3 << "S_rap" << iRap << "_pt" << iPT << "_cpm" << iCPM << ".root"; // outfilename << "tmpFiles/fit_Psi" << nState-3 << "S_rap" << iRap << "_pt" << iPT << ".root"; RooWorkspace* ws = new RooWorkspace(workspacename.c_str()); // define pt and y cuts on dataset std::stringstream cutString; cutString << "(JpsiCPM > " << cpmMin << " && JpsiCPM < "<< cpmMax << ") && " << "(JpsiPt >= " << ptMin << " && JpsiPt < "<< ptMax << ") && " << "(TMath::Abs(JpsiRap) >= " << yMin << " && TMath::Abs(JpsiRap) < " << yMax << ")"; cout << "cutString: " << cutString.str().c_str() << endl; // get the dataset for the fit RooDataSet* binData = (RooDataSet*)fullData->reduce(cutString.str().c_str()); std::stringstream name; name << "data_rap" << iRap << "_pt" << iPT << "_cpm" << iCPM;; binData->SetNameTitle(name.str().c_str(), "Data For Fitting"); // Import variables to workspace ws->import(*binData); ws->writeToFile(outfilename.str().c_str()); }//iCPM }//iPT }//iRap ////--------------------------------------------------------------- ////--Integrating rapidity and pt bins, in +/- 3*sigma mass window ////--------------------------------------------------------------- if(drawRapPt2D){ double yMin = onia::rapForPTRange[0]; double yMax = onia::rapForPTRange[onia::kNbRapForPTBins]; double ptMin = onia::pTRange[0][0]; double ptMax = onia::pTRange[0][onia::kNbPTBins[0]]; double cpmMin = onia::cpmRange[0]; double cpmMax = onia::cpmRange[onia::NchBins]; std::stringstream cutRapPt; cutRapPt << "(JpsiCPM > " << cpmMin << " && JpsiCPM < "<< cpmMax << ") && " << "(JpsiPt > " << ptMin << " && JpsiPt < "<< ptMax << ") && " << "(TMath::Abs(JpsiRap) > " << yMin << " && TMath::Abs(JpsiRap) < " << yMax << ")"; cout<<"cutRapPt: "<<cutRapPt.str().c_str()<<endl; RooDataSet* rapPtData = (RooDataSet*)fullData->reduce(cutRapPt.str().c_str()); std::stringstream nameRapPt; nameRapPt << "data_rap0_pt0_cpm0"; rapPtData->SetNameTitle(nameRapPt.str().c_str(), "Data For full rap and pt"); // output file name and workspace std::stringstream outfilename; outfilename << "tmpFiles/backupWorkSpace/fit_Psi" << nState-3 << "S_rap0_pt0_cpm0.root"; RooWorkspace* ws_RapPt = new RooWorkspace(workspacename.c_str()); //Import variables to workspace ws_RapPt->import(*rapPtData); ws_RapPt->writeToFile(outfilename.str().c_str()); TH2D* rapPt; TH1D* rap1p2; double MassMin; double MassMax; rap1p2 = new TH1D("rap1p2","rap1p2",30,0, 1.8); if(nState==4){ rapPt = new TH2D( "rapPt", "rapPt", 52,-1.3,1.3,144,0,72); MassMin=3.011;//massPsi1S-onia::nSigMass*sigma1S; MassMax=3.174;//massPsi1S+onia::nSigMass*sigma1S; // sigma 27.2 MeV // mean 3.093 GeV } if(nState==5){ rapPt = new TH2D( "rapPt", "rapPt", 64,-1.6,1.6,144,0,72); // rap<1.5 //rapPt = new TH2D( "rapPt", "rapPt", 52,-1.3,1.3,144,0,72); // rap<1.2 MassMin=3.576;//massPsi2S-onia::nSigMass*sigma2S; MassMax=3.786;//massPsi2S+onia::nSigMass*sigma2S; // sigma 34.9 MeV // pT > 7 // sigma 34.3 MeV // pT > 10 // mean 3.681 GeV } cout<<"Plotting rap-Pt for Psi"<<nState-3<<"S"<<endl; cout<<"MassMin for rap-Pt plot = "<<MassMin<<endl; cout<<"MassMax for rap-Pt plot = "<<MassMax<<endl; TTree *rapPtTree = (TTree*)rapPtData->tree(); std::stringstream cutMass; cutMass<<"(JpsiMass > " << MassMin << " && JpsiMass < "<< MassMax << ")"; //following two methods can only be used in root_v30, 34 does not work rapPtTree->Draw("JpsiPt:JpsiRap>>rapPt",cutMass.str().c_str(),"colz"); cout<<"debug"<<endl; rapPtTree->Draw("TMath::Abs(JpsiRap)>>rap1p2",cutMass.str().c_str()); TCanvas* c2 = new TCanvas("c2","c2",1200,1500); rapPt->SetYTitle("p_{T}(#mu#mu) [GeV]"); rapPt->SetXTitle("y(#mu#mu)"); gStyle->SetPalette(1); gPad->SetFillColor(kWhite); rapPt->SetTitle(0); rapPt->SetStats(0); gPad->SetLeftMargin(0.15); gPad->SetRightMargin(0.17); rapPt->GetYaxis()->SetTitleOffset(1.5); rapPt->Draw("colz"); TLine* rapPtLine; for(int iRap=0;iRap<onia::kNbRapForPTBins+1;iRap++){ rapPtLine= new TLine( -onia::rapForPTRange[iRap], onia::pTRange[0][0], -onia::rapForPTRange[iRap], onia::pTRange[0][onia::kNbPTBins[iRap]] ); rapPtLine->SetLineWidth( 2 ); rapPtLine->SetLineStyle( 1 ); rapPtLine->SetLineColor( kWhite ); rapPtLine->Draw(); rapPtLine= new TLine( onia::rapForPTRange[iRap], onia::pTRange[0][0], onia::rapForPTRange[iRap], onia::pTRange[0][onia::kNbPTBins[iRap]] ); rapPtLine->SetLineWidth( 2 ); rapPtLine->SetLineStyle( 1 ); rapPtLine->SetLineColor( kWhite ); rapPtLine->Draw(); int pTBegin = 0; if(nState==5) pTBegin = 1; for(int iPt=pTBegin;iPt<onia::kNbPTBins[iRap]+1;iPt++){ rapPtLine= new TLine( -onia::rapForPTRange[onia::kNbRapForPTBins], onia::pTRange[0][iPt], onia::rapForPTRange[onia::kNbRapForPTBins], onia::pTRange[0][iPt] ); rapPtLine->SetLineWidth( 2 ); rapPtLine->SetLineStyle( 1 ); rapPtLine->SetLineColor( kWhite ); rapPtLine->Draw(); } } char savename[200]; sprintf(savename,"Fit/rapPt_Psi%dS.pdf",nState-3); c2->SaveAs(savename); TCanvas* c3 = new TCanvas("c3","c3",1500,1200); rap1p2->SetYTitle("Events"); rap1p2->SetXTitle("y(#mu#mu)"); rap1p2->SetTitle(0); rap1p2->SetStats(0); rap1p2->GetYaxis()->SetTitleOffset(1.2); rap1p2->Draw(); sprintf(savename,"Fit/rapDimuon_1p2_Psi%dS.pdf",nState-3); c3->SaveAs(savename); } if(drawPtCPM2D){ double yMin = onia::rapForPTRange[0]; double yMax = onia::rapForPTRange[onia::kNbRapForPTBins]; double ptMin = onia::pTRange[0][0]; double ptMax = onia::pTRange[0][onia::kNbPTBins[0]]; double cpmMin = onia::cpmRange[0]; double cpmMax = onia::cpmRange[onia::NchBins]; std::stringstream cutRapPt; cutRapPt << "(JpsiCPM > " << cpmMin << " && JpsiCPM < "<< cpmMax << ") && " << "(JpsiPt > " << ptMin << " && JpsiPt < "<< ptMax << ") && " << "(TMath::Abs(JpsiRap) > " << yMin << " && TMath::Abs(JpsiRap) < " << yMax << ")"; cout<<"cutRapPt: "<<cutRapPt.str().c_str()<<endl; RooDataSet* rapPtData = (RooDataSet*)fullData->reduce(cutRapPt.str().c_str()); std::stringstream nameRapPt; nameRapPt << "data_rap0_pt0_cpm0"; rapPtData->SetNameTitle(nameRapPt.str().c_str(), "Data For full rap and pt"); // output file name and workspace std::stringstream outfilename; outfilename << "tmpFiles/backupWorkSpace/fit_Psi" << nState-3 << "S_rap0_pt0_cpm0.root"; RooWorkspace* ws_RapPt = new RooWorkspace(workspacename.c_str()); //Import variables to workspace ws_RapPt->import(*rapPtData); ws_RapPt->writeToFile(outfilename.str().c_str()); TH2D* PtCPM; double MassMin; double MassMax; if(nState==4){ PtCPM = new TH2D( "PtCPM", "PtCPM", 100,0,50,200,0,100); MassMin=3.011;//massPsi1S-onia::nSigMass*sigma1S; MassMax=3.174;//massPsi1S+onia::nSigMass*sigma1S; // sigma 27.2 MeV // mean 3.093 GeV } if(nState==5){ PtCPM = new TH2D( "PtCPM", "PtCPM", 100,0,50,200,0,100); // rap<1.5 //rapPt = new TH2D( "rapPt", "rapPt", 52,-1.3,1.3,144,0,72); // rap<1.2 MassMin=3.576;//massPsi2S-onia::nSigMass*sigma2S; MassMax=3.786;//massPsi2S+onia::nSigMass*sigma2S; // sigma 34.9 MeV // pT > 7 // sigma 34.3 MeV // pT > 10 // mean 3.681 GeV } cout<<"Plotting Pt-CPM for Psi"<<nState-3<<"S"<<endl; cout<<"MassMin for Pt-CPM plot = "<<MassMin<<endl; cout<<"MassMax for Pt-CPM plot = "<<MassMax<<endl; TTree *rapPtTree = (TTree*)rapPtData->tree(); std::stringstream cutMass; cutMass<<"(JpsiMass > " << MassMin << " && JpsiMass < "<< MassMax << ")"; //following two methods can only be used in root_v30, 34 does not work rapPtTree->Draw("JpsiCPM:JpsiPt>>PtCPM",cutMass.str().c_str(),"colz"); cout<<"debug"<<endl; TCanvas* c2 = new TCanvas("c2","c2",1200,1500); PtCPM->SetYTitle("N_{ch}"); PtCPM->SetXTitle("p_{T}(#mu#mu) [GeV]"); gStyle->SetPalette(1); gPad->SetFillColor(kWhite); PtCPM->SetTitle(0); PtCPM->SetStats(0); gPad->SetLeftMargin(0.15); gPad->SetRightMargin(0.17); PtCPM->GetYaxis()->SetTitleOffset(1.5); PtCPM->Draw("colz"); TLine* PtCPMLine; int iRap=0; for(int iPt=0;iPt<onia::kNbPTMaxBins+1;iPt++){ int cpmBegin = 0; if(nState==5) cpmBegin = 1; for(int icpm=cpmBegin;icpm<onia::NchBins+1;icpm++){ PtCPMLine= new TLine( onia::pTRange[iRap][0], onia::cpmRange[icpm], onia::pTRange[iRap][onia::kNbPTMaxBins], onia::cpmRange[icpm] ); PtCPMLine->SetLineWidth( 2 ); PtCPMLine->SetLineStyle( 1 ); PtCPMLine->SetLineColor( kWhite ); PtCPMLine->Draw(); PtCPMLine= new TLine( onia::pTRange[iRap][iPt], onia::cpmRange[0], onia::pTRange[iRap][iPt], onia::cpmRange[onia::NchBins] ); PtCPMLine->SetLineWidth( 2 ); PtCPMLine->SetLineStyle( 1 ); PtCPMLine->SetLineColor( kWhite ); PtCPMLine->Draw(); // PtCPMLine= new TLine( onia::pTRange[0][onia::kNbPTMaxBins], onia::cpmRange[icpm], onia::pTRange[0][onia::kNbPTMaxBins], onia::cpmRange[icpm] ); // PtCPMLine->SetLineWidth( 2 ); // PtCPMLine->SetLineStyle( 1 ); // PtCPMLine->SetLineColor( kWhite ); // PtCPMLine->Draw(); } } char savename[200]; sprintf(savename,"Fit/PtCPM_Psi%dS.pdf",nState-3); c2->SaveAs(savename); } f->Close(); }
void StandardTestStatDistributionDemo(const char* infile = "", const char* workspaceName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData"){ // the number of toy MC used to generate the distribution int nToyMC = 1000; // The parameter below is needed for asymptotic distribution to be chi-square, // but set to false if your model is not numerically stable if mu<0 bool allowNegativeMu=true; ///////////////////////////////////////////////////////////// // 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; } mc->Print(); ///////////////////////////////////////////////////////////// // Now find the upper limit based on the asymptotic results //////////////////////////////////////////////////////////// RooRealVar* firstPOI = (RooRealVar*) mc->GetParametersOfInterest()->first(); ProfileLikelihoodCalculator plc(*data,*mc); LikelihoodInterval* interval = plc.GetInterval(); double plcUpperLimit = interval->UpperLimit(*firstPOI); delete interval; cout << "\n\n--------------------------------------"<<endl; cout <<"Will generate sampling distribution at " << firstPOI->GetName() << " = " << plcUpperLimit <<endl; int nPOI = mc->GetParametersOfInterest()->getSize(); if(nPOI>1){ cout <<"not sure what to do with other parameters of interest, but here are their values"<<endl; mc->GetParametersOfInterest()->Print("v"); } ///////////////////////////////////////////// // create thte test stat sampler ProfileLikelihoodTestStat ts(*mc->GetPdf()); // to avoid effects from boundary and simplify asymptotic comparison, set min=-max if(allowNegativeMu) firstPOI->setMin(-1*firstPOI->getMax()); // temporary RooArgSet RooArgSet poi; poi.add(*mc->GetParametersOfInterest()); // create and configure the ToyMCSampler ToyMCSampler sampler(ts,nToyMC); sampler.SetPdf(*mc->GetPdf()); sampler.SetObservables(*mc->GetObservables()); sampler.SetGlobalObservables(*mc->GetGlobalObservables()); if(!mc->GetPdf()->canBeExtended() && (data->numEntries()==1)){ cout << "tell it to use 1 event"<<endl; sampler.SetNEventsPerToy(1); } firstPOI->setVal(plcUpperLimit); // set POI value for generation sampler.SetParametersForTestStat(*mc->GetParametersOfInterest()); // set POI value for evaluation if (useProof) { ProofConfig pc(*w, nworkers, "",false); sampler.SetProofConfig(&pc); // enable proof } firstPOI->setVal(plcUpperLimit); RooArgSet allParameters; allParameters.add(*mc->GetParametersOfInterest()); allParameters.add(*mc->GetNuisanceParameters()); allParameters.Print("v"); SamplingDistribution* sampDist = sampler.GetSamplingDistribution(allParameters); SamplingDistPlot plot; plot.AddSamplingDistribution(sampDist); plot.GetTH1F(sampDist)->GetYaxis()->SetTitle(Form("f(-log #lambda(#mu=%.2f) | #mu=%.2f)",plcUpperLimit,plcUpperLimit)); plot.SetAxisTitle(Form("-log #lambda(#mu=%.2f)",plcUpperLimit)); TCanvas* c1 = new TCanvas("c1"); c1->SetLogy(); plot.Draw(); double min = plot.GetTH1F(sampDist)->GetXaxis()->GetXmin(); double max = plot.GetTH1F(sampDist)->GetXaxis()->GetXmax(); TF1* f = new TF1("f",Form("2*ROOT::Math::chisquared_pdf(2*x,%d,0)",nPOI),min,max); f->Draw("same"); c1->SaveAs("standard_test_stat_distribution.pdf"); }
/// /// Perform 1d Prob scan. /// /// - Scan range defined through limit "scan". /// - Will fill the hCL histogram with the 1-CL curve. /// - Start at a scan value that is in the middle of the allowed /// range, preferably a solution, and scan up and down from there. /// - use the "probforce" command line flag to enable force minimum finding /// /// \param fast This will scan each scanpoint only once. /// \param reverse This will scan in reverse direction. /// When using the drag mode, this can sometimes make a difference. /// \return status: 2 = new global minimum found, 1 = error /// int MethodProbScan::scan1d(bool fast, bool reverse) { if ( arg->debug ) cout << "MethodProbScan::scan1d() : starting ... " << endl; nScansDone++; // The "improve" method doesn't need multiple scans. if ( arg->probforce || arg->probimprove ) fast = true; if ( arg->probforce ) scanDisableDragMode = true; // Save parameter values that were active at function call. if ( startPars ) delete startPars; startPars = new RooDataSet("startPars", "startPars", *w->set(parsName)); startPars->add(*w->set(parsName)); // // start scan from global minimum (not always a good idea as we need to set from other places as well) // setParameters(w, parsName, globalMin); // load scan parameter and scan range setLimit(w, scanVar1, "scan"); RooRealVar *par = w->var(scanVar1); assert(par); float min = hCL->GetXaxis()->GetXmin(); float max = hCL->GetXaxis()->GetXmax(); if ( fabs(par->getMin()-min)>1e-6 || fabs(par->getMax()-max)>1e-6 ){ cout << "MethodProbScan::scan1d() : WARNING : Scan range was changed after initScan()" << endl; cout << " was called so the old range will be used." << endl; } if ( arg->verbose ){ cout << "\nProb configuration:" << endl; cout << " combination : " << title << endl; cout << " scan variable : " << scanVar1 << endl; cout << " scan range : " << min << " ... " << max << endl; cout << " scan steps : " << nPoints1d << endl; cout << " fast mode : " << fast << endl; cout << endl; } // Set limit to all parameters. combiner->loadParameterLimits(); // fix scan parameter par->setConstant(true); // j = // 0 : start value -> upper limit // 1 : upper limit -> start value // 2 : start value -> lower limit // 3 : lower limit -> start value float startValue = par->getVal(); bool scanUp; // for the status bar float nTotalSteps = nPoints1d; nTotalSteps *= fast ? 1 : 2; float nStep = 0; float printFreq = nTotalSteps>15 ? 10 : nTotalSteps; // Report on the smallest new minimum we come across while scanning. // Sometimes the scan doesn't find the minimum // that was found before. Warn if this happens. double bestMinOld = chi2minGlobal; double bestMinFoundInScan = 100.; for ( int jj=0; jj<4; jj++ ) { int j = jj; if ( reverse ) switch(jj) { case 0: j = 2; break; case 1: j = 3; break; case 2: j = 0; break; case 3: j = 1; break; } float scanStart, scanStop; switch(j) { case 0: // UP setParameters(w, parsName, startPars->get(0)); scanStart = startValue; scanStop = par->getMax(); scanUp = true; break; case 1: // DOWN scanStart = par->getMax(); scanStop = startValue; scanUp = false; break; case 2: // DOWN setParameters(w, parsName, startPars->get(0)); scanStart = startValue; scanStop = par->getMin(); scanUp = false; break; case 3: // UP scanStart = par->getMin(); scanStop = startValue; scanUp = true; break; } if ( fast && ( j==1 || j==3 ) ) continue; for ( int i=0; i<nPoints1d; i++ ) { float scanvalue; if ( scanUp ) { scanvalue = min + (max-min)*(double)i/(double)nPoints1d + hCL->GetBinWidth(1)/2.; if ( scanvalue < scanStart ) continue; if ( scanvalue > scanStop ) break; } else { scanvalue = max - (max-min)*(double)(i+1)/(double)nPoints1d + hCL->GetBinWidth(1)/2.; if ( scanvalue > scanStart ) continue; if ( scanvalue < scanStop ) break; } // disable drag mode // (the improve method doesn't work with drag mode as parameter run // at their limits) if ( scanDisableDragMode ) setParameters(w, parsName, startPars->get(0)); // set the parameter of interest to the scan point par->setVal(scanvalue); // don't scan in unphysical region if ( scanvalue < par->getMin() || scanvalue > par->getMax() ) continue; // status bar if ( (((int)nStep % (int)(nTotalSteps/printFreq)) == 0)) cout << "MethodProbScan::scan1d() : scanning " << (float)nStep/(float)nTotalSteps*100. << "% \r" << flush; // fit! RooFitResult *fr = 0; if ( arg->probforce ) fr = fitToMinForce(w, combiner->getPdfName()); else if ( arg->probimprove ) fr = fitToMinImprove(w, combiner->getPdfName()); else fr = fitToMinBringBackAngles(w->pdf(pdfName), false, -1); double chi2minScan = fr->minNll(); if ( std::isinf(chi2minScan) ) chi2minScan=1e4; // else the toys in PDF_testConstraint don't work RooSlimFitResult *r = new RooSlimFitResult(fr); // try to save memory by using the slim fit result delete fr; allResults.push_back(r); bestMinFoundInScan = TMath::Min((double)chi2minScan, (double)bestMinFoundInScan); TString warningChi2Neg; if ( chi2minScan < 0 ){ float newChi2minScan = chi2minGlobal + 25.; // 5sigma more than best point warningChi2Neg = "MethodProbScan::scan1d() : WARNING : " + title; warningChi2Neg += TString(Form(" chi2 negative for scan point %i: %f",i,chi2minScan)); warningChi2Neg += " setting to: " + TString(Form("%f",newChi2minScan)); //cout << warningChi2Neg << "\r" << flush; cout << warningChi2Neg << endl; chi2minScan = newChi2minScan; } // If we find a minimum smaller than the old "global" minimum, this means that all // previous 1-CL values are too high. if ( chi2minScan<chi2minGlobal ){ if ( arg->verbose ) cout << "MethodProbScan::scan1d() : WARNING : '" << title << "' new global minimum found! " << " chi2minScan=" << chi2minScan << endl; chi2minGlobal = chi2minScan; // recompute previous 1-CL values for ( int k=1; k<=hCL->GetNbinsX(); k++ ){ hCL->SetBinContent(k, TMath::Prob(hChi2min->GetBinContent(k)-chi2minGlobal, 1)); } } double deltaChi2 = chi2minScan - chi2minGlobal; double oneMinusCL = TMath::Prob(deltaChi2, 1); // Save the 1-CL value and the corresponding fit result. // But only if better than before! if ( hCL->GetBinContent(hCL->FindBin(scanvalue)) <= oneMinusCL ){ hCL->SetBinContent(hCL->FindBin(scanvalue), oneMinusCL); hChi2min->SetBinContent(hCL->FindBin(scanvalue), chi2minScan); int iRes = hCL->FindBin(scanvalue)-1; curveResults[iRes] = r; } nStep++; } } cout << "MethodProbScan::scan1d() : scan done. " << endl; if ( bestMinFoundInScan-bestMinOld > 0.01 ){ cout << "MethodProbScan::scan1d() : WARNING: Scan didn't find similar minimum to what was found before!" << endl; cout << "MethodProbScan::scan1d() : Too strict parameter limits? Too coarse scan steps? Didn't load global minimum?" << endl; cout << "MethodProbScan::scan1d() : chi2 bestMinFoundInScan=" << bestMinFoundInScan << ", bestMinOld=" << bestMinOld << endl; } // attempt to correct for undercoverage if (pvalueCorrectorSet) { for ( int k=1; k<=hCL->GetNbinsX(); k++ ){ double pvalueProb = hCL->GetBinContent(k); pvalueProb = pvalueCorrector->transform(pvalueProb); hCL->SetBinContent(k, pvalueProb); } } setParameters(w, parsName, startPars->get(0)); saveSolutions(); if (arg->confirmsols) confirmSolutions(); if ( (bestMinFoundInScan-bestMinOld)/bestMinOld > 0.01 ) return 1; return 0; }
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 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 MakeSpinPlots::DrawBlindFit(TString tag, TString mcName,TString cosThetaBin){ TString fitTag="FULLFIT"; TString cat = "evtcat"; if(cosThetaBin!=""){ tag+="_"+cosThetaBin; fitTag="FULLCOSTFIT"; cat = "evtcat_cosT"; } TString dataTag = "_Combined"; if(cosThetaBin!="") dataTag+="_CosTBin"; TCanvas *cv = new TCanvas(Form("%s_%s",mcName.Data(),tag.Data())); RooRealVar* mass = ws->var("mass"); mass->setBins( (mass->getMax() - mass->getMin())/1.5 ); //enfore 1.5GeV bin width RooPlot* frame = mass->frame(); double Nb = ws->var(Form("Data_BKGFIT_%s_Nbkg",tag.Data()))->getVal(); cout << Nb << endl; RooDataSet *blind = (RooDataSet*)ws->data("Data"+dataTag)->reduce(TString("((mass<119) || (mass>135.5)) && ")+cat+"=="+cat+"::"+tag); blind->plotOn(frame); tPair lbl(mcName,tag); double nBkg = ws->data("Data"+dataTag)->sumEntries(cat+"=="+cat+"::"+tag); ws->pdf( Form("Data_BKGFIT_%s_bkgModel",tag.Data()) )->plotOn(frame,RooFit::Range("all"),RooFit::Normalization(nBkg/blind->sumEntries()), RooFit::LineColor(kRed)); //TLatex *prelim = new TLatex(250,x->GetXmax()-40.,"CMS Preliminary"); TLatex *prelim = new TLatex(0.12,0.96,"CMS Preliminary"); TLatex *lum = new TLatex(0.7,0.96,Form("#sqrt{s}=8 TeV L = %0.1f fb^{-1}",lumi)); prelim->SetNDC(); lum->SetNDC(); prelim->SetTextSize(0.045); prelim->SetTextColor(kBlack); lum->SetTextSize(0.045); lum->SetTextColor(kBlack); TLatex *owner = new TLatex(0.6,0.88,"Caltech-CMS Preliminary"); owner->SetNDC(); owner->SetTextSize(0.045); owner->SetTextColor(kBlack); TLatex *Nbkg = new TLatex(0.7,0.8,Form("N_{bkg}= %0.1f #pm %0.1f",nBackground[lbl].first,nBackground[lbl].second)); Nbkg->SetNDC(); Nbkg->SetTextSize(0.045); TLatex *sig = new TLatex(0.7,0.72,Form("#sigma_{eff} = %0.1f #pm %0.2f",fitSigEff[lbl].first,fitSigEff[lbl].second)); sig->SetNDC(); sig->SetTextSize(0.045); TLatex *expBkg = new TLatex(0.7,0.64,Form("B @ 125 = %0.1f",fitBkg1Sigma[lbl].first)); expBkg->SetNDC(); expBkg->SetTextSize(0.045); frame->addObject(prelim); frame->addObject(lum); //frame->addObject(owner); frame->addObject(Nbkg); frame->addObject(sig); frame->addObject(expBkg); frame->Draw(); cv->SaveAs( basePath+Form("/mgg-%s-%s-%s_BLIND.png",outputTag.Data(),mcName.Data(),tag.Data()) ); cv->SaveAs( basePath+Form("/C/mgg-%s-%s-%s_BLIND.C",outputTag.Data(),mcName.Data(),tag.Data()) ); cv->SaveAs( basePath+Form("/mgg-%s-%s-%s_BLIND.pdf",outputTag.Data(),mcName.Data(),tag.Data()) ); delete cv; }
void MakeSpinPlots::DrawIndFit(TString tag, TString mcName){ TCanvas *cv = new TCanvas(Form("%s_%s",mcName.Data(),tag.Data())); if(ws->var( Form("Data_%s_INDFIT_%s_Nsig",mcName.Data(),tag.Data()) ) == 0) return; RooRealVar* mass = ws->var("mass"); mass->setBins( (mass->getMax() - mass->getMin())/1.5 ); //enfore 1.5GeV bin width RooPlot* frame = mass->frame(); tPair lbl(mcName,tag); double Ns = ws->var( Form("Data_%s_INDFIT_%s_Nsig",mcName.Data(),tag.Data()) )->getVal(); double Nb = ws->var( Form("Data_%s_INDFIT_%s_Nbkg",mcName.Data(),tag.Data()) )->getVal(); double Nblind = ws->data("Data_Combined")->reduce("(mass>100 && mass<119) || (mass>135.5 && mass<170)")->sumEntries(TString("evtcat==evtcat::")+tag); double Ntot = ws->data("Data_Combined")->sumEntries(TString("evtcat==evtcat::")+tag); RooFitResult* fitres = (RooFitResult*)ws->obj(Form("Data_%s_INDFIT_fitResult",mcName.Data())); std::cout << fitres << std::endl; ws->data("Data_Combined")->reduce(TString("evtcat==evtcat::")+tag)->plotOn(frame,RooFit::LineColor(kWhite),RooFit::MarkerColor(kWhite)); //Data_Hgg125_INDFIT_EB_0 ws->pdf(Form("Data_%s_INDFIT_%s",mcName.Data(),tag.Data()))->plotOn(frame, RooFit::FillColor(kGreen),RooFit::VisualizeError(*fitres,2.0)); ws->pdf(Form("Data_%s_INDFIT_%s",mcName.Data(),tag.Data()))->plotOn(frame, RooFit::FillColor(kYellow),RooFit::VisualizeError(*fitres,1.0)); ws->pdf(Form("Data_%s_INDFIT_%s",mcName.Data(),tag.Data()))->plotOn(frame, RooFit::LineColor(kRed)); std::cout << "1" << std::endl; ws->pdf(Form("Data_BKGFIT_%s_bkgModel",tag.Data()))->plotOn(frame, RooFit::Normalization(Nb/(Nb+Ns)),RooFit::LineColor(kRed),RooFit::LineStyle(kDashed)); std::cout << "2" << std::endl; ws->data("Data_Combined")->reduce(TString("evtcat==evtcat::")+tag)->plotOn(frame); frame->Draw(); //TLatex *prelim = new TLatex(250,x->GetXmax()-40.,"CMS Preliminary"); TLatex *prelim = new TLatex(0.12,0.96,"CMS Preliminary"); TLatex *lum = new TLatex(0.7,0.96,Form("#sqrt{s}=8 TeV L = %0.1f fb^{-1}",lumi)); prelim->SetNDC(); lum->SetNDC(); prelim->SetTextSize(0.045); prelim->SetTextColor(kBlack); lum->SetTextSize(0.045); lum->SetTextColor(kBlack); TLatex *owner = new TLatex(0.6,0.88,"Alex Mott (Nov. 13, 2012)"); owner->SetNDC(); owner->SetTextSize(0.045); owner->SetTextColor(kBlack); TLatex *mu = new TLatex(0.7,0.8,Form("#mu = %0.1f #pm %0.2f", fitMean[lbl].first,fitMean[lbl].second)); mu->SetNDC(); mu->SetTextSize(0.045); TLatex *sig = new TLatex(0.7,0.72,Form("#sigma_{eff} = %0.1f #pm %0.2f", fitSigEff[lbl].first,fitSigEff[lbl].second)); sig->SetNDC(); sig->SetTextSize(0.045); float nSig = ws->var( Form("Data_%s_INDFIT_%s_Nsig",mcName.Data(),tag.Data()) )->getVal(); float nSigErr = ws->var( Form("Data_%s_INDFIT_%s_Nsig",mcName.Data(),tag.Data()) )->getError(); TLatex *Nsig = new TLatex(0.7,0.64,Form("N_{sig}= %0.1f #pm %0.1f",nSig,nSigErr)); Nsig->SetNDC(); Nsig->SetTextSize(0.045); frame->addObject(prelim); frame->addObject(lum); //frame->addObject(owner); frame->addObject(mu); frame->addObject(sig); frame->addObject(Nsig); frame->Draw(); cv->SaveAs( basePath+Form("/mgg-FloatedFraction-%s-%s-%s.png",outputTag.Data(),mcName.Data(),tag.Data()) ); cv->SaveAs( basePath+Form("/C/mgg-FloatedFraction-%s-%s-%s.C",outputTag.Data(),mcName.Data(),tag.Data()) ); cv->SaveAs( basePath+Form("/mgg-FloatedFraction-%s-%s-%s.pdf",outputTag.Data(),mcName.Data(),tag.Data()) ); delete cv; }
/// /// Find the global minimum in a more thorough way. /// First fit with external start parameters, then /// for each parameter that starts with "d" or "r" (typically angles and ratios): /// - at upper scan range, rest at start parameters /// - at lower scan range, rest at start parameters /// This amounts to a maximum of 1+2^n fits, where n is the number /// of parameters to be varied. /// /// \param w Workspace holding the pdf. /// \param name Name of the pdf without leading "pdf_". /// \param forceVariables Apply the force method for these variables only. Format /// "var1,var2,var3," (list must end with comma). Default is to apply for all angles, /// all ratios except rD_k3pi and rD_kpi, and the k3pi coherence factor. /// RooFitResult* Utils::fitToMinForce(RooWorkspace *w, TString name, TString forceVariables) { bool debug = true; TString parsName = "par_"+name; TString obsName = "obs_"+name; TString pdfName = "pdf_"+name; RooFitResult *r = 0; int printlevel = -1; RooMsgService::instance().setGlobalKillBelow(ERROR); // save start parameters if ( !w->set(parsName) ){ cout << "MethodProbScan::scan2d() : ERROR : parsName not found: " << parsName << endl; exit(1); } RooDataSet *startPars = new RooDataSet("startParsForce", "startParsForce", *w->set(parsName)); startPars->add(*w->set(parsName)); // set up parameters and ranges RooArgList *varyPars = new RooArgList(); TIterator* it = w->set(parsName)->createIterator(); while ( RooRealVar* p = (RooRealVar*)it->Next() ) { if ( p->isConstant() ) continue; if ( forceVariables=="" && ( false || TString(p->GetName()).BeginsWith("d") ///< use these variables // || TString(p->GetName()).BeginsWith("r") || TString(p->GetName()).BeginsWith("k") || TString(p->GetName()) == "g" ) && ! ( TString(p->GetName()) == "rD_k3pi" ///< don't use these || TString(p->GetName()) == "rD_kpi" // || TString(p->GetName()) == "dD_kpi" || TString(p->GetName()) == "d_dk" || TString(p->GetName()) == "d_dsk" )) { varyPars->add(*p); } else if ( forceVariables.Contains(TString(p->GetName())+",") ) { varyPars->add(*p); } } delete it; int nPars = varyPars->getSize(); if ( debug ) cout << "Utils::fitToMinForce() : nPars = " << nPars << " => " << pow(2.,nPars) << " fits" << endl; if ( debug ) cout << "Utils::fitToMinForce() : varying "; if ( debug ) varyPars->Print(); ////////// r = fitToMinBringBackAngles(w->pdf(pdfName), false, printlevel); ////////// int nErrors = 0; // We define a binary mask where each bit corresponds // to parameter at max or at min. for ( int i=0; i<pow(2.,nPars); i++ ) { if ( debug ) cout << "Utils::fitToMinForce() : fit " << i << " \r" << flush; setParameters(w, parsName, startPars->get(0)); for ( int ip=0; ip<nPars; ip++ ) { RooRealVar *p = (RooRealVar*)varyPars->at(ip); float oldMin = p->getMin(); float oldMax = p->getMax(); setLimit(w, p->GetName(), "force"); if ( i/(int)pow(2.,ip) % 2==0 ) { p->setVal(p->getMin()); } if ( i/(int)pow(2.,ip) % 2==1 ) { p->setVal(p->getMax()); } p->setRange(oldMin, oldMax); } // check if start parameters are sensible, skip if they're not double startParChi2 = getChi2(w->pdf(pdfName)); if ( startParChi2>2000 ){ nErrors += 1; continue; } // refit RooFitResult *r2 = fitToMinBringBackAngles(w->pdf(pdfName), false, printlevel); // In case the initial fit failed, accept the second one. // If both failed, still select the second one and hope the // next fit succeeds. if ( !(r->edm()<1 && r->covQual()==3) ){ delete r; r = r2; } else if ( r2->edm()<1 && r2->covQual()==3 && r2->minNll()<r->minNll() ){ // better minimum found! delete r; r = r2; } else{ delete r2; } } if ( debug ) cout << endl; if ( debug ) cout << "Utils::fitToMinForce() : nErrors = " << nErrors << endl; RooMsgService::instance().setGlobalKillBelow(INFO); // (re)set to best parameters setParameters(w, parsName, r); delete startPars; return r; }
void StandardBayesianNumericalDemo(const char* infile = "", const char* workspaceName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData") { // option definitions double confLevel = optBayes.confLevel; TString integrationType = optBayes.integrationType; int nToys = optBayes.nToys; bool scanPosterior = optBayes.scanPosterior; int nScanPoints = optBayes.nScanPoints; int intervalType = optBayes.intervalType; int maxPOI = optBayes.maxPOI; double nSigmaNuisance = optBayes.nSigmaNuisance; ///////////////////////////////////////////////////////////// // 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 BayesianCalculator // to find and plot the 95% credible interval // on the parameter of interest as specified // in the model config // before we do that, we must specify our prior // it belongs in the model config, but it may not have // been specified RooUniform prior("prior","",*mc->GetParametersOfInterest()); w->import(prior); mc->SetPriorPdf(*w->pdf("prior")); // do without systematics //mc->SetNuisanceParameters(RooArgSet() ); if (nSigmaNuisance > 0) { RooAbsPdf * pdf = mc->GetPdf(); assert(pdf); RooFitResult * res = pdf->fitTo(*data, Save(true), Minimizer(ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str()), Hesse(true), PrintLevel(ROOT::Math::MinimizerOptions::DefaultPrintLevel()-1) ); res->Print(); RooArgList nuisPar(*mc->GetNuisanceParameters()); for (int i = 0; i < nuisPar.getSize(); ++i) { RooRealVar * v = dynamic_cast<RooRealVar*> (&nuisPar[i] ); assert( v); v->setMin( TMath::Max( v->getMin(), v->getVal() - nSigmaNuisance * v->getError() ) ); v->setMax( TMath::Min( v->getMax(), v->getVal() + nSigmaNuisance * v->getError() ) ); std::cout << "setting interval for nuisance " << v->GetName() << " : [ " << v->getMin() << " , " << v->getMax() << " ]" << std::endl; } } BayesianCalculator bayesianCalc(*data,*mc); bayesianCalc.SetConfidenceLevel(confLevel); // 95% interval // default of the calculator is central interval. here use shortest , central or upper limit depending on input // doing a shortest interval might require a longer time since it requires a scan of the posterior function if (intervalType == 0) bayesianCalc.SetShortestInterval(); // for shortest interval if (intervalType == 1) bayesianCalc.SetLeftSideTailFraction(0.5); // for central interval if (intervalType == 2) bayesianCalc.SetLeftSideTailFraction(0.); // for upper limit if (!integrationType.IsNull() ) { bayesianCalc.SetIntegrationType(integrationType); // set integrationType bayesianCalc.SetNumIters(nToys); // set number of ietrations (i.e. number of toys for MC integrations) } // in case of toyMC make a nnuisance pdf if (integrationType.Contains("TOYMC") ) { RooAbsPdf * nuisPdf = RooStats::MakeNuisancePdf(*mc, "nuisance_pdf"); cout << "using TOYMC integration: make nuisance pdf from the model " << std::endl; nuisPdf->Print(); bayesianCalc.ForceNuisancePdf(*nuisPdf); scanPosterior = true; // for ToyMC the posterior is scanned anyway so used given points } // compute interval by scanning the posterior function if (scanPosterior) bayesianCalc.SetScanOfPosterior(nScanPoints); RooRealVar* poi = (RooRealVar*) mc->GetParametersOfInterest()->first(); if (maxPOI != -999 && maxPOI > poi->getMin()) poi->setMax(maxPOI); SimpleInterval* interval = bayesianCalc.GetInterval(); // print out the iterval on the first Parameter of Interest cout << "\n>>>> RESULT : " << confLevel*100 << "% interval on " << poi->GetName()<<" is : ["<< interval->LowerLimit() << ", "<< interval->UpperLimit() <<"] "<<endl; // make a plot // since plotting may take a long time (it requires evaluating // the posterior in many points) this command will speed up // by reducing the number of points to plot - do 50 // ignore errors of PDF if is zero RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::Ignore) ; cout << "\nDrawing plot of posterior function....." << endl; // always plot using numer of scan points bayesianCalc.SetScanOfPosterior(nScanPoints); RooPlot * plot = bayesianCalc.GetPosteriorPlot(); plot->Draw(); }
RooFitResult * safeFit(RooAbsPdf * pdf, RooDataSet * data, Str2VarMap p, ISVALIDF_PTR isValid, string opt = "", int nfree = -1, RooArgSet * cons = NULL, RooAbsReal * nll = NULL) { RooFitResult * res = NULL; RooRealVar cosThetaL("cosThetaL","cosThetaL",0.,-1.,1.); RooRealVar cosThetaB("cosThetaB","cosThetaB",0.,-1.,1.); RooArgSet obs(cosThetaL,cosThetaB); //if(opt.find("-scan")==string::npos) res = pdf->fitTo(*data,PrintLevel(-1),Save(),Extended(true)); if(p.size()==1 && p.find("afb") != p.end()) p["fL"] = GetParam(pdf,"fL"); else if(p.size()==1 && p.find("fL") != p.end()) p["afb"] = GetParam(pdf,"afb"); RooArgSet * nuisances = NULL; /* bool afb_iscost = false, fL_iscost = false, afbB_iscost = false; if (p.find("afb") != p.end()) { afb_iscost = ((RooRealVar*)p["afb"])->getAttribute("Constant"); ((RooRealVar*)p["afb"])->setConstant(); } if (p.find("fL") != p.end()) { fL_iscost = ((RooRealVar*)p["fL"])->getAttribute("Constant"); ((RooRealVar*)p["fL"])->setConstant(); } if (p.find("afbB") != p.end()) { afbB_iscost = ((RooRealVar*)p["afbB"])->getAttribute("Constant"); ((RooRealVar*)p["afbB"])->setConstant(); } RooArgSet * nuisances = copyFreePars(pdf,obs); if (p.find("afb") != p.end()) ((RooRealVar*)p["afb"])->setConstant(afb_iscost); if (p.find("afbB") != p.end()) ((RooRealVar*)p["afbB"])->setConstant(afbB_iscost); if (p.find("fL") != p.end()) ((RooRealVar*)p["fL"])->setConstant(fL_iscost); */ int np = 20; if((!res || res->covQual()!=3 || res->edm() > 0.1) && opt.find("-noscan")==string::npos) { if(!nll) nll = pdf->createNLL(*data); vector < double > mins, maxs, r; Str2VarMap::iterator iter; int pp = 0; for (iter = p.begin(); iter != p.end(); iter++) { RooRealVar * curp = (RooRealVar *)iter->second; maxs.push_back(curp->getMax()); mins.push_back(curp->getMin()); r.push_back((maxs.back() - mins.back())/(double)np); pp++; } findMin(pdf,data,nll,p,mins,maxs,np,isValid,nfree,opt+"-nofit",cons,nuisances); double prec = 1e6; while (prec > 0.001) { double maxr = 0; maxs.clear(); mins.clear(); pp=0; for (iter = p.begin(); iter != p.end(); iter++) { RooRealVar * curp = (RooRealVar *)iter->second; if((curp->getVal() + r[pp]) < curp->getMax()) maxs.push_back(curp->getVal() + r[pp]); else maxs.push_back(curp->getMax()); if((curp->getVal() - r[pp]) > curp->getMin()) mins.push_back(curp->getVal() - r[pp]); else mins.push_back(curp->getMin()); r[pp] = (maxs.back() - mins.back())/(double)np; if(r[pp] > maxr) maxr = r[pp]; pp++; } prec = maxr; res = findMin(pdf,data,nll,p,mins,maxs,np,isValid,nfree,opt,cons,nuisances); } //if(!mynll) delete nll; } return res; }