void Fitter::addGausFitModel(RooArgList *pdfs, RooArgList *coeffs, bool isLast) { for( int i=0;i< nGaussians ;++i) { RooRealVar *m = new RooRealVar( Form("fitmodel_gaus_mean_%d",i),Form("fitmodel_gaus_mean_%d",i), startMean_[i] ); RooRealVar *s = new RooRealVar( Form("fitmodel_gaus_sigma_%d",i), Form("fitmodel_gaus_sigma_%d",i), startSigma_[i] ); RooGaussian *gaus = new RooGaussian(Form("fitmodel_gaus_g%d",i),Form("fitmodel_gaus_g%d",i),*x_, *m, *s); vars_[ m->GetName() ] = m; vars_[ s->GetName() ] = s; pdfs -> add( *gaus ); if ( (i != nGaussians-1 ) or not isLast) { RooRealVar *f = new RooRealVar( Form("fitmodel_gaus_frac_%d",i) ,Form("fitmodel_gaus_frac_%d",i) , startFraction_[i], 0.01,1.0 ); vars_ [ f->GetName() ] = f; coeffs -> add( *f ) ; } } }
void GenericModel::ImportModelData(Int_t parameter_num, RooArgList* plist) { // Import all model datasets corresponding to the defined parameters, ranges & binnings RooArgList PLIST; if (plist) PLIST.addClone(*plist); RooRealVar* par = dynamic_cast<RooRealVar*>(fParameters.at(parameter_num)); RooAbsBinning& bins = par->getBinning(); Int_t N = bins.numBins(); RooRealVar* par_in_list = (RooRealVar*)PLIST.find(par->GetName()); if (!par_in_list) { PLIST.addClone(RooRealVar(par->GetName(), par->GetTitle(), 0.)); par_in_list = (RooRealVar*)PLIST.find(par->GetName()); } for (int i = 0; i < N; i++) { par_in_list->setMax(bins.binHigh(i)); par_in_list->setMin(bins.binLow(i)); par_in_list->setVal(bins.binCenter(i)); if ((parameter_num + 1) < GetNumberOfParameters()) ImportModelData(parameter_num + 1, &PLIST); else { AddModelData(PLIST, GetModelDataSet(PLIST)); } } }
double TwoBody::printMcmcUpperLimit( double peak, ModelConfig &_mc, std::string filename ){ // // print out the upper limit on the first Parameter of Interest // std::string _legend = "[TwoBody::printMcmcUpperLimit]: "; char buf[1024]; double _limit = numeric_limits<double>::max(); if (mcInt){ //mc.SetWorkspace(*ws); RooRealVar * firstPOI = (RooRealVar*) _mc.GetParametersOfInterest()->first(); _limit = mcInt->UpperLimit(*firstPOI); std::cout << "\n95% upper limit on " << firstPOI->GetName() << " is : " << _limit << endl; if (bMcmcConverged){ sprintf(buf, "%7.1f %7.6f", peak, _limit); } else{ sprintf(buf, "# %7.1f %7.6f # MCMC did not converge", peak, _limit); } } else{ sprintf(buf, "# MCMC did not converge"); } if (filename.size()!=0){ std::ofstream aFile; // append to file if exists aFile.open(filename.c_str(), std::ios_base::app); aFile << buf << std::endl; // close outfile here so it is safe even if subsequent iterations crash aFile.close(); } return _limit; }
/// /// Set all observables to 'toy' values drawn from the /// PDF using the current parameter values. A certain number /// of toys is pregenerated to speed up when doing mulitple toy fits. /// void PDF_Abs::setObservablesToy() { obsValSource = "toy"; if( !pdf ){ cout<< "PDF_Abs::setObservables(): ERROR: pdf not initialized."<<endl; exit(1); } if ( toyObservables==0 || iToyObs==nToyObs ) { RooRandom::randomGenerator()->SetSeed(0); if ( iToyObs==nToyObs ) delete toyObservables; toyObservables = pdf->generate(*(RooArgSet*)observables, nToyObs); iToyObs=0; } for ( int i=0; i<nObs; i++ ) { RooRealVar* pObs = (RooRealVar*)((RooArgList*)observables)->at(i); pObs->setVal(((RooRealVar*)toyObservables->get(iToyObs)->find(pObs->GetName()))->getVal()); } iToyObs+=1; }
TTree *dataset2tree(RooDataSet *dataset){ const RooArgSet *args = dataset->get(); if(args==NULL) return NULL; RooArgList argList(*args); Double_t variables[50]; Long64_t nEntries= dataset->numEntries(); //nEntries=1; TTree *tree = new TTree("tree","tree"); tree->SetDirectory(0); TIterator *it1=NULL; it1 = argList.createIterator(); int index1=0; for(RooRealVar *var = (RooRealVar *) it1->Next(); var!=NULL; var = (RooRealVar *) it1->Next(),index1++){ TString name(var->GetName()); name.ReplaceAll("-","_"); tree->Branch(name, &(variables[index1]), name+"/D"); } // tree->Print(); for(Long64_t jentry=0; jentry<nEntries; jentry++){ TIterator *it=NULL; RooArgList argList1(*(dataset->get(jentry))); it = argList1.createIterator(); //(dataset->get(jentry))->Print(); int index=0; for(RooRealVar *var = (RooRealVar *) it->Next(); var!=NULL; var = (RooRealVar *) it->Next(), index++){ variables[index]=var->getVal(); //var->Print(); } delete it; tree->Fill(); } tree->ResetBranchAddresses(); // tree->Print(); return tree; }
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 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 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; }
/// /// 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 combinedWorkspace_4WS(const char* name_pbpb_pass="******", const char* name_pbpb_fail="fitresult_pbpb_fail.root", const char* name_pp_pass="******", const char* name_pp_fail="fitresult_pp_fail.root", const char* name_out="fitresult_combo.root", const float systval = 0., const char* subDirName ="wsTest", int nCPU=2){ // subdir: Directory to save workspaces under currentPATH/CombinedWorkspaces/subDir/ // set things silent gErrorIgnoreLevel=kError; RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR); bool dosyst = (systval > 0.); TString nameOut(name_out); RooWorkspace * ws = test_combine_4WS(name_pbpb_pass, name_pp_pass, name_pbpb_fail, name_pp_fail, false, nCPU); RooAbsData * data = ws->data("dOS_DATA"); RooRealVar* RFrac2Svs1S_PbPbvsPP_P = ws->var("RFrac2Svs1S_PbPbvsPP_P"); RooRealVar* leftEdge = new RooRealVar("leftEdge","leftEdge",-10); RooRealVar* rightEdge = new RooRealVar("rightEdge","rightEdge",10); RooGenericPdf step("step", "step", "(@0 >= @1) && (@0 < @2)", RooArgList(*RFrac2Svs1S_PbPbvsPP_P, *leftEdge, *rightEdge)); ws->import(step); ws->factory( "Uniform::flat(RFrac2Svs1S_PbPbvsPP_P)" ); // systematics if (dosyst) { ws->factory( Form("kappa_syst[%f]",systval) ); ws->factory( "expr::alpha_syst('kappa_syst*beta_syst',kappa_syst,beta_syst[0,-5,5])" ); ws->factory( "Gaussian::constr_syst(beta_syst,glob_syst[0,-5,5],1)" ); // add systematics into the double ratio ws->factory( "expr::RFrac2Svs1S_PbPbvsPP_P_syst('@0+@1',RFrac2Svs1S_PbPbvsPP_P,alpha_syst)" ); // build the pbpb pdf RooRealVar* effjpsi_pp_P = (RooRealVar*)ws->var("effjpsi_pp_P"); RooRealVar* effpsip_pp_P = (RooRealVar*)ws->var("effpsip_pp_P"); RooRealVar* effjpsi_pp_NP = (RooRealVar*)ws->var("effjpsi_pp_NP"); Double_t Npsi2SPbPbPass = npsip_pbpb_pass_from_doubleratio_prompt(ws, RooArgList(*effjpsi_pp_P,*effpsip_pp_P,*effjpsi_pp_NP),true); // Create and import N_Psi2S_PbPb_pass_syst ws->factory( "SUM::pdfMASS_Tot_PbPb_pass_syst(N_Jpsi_PbPb_pass * pdfMASS_Jpsi_PbPb_pass, N_Psi2S_PbPb_pass_syst * pdfMASS_Psi2S_PbPb_pass, N_Bkg_PbPb_pass * pdfMASS_Bkg_PbPb_pass)" ); ws->factory( "PROD::pdfMASS_Tot_PbPb_pass_constr(pdfMASS_Tot_PbPb_pass_syst,constr_syst)" ); // build the combined pdf ws->factory("SIMUL::simPdf_syst_noconstr(sample,PbPb_pass=pdfMASS_Tot_PbPb_pass_syst,PbPb_fail=pdfMASS_Tot_PbPb_fail,PP_pass=pdfMASS_Tot_PP_pass,PP_fail=pdfMASS_Tot_PP_fail)"); RooSimultaneous *simPdf = (RooSimultaneous*) ws->pdf("simPdf_syst_noconstr"); RooGaussian *constr_syst = (RooGaussian*) ws->pdf("constr_syst"); RooProdPdf *simPdf_constr = new RooProdPdf("simPdf_syst","simPdf_syst",RooArgSet(*simPdf,*constr_syst)); ws->import(*simPdf_constr); } else { ws->factory("SIMUL::simPdf_syst(sample,PbPb_pass=pdfMASS_Tot_PbPb_pass,PbPb_fail=pdfMASS_Tot_PbPb_fail,PP_pass=pdfMASS_Tot_PP_pass,PP_fail=pdfMASS_Tot_PP_fail)"); } ws->Print(); if (dosyst) ws->var("beta_syst")->setConstant(kFALSE); ///////////////////////////////////////////////////////////////////// RooRealVar * pObs = ws->var("invMass"); // get the pointer to the observable RooArgSet obs("observables"); obs.add(*pObs); obs.add( *ws->cat("sample")); // ///////////////////////////////////////////////////////////////////// if (dosyst) ws->var("glob_syst")->setConstant(true); RooArgSet globalObs("global_obs"); if (dosyst) globalObs.add( *ws->var("glob_syst") ); // ws->Print(); RooArgSet poi("poi"); poi.add( *ws->var("RFrac2Svs1S_PbPbvsPP_P") ); // create set of nuisance parameters RooArgSet nuis("nuis"); if (dosyst) nuis.add( *ws->var("beta_syst") ); // set parameters constant RooArgSet allVars = ws->allVars(); TIterator* it = allVars.createIterator(); RooRealVar *theVar = (RooRealVar*) it->Next(); while (theVar) { TString varname(theVar->GetName()); // if (varname != "RFrac2Svs1S_PbPbvsPP" // && varname != "invMass" // && varname != "sample" // ) // theVar->setConstant(); if ( varname.Contains("f_Jpsi_PP") || varname.Contains("f_Jpsi_PbPb") || varname.Contains("rSigma21_Jpsi_PP") || varname.Contains("m_Jpsi_PP") || varname.Contains("m_Jpsi_PbPb") || varname.Contains("sigma1_Jpsi_PP") || varname.Contains("sigma1_Jpsi_PbPb") || (varname.Contains("lambda")) || (varname.Contains("_fail") && !varname.Contains("RFrac2Svs1S"))) { theVar->setConstant(); } if (varname=="glob_syst" || varname=="beta_syst" ) { cout << varname << endl; theVar->setConstant(!dosyst); } theVar = (RooRealVar*) it->Next(); } // create signal+background Model Config RooStats::ModelConfig sbHypo("SbHypo"); sbHypo.SetWorkspace( *ws ); sbHypo.SetPdf( *ws->pdf("simPdf_syst") ); sbHypo.SetObservables( obs ); sbHypo.SetGlobalObservables( globalObs ); sbHypo.SetParametersOfInterest( poi ); sbHypo.SetNuisanceParameters( nuis ); sbHypo.SetPriorPdf( *ws->pdf("step") ); // this is optional ///////////////////////////////////////////////////////////////////// RooAbsReal * pNll = sbHypo.GetPdf()->createNLL( *data,NumCPU(nCPU) ); RooMinuit(*pNll).migrad(); // minimize likelihood wrt all parameters before making plots if (controlPlots) { RooPlot *framepoi = ((RooRealVar *)poi.first())->frame(Bins(10),Range(0.,1),Title("LL and profileLL in RFrac2Svs1S_PbPbvsPP_P")); pNll->plotOn(framepoi,ShiftToZero()); framepoi->SetMinimum(0); framepoi->SetMaximum(10); TCanvas *cpoi = new TCanvas(); cpoi->cd(); framepoi->Draw(); cpoi->SaveAs("cpoi.pdf"); } ((RooRealVar *)poi.first())->setMin(0.); RooArgSet * pPoiAndNuisance = new RooArgSet("poiAndNuisance"); pPoiAndNuisance->add( nuis ); pPoiAndNuisance->add( poi ); sbHypo.SetSnapshot(*pPoiAndNuisance); if (controlPlots) { RooPlot* xframeSB_PP_pass = pObs->frame(Title("SBhypo_PP_pass")); data->plotOn(xframeSB_PP_pass,Cut("sample==sample::PP_pass")); RooAbsPdf *pdfSB_PP_pass = sbHypo.GetPdf(); RooCategory *sample = ws->cat("sample"); pdfSB_PP_pass->plotOn(xframeSB_PP_pass,Slice(*sample,"PP_pass"),ProjWData(*sample,*data)); TCanvas *c1 = new TCanvas(); c1->cd(); xframeSB_PP_pass->Draw(); c1->SaveAs("c1.pdf"); RooPlot* xframeSB_PP_fail = pObs->frame(Title("SBhypo_PP_fail")); data->plotOn(xframeSB_PP_fail,Cut("sample==sample::PP_fail")); RooAbsPdf *pdfSB_PP_fail = sbHypo.GetPdf(); pdfSB_PP_fail->plotOn(xframeSB_PP_fail,Slice(*sample,"PP_fail"),ProjWData(*sample,*data)); TCanvas *c2 = new TCanvas(); c2->cd(); xframeSB_PP_fail->Draw(); c2->SaveAs("c1.pdf"); RooPlot* xframeB_PbPb_pass = pObs->frame(Title("SBhypo_PbPb_pass")); data->plotOn(xframeB_PbPb_pass,Cut("sample==sample::PbPb_pass")); RooAbsPdf *pdfB_PbPb_pass = sbHypo.GetPdf(); pdfB_PbPb_pass->plotOn(xframeB_PbPb_pass,Slice(*sample,"PbPb_pass"),ProjWData(*sample,*data)); TCanvas *c3 = new TCanvas(); c3->cd(); xframeB_PbPb_pass->Draw(); c3->SetLogy(); c3->SaveAs("c2.pdf"); RooPlot* xframeB_PbPb_fail = pObs->frame(Title("SBhypo_PbPb_fail")); data->plotOn(xframeB_PbPb_fail,Cut("sample==sample::PbPb_fail")); RooAbsPdf *pdfB_PbPb_fail = sbHypo.GetPdf(); pdfB_PbPb_fail->plotOn(xframeB_PbPb_fail,Slice(*sample,"PbPb_fail"),ProjWData(*sample,*data)); TCanvas *c4 = new TCanvas(); c4->cd(); xframeB_PbPb_fail->Draw(); c4->SetLogy(); c4->SaveAs("c2.pdf"); } delete pNll; delete pPoiAndNuisance; ws->import( sbHypo ); ///////////////////////////////////////////////////////////////////// RooStats::ModelConfig bHypo = sbHypo; bHypo.SetName("BHypo"); bHypo.SetWorkspace(*ws); pNll = bHypo.GetPdf()->createNLL( *data,NumCPU(nCPU) ); // RooMinuit(*pNll).migrad(); // minimize likelihood wrt all parameters before making plots RooArgSet poiAndGlobalObs("poiAndGlobalObs"); poiAndGlobalObs.add( poi ); poiAndGlobalObs.add( globalObs ); RooAbsReal * pProfile = pNll->createProfile( poiAndGlobalObs ); // do not profile POI and global observables ((RooRealVar *)poi.first())->setVal( 0 ); // set RFrac2Svs1S_PbPbvsPP=0 here pProfile->getVal(); // this will do fit and set nuisance parameters to profiled values pPoiAndNuisance = new RooArgSet( "poiAndNuisance" ); pPoiAndNuisance->add( nuis ); pPoiAndNuisance->add( poi ); bHypo.SetSnapshot(*pPoiAndNuisance); delete pNll; delete pPoiAndNuisance; // import model config into workspace bHypo.SetWorkspace(*ws); ws->import( bHypo ); ///////////////////////////////////////////////////////////////////// ws->Print(); bHypo.Print(); sbHypo.Print(); // save workspace to file string mainDIR = gSystem->ExpandPathName(gSystem->pwd()); string wsDIR = mainDIR + "/CombinedWorkspaces/"; string ssubDirName=""; if (subDirName) ssubDirName.append(subDirName); string subDIR = wsDIR + ssubDirName; void * dirp = gSystem->OpenDirectory(wsDIR.c_str()); if (dirp) gSystem->FreeDirectory(dirp); else gSystem->mkdir(wsDIR.c_str(), kTRUE); void * dirq = gSystem->OpenDirectory(subDIR.c_str()); if (dirq) gSystem->FreeDirectory(dirq); else gSystem->mkdir(subDIR.c_str(), kTRUE); const char* saveName = Form("%s/%s",subDIR.c_str(),nameOut.Data()); ws->writeToFile(saveName); }
void StandardProfileLikelihoodDemo(const char* infile = "", const char* workspaceName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData"){ double confLevel = optPL.confLevel; double nScanPoints = optPL.nScanPoints; bool plotAsTF1 = optPL.plotAsTF1; double poiXMin = optPL.poiMinPlot; double poiXMax = optPL.poiMaxPlot; bool doHypoTest = optPL.doHypoTest; double nullParamValue = optPL.nullValue; // ------------------------------------------------------- // 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 ProfileLikelihoodCalculator // to find and plot the 95% confidence interval // on the parameter of interest as specified // in the model config ProfileLikelihoodCalculator pl(*data,*mc); pl.SetConfidenceLevel(confLevel); // 95% interval LikelihoodInterval* interval = pl.GetInterval(); // print out the interval on the first Parameter of Interest RooRealVar* firstPOI = (RooRealVar*) mc->GetParametersOfInterest()->first(); cout << "\n>>>> RESULT : " << confLevel*100 << "% interval on " <<firstPOI->GetName()<<" is : ["<< interval->LowerLimit(*firstPOI) << ", "<< interval->UpperLimit(*firstPOI) <<"]\n "<<endl; // make a plot cout << "making a plot of the profile likelihood function ....(if it is taking a lot of time use less points or the TF1 drawing option)\n"; LikelihoodIntervalPlot plot(interval); plot.SetNPoints(nScanPoints); // do not use too many points, it could become very slow for some models if (poiXMin < poiXMax) plot.SetRange(poiXMin, poiXMax); TString opt; if (plotAsTF1) opt += TString("tf1"); plot.Draw(opt); // use option TF1 if too slow (plot.Draw("tf1") // if requested perform also an hypothesis test for the significance if (doHypoTest) { RooArgSet nullparams("nullparams"); nullparams.addClone(*firstPOI); nullparams.setRealValue(firstPOI->GetName(), nullParamValue); pl.SetNullParameters(nullparams); std::cout << "Perform Test of Hypothesis : null Hypothesis is " << firstPOI->GetName() << nullParamValue << std::endl; auto result = pl.GetHypoTest(); std::cout << "\n>>>> Hypotheis Test Result \n"; result->Print(); } }
void rf403_weightedevts() { // C r e a t e o b s e r v a b l e a n d u n w e i g h t e d d a t a s e t // ------------------------------------------------------------------------------- // Declare observable RooRealVar x("x","x",-10,10) ; x.setBins(40) ; // Construction a uniform pdf RooPolynomial p0("px","px",x) ; // Sample 1000 events from pdf RooDataSet* data = p0.generate(x,1000) ; // C a l c u l a t e w e i g h t a n d m a k e d a t a s e t w e i g h t e d // ----------------------------------------------------------------------------------- // Construct formula to calculate (fake) weight for events RooFormulaVar wFunc("w","event weight","(x*x+10)",x) ; // Add column with variable w to previously generated dataset RooRealVar* w = (RooRealVar*) data->addColumn(wFunc) ; // Dataset d is now a dataset with two observable (x,w) with 1000 entries data->Print() ; // Instruct dataset wdata in interpret w as event weight rather than as observable RooDataSet wdata(data->GetName(),data->GetTitle(),data,*data->get(),0,w->GetName()) ; // Dataset d is now a dataset with one observable (x) with 1000 entries and a sum of weights of ~430K wdata.Print() ; // U n b i n n e d M L f i t t o w e i g h t e d d a t a // --------------------------------------------------------------- // Construction quadratic polynomial pdf for fitting RooRealVar a0("a0","a0",1) ; RooRealVar a1("a1","a1",0,-1,1) ; RooRealVar a2("a2","a2",1,0,10) ; RooPolynomial p2("p2","p2",x,RooArgList(a0,a1,a2),0) ; // Fit quadratic polynomial to weighted data // NOTE: A plain Maximum likelihood fit to weighted data does in general // NOT result in correct error estimates, unless individual // event weights represent Poisson statistics themselves. // // Fit with 'wrong' errors RooFitResult* r_ml_wgt = p2.fitTo(wdata,Save()) ; // A first order correction to estimated parameter errors in an // (unbinned) ML fit can be obtained by calculating the // covariance matrix as // // V' = V C-1 V // // where V is the covariance matrix calculated from a fit // to -logL = - sum [ w_i log f(x_i) ] and C is the covariance // matrix calculated from -logL' = -sum [ w_i^2 log f(x_i) ] // (i.e. the weights are applied squared) // // A fit in this mode can be performed as follows: RooFitResult* r_ml_wgt_corr = p2.fitTo(wdata,Save(),SumW2Error(kTRUE)) ; // P l o t w e i g h e d d a t a a n d f i t r e s u l t // --------------------------------------------------------------- // Construct plot frame RooPlot* frame = x.frame(Title("Unbinned ML fit, binned chi^2 fit to weighted data")) ; // Plot data using sum-of-weights-squared error rather than Poisson errors wdata.plotOn(frame,DataError(RooAbsData::SumW2)) ; // Overlay result of 2nd order polynomial fit to weighted data p2.plotOn(frame) ; // M L F i t o f p d f t o e q u i v a l e n t u n w e i g h t e d d a t a s e t // ----------------------------------------------------------------------------------------- // Construct a pdf with the same shape as p0 after weighting RooGenericPdf genPdf("genPdf","x*x+10",x) ; // Sample a dataset with the same number of events as data RooDataSet* data2 = genPdf.generate(x,1000) ; // Sample a dataset with the same number of weights as data RooDataSet* data3 = genPdf.generate(x,43000) ; // Fit the 2nd order polynomial to both unweighted datasets and save the results for comparison RooFitResult* r_ml_unw10 = p2.fitTo(*data2,Save()) ; RooFitResult* r_ml_unw43 = p2.fitTo(*data3,Save()) ; // C h i 2 f i t o f p d f t o b i n n e d w e i g h t e d d a t a s e t // ------------------------------------------------------------------------------------ // Construct binned clone of unbinned weighted dataset RooDataHist* binnedData = wdata.binnedClone() ; binnedData->Print("v") ; // Perform chi2 fit to binned weighted dataset using sum-of-weights errors // // NB: Within the usual approximations of a chi2 fit, a chi2 fit to weighted // data using sum-of-weights-squared errors does give correct error // estimates RooChi2Var chi2("chi2","chi2",p2,*binnedData,DataError(RooAbsData::SumW2)) ; RooMinuit m(chi2) ; m.migrad() ; m.hesse() ; // Plot chi^2 fit result on frame as well RooFitResult* r_chi2_wgt = m.save() ; p2.plotOn(frame,LineStyle(kDashed),LineColor(kRed)) ; // C o m p a r e f i t r e s u l t s o f c h i 2 , M L f i t s t o ( u n ) w e i g h t e d d a t a // --------------------------------------------------------------------------------------------------------------- // Note that ML fit on 1Kevt of weighted data is closer to result of ML fit on 43Kevt of unweighted data // than to 1Kevt of unweighted data, whereas the reference chi^2 fit with SumW2 error gives a result closer to // that of an unbinned ML fit to 1Kevt of unweighted data. cout << "==> ML Fit results on 1K unweighted events" << endl ; r_ml_unw10->Print() ; cout << "==> ML Fit results on 43K unweighted events" << endl ; r_ml_unw43->Print() ; cout << "==> ML Fit results on 1K weighted events with a summed weight of 43K" << endl ; r_ml_wgt->Print() ; cout << "==> Corrected ML Fit results on 1K weighted events with a summed weight of 43K" << endl ; r_ml_wgt_corr->Print() ; cout << "==> Chi2 Fit results on 1K weighted events with a summed weight of 43K" << endl ; r_chi2_wgt->Print() ; new TCanvas("rf403_weightedevts","rf403_weightedevts",600,600) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.8) ; frame->Draw() ; }
void fit_mass(TString fileN="") {//suffix added before file extension, e.g., '.pdf' TString placeholder;//to add strings before using them, e.g., for saving text files gROOT->SetBatch(kTRUE); gROOT->ProcessLine(".x /afs/cern.ch/user/m/mwilkins/cmtuser/src/lhcbStyle.C"); // gStyle->SetPadTickX(1); // gStyle->SetPadTickY(1); // gStyle->SetPadLeftMargin(0.15); // gStyle->SetTextSize(0.3); // //open file and get histogram // TFile *inHistos = new TFile("/afs/cern.ch/work/m/mwilkins/Lb2JpsiLtr/data/histos_data.root", "READ"); // TH1F * h100 = (TH1F*)inHistos->Get("h70"); // cout<<"data histogram gotten"<<endl; //unbinned TFile *hastree = new TFile("/afs/cern.ch/work/m/mwilkins/Lb2JpsiLtr/data/cutfile_Optimized.root", "READ"); TTree * h100 = (TTree*)hastree->Get("mytree"); cout<<"tree gotten"<<endl; TFile *SMChistos= new TFile("/afs/cern.ch/work/m/mwilkins/Lb2JpsiLtr/MC/withKScut/histos_SMCfile_fullMC.root", "READ"); cout<<"SMC file opened"<<endl; TH1F *SMCh = (TH1F*)SMChistos->Get("h00"); cout<<"SMC hist gotten"<<endl; RooRealVar *mass = new RooRealVar("Bs_LOKI_MASS_JpsiConstr","m(J/#psi #Lambda)",4100,6100,"MeV"); mass->setRange("bkg1",4300,4800); mass->setRange("bkg2",5700,5950); mass->setRange("bkg3",4300,5500); mass->setRange("bkg4",5100,5500); mass->setRange("L",5350,5950); mass->setRange("tot",4300,5950); cout<<"mass declared"<<endl; // RooDataHist *data = new RooDataHist("data","1D",RooArgList(*mass),h100); //unbinned RooDataSet *data = new RooDataSet("data","1D",h100,*mass); cout<<"data declared"<<endl; RooDataHist *SMC = new RooDataHist("SMC","1D",RooArgList(*mass),SMCh); cout<<"SMC hist assigned to RooDataHist"<<endl; // Construct Pdf Model // /\0 //gaussian RooRealVar mean1L("mean1L","/\\ gaus 1: mean",5621.103095,5525,5700); RooRealVar sig1L("sig1L","/\\ gaus 1: sigma",6.898126,0,100); RooGaussian gau1L("gau1L","#Lambda signal: gaussian 1",*mass,mean1L,sig1L); RooFormulaVar mean2L("mean2L","@0",mean1L); RooRealVar sig2L("sig2L","/\\ gaus 2: sigma",14.693117,0,100); RooGaussian gau2L("gau2L","#Lambda signal: gaussian 2",*mass,mean2L,sig2L); RooRealVar f1L("f1L","/\\ signal: fraction gaussian 1",0.748776,0,1); RooAddPdf sigL("sigL","#Lambda signal",RooArgList(gau1L,gau2L),RooArgList(f1L)); // //CB // RooRealVar mean3L("mean3L","/\\ CB: mean",5621.001,5525,5700); // RooRealVar sig3L("sig3L","/\\ CB: sigma",5.161,0,100); // RooRealVar alphaL3("alphaL3","/\\ CB: alpha",2.077,0,1000); // RooRealVar nL3("nL1","/\\ CB: n",0.286,0,1000); // RooCBShape CBL("CBL","#Lambda signal: CB",*mass,mean3L,sig3L,alphaL3,nL3); // RooRealVar mean4L("mean4L","/\\ gaus: mean",5621.804,5525,5700); // RooRealVar sig4L("sig4L","/\\ gaus: sigma",10.819,0,100); // RooGaussian gauL("gauL","#Lambda signal: gaussian",*mass,mean4L,sig4L); // RooRealVar f1L("f1L","/\\ signal: fraction CB",0.578,0,1); // RooAddPdf sigL("sigL","#Lambda signal",RooArgList(CBL,gauL),RooArgList(f1L)); // sigma0 //using RooHistPdf from MC--no need to build pdf here RooHistPdf sigS = makeroohistpdf(SMC,mass,"sigS","#Sigma^{0} signal (RooHistPdf)"); // /\* cout<<"Lst stuff"<<endl; RooRealVar meanLst1("meanLst1","/\\*(misc.): mean1",5011.031237,4900,5100); RooRealVar sigLst1("sigLst1","/\\*(misc.): sigma1",70.522092,0,100); RooRealVar meanLst2("mean5Lst2","/\\*(1405): mean2",5245.261703,5100,5350); RooRealVar sigLst2("sigLst2","/\\*(1405): sigma2",64.564763,0,100); RooRealVar alphaLst2("alphaLst2","/\\*(1405): alpha2",29.150301); RooRealVar nLst2("nLst2","/\\*(1405): n2",4.615817,0,50); RooGaussian gauLst1("gauLst1","#Lambda*(misc.), gaus",*mass,meanLst1,sigLst1); RooCBShape gauLst2("gauLst2","#Lambda*(1405), CB",*mass,meanLst2,sigLst2,alphaLst2,nLst2); // RooRealVar fLst1("fLst1","/\\* bkg: fraction gaus 1",0.743,0,1); // RooAddPdf bkgLst("bkgLst","#Lambda* signal",RooArgList(gauLst1,gauLst2),RooArgList(fLst1)); //Poly func BKG mass // RooRealVar b0("b0","Background: Chebychev b0",-1.071,-10000,10000); RooRealVar b1("b1","Background: Chebychev b1",-1.323004,-10,-0.00000000000000000000001); RooRealVar b2("b2","Background: Chebychev b2",0.145494,0,10); RooRealVar b3("b3","Background: Chebychev b3",-0.316,-10000,10000); RooRealVar b4("b4","Background: Chebychev b4",0.102,-10000,10000); RooRealVar b5("b5","Background: Chebychev b5",0.014,-10000,10000); RooRealVar b6("b6","Background: Chebychev b6",-0.015,-10000,10000); RooRealVar b7("b7","Background: Chebychev b7",0.012,-10000,10000); RooArgList bList(b1,b2); RooChebychev bkg("bkg","Background", *mass, bList); // TF1 *ep = new TF1("ep","[2]*exp([0]*x+[1]*x*x)",4300,5950); // ep->SetParameter(0,1); // ep->SetParameter(1,-1); // ep->SetParameter(2,2000); // ep->SetParName(0,"a"); // ep->SetParName(1,"b"); // ep->SetParName(2,"c"); // RooRealVar a("a","Background: Coefficent of x",1,-10000,10000); // RooRealVar b("b","Background: Coefficent of x*x",-1,-10000,10000); // RooRealVar c("c","Background: Coefficent of exp()",2000,-10000,10000); // RooTFnPdfBinding bkg("ep","ep",ep,RooArgList(*mass,a,b)); //number of each shape RooRealVar nbkg("nbkg","N bkg",2165.490249,0,100000000); RooRealVar nsigL("nsigL","N /\\",1689.637290,0,1000000000); RooRealVar nsigS("nsigS","N sigma",0.000002,0,10000000000); RooRealVar ngauLst1("ngauLst1","N /\\*(misc.)",439.812103,0,10000000000); RooRealVar ngauLst2("ngauLst2","N /\\*(1405)",152.061617,0,10000000000); RooRealVar nbkgLst("nbkgLst","N /\\*",591.828,0,1000000000); //add shapes and their number to a totalPdf RooArgList shapes; RooArgList yields; shapes.add(sigL); yields.add(nsigL); shapes.add(sigS); yields.add(nsigS); // shapes.add(bkgLst); yields.add(nbkgLst); shapes.add(gauLst1); yields.add(ngauLst1); shapes.add(gauLst2); yields.add(ngauLst2); shapes.add(bkg); yields.add(nbkg); RooAddPdf totalPdf("totalPdf","totalPdf",shapes,yields); //fit the totalPdf RooAbsReal * nll = totalPdf.createNLL(*data,Extended(kTRUE),Range("tot")); RooMinuit m(*nll); m.setVerbose(kFALSE); m.migrad(); m.minos(); m.minos(); //display and save information ofstream textfile;//create text file to hold data placeholder = "plots/fit"+fileN+".txt"; textfile.open(placeholder); TString outputtext;//for useful text //plot things RooPlot *framex = mass->frame(); framex->GetYaxis()->SetTitle("Events/(5 MeV)"); data->plotOn(framex,Name("Hist"),MarkerColor(kBlack),LineColor(kBlack),DataError(RooAbsData::SumW2)); totalPdf.plotOn(framex,Name("curvetot"),LineColor(kBlue)); RooArgSet* totalPdfComponents = totalPdf.getComponents(); TIterator* itertPC = totalPdfComponents->createIterator(); RooAddPdf* vartPC = (RooAddPdf*) itertPC->Next(); vartPC = (RooAddPdf*) itertPC->Next();//skip totalPdf int i=0;//color index TLegend *leg = new TLegend(0.2, 0.02, .4, .42); leg->SetTextSize(0.06); leg->AddEntry(framex->findObject("curvetot"),"Total PDF","l"); while(vartPC){//loop over compotents of totalPdf TString vartPCtitle = vartPC->GetTitle(); TIterator* itercompPars;//forward declare so it persists outside the if statement RooRealVar* varcompPars; if(!(vartPCtitle.Contains(":")||vartPCtitle.Contains("@"))){//only for non-sub-shapes while(i==0||i==10||i==4||i==1||i==5||(i>=10&&i<=27))i++;//avoid white and blue and black and yellow and horribleness RooArgSet* compPars = vartPC->getParameters(data);//set of the parameters of the component the loop is on itercompPars = compPars->createIterator(); varcompPars = (RooRealVar*) itercompPars->Next(); while(varcompPars){//write and print mean, sig, etc. of sub-shapes TString vartitle = varcompPars->GetTitle(); double varval = varcompPars->getVal(); TString varvalstring = Form("%f",varval); double hi = varcompPars->getErrorHi(); TString varerrorstring = "[exact]"; if(hi!=-1){ double lo = varcompPars->getErrorLo(); double varerror = TMath::Max(fabs(lo),hi); varerrorstring = Form("%E",varerror); } outputtext = vartitle+" = "+varvalstring+" +/- "+varerrorstring; textfile<<outputtext<<endl; cout<<outputtext<<endl; varcompPars = (RooRealVar*) itercompPars->Next(); } totalPdf.plotOn(framex,Name(vartPC->GetName()),LineStyle(kDashed),LineColor(i),Components(vartPC->GetName())); leg->AddEntry(framex->findObject(vartPC->GetName()),vartPCtitle,"l"); i++; } vartPC = (RooAddPdf*) itertPC->Next(); itercompPars->Reset();//make sure it's ready for the next vartPC } // Calculate chi2/ndf RooArgSet *floatpar = totalPdf.getParameters(data); int floatpars = (floatpar->selectByAttrib("Constant",kFALSE))->getSize(); Double_t chi2 = framex->chiSquare("curvetot","Hist",floatpars); TString chi2string = Form("%f",chi2); //create text box to list important parameters on the plot // TPaveText* txt = new TPaveText(0.1,0.5,0.7,0.9,"NBNDC"); // txt->SetTextSize(0.06); // txt->SetTextColor(kBlack); // txt->SetBorderSize(0); // txt->SetFillColor(0); // txt->SetFillStyle(0); outputtext = "#chi^{2}/N_{DoF} = "+chi2string; cout<<outputtext<<endl; textfile<<outputtext<<endl; // txt->AddText(outputtext); // Print stuff TIterator* iteryields = yields.createIterator(); RooRealVar* varyields = (RooRealVar*) iteryields->Next();//only inherits things from TObject unless class specified vector<double> Y, E;//holds yields and associated errors vector<TString> YS, ES;//holds strings of the corresponding yields int j=0;//count vector position int jS=0, jL=0;//these hold the position of the S and L results;initialized in case there is no nsigS or nsigL while(varyields){//loop over yields TString varname = varyields->GetName(); TString vartitle = varyields->GetTitle(); double varval = varyields->getVal(); Y.push_back(varval); double lo = varyields->getErrorLo(); double hi = varyields->getErrorHi(); E.push_back(TMath::Max(fabs(lo),hi)); YS.push_back(Form("%f",Y[j])); ES.push_back(Form("%f",E[j])); if(varname=="nsigS") jS=j; if(varname=="nsigL") jL=j; outputtext = vartitle+" = "+YS[j]+" +/- "+ES[j]; cout<<outputtext<<endl; textfile<<outputtext<<endl; //txt->AddText(outputtext); varyields = (RooRealVar*) iteryields->Next(); j++; } //S/L double result = Y[jS]/Y[jL]; cout<<"result declared"<<endl; double E_result = TMath::Abs(result)*sqrt(pow(E[jS]/Y[jS],2)+pow(E[jL]/Y[jL],2)); cout<<"E_result declared"<<endl; TString resultstring = Form("%E",result); TString E_resultstring = Form("%E",E_result); outputtext = "Y_{#Sigma^{0}}/Y_{#Lambda} = "+resultstring+" +/- "+E_resultstring; cout<<outputtext<<endl; textfile<<outputtext<<endl; //txt->AddText(outputtext); double resultlimit = (Y[jS]+E[jS])/(Y[jL]-E[jL]); outputtext = Form("%E",resultlimit); outputtext = "limit = "+outputtext; cout<<outputtext<<endl; textfile<<outputtext<<endl; //txt->AddText(outputtext); // Create canvas and pads, set style TCanvas *c1 = new TCanvas("c1","data fits",1200,800); TPad *pad1 = new TPad("pad1","pad1",0.0,0.3,1.0,1.0); TPad *pad2 = new TPad("pad2","pad2",0.0,0.0,1.0,0.3); pad1->SetBottomMargin(0); pad2->SetTopMargin(0); pad2->SetBottomMargin(0.5); pad2->SetBorderMode(0); pad1->SetBorderMode(0); c1->SetBorderMode(0); pad2->Draw(); pad1->Draw(); pad1->cd(); framex->SetMinimum(1); framex->SetMaximum(3000); framex->addObject(leg);//add legend to frame //framex->addObject(txt);//add text to frame gPad->SetTopMargin(0.06); pad1->SetLogy(); // pad1->Range(4100,0,6100,0.0005); pad1->Update(); framex->Draw(); // Pull distribution RooPlot *framex2 = mass->frame(); RooHist* hpull = framex->pullHist("Hist","curvetot"); framex2->addPlotable(hpull,"P"); hpull->SetLineColor(kBlack); hpull->SetMarkerColor(kBlack); framex2->SetTitle(0); framex2->GetYaxis()->SetTitle("Pull"); framex2->GetYaxis()->SetTitleSize(0.15); framex2->GetYaxis()->SetLabelSize(0.15); framex2->GetXaxis()->SetTitleSize(0.2); framex2->GetXaxis()->SetLabelSize(0.15); framex2->GetYaxis()->CenterTitle(); framex2->GetYaxis()->SetTitleOffset(0.45); framex2->GetXaxis()->SetTitleOffset(1.1); framex2->GetYaxis()->SetNdivisions(505); framex2->GetYaxis()->SetRangeUser(-8.8,8.8); pad2->cd(); framex2->Draw(); c1->cd(); placeholder = "plots/fit"+fileN+".eps"; c1->Print(placeholder); placeholder = "plots/fit"+fileN+".C"; c1->SaveAs(placeholder); textfile.close(); }
void makeAndImportDataSets(TFile *fin, RooWorkspace *wspace, RooRealVar &x){ // Get TTrees from input files and fill RooDataSets! //const char *name = x.GetName(); RooRealVar weight("weight","weight",0,100); weight.removeRange(); RooArgSet treevariables(x,weight); // List all branches in the tree and add them as variables TObjArray *branches = (TObjArray*) ((TTree*)fin->Get("data_obs"))->GetListOfBranches(); TIter next(branches); TBranch *br; while ( (br = (TBranch*)next()) ){ const char *brname = br->GetName(); std::cout << brname << std::endl; if ( *brname==*weight.GetName() ) continue; if ( *brname==*x.GetName() ) continue; RooRealVar *vartmp = new RooRealVar(brname,brname,0,1); vartmp->removeRange(); treevariables.add(*vartmp); } // RooRealVar cvar(cutvar.c_str(),cutvar.c_str(),0,100); // cvar.removeRange(); std::cout << "Building RooDataSets " << std::endl; treevariables.Print("V"); //assert(0); // Zvv Signal region MC sample RooDataSet zvv("DY","DY",treevariables,RooFit::Import(*((TTree*)fin->Get("DY"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); // Zvv Control sample // Data ... (double mu) Zvv_control RooDataSet zvvcontrol("Zvv_control","Zvv_control",treevariables,RooFit::Import(*((TTree*)fin->Get("Zvv_control"))),RooFit::Cut(cutstring.c_str())); // Backgrounds ... Zvv_control_bkg_mc RooDataSet zvvcontrolbkgmc("Zvv_control_bkg_mc","Zvv_control_bkg_mc",treevariables,RooFit::Import(*((TTree*)fin->Get("T_control_bkg_mc"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet zvvcontrolbkgmc_1("1","1",treevariables,RooFit::Import(*(TTree*)fin->Get("TT_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet zvvcontrolbkgmc_2("2","2",treevariables,RooFit::Import(*(TTree*)fin->Get("WW_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet zvvcontrolbkgmc_3("3","3",treevariables,RooFit::Import(*(TTree*)fin->Get("WZ_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet zvvcontrolbkgmc_4("4","4",treevariables,RooFit::Import(*(TTree*)fin->Get("ZZ_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); zvvcontrolbkgmc.append(zvvcontrolbkgmc_1); zvvcontrolbkgmc.append(zvvcontrolbkgmc_2); zvvcontrolbkgmc.append(zvvcontrolbkgmc_3); zvvcontrolbkgmc.append(zvvcontrolbkgmc_4); // MC ... Zvv_control_mc RooDataSet zvvcontrolmc("Zvv_control_mc","Zvv_control_mc",treevariables,RooFit::Import(*((TTree*)fin->Get("Zvv_control_mc"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); std::cout << " Weighs of datasets " << std::endl; std::cout << " Zvv_control " << zvvcontrol.sumEntries() << std::endl; std::cout << " Zvv_control_mc " << zvvcontrolmc.sumEntries() << std::endl; // Wlv Control sample (single mu) // Data ... (double mu) // Backgrounds ... //.append() // MC ... // Store these to the output workspace wspace->import(zvvcontrol); wspace->import(zvvcontrolmc); wspace->import(zvvcontrolbkgmc); wspace->import(zvv); // Wlv Signal region MC sample RooDataSet wlv("W","W",treevariables,RooFit::Import(*((TTree*)fin->Get("W"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet wlv_ht("WHT","WHT",treevariables,RooFit::Import(*((TTree*)fin->Get("WHT"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); wlv.append(wlv_ht); // Wlv Control sample // Data ... (single mu) Wlv_control RooDataSet wlvcontrol("Wlv_control","Wlv_control",treevariables,RooFit::Import(*((TTree*)fin->Get("Wlv_control"))),RooFit::Cut(cutstring.c_str())); // Backgrounds ... Wlv_control_bkg_mc RooDataSet wlvcontrolbkgmc("Wlv_control_bkg_mc","Wlv_control_bkg_mc",treevariables,RooFit::Import(*((TTree*)fin->Get("T_sl_control_bkg_mc"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet wlvcontrolbkgmc_1("1","1",treevariables,RooFit::Import(*(TTree*)fin->Get("TT_sl_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet wlvcontrolbkgmc_2("2","2",treevariables,RooFit::Import(*(TTree*)fin->Get("DY_sl_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet wlvcontrolbkgmc_3("3","3",treevariables,RooFit::Import(*(TTree*)fin->Get("WZ_sl_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet wlvcontrolbkgmc_4("4","4",treevariables,RooFit::Import(*(TTree*)fin->Get("ZZ_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet wlvcontrolbkgmc_5("5","5",treevariables,RooFit::Import(*(TTree*)fin->Get("WW_control_bkg_mc")),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); wlvcontrolbkgmc.append(wlvcontrolbkgmc_1); wlvcontrolbkgmc.append(wlvcontrolbkgmc_2); wlvcontrolbkgmc.append(wlvcontrolbkgmc_3); wlvcontrolbkgmc.append(wlvcontrolbkgmc_4); wlvcontrolbkgmc.append(wlvcontrolbkgmc_5); // MC ... Zvv_control_mc RooDataSet wlvcontrolmc("Wlv_control_mc","Wlv_control_mc",treevariables,RooFit::Import(*((TTree*)fin->Get("Wlv_control_mc_1"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); RooDataSet wlvcontrolmc_2("Wlv_control_mc_2","Wlv_control_mc_2",treevariables,RooFit::Import(*((TTree*)fin->Get("Wlv_control_mc_2"))),RooFit::Cut(cutstring.c_str()),RooFit::WeightVar("weight")); wlvcontrolmc.append(wlvcontrolmc_2); std::cout << " Weighs of datasets " << std::endl; std::cout << " Wlv_control " << wlvcontrol.sumEntries() << std::endl; std::cout << " Wlv_control_mc " << wlvcontrolmc.sumEntries() << std::endl; // Wlv Control sample (single mu) // Data ... (double mu) // Backgrounds ... //.append() // MC ... // Store these to the output workspace wspace->import(wlvcontrol); wspace->import(wlvcontrolmc); wspace->import(wlvcontrolbkgmc); wspace->import(wlv); }
void StandardBayesianNumericalDemo(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 //////////////////////////////////////////////////////////// TString filename = infile; if (filename.IsNull()) { filename = "results/example_combined_GaussExample_model.root"; std::cout << "Use standard file generated with HistFactory : " << filename << std::endl; } // Check if example input file exists TFile *file = TFile::Open(filename); // if input file was specified but not found, quit if(!file && !TString(infile).IsNull()){ cout <<"file " << filename << " 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; } ///////////////////////////////////////////////////////////// // 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() ); BayesianCalculator bayesianCalc(*data,*mc); bayesianCalc.SetConfidenceLevel(0.95); // 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) } // compute interval by scanning the posterior function if (scanPosterior) bayesianCalc.SetScanOfPosterior(nScanPoints); SimpleInterval* interval = bayesianCalc.GetInterval(); // 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() << ", "<< 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 cout << "\nDrawing plot of posterior function....." << endl; bayesianCalc.SetScanOfPosterior(nScanPoints); RooPlot * plot = bayesianCalc.GetPosteriorPlot(); plot->Draw(); }
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"); }
void CountingModelCross_2( int nobs_4m = 27, // number of observed events double b_4m = 0.09, // number of background events double sigmab_4m = 0.16, // relative uncertainty in b 1 int nobs_2e2m = 30, // number of observed events double b_2e2m = 0.47, // number of background events double sigmab_2e2m = 0.26, // relative uncertainty in b 2 int nobs_4e = 8, // number of observed events double b_4e = 0.44, // number of background events double sigmab_4e = 0.35 // relative uncertainty in b 2 ) { RooWorkspace w("w"); // make Poisson model * Gaussian constraint w.factory("prod:s_4m(cross[34.7,0.,10000000],BR_4m[0.5,0,1],Acc_4m[0.5,0.,1.],Lumi[2.229,0.,10000])"); w.factory("prod:s_2e2m(cross[34.7,0.,10000000],BR_2e2m[0.5,0,1],Acc_2e2m[0.5,0.,1.],Lumi[2.229,0.,10000])"); w.factory("prod:s_4e(cross[34.7,0.,10000000],BR_4e[0.5,0,1],Acc_4e[0.5,0.,1.],Lumi[2.229,0.,10000])"); w.factory("sum:nexp_4m(s_4m,b_4m[1,0,10])"); w.factory("sum:nexp_2e2m(s_2e2m,b_2e2m[1,0,10])"); w.factory("sum:nexp_4e(s_4e,b_4e[1,0,10])"); w.var("b_4m")->setVal(b_4m); w.var("b_2e2m")->setVal(b_2e2m); w.var("b_4e")->setVal(b_4e); // Poisson of (n | s+b) w.factory("Poisson:pdf_4m(nobs_4m[0,50],nexp_4m)"); w.factory("Poisson:pdf_2e2m(nobs_2e2m[0,50],nexp_2e2m)"); w.factory("Poisson:pdf_4e(nobs_4e[0,50],nexp_4e)"); w.factory("Gaussian:constraint_4m(b0_4m[0,10],b_4m,sigmab_4m[1])"); w.factory("Gaussian:constraint_2e2m(b0_2e2m[0,10],b_2e2m,sigmab_2e2m[1])"); w.factory("Gaussian:constraint_4e(b0_4e[0,10],b_4e,sigmab_4e[1])"); w.factory("Gaussian:constraintAcc_4m(Acc0_4m[0,1],Acc_4m,sigmaAcc_4m[1])"); w.factory("Gaussian:constraintAcc_2e2m(Acc0_2e2m[0,1],Acc_2e2m,sigmaAcc_2e2m[1])"); w.factory("Gaussian:constraintAcc_4e(Acc0_4e[0,1],Acc_4e,sigmaAcc_4e[1])"); w.factory("PROD:model_4m(pdf_4m,constraint_4m,constraintAcc_4m)"); w.factory("PROD:model_2e2m(pdf_2e2m,constraint_2e2m,constraintAcc_2e2m)"); w.factory("PROD:model_4e(pdf_4e,constraint_4e,constraintAcc_4e)"); w.factory("PROD:model(model_4m,model_2e2m,model_4e)"); w.var("b0_4m")->setVal(b_4m); w.var("b0_2e2m")->setVal(b_2e2m); w.var("b0_4e")->setVal(b_4e); w.var("b0_4m")->setConstant(true); // needed for being treated as global observables w.var("b0_2e2m")->setConstant(true); // needed for being treated as global observables w.var("b0_4e")->setConstant(true); // needed for being treated as global observables // w.var("Acc_4m")->setVal(0.844); // w.var("Acc_2e2m")->setVal(0.694); // w.var("Acc_4e")->setVal(0.60); Float_t Acc_4m = 0.844*0.5388; Float_t Acc_2e2m = 0.694*0.5388; Float_t Acc_4e = 0.60*0.5388; // Float_t Acc_4m = 0.844; // Float_t Acc_2e2m = 0.694; // Float_t Acc_4e = 0.60; Float_t sigmaAcc_4m = 0.0097 ; Float_t sigmaAcc_2e2m = 0.0097 ; Float_t sigmaAcc_4e = 0.0097 ; Float_t BRele = 0.03363; Float_t BRmu = 0.03366; Float_t BR_4m = BRmu*BRmu; Float_t BR_2e2m = 2*BRmu*BRele; Float_t BR_4e = BRele*BRele; Float_t BR = BR_4m+BR_2e2m+BR_4e; cout<<"BR sum"<<BR<<" BRmean "<<(BR_4m + BR_4e + BR_2e2m)/3.<<" BR_4m "<<BR_4m<<" BR_2e2m "<<BR_2e2m<<" BR_4e "<<BR_4e<<endl; w.var("BR_4m")->setVal(BR_4m); w.var("BR_2e2m")->setVal(BR_2e2m); w.var("BR_4e")->setVal(BR_4e); w.var("BR_4m")->setConstant(true); // needed for being treated as global observables w.var("BR_2e2m")->setConstant(true); // needed for being treated as global observables w.var("BR_4e")->setConstant(true); // needed for being treated as global observables w.var("Lumi")->setVal(2.560); w.var("Lumi")->setConstant(true); w.var("sigmab_4m")->setVal(sigmab_4m*b_4m); w.var("sigmab_2e2m")->setVal(sigmab_2e2m*b_2e2m); w.var("sigmab_4e")->setVal(sigmab_4e*b_4e); w.var("sigmaAcc_4m")->setVal(sigmaAcc_4m*Acc_4m); w.var("sigmaAcc_2e2m")->setVal(sigmaAcc_2e2m*Acc_2e2m); w.var("sigmaAcc_4e")->setVal(sigmaAcc_4e*Acc_4e); ModelConfig mc("ModelConfig",&w); mc.SetPdf(*w.pdf("model")); mc.SetParametersOfInterest(*w.var("cross")); mc.SetObservables(RooArgSet(*w.var("nobs_4m"),*w.var("nobs_2e2m"),*w.var("nobs_4e"))); // mc.SetNuisanceParameters(RooArgSet(*w.var("b_4m"),*w.var("b_2e2m"),*w.var("b_4e"))); //mc.SetObservables(RooArgSet(*w.var("nobs_4m"),*w.var("nobs_2e2m"))); // mc.SetNuisanceParameters(RooArgSet(*w.var("b_4m"),*w.var("b_2e2m"),*w.var("Acc_4m"),*w.var("Acc_2e2m"))); mc.SetNuisanceParameters(RooArgSet(*w.var("b_4m"),*w.var("b_2e2m"),*w.var("b_4e"),*w.var("Acc_4m"),*w.var("Acc_2e2m"),*w.var("Acc_4e"))); mc.SetParametersOfInterest(*w.var("cross")); // these are needed for the hypothesis tests mc.SetSnapshot(*w.var("cross")); // mc.SetGlobalObservables(RooArgSet(*w.var("b0_4m"),*w.var("b0_2e2m"),*w.var("b0_4e"))); mc.Print(); // import model in the workspace w.import(mc); // make data set with the namber of observed events RooDataSet data("data","", RooArgSet(*w.var("nobs_4m"),*w.var("nobs_2e2m"),*w.var("nobs_4e"))); //RooDataSet data("data","", RooArgSet(*w.var("nobs_4m"),*w.var("nobs_2e2m"))); w.var("nobs_4m")->setVal(nobs_4m); data.add(*w.var("nobs_4m") ); w.var("nobs_2e2m")->setVal(nobs_2e2m); data.add(*w.var("nobs_2e2m") ); w.var("nobs_4e")->setVal(nobs_4e); data.add(*w.var("nobs_4e") ); // import data set in workspace and save it in a file ProfileLikelihoodCalculator pl(data, mc); pl.SetConfidenceLevel(0.68); // 95% interval LikelihoodInterval* interval = pl.GetInterval(); // print out the iterval on the first Parameter of Interest RooRealVar* firstPOI = (RooRealVar*) mc.GetParametersOfInterest()->first(); cout << "\n65% interval on " <<firstPOI->GetName()<<" is : ["<< interval->LowerLimit(*firstPOI) << ", "<< interval->UpperLimit(*firstPOI) <<"] "<<endl; std::cout<<"Cross "<<mc.GetParametersOfInterest()->getRealValue("cross")*BR<<std::endl; w.import(data); w.Print(); TString fileName = "CountingModel.root"; // write workspace in the file (recreate file if already existing) w.writeToFile(fileName, true); }
/// /// Print this PDF in a verbose way: /// - observables /// - correlations /// - parameters /// void PDF_Abs::print() const { TString cleanName = name; cout << "PDF: " << cleanName.ReplaceAll(uniqueID,"") << " (" << uniqueID << ")" << endl << endl; if ( observables ){ cout << " observables:" << endl; cout << " nObs = " << nObs << endl; cout << " values from: " << obsValSource << endl; cout << " errors from: " << obsErrSource << endl; for ( int iObs=0; iObs<nObs; iObs++ ){ RooRealVar* v = (RooRealVar*)observables->at(iObs); TString obsName = v->GetName(); obsName.ReplaceAll(uniqueID,""); printf(" %-20s = %8.5f +/- %7.5f +/- %7.5f\n", obsName.Data(), v->getVal(), StatErr[iObs], SystErr[iObs]); } } else cout << "PDF_Abs::print() : observables not initialized. Call initObservables() first." << endl; cout << endl; if ( nObs>1 ){ printCorMatrix("(stat+syst)", corSource, corMatrix); printCorMatrix("(stat)", corSource, corStatMatrix); printCorMatrix("(syst)", corSource, corSystMatrix); } if ( parameters ){ cout << " parameters:" << endl; cout << " nPar = " << parameters->getSize() << endl; cout << " "; bool first=true; TIterator* it = parameters->createIterator(); while ( RooAbsReal* v = (RooAbsReal*)it->Next() ){ cout << (first?"":", ") << v->GetName(); first=false; } delete it; cout << endl; } else cout << "PDF_Abs::print() : parameters not initialized. Call initParameters() first." << endl; cout << endl; if ( theory ){ cout << " relations:" << endl; TIterator* it = theory->createIterator(); while ( RooAbsReal* v = (RooAbsReal*)it->Next() ){ // it's not easy to extract the formula from a RooFormulaVar. TString thName = v->GetName(); thName.ReplaceAll(uniqueID,""); printf(" %-20s = ", thName.Data()); ostringstream stream; v->printMetaArgs(stream); TString formula = stream.str(); formula.ReplaceAll("formula=", ""); formula.ReplaceAll("\"", ""); if ( formula=="" ) formula = v->ClassName(); // compiled custom Roo*Var classes don't have a formula cout << formula << endl; } delete it; } else cout << "PDF_Abs::print() : theory not initialized. Call initRelations() first." << endl; cout << endl; }
void PDF_GLWADS_DKDpi_K3pi::setUncertainties(config c) { switch(c) { case lumi1fb:{ obsErrSource = "1fb-1, ExpNll/sept2012K3PIResult.root"; TString File = this->dir+"/ExpNll/sept2012K3PIResult.root"; TFile *fr = TFile::Open(File); RooFitResult *r = (RooFitResult*)fr->Get("fitresult_model_reducedData_binned"); assert(r); for ( int i=0; i<nObs; i++ ) { RooRealVar* pObs = (RooRealVar*)((RooArgList*)observables)->at(i); RooRealVar* pRes = (RooRealVar*)r->floatParsFinal().find(obsTmkToMalcolm(pObs->GetName())); assert(pRes); StatErr[i] = pRes->getError(); } SystErr[0] = 0.0026; // rkp_k3pi_obs SystErr[1] = 0.018; // afav_dk_obs SystErr[2] = 0.010; // afav_dpi_obs SystErr[3] = 0.0010; // rp_dk_obs SystErr[4] = 0.0008; // rm_dk_obs SystErr[5] = 0.00011; // rp_dpi_obs SystErr[6] = 0.00011; // rm_dpi_obs fr->Close(); delete r; delete fr; break; } case lumi3fb:{ obsErrSource = "3fb-1 ANA v7 unblind"; // https://twiki.cern.ch/twiki/pub/LHCbPhysics/B2D0K/LHCb-ANA-2014-071-v7.pdf (see Vavas email 04/08/15) // these get transformed over from the new inputs using ExpNll/transportGLWADS_new_to_old.py // in the case of the DK only (robust) combination some of the observables don't exist // usemap as the temp store std::map< TString, double > stat_errs; stat_errs["rkp_k3pi_obs"] = 0.0010; // rkp_k3pi_obs stat_errs["afav_dk_k3pi_obs"] = 0.0119; // afav_dk_obs stat_errs["afav_dpi_k3pi_obs"] = 0.1; // afav_dpi_obs // now Aprod, large error to disable it stat_errs["rp_dk_k3pi_obs"] = 0.002421; // rp_dk_obs stat_errs["rm_dk_k3pi_obs"] = 0.001756; // rm_dk_obs stat_errs["rp_dpi_k3pi_obs"] = 0.000252; // rp_dpi_obs stat_errs["rm_dpi_k3pi_obs"] = 0.000258; // rm_dpi_obs for ( int i=0; i<nObs; i++ ) { RooRealVar* pObs = (RooRealVar*)((RooArgList*)observables)->at(i); StatErr[i] = stat_errs[pObs->GetName()]; } stat_errs.clear(); std::map< TString, double > syst_errs; syst_errs["rkp_k3pi_obs"] = 0.0170; // rkp_k3pi_obs syst_errs["afav_dk_k3pi_obs"] = 0.0019; // afav_dk_obs syst_errs["afav_dpi_k3pi_obs"] = 0.1; // afav_dpi_obs // now Aprod, large error to disable it syst_errs["rp_dk_k3pi_obs"] = 0.000950; // rp_dk_obs syst_errs["rm_dk_k3pi_obs"] = 0.000673; // rm_dk_obs syst_errs["rp_dpi_k3pi_obs"] = 0.000061; // rp_dpi_obs syst_errs["rm_dpi_k3pi_obs"] = 0.000064; // rm_dpi_obs for ( int i=0; i<nObs; i++ ) { RooRealVar* pObs = (RooRealVar*)((RooArgList*)observables)->at(i); SystErr[i] = syst_errs[pObs->GetName()]; } syst_errs.clear(); break; } case lumi9fb:{ setUncertainties(lumi3fb); obsErrSource = "9fb-1 errors obtained from scaling down the 3fb-1 errors (lumi3fb)"; for ( int i=0; i<nObs; i++ ){ StatErr[i] /= (sqrt(2.7)); SystErr[i] /= (sqrt(2.7)); } break; } default:{ cout << "PDF_GLWADS_DKDpi_K3pi::setUncertainties() : ERROR : config "+ConfigToTString(c)+" not found." << endl; exit(1); } } }
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 ws_constrained_profile3D( const char* wsfile = "rootfiles/ws-data-unblind.root", const char* new_poi_name = "n_M234_H4_3b", int npoiPoints = 20, double poiMinVal = 0., double poiMaxVal = 20., double constraintWidth = 1.5, double ymax = 10., int verbLevel=0 ) { gStyle->SetOptStat(0) ; //--- make output directory. char command[10000] ; sprintf( command, "basename %s", wsfile ) ; TString wsfilenopath = gSystem->GetFromPipe( command ) ; wsfilenopath.ReplaceAll(".root","") ; char outputdirstr[1000] ; sprintf( outputdirstr, "outputfiles/scans-%s", wsfilenopath.Data() ) ; TString outputdir( outputdirstr ) ; printf("\n\n Creating output directory: %s\n\n", outputdir.Data() ) ; sprintf(command, "mkdir -p %s", outputdir.Data() ) ; gSystem->Exec( command ) ; //--- Tell RooFit to shut up about anything less important than an ERROR. RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ; if ( verbLevel > 0 ) { printf("\n\n Verbose level : %d\n\n", verbLevel) ; } TFile* wstf = new TFile( wsfile ) ; RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") ); if ( verbLevel > 0 ) { ws->Print() ; } RooDataSet* rds = (RooDataSet*) ws->obj( "ra2b_observed_rds" ) ; if ( verbLevel > 0 ) { printf("\n\n\n ===== RooDataSet ====================\n\n") ; rds->Print() ; rds->printMultiline(cout, 1, kTRUE, "") ; } ModelConfig* modelConfig = (ModelConfig*) ws->obj( "SbModel" ) ; RooAbsPdf* likelihood = modelConfig->GetPdf() ; RooRealVar* rrv_mu_susy_all0lep = ws->var("mu_susy_all0lep") ; if ( rrv_mu_susy_all0lep == 0x0 ) { printf("\n\n\n *** can't find mu_susy_all0lep in workspace. Quitting.\n\n\n") ; return ; } //-- do BG only. rrv_mu_susy_all0lep->setVal(0.) ; rrv_mu_susy_all0lep->setConstant( kTRUE ) ; //-- do a prefit. printf("\n\n\n ====== Pre fit with unmodified nll var.\n\n") ; RooFitResult* dataFitResultSusyFixed = likelihood->fitTo(*rds, Save(true),Hesse(false),Minos(false),Strategy(1),PrintLevel(verbLevel)); int dataSusyFixedFitCovQual = dataFitResultSusyFixed->covQual() ; if ( dataSusyFixedFitCovQual < 2 ) { printf("\n\n\n *** Failed fit! Cov qual %d. Quitting.\n\n", dataSusyFixedFitCovQual ) ; return ; } double dataFitSusyFixedNll = dataFitResultSusyFixed->minNll() ; if ( verbLevel > 0 ) { dataFitResultSusyFixed->Print("v") ; } printf("\n\n Nll value, from fit result : %.3f\n\n", dataFitSusyFixedNll ) ; delete dataFitResultSusyFixed ; //-- Construct the new POI parameter. RooAbsReal* new_poi_rar(0x0) ; new_poi_rar = ws->var( new_poi_name ) ; if ( new_poi_rar == 0x0 ) { printf("\n\n New POI %s is not a variable. Trying function.\n\n", new_poi_name ) ; new_poi_rar = ws->function( new_poi_name ) ; if ( new_poi_rar == 0x0 ) { printf("\n\n New POI %s is not a function. I quit.\n\n", new_poi_name ) ; return ; } } else { printf("\n\n New POI %s is a variable with current value %.1f.\n\n", new_poi_name, new_poi_rar->getVal() ) ; } if ( npoiPoints <=0 ) { printf("\n\n Quitting now.\n\n" ) ; return ; } double startPoiVal = new_poi_rar->getVal() ; //--- The RooNLLVar is NOT equivalent to what minuit uses. // RooNLLVar* nll = new RooNLLVar("nll","nll", *likelihood, *rds ) ; // printf("\n\n Nll value, from construction : %.3f\n\n", nll->getVal() ) ; //--- output of createNLL IS what minuit uses, so use that. RooAbsReal* nll = likelihood -> createNLL( *rds, Verbose(true) ) ; RooRealVar* rrv_poiValue = new RooRealVar( "poiValue", "poiValue", 0., -10000., 10000. ) ; /// rrv_poiValue->setVal( poiMinVal ) ; /// rrv_poiValue->setConstant(kTRUE) ; RooRealVar* rrv_constraintWidth = new RooRealVar("constraintWidth","constraintWidth", 0.1, 0.1, 1000. ) ; rrv_constraintWidth -> setVal( constraintWidth ) ; rrv_constraintWidth -> setConstant(kTRUE) ; if ( verbLevel > 0 ) { printf("\n\n ======= debug likelihood print\n\n") ; likelihood->Print("v") ; printf("\n\n ======= debug nll print\n\n") ; nll->Print("v") ; } //---------------------------------------------------------------------------------------------- RooMinuit* rminuit( 0x0 ) ; RooMinuit* rminuit_uc = new RooMinuit( *nll ) ; rminuit_uc->setPrintLevel(verbLevel-1) ; rminuit_uc->setNoWarn() ; rminuit_uc->migrad() ; rminuit_uc->hesse() ; RooFitResult* rfr_uc = rminuit_uc->fit("mr") ; double floatParInitVal[10000] ; char floatParName[10000][100] ; int nFloatParInitVal(0) ; RooArgList ral_floats = rfr_uc->floatParsFinal() ; TIterator* floatParIter = ral_floats.createIterator() ; { RooRealVar* par ; while ( (par = (RooRealVar*) floatParIter->Next()) ) { sprintf( floatParName[nFloatParInitVal], "%s", par->GetName() ) ; floatParInitVal[nFloatParInitVal] = par->getVal() ; nFloatParInitVal++ ; } } //------- printf("\n\n Unbiased best value for new POI %s is : %7.1f\n\n", new_poi_rar->GetName(), new_poi_rar->getVal() ) ; double best_poi_val = new_poi_rar->getVal() ; char minuit_formula[10000] ; sprintf( minuit_formula, "%s+%s*(%s-%s)*(%s-%s)", nll->GetName(), rrv_constraintWidth->GetName(), new_poi_rar->GetName(), rrv_poiValue->GetName(), new_poi_rar->GetName(), rrv_poiValue->GetName() ) ; printf("\n\n Creating new minuit variable with formula: %s\n\n", minuit_formula ) ; RooFormulaVar* new_minuit_var = new RooFormulaVar("new_minuit_var", minuit_formula, RooArgList( *nll, *rrv_constraintWidth, *new_poi_rar, *rrv_poiValue, *new_poi_rar, *rrv_poiValue ) ) ; printf("\n\n Current value is %.2f\n\n", new_minuit_var->getVal() ) ; rminuit = new RooMinuit( *new_minuit_var ) ; RooAbsReal* plot_var = nll ; printf("\n\n Current value is %.2f\n\n", plot_var->getVal() ) ; rminuit->setPrintLevel(verbLevel-1) ; if ( verbLevel <=0 ) { rminuit->setNoWarn() ; } //---------------------------------------------------------------------------------------------- //-- If POI range is -1 to -1, automatically determine the range using the set value. if ( poiMinVal < 0. && poiMaxVal < 0. ) { printf("\n\n Automatic determination of scan range.\n\n") ; if ( startPoiVal <= 0. ) { printf("\n\n *** POI starting value zero or negative %g. Quit.\n\n\n", startPoiVal ) ; return ; } poiMinVal = startPoiVal - 3.5 * sqrt(startPoiVal) ; poiMaxVal = startPoiVal + 6.0 * sqrt(startPoiVal) ; if ( poiMinVal < 0. ) { poiMinVal = 0. ; } printf(" Start val = %g. Scan range: %g to %g\n\n", startPoiVal, poiMinVal, poiMaxVal ) ; } //---------------------------------------------------------------------------------------------- double poiVals_scanDown[1000] ; double nllVals_scanDown[1000] ; //-- Do scan down from best value. printf("\n\n +++++ Starting scan down from best value.\n\n") ; double minNllVal(1.e9) ; for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) { ////double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*(npoiPoints-1)) ; double poiValue = best_poi_val - poivi*(best_poi_val-poiMinVal)/(1.*(npoiPoints/2-1)) ; rrv_poiValue -> setVal( poiValue ) ; rrv_poiValue -> setConstant( kTRUE ) ; //+++++++++++++++++++++++++++++++++++ rminuit->migrad() ; rminuit->hesse() ; RooFitResult* rfr = rminuit->save() ; //+++++++++++++++++++++++++++++++++++ if ( verbLevel > 0 ) { rfr->Print("v") ; } float fit_minuit_var_val = rfr->minNll() ; printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI : %.5f %.5f %.5f %.5f\n", poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ; cout << flush ; poiVals_scanDown[poivi] = new_poi_rar->getVal() ; nllVals_scanDown[poivi] = plot_var->getVal() ; if ( nllVals_scanDown[poivi] < minNllVal ) { minNllVal = nllVals_scanDown[poivi] ; } delete rfr ; } // poivi printf("\n\n +++++ Resetting floats to best fit values.\n\n") ; for ( int pi=0; pi<nFloatParInitVal; pi++ ) { RooRealVar* par = ws->var( floatParName[pi] ) ; par->setVal( floatParInitVal[pi] ) ; } // pi. printf("\n\n +++++ Starting scan up from best value.\n\n") ; //-- Now do scan up. double poiVals_scanUp[1000] ; double nllVals_scanUp[1000] ; for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) { double poiValue = best_poi_val + poivi*(poiMaxVal-best_poi_val)/(1.*(npoiPoints/2-1)) ; rrv_poiValue -> setVal( poiValue ) ; rrv_poiValue -> setConstant( kTRUE ) ; //+++++++++++++++++++++++++++++++++++ rminuit->migrad() ; rminuit->hesse() ; RooFitResult* rfr = rminuit->save() ; //+++++++++++++++++++++++++++++++++++ if ( verbLevel > 0 ) { rfr->Print("v") ; } float fit_minuit_var_val = rfr->minNll() ; printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI : %.5f %.5f %.5f %.5f\n", poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ; cout << flush ; poiVals_scanUp[poivi] = new_poi_rar->getVal() ; nllVals_scanUp[poivi] = plot_var->getVal() ; if ( nllVals_scanUp[poivi] < minNllVal ) { minNllVal = nllVals_scanUp[poivi] ; } delete rfr ; } // poivi double poiVals[1000] ; double nllVals[1000] ; int pointCount(0) ; for ( int pi=0; pi<npoiPoints/2; pi++ ) { poiVals[pi] = poiVals_scanDown[(npoiPoints/2-1)-pi] ; nllVals[pi] = nllVals_scanDown[(npoiPoints/2-1)-pi] ; pointCount++ ; } for ( int pi=1; pi<npoiPoints/2; pi++ ) { poiVals[pointCount] = poiVals_scanUp[pi] ; nllVals[pointCount] = nllVals_scanUp[pi] ; pointCount++ ; } npoiPoints = pointCount ; printf("\n\n --- TGraph arrays:\n") ; for ( int i=0; i<npoiPoints; i++ ) { printf(" %2d : poi = %6.1f, nll = %g\n", i, poiVals[i], nllVals[i] ) ; } printf("\n\n") ; double nllDiffVals[1000] ; double poiAtMinlnL(-1.) ; double poiAtMinusDelta2(-1.) ; double poiAtPlusDelta2(-1.) ; for ( int poivi=0; poivi < npoiPoints ; poivi++ ) { nllDiffVals[poivi] = 2.*(nllVals[poivi] - minNllVal) ; double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*npoiPoints) ; if ( nllDiffVals[poivi] < 0.01 ) { poiAtMinlnL = poiValue ; } if ( poiAtMinusDelta2 < 0. && nllDiffVals[poivi] < 2.5 ) { poiAtMinusDelta2 = poiValue ; } if ( poiAtMinlnL > 0. && poiAtPlusDelta2 < 0. && nllDiffVals[poivi] > 2.0 ) { poiAtPlusDelta2 = poiValue ; } } // poivi printf("\n\n Estimates for poi at delta ln L = -2, 0, +2: %g , %g , %g\n\n", poiAtMinusDelta2, poiAtMinlnL, poiAtPlusDelta2 ) ; //--- Main canvas TCanvas* cscan = (TCanvas*) gDirectory->FindObject("cscan") ; if ( cscan == 0x0 ) { printf("\n Creating canvas.\n\n") ; cscan = new TCanvas("cscan","Delta nll") ; } char gname[1000] ; TGraph* graph = new TGraph( npoiPoints, poiVals, nllDiffVals ) ; sprintf( gname, "scan_%s", new_poi_name ) ; graph->SetName( gname ) ; double poiBest(-1.) ; double poiMinus1stdv(-1.) ; double poiPlus1stdv(-1.) ; double poiMinus2stdv(-1.) ; double poiPlus2stdv(-1.) ; double twoDeltalnLMin(1e9) ; int nscan(1000) ; for ( int xi=0; xi<nscan; xi++ ) { double x = poiVals[0] + xi*(poiVals[npoiPoints-1]-poiVals[0])/(nscan-1) ; double twoDeltalnL = graph -> Eval( x, 0, "S" ) ; if ( poiMinus1stdv < 0. && twoDeltalnL < 1.0 ) { poiMinus1stdv = x ; printf(" set m1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( poiMinus2stdv < 0. && twoDeltalnL < 4.0 ) { poiMinus2stdv = x ; printf(" set m2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( twoDeltalnL < twoDeltalnLMin ) { poiBest = x ; twoDeltalnLMin = twoDeltalnL ; } if ( twoDeltalnLMin < 0.3 && poiPlus1stdv < 0. && twoDeltalnL > 1.0 ) { poiPlus1stdv = x ; printf(" set p1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( twoDeltalnLMin < 0.3 && poiPlus2stdv < 0. && twoDeltalnL > 4.0 ) { poiPlus2stdv = x ; printf(" set p2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( xi%100 == 0 ) { printf( " %4d : poi=%6.2f, 2DeltalnL = %6.2f\n", xi, x, twoDeltalnL ) ; } } printf("\n\n POI estimate : %g +%g -%g [%g,%g], two sigma errors: +%g -%g [%g,%g]\n\n", poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), poiMinus1stdv, poiPlus1stdv, (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv), poiMinus2stdv, poiPlus2stdv ) ; printf(" %s val,pm1sig,pm2sig: %7.2f %7.2f %7.2f %7.2f %7.2f\n", new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv) ) ; char htitle[1000] ; sprintf(htitle, "%s profile likelihood scan: -2ln(L/Lm)", new_poi_name ) ; TH1F* hscan = new TH1F("hscan", htitle, 10, poiMinVal, poiMaxVal ) ; hscan->SetMinimum(0.) ; hscan->SetMaximum(ymax) ; hscan->DrawCopy() ; graph->SetLineColor(4) ; graph->SetLineWidth(3) ; graph->Draw("CP") ; gPad->SetGridx(1) ; gPad->SetGridy(1) ; cscan->Update() ; TLine* line = new TLine() ; line->SetLineColor(2) ; line->DrawLine(poiMinVal, 1., poiPlus1stdv, 1.) ; line->DrawLine(poiMinus1stdv,0., poiMinus1stdv, 1.) ; line->DrawLine(poiPlus1stdv ,0., poiPlus1stdv , 1.) ; TText* text = new TText() ; text->SetTextSize(0.04) ; char tstring[1000] ; sprintf( tstring, "%s = %.1f +%.1f -%.1f", new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv) ) ; text -> DrawTextNDC( 0.15, 0.85, tstring ) ; sprintf( tstring, "68%% interval [%.1f, %.1f]", poiMinus1stdv, poiPlus1stdv ) ; text -> DrawTextNDC( 0.15, 0.78, tstring ) ; char hname[1000] ; sprintf( hname, "hscanout_%s", new_poi_name ) ; TH1F* hsout = new TH1F( hname,"scan results",4,0.,4.) ; double obsVal(-1.) ; hsout->SetBinContent(1, obsVal ) ; hsout->SetBinContent(2, poiPlus1stdv ) ; hsout->SetBinContent(3, poiBest ) ; hsout->SetBinContent(4, poiMinus1stdv ) ; TAxis* xaxis = hsout->GetXaxis() ; xaxis->SetBinLabel(1,"Observed val.") ; xaxis->SetBinLabel(2,"Model+1sd") ; xaxis->SetBinLabel(3,"Model") ; xaxis->SetBinLabel(4,"Model-1sd") ; char outrootfile[10000] ; sprintf( outrootfile, "%s/scan-ff-%s.root", outputdir.Data(), new_poi_name ) ; char outpdffile[10000] ; sprintf( outpdffile, "%s/scan-ff-%s.pdf", outputdir.Data(), new_poi_name ) ; cscan->Update() ; cscan->Draw() ; printf("\n Saving %s\n", outpdffile ) ; cscan->SaveAs( outpdffile ) ; //--- save in root file printf("\n Saving %s\n", outrootfile ) ; TFile fout(outrootfile,"recreate") ; graph->Write() ; hsout->Write() ; fout.Close() ; delete ws ; wstf->Close() ; }
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 StandardHistFactoryPlotsWithCategories(const char* infile = "", const char* workspaceName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData"){ double nSigmaToVary=5.; double muVal=0; bool doFit=false; // ------------------------------------------------------- // 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; } // ------------------------------------------------------- // now use the profile inspector RooRealVar* obs = (RooRealVar*)mc->GetObservables()->first(); TList* list = new TList(); RooRealVar * firstPOI = dynamic_cast<RooRealVar*>(mc->GetParametersOfInterest()->first()); firstPOI->setVal(muVal); // firstPOI->setConstant(); if(doFit){ mc->GetPdf()->fitTo(*data); } // ------------------------------------------------------- mc->GetNuisanceParameters()->Print("v"); int nPlotsMax = 1000; cout <<" check expectedData by category"<<endl; RooDataSet* simData=NULL; RooSimultaneous* simPdf = NULL; if(strcmp(mc->GetPdf()->ClassName(),"RooSimultaneous")==0){ cout <<"Is a simultaneous PDF"<<endl; simPdf = (RooSimultaneous *)(mc->GetPdf()); } else { cout <<"Is not a simultaneous PDF"<<endl; } if(doFit) { RooCategory* channelCat = (RooCategory*) (&simPdf->indexCat()); TIterator* iter = channelCat->typeIterator() ; RooCatType* tt = NULL; tt=(RooCatType*) iter->Next(); RooAbsPdf* pdftmp = ((RooSimultaneous*)mc->GetPdf())->getPdf(tt->GetName()) ; RooArgSet* obstmp = pdftmp->getObservables(*mc->GetObservables()) ; obs = ((RooRealVar*)obstmp->first()); RooPlot* frame = obs->frame(); cout <<Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())<<endl; cout << tt->GetName() << " " << channelCat->getLabel() <<endl; data->plotOn(frame,MarkerSize(1),Cut(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())),DataError(RooAbsData::None)); Double_t normCount = data->sumEntries(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())) ; pdftmp->plotOn(frame,LineWidth(2.),Normalization(normCount,RooAbsReal::NumEvent)) ; frame->Draw(); cout <<"expected events = " << mc->GetPdf()->expectedEvents(*data->get()) <<endl; return; } int nPlots=0; if(!simPdf){ TIterator* it = mc->GetNuisanceParameters()->createIterator(); RooRealVar* var = NULL; while( (var = (RooRealVar*) it->Next()) != NULL){ RooPlot* frame = obs->frame(); frame->SetYTitle(var->GetName()); data->plotOn(frame,MarkerSize(1)); var->setVal(0); mc->GetPdf()->plotOn(frame,LineWidth(1.)); var->setVal(1); mc->GetPdf()->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(1)); var->setVal(-1); mc->GetPdf()->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(1)); list->Add(frame); var->setVal(0); } } else { RooCategory* channelCat = (RooCategory*) (&simPdf->indexCat()); // TIterator* iter = simPdf->indexCat().typeIterator() ; TIterator* iter = channelCat->typeIterator() ; RooCatType* tt = NULL; while(nPlots<nPlotsMax && (tt=(RooCatType*) iter->Next())) { cout << "on type " << tt->GetName() << " " << endl; // Get pdf associated with state from simpdf RooAbsPdf* pdftmp = simPdf->getPdf(tt->GetName()) ; // Generate observables defined by the pdf associated with this state RooArgSet* obstmp = pdftmp->getObservables(*mc->GetObservables()) ; // obstmp->Print(); obs = ((RooRealVar*)obstmp->first()); TIterator* it = mc->GetNuisanceParameters()->createIterator(); RooRealVar* var = NULL; while(nPlots<nPlotsMax && (var = (RooRealVar*) it->Next())){ TCanvas* c2 = new TCanvas("c2"); RooPlot* frame = obs->frame(); frame->SetName(Form("frame%d",nPlots)); frame->SetYTitle(var->GetName()); cout <<Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())<<endl; cout << tt->GetName() << " " << channelCat->getLabel() <<endl; data->plotOn(frame,MarkerSize(1),Cut(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())),DataError(RooAbsData::None)); Double_t normCount = data->sumEntries(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())) ; if(strcmp(var->GetName(),"Lumi")==0){ cout <<"working on lumi"<<endl; var->setVal(w->var("nominalLumi")->getVal()); var->Print(); } else{ var->setVal(0); } // w->allVars().Print("v"); // mc->GetNuisanceParameters()->Print("v"); // pdftmp->plotOn(frame,LineWidth(2.)); // mc->GetPdf()->plotOn(frame,LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data)); //pdftmp->plotOn(frame,LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data)); normCount = pdftmp->expectedEvents(*obs); pdftmp->plotOn(frame,LineWidth(2.),Normalization(normCount,RooAbsReal::NumEvent)) ; if(strcmp(var->GetName(),"Lumi")==0){ cout <<"working on lumi"<<endl; var->setVal(w->var("nominalLumi")->getVal()+0.05); var->Print(); } else{ var->setVal(nSigmaToVary); } // pdftmp->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2)); // mc->GetPdf()->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data)); //pdftmp->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data)); normCount = pdftmp->expectedEvents(*obs); pdftmp->plotOn(frame,LineWidth(2.),LineColor(kRed),LineStyle(kDashed),Normalization(normCount,RooAbsReal::NumEvent)) ; if(strcmp(var->GetName(),"Lumi")==0){ cout <<"working on lumi"<<endl; var->setVal(w->var("nominalLumi")->getVal()-0.05); var->Print(); } else{ var->setVal(-nSigmaToVary); } // pdftmp->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2)); // mc->GetPdf()->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2),Slice(*channelCat,tt->GetName()),ProjWData(*data)); //pdftmp->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2),Slice(*channelCat,tt->GetName()),ProjWData(*data)); normCount = pdftmp->expectedEvents(*obs); pdftmp->plotOn(frame,LineWidth(2.),LineColor(kGreen),LineStyle(kDashed),Normalization(normCount,RooAbsReal::NumEvent)) ; // set them back to normal if(strcmp(var->GetName(),"Lumi")==0){ cout <<"working on lumi"<<endl; var->setVal(w->var("nominalLumi")->getVal()); var->Print(); } else{ var->setVal(0); } list->Add(frame); // quit making plots ++nPlots; frame->Draw(); c2->SaveAs(Form("%s_%s_%s.pdf",tt->GetName(),obs->GetName(),var->GetName())); delete c2; } } } // ------------------------------------------------------- // 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(); } }
//put very small data entries in a binned dataset to avoid unphysical pdfs, specifically for H->ZZ->4l RooDataSet* makeData(RooDataSet* orig, RooSimultaneous* simPdf, const RooArgSet* observables, RooRealVar* firstPOI, double mass, double& mu_min) { double max_soverb = 0; mu_min = -10e9; map<string, RooDataSet*> data_map; firstPOI->setVal(0); RooCategory* cat = (RooCategory*)&simPdf->indexCat(); TList* datalist = orig->split(*(RooAbsCategory*)cat, true); TIterator* dataItr = datalist->MakeIterator(); RooAbsData* ds; RooRealVar* weightVar = new RooRealVar("weightVar","weightVar",1); while ((ds = (RooAbsData*)dataItr->Next())) { string typeName(ds->GetName()); cat->setLabel(typeName.c_str()); RooAbsPdf* pdf = simPdf->getPdf(typeName.c_str()); cout << "pdf: " << pdf << endl; RooArgSet* obs = pdf->getObservables(observables); cout << "obs: " << obs << endl; RooArgSet obsAndWeight(*obs, *weightVar); obsAndWeight.add(*cat); stringstream datasetName; datasetName << "newData_" << typeName; RooDataSet* thisData = new RooDataSet(datasetName.str().c_str(),datasetName.str().c_str(), obsAndWeight, WeightVar(*weightVar)); RooRealVar* firstObs = (RooRealVar*)obs->first(); //int ibin = 0; int nrEntries = ds->numEntries(); for (int ib=0;ib<nrEntries;ib++) { const RooArgSet* event = ds->get(ib); const RooRealVar* thisObs = (RooRealVar*)event->find(firstObs->GetName()); firstObs->setVal(thisObs->getVal()); firstPOI->setVal(0); double b = pdf->expectedEvents(*firstObs)*pdf->getVal(obs); firstPOI->setVal(1); double s = pdf->expectedEvents(*firstObs)*pdf->getVal(obs) - b; if (s > 0) { mu_min = max(mu_min, -b/s); double soverb = s/b; if (soverb > max_soverb) { max_soverb = soverb; cout << "Found new max s/b: " << soverb << " in pdf " << pdf->GetName() << " at m = " << thisObs->getVal() << endl; } } if (b == 0 && s != 0) { cout << "Expecting non-zero signal and zero bg at m=" << firstObs->getVal() << " in pdf " << pdf->GetName() << endl; } if (s+b <= 0) { cout << "expecting zero" << endl; continue; } double weight = ds->weight(); if ((typeName.find("ATLAS_H_4mu") != string::npos || typeName.find("ATLAS_H_4e") != string::npos || typeName.find("ATLAS_H_2mu2e") != string::npos || typeName.find("ATLAS_H_2e2mu") != string::npos) && fabs(firstObs->getVal() - mass) < 10 && weight == 0) { cout << "adding event: " << firstObs->getVal() << endl; thisData->add(*event, pow(10., -9.)); } else { //weight = max(pow(10.0, -9), weight); thisData->add(*event, weight); } } data_map[string(ds->GetName())] = (RooDataSet*)thisData; } RooDataSet* newData = new RooDataSet("newData","newData",RooArgSet(*observables, *weightVar), Index(*cat), Import(data_map), WeightVar(*weightVar)); orig->Print(); newData->Print(); //newData->tree()->Scan("*"); return newData; }
void constrained_scan( const char* wsfile = "outputfiles/ws.root", const char* new_poi_name="mu_bg_4b_msig_met1", double constraintWidth=1.5, int npoiPoints = 20, double poiMinVal = 0., double poiMaxVal = 10.0, double ymax = 9., int verbLevel=1 ) { TString outputdir("outputfiles") ; gStyle->SetOptStat(0) ; TFile* wstf = new TFile( wsfile ) ; RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") ); ws->Print() ; RooDataSet* rds = (RooDataSet*) ws->obj( "hbb_observed_rds" ) ; cout << "\n\n\n ===== RooDataSet ====================\n\n" << endl ; rds->Print() ; rds->printMultiline(cout, 1, kTRUE, "") ; RooRealVar* rv_sig_strength = ws->var("sig_strength") ; if ( rv_sig_strength == 0x0 ) { printf("\n\n *** can't find sig_strength in workspace.\n\n" ) ; return ; } RooAbsPdf* likelihood = ws->pdf("likelihood") ; if ( likelihood == 0x0 ) { printf("\n\n *** can't find likelihood in workspace.\n\n" ) ; return ; } printf("\n\n Likelihood:\n") ; likelihood -> Print() ; /////rv_sig_strength -> setConstant( kFALSE ) ; rv_sig_strength -> setVal(0.) ; rv_sig_strength -> setConstant( kTRUE ) ; likelihood->fitTo( *rds, Save(false), PrintLevel(0), Hesse(true), Strategy(1) ) ; //RooFitResult* fitResult = likelihood->fitTo( *rds, Save(true), PrintLevel(0), Hesse(true), Strategy(1) ) ; //double minNllSusyFloat = fitResult->minNll() ; //double susy_ss_atMinNll = rv_sig_strength -> getVal() ; RooMsgService::instance().getStream(1).removeTopic(Minimization) ; RooMsgService::instance().getStream(1).removeTopic(Fitting) ; //-- Construct the new POI parameter. RooAbsReal* new_poi_rar(0x0) ; new_poi_rar = ws->var( new_poi_name ) ; if ( new_poi_rar == 0x0 ) { printf("\n\n New POI %s is not a variable. Trying function.\n\n", new_poi_name ) ; new_poi_rar = ws->function( new_poi_name ) ; if ( new_poi_rar == 0x0 ) { printf("\n\n New POI %s is not a function. I quit.\n\n", new_poi_name ) ; return ; } else { printf("\n Found it.\n\n") ; } } else { printf("\n\n New POI %s is a variable with current value %.1f.\n\n", new_poi_name, new_poi_rar->getVal() ) ; } double startPoiVal = new_poi_rar->getVal() ; RooAbsReal* nll = likelihood -> createNLL( *rds, Verbose(true) ) ; RooRealVar* rrv_poiValue = new RooRealVar( "poiValue", "poiValue", 0., -10000., 10000. ) ; RooRealVar* rrv_constraintWidth = new RooRealVar("constraintWidth","constraintWidth", 0.1, 0.1, 1000. ) ; rrv_constraintWidth -> setVal( constraintWidth ) ; rrv_constraintWidth -> setConstant(kTRUE) ; RooMinuit* rminuit( 0x0 ) ; RooMinuit* rminuit_uc = new RooMinuit( *nll ) ; rminuit_uc->setPrintLevel(verbLevel-1) ; rminuit_uc->setNoWarn() ; rminuit_uc->migrad() ; rminuit_uc->hesse() ; RooFitResult* rfr_uc = rminuit_uc->fit("mr") ; double floatParInitVal[10000] ; char floatParName[10000][100] ; int nFloatParInitVal(0) ; RooArgList ral_floats = rfr_uc->floatParsFinal() ; TIterator* floatParIter = ral_floats.createIterator() ; { RooRealVar* par ; while ( (par = (RooRealVar*) floatParIter->Next()) ) { sprintf( floatParName[nFloatParInitVal], "%s", par->GetName() ) ; floatParInitVal[nFloatParInitVal] = par->getVal() ; nFloatParInitVal++ ; } } printf("\n\n Unbiased best value for new POI %s is : %7.1f\n\n", new_poi_rar->GetName(), new_poi_rar->getVal() ) ; double best_poi_val = new_poi_rar->getVal() ; char minuit_formula[10000] ; sprintf( minuit_formula, "%s+%s*(%s-%s)*(%s-%s)", nll->GetName(), rrv_constraintWidth->GetName(), new_poi_rar->GetName(), rrv_poiValue->GetName(), new_poi_rar->GetName(), rrv_poiValue->GetName() ) ; printf("\n\n Creating new minuit variable with formula: %s\n\n", minuit_formula ) ; RooFormulaVar* new_minuit_var = new RooFormulaVar("new_minuit_var", minuit_formula, RooArgList( *nll, *rrv_constraintWidth, *new_poi_rar, *rrv_poiValue, *new_poi_rar, *rrv_poiValue ) ) ; printf("\n\n Current value is %.2f\n\n", new_minuit_var->getVal() ) ; rminuit = new RooMinuit( *new_minuit_var ) ; RooAbsReal* plot_var = nll ; printf("\n\n Current value is %.2f\n\n", plot_var->getVal() ) ; rminuit->setPrintLevel(verbLevel-1) ; if ( verbLevel <=0 ) { rminuit->setNoWarn() ; } if ( poiMinVal < 0. && poiMaxVal < 0. ) { printf("\n\n Automatic determination of scan range.\n\n") ; if ( startPoiVal <= 0. ) { printf("\n\n *** POI starting value zero or negative %g. Quit.\n\n\n", startPoiVal ) ; return ; } poiMinVal = startPoiVal - 3.5 * sqrt(startPoiVal) ; poiMaxVal = startPoiVal + 6.0 * sqrt(startPoiVal) ; if ( poiMinVal < 0. ) { poiMinVal = 0. ; } printf(" Start val = %g. Scan range: %g to %g\n\n", startPoiVal, poiMinVal, poiMaxVal ) ; } //---------------------------------------------------------------------------------------------- double poiVals_scanDown[1000] ; double nllVals_scanDown[1000] ; //-- Do scan down from best value. printf("\n\n +++++ Starting scan down from best value.\n\n") ; double minNllVal(1.e9) ; for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) { ////double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*(npoiPoints-1)) ; double poiValue = best_poi_val - poivi*(best_poi_val-poiMinVal)/(1.*(npoiPoints/2-1)) ; rrv_poiValue -> setVal( poiValue ) ; rrv_poiValue -> setConstant( kTRUE ) ; //+++++++++++++++++++++++++++++++++++ rminuit->migrad() ; rminuit->hesse() ; RooFitResult* rfr = rminuit->save() ; //+++++++++++++++++++++++++++++++++++ if ( verbLevel > 0 ) { rfr->Print("v") ; } float fit_minuit_var_val = rfr->minNll() ; printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI : %.5f %.5f %.5f %.5f\n", poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ; cout << flush ; poiVals_scanDown[poivi] = new_poi_rar->getVal() ; nllVals_scanDown[poivi] = plot_var->getVal() ; if ( nllVals_scanDown[poivi] < minNllVal ) { minNllVal = nllVals_scanDown[poivi] ; } delete rfr ; } // poivi printf("\n\n +++++ Resetting floats to best fit values.\n\n") ; for ( int pi=0; pi<nFloatParInitVal; pi++ ) { RooRealVar* par = ws->var( floatParName[pi] ) ; par->setVal( floatParInitVal[pi] ) ; } // pi. printf("\n\n +++++ Starting scan up from best value.\n\n") ; //-- Now do scan up. double poiVals_scanUp[1000] ; double nllVals_scanUp[1000] ; for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) { double poiValue = best_poi_val + poivi*(poiMaxVal-best_poi_val)/(1.*(npoiPoints/2-1)) ; rrv_poiValue -> setVal( poiValue ) ; rrv_poiValue -> setConstant( kTRUE ) ; //+++++++++++++++++++++++++++++++++++ rminuit->migrad() ; rminuit->hesse() ; RooFitResult* rfr = rminuit->save() ; //+++++++++++++++++++++++++++++++++++ if ( verbLevel > 0 ) { rfr->Print("v") ; } float fit_minuit_var_val = rfr->minNll() ; printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI : %.5f %.5f %.5f %.5f\n", poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ; cout << flush ; poiVals_scanUp[poivi] = new_poi_rar->getVal() ; nllVals_scanUp[poivi] = plot_var->getVal() ; if ( nllVals_scanUp[poivi] < minNllVal ) { minNllVal = nllVals_scanUp[poivi] ; } delete rfr ; } // poivi double poiVals[1000] ; double nllVals[1000] ; int pointCount(0) ; for ( int pi=0; pi<npoiPoints/2; pi++ ) { poiVals[pi] = poiVals_scanDown[(npoiPoints/2-1)-pi] ; nllVals[pi] = nllVals_scanDown[(npoiPoints/2-1)-pi] ; pointCount++ ; } for ( int pi=1; pi<npoiPoints/2; pi++ ) { poiVals[pointCount] = poiVals_scanUp[pi] ; nllVals[pointCount] = nllVals_scanUp[pi] ; pointCount++ ; } npoiPoints = pointCount ; printf("\n\n --- TGraph arrays:\n") ; for ( int i=0; i<npoiPoints; i++ ) { printf(" %2d : poi = %6.1f, nll = %g\n", i, poiVals[i], nllVals[i] ) ; } printf("\n\n") ; double nllDiffVals[1000] ; double poiAtMinlnL(-1.) ; double poiAtMinusDelta2(-1.) ; double poiAtPlusDelta2(-1.) ; for ( int poivi=0; poivi < npoiPoints ; poivi++ ) { nllDiffVals[poivi] = 2.*(nllVals[poivi] - minNllVal) ; double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*npoiPoints) ; if ( nllDiffVals[poivi] < 0.01 ) { poiAtMinlnL = poiValue ; } if ( poiAtMinusDelta2 < 0. && nllDiffVals[poivi] < 2.5 ) { poiAtMinusDelta2 = poiValue ; } if ( poiAtMinlnL > 0. && poiAtPlusDelta2 < 0. && nllDiffVals[poivi] > 2.0 ) { poiAtPlusDelta2 = poiValue ; } } // poivi printf("\n\n Estimates for poi at delta ln L = -2, 0, +2: %g , %g , %g\n\n", poiAtMinusDelta2, poiAtMinlnL, poiAtPlusDelta2 ) ; //--- Main canvas TCanvas* cscan = (TCanvas*) gDirectory->FindObject("cscan") ; if ( cscan == 0x0 ) { printf("\n Creating canvas.\n\n") ; cscan = new TCanvas("cscan","Delta nll") ; } char gname[1000] ; TGraph* graph = new TGraph( npoiPoints, poiVals, nllDiffVals ) ; sprintf( gname, "scan_%s", new_poi_name ) ; graph->SetName( gname ) ; double poiBest(-1.) ; double poiMinus1stdv(-1.) ; double poiPlus1stdv(-1.) ; double poiMinus2stdv(-1.) ; double poiPlus2stdv(-1.) ; double twoDeltalnLMin(1e9) ; int nscan(1000) ; for ( int xi=0; xi<nscan; xi++ ) { double x = poiVals[0] + xi*(poiVals[npoiPoints-1]-poiVals[0])/(nscan-1) ; double twoDeltalnL = graph -> Eval( x, 0, "S" ) ; if ( poiMinus1stdv < 0. && twoDeltalnL < 1.0 ) { poiMinus1stdv = x ; printf(" set m1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( poiMinus2stdv < 0. && twoDeltalnL < 4.0 ) { poiMinus2stdv = x ; printf(" set m2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( twoDeltalnL < twoDeltalnLMin ) { poiBest = x ; twoDeltalnLMin = twoDeltalnL ; } if ( twoDeltalnLMin < 0.3 && poiPlus1stdv < 0. && twoDeltalnL > 1.0 ) { poiPlus1stdv = x ; printf(" set p1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( twoDeltalnLMin < 0.3 && poiPlus2stdv < 0. && twoDeltalnL > 4.0 ) { poiPlus2stdv = x ; printf(" set p2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;} if ( xi%100 == 0 ) { printf( " %4d : poi=%6.2f, 2DeltalnL = %6.2f\n", xi, x, twoDeltalnL ) ; } } printf("\n\n POI estimate : %g +%g -%g [%g,%g], two sigma errors: +%g -%g [%g,%g]\n\n", poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), poiMinus1stdv, poiPlus1stdv, (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv), poiMinus2stdv, poiPlus2stdv ) ; printf(" %s val,pm1sig,pm2sig: %7.2f %7.2f %7.2f %7.2f %7.2f\n", new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv) ) ; char htitle[1000] ; sprintf(htitle, "%s profile likelihood scan: -2ln(L/Lm)", new_poi_name ) ; TH1F* hscan = new TH1F("hscan", htitle, 10, poiMinVal, poiMaxVal ) ; hscan->SetMinimum(0.) ; hscan->SetMaximum(ymax) ; hscan->DrawCopy() ; graph->SetLineColor(4) ; graph->SetLineWidth(3) ; graph->Draw("CP") ; gPad->SetGridx(1) ; gPad->SetGridy(1) ; cscan->Update() ; TLine* line = new TLine() ; line->SetLineColor(2) ; line->DrawLine(poiMinVal, 1., poiPlus1stdv, 1.) ; line->DrawLine(poiMinus1stdv,0., poiMinus1stdv, 1.) ; line->DrawLine(poiPlus1stdv ,0., poiPlus1stdv , 1.) ; TText* text = new TText() ; text->SetTextSize(0.04) ; char tstring[1000] ; sprintf( tstring, "%s = %.1f +%.1f -%.1f", new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv) ) ; text -> DrawTextNDC( 0.15, 0.85, tstring ) ; sprintf( tstring, "68%% interval [%.1f, %.1f]", poiMinus1stdv, poiPlus1stdv ) ; text -> DrawTextNDC( 0.15, 0.78, tstring ) ; char hname[1000] ; sprintf( hname, "hscanout_%s", new_poi_name ) ; TH1F* hsout = new TH1F( hname,"scan results",4,0.,4.) ; double obsVal(-1.) ; hsout->SetBinContent(1, obsVal ) ; hsout->SetBinContent(2, poiPlus1stdv ) ; hsout->SetBinContent(3, poiBest ) ; hsout->SetBinContent(4, poiMinus1stdv ) ; TAxis* xaxis = hsout->GetXaxis() ; xaxis->SetBinLabel(1,"Observed val.") ; xaxis->SetBinLabel(2,"Model+1sd") ; xaxis->SetBinLabel(3,"Model") ; xaxis->SetBinLabel(4,"Model-1sd") ; char outrootfile[10000] ; sprintf( outrootfile, "%s/scan-ff-%s.root", outputdir.Data(), new_poi_name ) ; char outpdffile[10000] ; sprintf( outpdffile, "%s/scan-ff-%s.pdf", outputdir.Data(), new_poi_name ) ; cscan->Update() ; cscan->Draw() ; printf("\n Saving %s\n", outpdffile ) ; cscan->SaveAs( outpdffile ) ; //--- save in root file printf("\n Saving %s\n", outrootfile ) ; TFile fout(outrootfile,"recreate") ; graph->Write() ; hsout->Write() ; fout.Close() ; delete ws ; wstf->Close() ; } // constrained_scan.
// 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; }
void printCtauFrom2DParameters(RooWorkspace myws, TPad* Pad, bool isPbPb, string pdfName, bool isWeighted) { Pad->cd(); TLatex *t = new TLatex(); t->SetNDC(); t->SetTextSize(0.026); float dy = 0.045; RooArgSet* Parameters = (RooArgSet*)myws.pdf(pdfName.c_str())->getParameters(RooArgSet(*myws.var("invMass"), *myws.var("ctau"), *myws.var("ctauErr")))->selectByAttrib("Constant",kFALSE); TIterator* parIt = Parameters->createIterator(); for (RooRealVar* it = (RooRealVar*)parIt->Next(); it!=NULL; it = (RooRealVar*)parIt->Next() ) { stringstream ss(it->GetName()); string s1, s2, s3, label; getline(ss, s1, '_'); getline(ss, s2, '_'); getline(ss, s3, '_'); // Parse the parameter's labels if(s1=="invMass"){continue;} else if(s1=="ctau"){continue;} else if(s1=="MassRatio"){continue;} else if(s1=="One"){continue;} else if(s1=="mMin"){continue;} else if(s1=="mMax"){continue;} else if(s1=="rSigma21"){ s1="(#sigma_{2}/#sigma_{1})"; } else if(s1=="rSigma32"){ s1="(#sigma_{3}/#sigma_{2})"; } else if(s1=="rSigma43"){ s1="(#sigma_{4}/#sigma_{3})"; } else if(s1.find("sigma")!=std::string::npos || s1.find("lambda")!=std::string::npos || s1.find("alpha")!=std::string::npos){ s1=Form("#%s",s1.c_str()); } if(s2=="CtauRes") { s2="Res"; } else if(s2=="JpsiNoPR") { s2="J/#psi[NoPR]"; } else if(s2=="JpsiPR") { s2="J/#psi[PR]"; } else if(s2=="Jpsi" && (s1=="N" || s1=="b")) { s2="J/#psi"; } else if(s2=="Psi2SNoPR") { s2="#psi(2S)[NoPR]"; } else if(s2=="Psi2SPR") { s2="#psi(2S)[PR]"; } else if(s2=="Psi2S" && (s1=="N" || s1=="b")) { s2="#psi(2S)"; } else if(s2=="BkgNoPR") { s2="bkg[NoPR]"; } else if(s2=="BkgPR") { s2="bkg[PR]"; } else if(s2=="Bkg" && (s1=="N" || s1=="b")) { s2="bkg"; } else {continue;} if(s3!=""){ label=Form("%s_{%s}^{%s}", s1.c_str(), s2.c_str(), s3.c_str()); } else { label=Form("%s^{%s}", s1.c_str(), s2.c_str()); } // Print the parameter's results if(s1=="N"){ t->DrawLatex(0.69, 0.75-dy, Form((isWeighted?"%s = %.6f#pm%.6f ":"%s = %.0f#pm%.0f "), label.c_str(), it->getValV(), it->getError())); dy+=0.045; } else if(s1=="b"){ t->DrawLatex(0.69, 0.75-dy, Form("%s = %.4f#pm%.4f ", label.c_str(), it->getValV(), it->getError())); dy+=0.045; } else if(s1.find("sigma")!=std::string::npos) { if (s2.find("Res")!=std::string::npos) { t->DrawLatex(0.69, 0.75-dy, Form("%s = %.2f#pm%.2f", label.c_str(), it->getValV(), it->getError())); dy+=0.045; } else { t->DrawLatex(0.69, 0.75-dy, Form("%s = %.2f#pm%.2f mm", label.c_str(), it->getValV(), it->getError())); dy+=0.045; } } else if(s1.find("lambda")!=std::string::npos){ t->DrawLatex(0.69, 0.75-dy, Form("%s = %.4f#pm%.4f", label.c_str(), it->getValV(), it->getError())); dy+=0.045; } else if(s1.find("ctau")!=std::string::npos){ t->DrawLatex(0.69, 0.75-dy, Form("%s = %.4f#pm%.4f mm", (label.insert(1, string("#"))).c_str(), it->getValV(), it->getError())); dy+=0.045; } else { t->DrawLatex(0.69, 0.75-dy, Form("%s = %.4f#pm%.4f", label.c_str(), it->getValV(), it->getError())); dy+=0.045; } } };
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(); }
void ws_cls_hybrid1_ag( const char* wsfile = "output-files/expected-ws-lm9-2BL.root", bool isBgonlyStudy=false, double poiVal = 150.0, int nToys=100, bool makeTtree=true, int verbLevel=0 ) { TTree* toytt(0x0) ; TFile* ttfile(0x0) ; int tt_gen_Nsig ; int tt_gen_Nsb ; int tt_gen_Nsig_sl ; int tt_gen_Nsb_sl ; int tt_gen_Nsig_ldp ; int tt_gen_Nsb_ldp ; int tt_gen_Nsig_ee ; int tt_gen_Nsb_ee ; int tt_gen_Nsig_mm ; int tt_gen_Nsb_mm ; double tt_testStat ; double tt_dataTestStat ; double tt_hypo_mu_susy_sig ; char ttname[1000] ; char tttitle[1000] ; if ( makeTtree ) { ttfile = gDirectory->GetFile() ; if ( ttfile == 0x0 ) { printf("\n\n\n *** asked for a ttree but no open file???\n\n") ; return ; } if ( isBgonlyStudy ) { sprintf( ttname, "toytt_%.0f_bgo", poiVal ) ; sprintf( tttitle, "Toy study for background only, mu_susy_sig = %.0f", poiVal ) ; } else { sprintf( ttname, "toytt_%.0f_spb", poiVal ) ; sprintf( tttitle, "Toy study for signal+background, mu_susy_sig = %.0f", poiVal ) ; } printf("\n\n Creating TTree : %s : %s\n\n", ttname, tttitle ) ; gDirectory->pwd() ; gDirectory->ls() ; toytt = new TTree( ttname, tttitle ) ; gDirectory->ls() ; toytt -> Branch( "gen_Nsig" , &tt_gen_Nsig , "gen_Nsig/I" ) ; toytt -> Branch( "gen_Nsb" , &tt_gen_Nsb , "gen_Nsb/I" ) ; toytt -> Branch( "gen_Nsig_sl" , &tt_gen_Nsig_sl , "gen_Nsig_sl/I" ) ; toytt -> Branch( "gen_Nsb_sl" , &tt_gen_Nsb_sl , "gen_Nsb_sl/I" ) ; toytt -> Branch( "gen_Nsig_ldp" , &tt_gen_Nsig_ldp , "gen_Nsig_ldp/I" ) ; toytt -> Branch( "gen_Nsb_ldp" , &tt_gen_Nsb_ldp , "gen_Nsb_ldp/I" ) ; toytt -> Branch( "gen_Nsig_ee" , &tt_gen_Nsig_ee , "gen_Nsig_ee/I" ) ; toytt -> Branch( "gen_Nsb_ee" , &tt_gen_Nsb_ee , "gen_Nsb_ee/I" ) ; toytt -> Branch( "gen_Nsig_mm" , &tt_gen_Nsig_mm , "gen_Nsig_mm/I" ) ; toytt -> Branch( "gen_Nsb_mm" , &tt_gen_Nsb_mm , "gen_Nsb_mm/I" ) ; toytt -> Branch( "testStat" , &tt_testStat , "testStat/D" ) ; toytt -> Branch( "dataTestStat" , &tt_dataTestStat , "dataTestStat/D" ) ; toytt -> Branch( "hypo_mu_susy_sig" , &tt_hypo_mu_susy_sig , "hypo_mu_susy_sig/D" ) ; } //--- Tell RooFit to shut up about anything less important than an ERROR. RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ; random_ng = new TRandom2(12345) ; /// char sel[100] ; /// if ( strstr( wsfile, "1BL" ) != 0 ) { /// sprintf( sel, "1BL" ) ; /// } else if ( strstr( wsfile, "2BL" ) != 0 ) { /// sprintf( sel, "2BL" ) ; /// } else if ( strstr( wsfile, "3B" ) != 0 ) { /// sprintf( sel, "3B" ) ; /// } else if ( strstr( wsfile, "1BT" ) != 0 ) { /// sprintf( sel, "1BT" ) ; /// } else if ( strstr( wsfile, "2BT" ) != 0 ) { /// sprintf( sel, "2BT" ) ; /// } else { /// printf("\n\n\n *** can't figure out which selection this is. I quit.\n\n" ) ; /// return ; /// } /// printf("\n\n selection is %s\n\n", sel ) ; TFile* wstf = new TFile( wsfile ) ; RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") ); ws->Print() ; RooDataSet* rds = (RooDataSet*) ws->obj( "ra2b_observed_rds" ) ; printf("\n\n\n ===== RooDataSet ====================\n\n") ; rds->Print() ; rds->printMultiline(cout, 1, kTRUE, "") ; ModelConfig* modelConfig = (ModelConfig*) ws->obj( "SbModel" ) ; RooAbsPdf* likelihood = modelConfig->GetPdf() ; const RooArgSet* nuisanceParameters = modelConfig->GetNuisanceParameters() ; RooRealVar* rrv_mu_susy_sig = ws->var("mu_susy_sig") ; if ( rrv_mu_susy_sig == 0x0 ) { printf("\n\n\n *** can't find mu_susy_sig in workspace. Quitting.\n\n\n") ; return ; } //// printf("\n\n\n ===== Doing a fit ====================\n\n") ; //// RooFitResult* preFitResult = likelihood->fitTo( *rds, Save(true) ) ; //// const RooArgList preFitFloatVals = preFitResult->floatParsFinal() ; //// { //// TIterator* parIter = preFitFloatVals.createIterator() ; //// while ( RooRealVar* par = (RooRealVar*) parIter->Next() ) { //// printf(" %20s : %8.2f\n", par->GetName(), par->getVal() ) ; //// } //// } //--- Get pointers to the model predictions of the observables. rfv_n_sig = ws->function("n_sig") ; rfv_n_sb = ws->function("n_sb") ; rfv_n_sig_sl = ws->function("n_sig_sl") ; rfv_n_sb_sl = ws->function("n_sb_sl") ; rfv_n_sig_ldp = ws->function("n_sig_ldp") ; rfv_n_sb_ldp = ws->function("n_sb_ldp") ; rfv_n_sig_ee = ws->function("n_sig_ee") ; rfv_n_sb_ee = ws->function("n_sb_ee") ; rfv_n_sig_mm = ws->function("n_sig_mm") ; rfv_n_sb_mm = ws->function("n_sb_mm") ; if ( rfv_n_sig == 0x0 ) { printf("\n\n\n *** can't find n_sig in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sb == 0x0 ) { printf("\n\n\n *** can't find n_sb in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sig_sl == 0x0 ) { printf("\n\n\n *** can't find n_sig_sl in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sb_sl == 0x0 ) { printf("\n\n\n *** can't find n_sb_sl in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sig_ldp == 0x0 ) { printf("\n\n\n *** can't find n_sig_ldp in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sb_ldp == 0x0 ) { printf("\n\n\n *** can't find n_sb_ldp in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sig_ee == 0x0 ) { printf("\n\n\n *** can't find n_sig_ee in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sb_ee == 0x0 ) { printf("\n\n\n *** can't find n_sb_ee in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sig_mm == 0x0 ) { printf("\n\n\n *** can't find n_sig_mm in workspace. Quitting.\n\n\n") ; return ; } if ( rfv_n_sb_mm == 0x0 ) { printf("\n\n\n *** can't find n_sb_mm in workspace. Quitting.\n\n\n") ; return ; } //--- Get pointers to the observables. const RooArgSet* dsras = rds->get() ; TIterator* obsIter = dsras->createIterator() ; while ( RooRealVar* obs = (RooRealVar*) obsIter->Next() ) { if ( strcmp( obs->GetName(), "Nsig" ) == 0 ) { rrv_Nsig = obs ; } if ( strcmp( obs->GetName(), "Nsb" ) == 0 ) { rrv_Nsb = obs ; } if ( strcmp( obs->GetName(), "Nsig_sl" ) == 0 ) { rrv_Nsig_sl = obs ; } if ( strcmp( obs->GetName(), "Nsb_sl" ) == 0 ) { rrv_Nsb_sl = obs ; } if ( strcmp( obs->GetName(), "Nsig_ldp" ) == 0 ) { rrv_Nsig_ldp = obs ; } if ( strcmp( obs->GetName(), "Nsb_ldp" ) == 0 ) { rrv_Nsb_ldp = obs ; } if ( strcmp( obs->GetName(), "Nsig_ee" ) == 0 ) { rrv_Nsig_ee = obs ; } if ( strcmp( obs->GetName(), "Nsb_ee" ) == 0 ) { rrv_Nsb_ee = obs ; } if ( strcmp( obs->GetName(), "Nsig_mm" ) == 0 ) { rrv_Nsig_mm = obs ; } if ( strcmp( obs->GetName(), "Nsb_mm" ) == 0 ) { rrv_Nsb_mm = obs ; } } if ( rrv_Nsig == 0x0 ) { printf("\n\n\n *** can't find Nsig in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsb == 0x0 ) { printf("\n\n\n *** can't find Nsb in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsig_sl == 0x0 ) { printf("\n\n\n *** can't find Nsig_sl in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsb_sl == 0x0 ) { printf("\n\n\n *** can't find Nsb_sl in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsig_ldp == 0x0 ) { printf("\n\n\n *** can't find Nsig_ldp in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsb_ldp == 0x0 ) { printf("\n\n\n *** can't find Nsb_ldp in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsig_ee == 0x0 ) { printf("\n\n\n *** can't find Nsig_ee in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsb_ee == 0x0 ) { printf("\n\n\n *** can't find Nsb_ee in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsig_mm == 0x0 ) { printf("\n\n\n *** can't find Nsig_mm in dataset. Quitting.\n\n\n") ; return ; } if ( rrv_Nsb_mm == 0x0 ) { printf("\n\n\n *** can't find Nsb_mm in dataset. Quitting.\n\n\n") ; return ; } printf("\n\n\n === Model values for observables\n\n") ; printObservables() ; //--- save the actual values of the observables. saveObservables() ; //--- evaluate the test stat on the data: fit with susy floating. rrv_mu_susy_sig->setVal( poiVal ) ; rrv_mu_susy_sig->setConstant( kTRUE ) ; printf("\n\n\n ====== Fitting the data with susy fixed.\n\n") ; RooFitResult* dataFitResultSusyFixed = likelihood->fitTo(*rds, Save(true)); int dataSusyFixedFitCovQual = dataFitResultSusyFixed->covQual() ; if ( dataSusyFixedFitCovQual != 3 ) { printf("\n\n\n *** Failed fit! Cov qual %d. Quitting.\n\n", dataSusyFixedFitCovQual ) ; return ; } double dataFitSusyFixedNll = dataFitResultSusyFixed->minNll() ; rrv_mu_susy_sig->setVal( 0.0 ) ; rrv_mu_susy_sig->setConstant( kFALSE ) ; printf("\n\n\n ====== Fitting the data with susy floating.\n\n") ; RooFitResult* dataFitResultSusyFloat = likelihood->fitTo(*rds, Save(true)); int dataSusyFloatFitCovQual = dataFitResultSusyFloat->covQual() ; if ( dataSusyFloatFitCovQual != 3 ) { printf("\n\n\n *** Failed fit! Cov qual %d. Quitting.\n\n", dataSusyFloatFitCovQual ) ; return ; } double dataFitSusyFloatNll = dataFitResultSusyFloat->minNll() ; double dataTestStat = 2.*( dataFitSusyFixedNll - dataFitSusyFloatNll) ; printf("\n\n\n Data value of test stat : %8.2f\n", dataTestStat ) ; printf("\n\n\n === Nuisance parameters\n\n") ; { int npi(0) ; TIterator* npIter = nuisanceParameters->createIterator() ; while ( RooRealVar* np_rrv = (RooRealVar*) npIter->Next() ) { np_initial_val[npi] = np_rrv->getVal() ; //--- I am assuming that the order of the NPs in the iterator does not change. TString npname( np_rrv->GetName() ) ; npname.ReplaceAll("_prim","") ; RooAbsReal* np_rfv = ws->function( npname ) ; TString pdfname( np_rrv->GetName() ) ; pdfname.ReplaceAll("_prim","") ; pdfname.Prepend("pdf_") ; RooAbsPdf* np_pdf = ws->pdf( pdfname ) ; if ( np_pdf == 0x0 ) { printf("\n\n *** Can't find nuisance parameter pdf with name %s.\n\n", pdfname.Data() ) ; } if ( np_rfv != 0x0 ) { printf(" %20s : %8.2f , %20s, %8.2f\n", np_rrv->GetName(), np_rrv->getVal(), np_rfv->GetName(), np_rfv->getVal() ) ; } else { printf(" %20s : %8.2f\n", np_rrv->GetName(), np_rrv->getVal() ) ; } npi++ ; } // np_rrv iterator. np_count = npi ; } tt_dataTestStat = dataTestStat ; tt_hypo_mu_susy_sig = poiVal ; printf("\n\n\n === Doing the toys\n\n") ; int nToyOK(0) ; int nToyWorseThanData(0) ; for ( int ti=0; ti<nToys; ti++ ) { printf("\n\n\n ======= Toy %4d\n\n\n", ti ) ; //--- 1) pick values for the nuisance parameters from the PDFs and fix them. { TIterator* npIter = nuisanceParameters->createIterator() ; while ( RooRealVar* np_rrv = (RooRealVar*) npIter->Next() ) { TString pdfname( np_rrv->GetName() ) ; pdfname.ReplaceAll("_prim","") ; pdfname.Prepend("pdf_") ; RooAbsPdf* np_pdf = ws->pdf( pdfname ) ; if ( np_pdf == 0x0 ) { printf("\n\n *** Can't find nuisance parameter pdf with name %s.\n\n", pdfname.Data() ) ; return ; } RooDataSet* nprds = np_pdf->generate( RooArgSet(*np_rrv) ,1) ; const RooArgSet* npdsras = nprds->get() ; TIterator* valIter = npdsras->createIterator() ; RooRealVar* val = (RooRealVar*) valIter->Next() ; //--- reset the value of the nuisance parameter and fix it for the toy model definition fit. np_rrv->setVal( val->getVal() ) ; np_rrv->setConstant( kTRUE ) ; TString npname( np_rrv->GetName() ) ; npname.ReplaceAll("_prim","") ; RooAbsReal* np_rfv = ws->function( npname ) ; if ( verbLevel > 0 ) { if ( np_rfv != 0x0 ) { printf(" %20s : %8.2f , %15s, %8.3f\n", val->GetName(), val->getVal(), np_rfv->GetName(), np_rfv->getVal() ) ; } else if ( strstr( npname.Data(), "eff_sf" ) != 0 ) { np_rfv = ws->function( "eff_sf_sig" ) ; RooAbsReal* np_rfv2 = ws->function( "eff_sf_sb" ) ; printf(" %20s : %8.2f , %15s, %8.3f , %15s, %8.3f\n", val->GetName(), val->getVal(), np_rfv->GetName(), np_rfv->getVal(), np_rfv2->GetName(), np_rfv2->getVal() ) ; } else if ( strstr( npname.Data(), "sf_ll" ) != 0 ) { np_rfv = ws->function( "sf_ee" ) ; RooAbsReal* np_rfv2 = ws->function( "sf_mm" ) ; printf(" %20s : %8.2f , %15s, %8.3f , %15s, %8.3f\n", val->GetName(), val->getVal(), np_rfv->GetName(), np_rfv->getVal(), np_rfv2->GetName(), np_rfv2->getVal() ) ; } else { printf(" %20s : %8.2f\n", val->GetName(), val->getVal() ) ; } } delete nprds ; } // np_rrv iterator } //--- 2) Fit the dataset with these values for the nuisance parameters. if ( isBgonlyStudy ) { //-- fit with susy yield fixed to zero. rrv_mu_susy_sig -> setVal( 0. ) ; if ( verbLevel > 0 ) { printf("\n Setting mu_susy_sig to zero.\n\n") ; } } else { //-- fit with susy yield fixed to predicted value. rrv_mu_susy_sig -> setVal( poiVal ) ; if ( verbLevel > 0 ) { printf("\n Setting mu_susy_sig to %8.1f.\n\n", poiVal) ; } } rrv_mu_susy_sig->setConstant( kTRUE ) ; if ( verbLevel > 0 ) { printf("\n\n") ; printf(" Fitting with these values for the observables to define the model for toy generation.\n") ; rds->printMultiline(cout, 1, kTRUE, "") ; printf("\n\n") ; } RooFitResult* toyModelDefinitionFitResult(0x0) ; if ( verbLevel < 2 ) { toyModelDefinitionFitResult = likelihood->fitTo(*rds, Save(true), PrintLevel(-1)); } else { toyModelDefinitionFitResult = likelihood->fitTo(*rds, Save(true)); } int toyModelDefFitCovQual = toyModelDefinitionFitResult->covQual() ; if ( verbLevel > 0 ) { printf("\n fit covariance matrix quality: %d\n\n", toyModelDefFitCovQual ) ; } if ( toyModelDefFitCovQual != 3 ) { printf("\n\n\n *** Bad toy model definition fit. Cov qual %d. Aborting this toy.\n\n\n", toyModelDefFitCovQual ) ; continue ; } delete toyModelDefinitionFitResult ; if ( verbLevel > 0 ) { printf("\n\n\n === Model values for observables. These will be used to generate the toy dataset.\n\n") ; printObservables() ; } //--- 3) Generate a new set of observables based on this model. generateObservables() ; printf("\n\n\n Generated dataset\n") ; rds->Print() ; rds->printMultiline(cout, 1, kTRUE, "") ; //--- Apparently, I need to make a new RooDataSet... Resetting the // values in the old one doesn't stick. If you do likelihood->fitTo(*rds), it // uses the original values, not the reset ones, in the fit. RooArgSet toyFitobservedParametersList ; toyFitobservedParametersList.add( *rrv_Nsig ) ; toyFitobservedParametersList.add( *rrv_Nsb ) ; toyFitobservedParametersList.add( *rrv_Nsig_sl ) ; toyFitobservedParametersList.add( *rrv_Nsb_sl ) ; toyFitobservedParametersList.add( *rrv_Nsig_ldp ) ; toyFitobservedParametersList.add( *rrv_Nsb_ldp ) ; toyFitobservedParametersList.add( *rrv_Nsig_ee ) ; toyFitobservedParametersList.add( *rrv_Nsb_ee ) ; toyFitobservedParametersList.add( *rrv_Nsig_mm ) ; toyFitobservedParametersList.add( *rrv_Nsb_mm ) ; RooDataSet* toyFitdsObserved = new RooDataSet("toyfit_ra2b_observed_rds", "RA2b toy observed data values", toyFitobservedParametersList ) ; toyFitdsObserved->add( toyFitobservedParametersList ) ; //--- 4) Reset and free the nuisance parameters. { if ( verbLevel > 0 ) { printf("\n\n") ; } int npi(0) ; TIterator* npIter = nuisanceParameters->createIterator() ; while ( RooRealVar* np_rrv = (RooRealVar*) npIter->Next() ) { np_rrv -> setVal( np_initial_val[npi] ) ; // assuming that the order in the iterator does not change. np_rrv -> setConstant( kFALSE ) ; npi++ ; if ( verbLevel > 0 ) { printf(" reset %20s to %8.2f and freed it.\n", np_rrv->GetName() , np_rrv->getVal() ) ; } } // np_rrv iterator. if ( verbLevel > 0 ) { printf("\n\n") ; } } //--- 5a) Evaluate the test statistic: Fit with susy yield floating to get the absolute maximum log likelihood. if ( verbLevel > 0 ) { printf("\n\n Evaluating the test statistic for this toy. Fitting with susy floating.\n\n") ; } rrv_mu_susy_sig->setVal( 0.0 ) ; rrv_mu_susy_sig->setConstant( kFALSE ) ; if ( verbLevel > 0 ) { printf("\n toy dataset\n\n") ; toyFitdsObserved->printMultiline(cout, 1, kTRUE, "") ; } /////---- nfg. Need to create a new dataset ---------- /////RooFitResult* maxLikelihoodFitResult = likelihood->fitTo(*rds, Save(true), PrintLevel(-1)); /////RooFitResult* maxLikelihoodFitResult = likelihood->fitTo(*rds, Save(true)); /////-------------- RooFitResult* maxLikelihoodFitResult(0x0) ; if ( verbLevel < 2 ) { maxLikelihoodFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true), PrintLevel(-1)); } else { maxLikelihoodFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true)); } if ( verbLevel > 0 ) { printObservables() ; } int mlFitCovQual = maxLikelihoodFitResult->covQual() ; if ( verbLevel > 0 ) { printf("\n fit covariance matrix quality: %d , -log likelihood %f\n\n", mlFitCovQual, maxLikelihoodFitResult->minNll() ) ; } if ( mlFitCovQual != 3 ) { printf("\n\n\n *** Bad maximum likelihood fit (susy floating). Cov qual %d. Aborting this toy.\n\n\n", mlFitCovQual ) ; continue ; } double maxL_susyFloat = maxLikelihoodFitResult->minNll() ; double maxL_mu_susy_sig = rrv_mu_susy_sig->getVal() ; delete maxLikelihoodFitResult ; //--- 5b) Evaluate the test statistic: Fit with susy yield fixed to hypothesis value. // This is only necessary if the maximum likelihood fit value of the susy yield // is less than the hypothesis value (to get a one-sided limit). double testStat(0.0) ; double maxL_susyFixed(0.0) ; if ( maxL_mu_susy_sig < poiVal ) { if ( verbLevel > 0 ) { printf("\n\n Evaluating the test statistic for this toy. Fitting with susy fixed to %8.2f.\n\n", poiVal ) ; } rrv_mu_susy_sig->setVal( poiVal ) ; rrv_mu_susy_sig->setConstant( kTRUE ) ; if ( verbLevel > 0 ) { printf("\n toy dataset\n\n") ; rds->printMultiline(cout, 1, kTRUE, "") ; } ////--------- nfg. need to make a new dataset --------------- ////RooFitResult* susyFixedFitResult = likelihood->fitTo(*rds, Save(true), PrintLevel(-1)); ////RooFitResult* susyFixedFitResult = likelihood->fitTo(*rds, Save(true)); ////----------------------------- RooFitResult* susyFixedFitResult(0x0) ; if ( verbLevel < 2 ) { susyFixedFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true), PrintLevel(-1)); } else { susyFixedFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true)); } if ( verbLevel > 0 ) { printObservables() ; } int susyFixedFitCovQual = susyFixedFitResult->covQual() ; if ( verbLevel > 0 ) { printf("\n fit covariance matrix quality: %d , -log likelihood %f\n\n", susyFixedFitCovQual, susyFixedFitResult->minNll() ) ; } if ( susyFixedFitCovQual != 3 ) { printf("\n\n\n *** Bad maximum likelihood fit (susy fixed). Cov qual %d. Aborting this toy.\n\n\n", susyFixedFitCovQual ) ; continue ; } maxL_susyFixed = susyFixedFitResult->minNll() ; testStat = 2. * (maxL_susyFixed - maxL_susyFloat) ; delete susyFixedFitResult ; } else { if ( verbLevel > 0 ) { printf("\n\n Floating value of susy yield greater than hypo value (%8.2f > %8.2f). Setting test stat to zero.\n\n", maxL_mu_susy_sig, poiVal ) ; } testStat = 0.0 ; } printf(" --- test stat for toy %4d : %8.2f\n", ti, testStat ) ; nToyOK++ ; if ( testStat > dataTestStat ) { nToyWorseThanData++ ; } if ( makeTtree ) { tt_testStat = testStat ; tt_gen_Nsig = rrv_Nsig->getVal() ; tt_gen_Nsb = rrv_Nsb->getVal() ; tt_gen_Nsig_sl = rrv_Nsig_sl->getVal() ; tt_gen_Nsb_sl = rrv_Nsb_sl->getVal() ; tt_gen_Nsig_ldp = rrv_Nsig_ldp->getVal() ; tt_gen_Nsb_ldp = rrv_Nsb_ldp->getVal() ; tt_gen_Nsig_ee = rrv_Nsig_ee->getVal() ; tt_gen_Nsb_ee = rrv_Nsb_ee->getVal() ; tt_gen_Nsig_mm = rrv_Nsig_mm->getVal() ; tt_gen_Nsb_mm = rrv_Nsb_mm->getVal() ; toytt->Fill() ; } //--- *) reset things for the next toy. resetObservables() ; delete toyFitdsObserved ; } // ti. wstf->Close() ; printf("\n\n\n") ; if ( nToyOK == 0 ) { printf("\n\n\n *** All toys bad !?!?!\n\n\n") ; return ; } double pValue = (1.0*nToyWorseThanData) / (1.0*nToyOK) ; if ( isBgonlyStudy ) { printf("\n\n\n p-value result, BG-only , poi=%3.0f : %4d / %4d = %6.3f\n\n\n\n", poiVal, nToyWorseThanData, nToyOK, pValue ) ; } else { printf("\n\n\n p-value result, S-plus-B, poi=%3.0f : %4d / %4d = %6.3f\n\n\n\n", poiVal, nToyWorseThanData, nToyOK, pValue ) ; } if ( makeTtree ) { printf("\n\n Writing TTree : %s : %s\n\n", ttname, tttitle ) ; ttfile->cd() ; toytt->Write() ; } } // ws_cls_hybrid1