void upper_limit_Bayesian_MCMC(Model* model,double confidence,int Niters){ cout<<"///////////////////////////////////////////////////////////////////////////////////////////"<<endl; cout<<"Calculating upper limit with the MCMC method"<<endl; cout<<"///////////////////////////////////////////////////////////////////////////////////////////"<<endl; RooWorkspace* wspace = new RooWorkspace("wspace"); ModelConfig* modelConfig = new ModelConfig("bayes"); modelConfig->SetWorkspace(*wspace); modelConfig->SetPdf(*model->get_complete_likelihood()); modelConfig->SetPriorPdf(*model->get_POI_prior()); modelConfig->SetParametersOfInterest(*model->get_POI_set()); // modelConfig->SetNuisanceParameters(); modelConfig->SetNuisanceParameters(*model->get_nuisance_set()); //configure the calculator //model->Print(); cout<<" POI size "<<model->get_POI_set()->getSize()<<endl; RooRealVar* firstPOI = (RooRealVar*) modelConfig->GetParametersOfInterest()->first(); MCMCCalculator mcmccalc(*model->get_data(), *modelConfig ); mcmccalc.SetTestSize(1-confidence); mcmccalc.SetLeftSideTailFraction(0); mcmccalc.SetNumIters(Niters); MCMCInterval* interval = mcmccalc.GetInterval(); double ul = interval->UpperLimit(*firstPOI); cout<<"UpperLimit: "<<ul<<endl; }
double upper_limit_FC(Model* model,double confidence){ cout<<"///////////////////////////////////////////////////////////////////////////////////////////"<<endl; cout<<"Calculating upper limit with the FC method"<<endl; cout<<"///////////////////////////////////////////////////////////////////////////////////////////"<<endl; RooWorkspace* wspace = new RooWorkspace("wspace"); ModelConfig* modelConfig = new ModelConfig("FC"); modelConfig->SetWorkspace(*wspace); modelConfig->SetPdf(*model->get_complete_likelihood()); modelConfig->SetPriorPdf(*model->get_POI_prior()); modelConfig->SetParametersOfInterest(*model->get_POI_set()); //modelConfig->SetParametersOfInterest(*wspace->set("poi")); //modelConfig->SetNuisanceParameters(*wspace->set("nuis")); // modelConfig->SetNuisanceParameters(); modelConfig->SetNuisanceParameters(*model->get_nuisance_set()); RooDataSet* data = model->get_data(); RooArgSet* poi= model->get_POI_set(); //configure the calculator //model->Print(); cout<<" POI size "<<model->get_POI_set()->getSize()<<endl; // use FeldmaCousins (takes ~20 min) FeldmanCousins fc(*data, *modelConfig); fc.SetConfidenceLevel(0.95); //0.9 central limit=0.95 upper limit //fc.SetTestSize(.1); // set size of test //number counting: dataset always has 1 entry with N events observed fc.FluctuateNumDataEntries(false); fc.UseAdaptiveSampling(true); fc.SetNBins(200); PointSetInterval* fcInt = NULL; //ConfInterval* interval = 0; RooRealVar* firstPOI = (RooRealVar*) modelConfig->GetParametersOfInterest()->first(); // if(doFeldmanCousins){ // takes 7 minutes fcInt = (PointSetInterval*) fc.GetInterval(); // fix cast //xs} //interval = (PointSetInterval*) fc.GetInterval(); cout<<" ["<<fcInt->LowerLimit( *firstPOI ) << ", " << fcInt->UpperLimit( *firstPOI ) << "]" << endl; cout<<" ["<<fcInt->LowerLimit( *firstPOI ) << ", " << fcInt->UpperLimit( *firstPOI ) << "]" << endl; double ul=fcInt->UpperLimit( *firstPOI ); //double ul=interval->UpperLimit( *firstPOI ); return ul; }
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; }
Double_t TwoBody::GetPoiUpper(std::string channel, Double_t peak, ModelConfig &_mc){ // // Estimate a good value for the upper boundary of the range of POI // std::string legend = "[TwoBody::GetPoiUpper]: "; double _range = -1.0; std::cout << legend << "doing a rough estimate of the POI range" << std::endl; // adding auto-channel option (multi) while // preserving backwards compatibility // if single channel _range = GetPoiUpperSimple(channel, peak); std::cout << legend << "crude estimate for poi range (x3): " << 3.0*_range << std::endl; std::cout << legend << "this will be used if the profile likelihood ratio estimate fails" << std::endl; std::cout << legend << "will try to estimate POI range better with profile likelihood ratio limit now" << std::endl; Double_t result = 0.1; // estimate limit with profile likelihood ratio and // set the range to 3 times the limit // query intervals RooFit::MsgLevel msglevel = RooMsgService::instance().globalKillBelow(); RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL); RooRealVar * _poi = (RooRealVar *)_mc.GetParametersOfInterest()->first(); double upper_limit = GetPlrInterval(0.95, _mc)->UpperLimit( *_poi ); RooMsgService::instance().setGlobalKillBelow(msglevel); // safety in case upper limit == 0 if (upper_limit<std::numeric_limits<double>::min()){ upper_limit = _range; } result = 3.0*upper_limit; return result; }
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 splitws(string inFolderName, double mass, string channel) { cout << "Splitting workspace in " << channel << endl; int flatInterpCode = 4; int shapeInterpCode = 4; bool do2011 = 0; if (inFolderName.find("2011") != string::npos) do2011 = 1; bool conditionalAsimov = 0; bool doData = 1; //if (inFolderName.find("_blind_") != string::npos) { //conditionalAsimov = 0; //} //else { //conditionalAsimov = 1; //} set<string> channelNames; if (channel == "01j") { channelNames.insert("em_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); } else if (channel == "0j") { channelNames.insert("em_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); } else if (channel == "1j") { channelNames.insert("em_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); } else if (channel == "OF01j") { channelNames.insert("em_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_sscr_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_sscr_1j"+string(!do2011?"_2012":"")); } else if (channel == "OF0j") { channelNames.insert("em_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_sscr_0j"+string(!do2011?"_2012":"")); } else if (channel == "OF1j") { channelNames.insert("em_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_sscr_1j"+string(!do2011?"_2012":"")); } else if (channel == "SF01j") { channelNames.insert("SF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); } else if (channel == "SF0j") { channelNames.insert("SF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); } else if (channel == "SF1j") { channelNames.insert("SF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); } else if (channel == "2j") { channelNames.insert("em_signalLike1_2j"+string(!do2011?"_2012":"")); channelNames.insert("ee_signalLike1_2j"+string(!do2011?"_2012":"")); channelNames.insert("SF_topbox_2j"+string(!do2011?"_2012":"")); } else if (channel == "OF2j") { channelNames.insert("em_signalLike1_2j"+string(!do2011?"_2012":"")); channelNames.insert("SF_topbox_2j"+string(!do2011?"_2012":"")); } else if (channel == "SF2j") { channelNames.insert("ee_signalLike1_2j"+string(!do2011?"_2012":"")); channelNames.insert("SF_topbox_2j"+string(!do2011?"_2012":"")); } else if (channel == "OF") { channelNames.insert("em_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_0j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike1_1j"+string(!do2011?"_2012":"")); channelNames.insert("me_signalLike2_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); channelNames.insert("em_signalLike1_2j"+string(!do2011?"_2012":"")); channelNames.insert("SF_topbox_2j"+string(!do2011?"_2012":"")); } else if (channel == "SF") { channelNames.insert("SF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_0j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_0j"+string(!do2011?"_2012":"")); channelNames.insert("SF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_AfrecSR_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_ASR_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("SF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CfrecZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_CZpeak_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_mainControl_1j"+string(!do2011?"_2012":"")); channelNames.insert("OF_topbox_1j"+string(!do2011?"_2012":"")); channelNames.insert("ee_signalLike1_2j"+string(!do2011?"_2012":"")); channelNames.insert("SF_topbox_2j"+string(!do2011?"_2012":"")); } else { cout << "Channel " << channel << " not defined. Please check!" << endl; exit(1); } // bool fix = 1; stringstream inFileName; inFileName << "workspaces/" << inFolderName << "/" << mass << ".root"; TFile f(inFileName.str().c_str()); RooWorkspace* w = (RooWorkspace*)f.Get("combWS"); if (!w) w = (RooWorkspace*)f.Get("combined"); RooDataSet* data = (RooDataSet*)w->data("combData"); if (!data) data = (RooDataSet*)w->data("obsData"); ModelConfig* mc = (ModelConfig*)w->obj("ModelConfig"); RooRealVar* weightVar = w->var("weightVar"); RooRealVar* mu = (RooRealVar*)mc->GetParametersOfInterest()->first(); if (!mu) mu = w->var("SigXsecOverSM"); const RooArgSet* mc_obs = mc->GetObservables(); const RooArgSet* mc_nuis = mc->GetNuisanceParameters(); const RooArgSet* mc_globs = mc->GetGlobalObservables(); const RooArgSet* mc_poi = mc->GetParametersOfInterest(); RooArgSet nuis = *mc_nuis; RooArgSet antiNuis = *mc_nuis; RooArgSet globs = *mc_globs; RooArgSet antiGlobs = *mc_globs; RooArgSet allParams; RooSimultaneous* simPdf = (RooSimultaneous*)mc->GetPdf(); RooCategory* cat = (RooCategory*)&simPdf->indexCat(); RooArgSet nuis_tmp = nuis; RooArgSet fullConstraints = *simPdf->getAllConstraints(*mc_obs,nuis_tmp,false); vector<string> foundChannels; vector<string> skippedChannels; cout << "Getting constraints" << endl; map<string, RooDataSet*> data_map; map<string, RooAbsPdf*> pdf_map; RooCategory* decCat = new RooCategory("dec_channel","dec_channel"); // int i = 0; TIterator* catItr = cat->typeIterator(); RooCatType* type; RooArgSet allConstraints; while ((type = (RooCatType*)catItr->Next())) { RooAbsPdf* pdf = simPdf->getPdf(type->GetName()); string typeName(type->GetName()); if (channelNames.size() && channelNames.find(typeName) == channelNames.end()) { skippedChannels.push_back(typeName); continue; } cout << "On channel " << type->GetName() << endl; foundChannels.push_back(typeName); decCat->defineType(type->GetName()); // pdf->getParameters(*data)->Print("v"); RooArgSet nuis_tmp1 = nuis; RooArgSet nuis_tmp2 = nuis; RooArgSet* constraints = pdf->getAllConstraints(*mc_obs, nuis_tmp1, true); constraints->Print(); allConstraints.add(*constraints); } catItr->Reset(); while ((type = (RooCatType*)catItr->Next())) { RooAbsPdf* pdf = simPdf->getPdf(type->GetName()); string typeName(type->GetName()); cout << "Considering type " << typeName << endl; if (channelNames.size() && channelNames.find(typeName) == channelNames.end()) continue; cout << "On channel " << type->GetName() << endl; RooArgSet nuis_tmp1 = nuis; RooArgSet nuis_tmp2 = nuis; RooArgSet* constraints = pdf->getAllConstraints(*mc_obs, nuis_tmp1, true); cout << "Adding pdf to map: " << typeName << " = " << pdf->GetName() << endl; pdf_map[typeName] = pdf; RooProdPdf prod("prod","prod",*constraints); RooArgSet* params = pdf->getParameters(*data); antiNuis.remove(*params); antiGlobs.remove(*params); allParams.add(*params); // cout << type->GetName() << endl; } // return; RooArgSet decNuis; TIterator* nuiItr = mc_nuis->createIterator(); TIterator* parItr = allParams.createIterator(); RooAbsArg* nui, *par; while ((par = (RooAbsArg*)parItr->Next())) { nuiItr->Reset(); while ((nui = (RooAbsArg*)nuiItr->Next())) { if (par == nui) decNuis.add(*nui); } } RooArgSet decGlobs; TIterator* globItr = mc_globs->createIterator(); parItr->Reset(); RooAbsArg* glob; while ((par = (RooAbsArg*)parItr->Next())) { globItr->Reset(); while ((glob = (RooAbsArg*)globItr->Next())) { if (par == glob) decGlobs.add(*glob); } } // antiNuis.Print(); // nuis.Print(); // globs.Print(); // i = 0; TList* datalist = data->split(*cat, true); TIterator* dataItr = datalist->MakeIterator(); RooAbsData* ds; while ((ds = (RooAbsData*)dataItr->Next())) { string typeName(ds->GetName()); if (channelNames.size() && channelNames.find(typeName) == channelNames.end()) continue; cout << "Adding dataset to map: " << ds->GetName() << endl; data_map[string(ds->GetName())] = (RooDataSet*)ds; cout << ds->GetName() << endl; } RooSimultaneous* decPdf = new RooSimultaneous("decPdf","decPdf",pdf_map,*decCat); RooArgSet decObs = *decPdf->getObservables(data); // decObs.add(*(RooAbsArg*)weightVar); decObs.add(*(RooAbsArg*)decCat); decObs.Print(); nuis.remove(antiNuis); globs.remove(antiGlobs); // nuis.Print("v"); RooDataSet* decData = new RooDataSet("obsData","obsData",RooArgSet(decObs,*(RooAbsArg*)weightVar),Index(*decCat),Import(data_map),WeightVar(*weightVar)); decData->Print(); RooArgSet poi(*(RooAbsArg*)mu); RooWorkspace decWS("combined"); ModelConfig decMC("ModelConfig",&decWS); decMC.SetPdf(*decPdf); decMC.SetObservables(decObs); decMC.SetNuisanceParameters(decNuis); decMC.SetGlobalObservables(decGlobs); decMC.SetParametersOfInterest(poi); decMC.Print(); decWS.import(*decPdf); decWS.import(decMC); decWS.import(*decData); // decWS.Print(); ModelConfig* mcInWs = (ModelConfig*)decWS.obj("ModelConfig"); decPdf = (RooSimultaneous*)mcInWs->GetPdf(); // setup(mcInWs); // return; mcInWs->GetNuisanceParameters()->Print("v"); mcInWs->GetGlobalObservables()->Print("v"); // decData->tree()->Scan("*"); // Make asimov data RooArgSet funcs = decWS.allFunctions(); TIterator* it = funcs.createIterator(); TObject* tempObj = 0; while((tempObj=it->Next())) { FlexibleInterpVar* flex = dynamic_cast<FlexibleInterpVar*>(tempObj); if(flex) { flex->setAllInterpCodes(flatInterpCode); } PiecewiseInterpolation* piece = dynamic_cast<PiecewiseInterpolation*>(tempObj); if(piece) { piece->setAllInterpCodes(shapeInterpCode); } } RooDataSet* dataInWs = (RooDataSet*)decWS.data("obsData"); makeAsimovData(mcInWs, conditionalAsimov && doData, &decWS, mcInWs->GetPdf(), dataInWs, 0); makeAsimovData(mcInWs, conditionalAsimov && doData, &decWS, mcInWs->GetPdf(), dataInWs, 1); makeAsimovData(mcInWs, conditionalAsimov && doData, &decWS, mcInWs->GetPdf(), dataInWs, 2); system(("mkdir -vp workspaces/"+inFolderName+"_"+channel).c_str()); stringstream outFileName; outFileName << "workspaces/" << inFolderName << "_" << channel << "/" << mass << ".root"; cout << "Exporting" << endl; decWS.writeToFile(outFileName.str().c_str()); cout << "\nIncluded the following channels: " << endl; for (int i=0;i<(int)foundChannels.size();i++) { cout << "-> " << foundChannels[i] << endl; } cout << "\nSkipping the following channels: " << endl; for (int i=0;i<(int)skippedChannels.size();i++) { cout << "-> " << skippedChannels[i] << endl; } cout << "Done" << endl; // decPdf->fitTo(*decData, Hesse(0), Minos(0), PrintLevel(0)); }
// 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 RunToyScan5(TString fileName, double startVal, double stopVal, TString outFile) { void frequentist(TString fileName) { cout << "Starting frequentist " << time(NULL) << endl; double startVal = 0; double stopVal = 200; TString outFile = ""; int nToys = 1 ; int nscanpoints = 2 ; /* gROOT->LoadMacro("RooBetaPdf.cxx+") ; gROOT->LoadMacro("RooRatio.cxx+") ; gROOT->LoadMacro("RooPosDefCorrGauss.cxx+") ; */ // get relevant objects out of the "ws" file TFile *file = TFile::Open(fileName); if(!file){ cout <<"file not found" << endl; return; } RooWorkspace* w = (RooWorkspace*) file->Get("workspace"); if(!w){ cout <<"workspace not found" << endl; return; } ModelConfig* mc = (ModelConfig*) w->obj("S+B_model"); RooAbsData* data = w->data("data"); if( !data || !mc ){ w->Print(); cout << "data or ModelConfig was not found" <<endl; return; } RooRealVar* myPOI = (RooRealVar*) mc->GetParametersOfInterest()->first(); myPOI->setRange(0, 1000.); ModelConfig* bModel = (ModelConfig*) w->obj("B_model"); ModelConfig* sbModel = (ModelConfig*) w->obj("S+B_model"); ProfileLikelihoodTestStat profll(*sbModel->GetPdf()); profll.SetPrintLevel(2); profll.SetOneSided(1); TestStatistic * testStat = &profll; HypoTestCalculatorGeneric * hc = 0; hc = new FrequentistCalculator(*data, *bModel, *sbModel); ToyMCSampler *toymcs = (ToyMCSampler*)hc->GetTestStatSampler(); toymcs->SetMaxToys(10000); toymcs->SetNEventsPerToy(1); toymcs->SetTestStatistic(testStat); ((FrequentistCalculator *)hc)->SetToys(nToys,nToys); HypoTestInverter calc(*hc); calc.SetConfidenceLevel(0.95); calc.UseCLs(true); //calc.SetVerbose(true); calc.SetVerbose(2); cout << "About to set fixed scan " << time(NULL) << endl; calc.SetFixedScan(nscanpoints,startVal,stopVal); cout << "About to do inverter " << time(NULL) << endl; HypoTestInverterResult * res_toysCLs_calculator = calc.GetInterval(); cout << "CLs = " << res_toysCLs_calculator->UpperLimit() << " CLs_exp = " << res_toysCLs_calculator->GetExpectedUpperLimit(0) << " CLs_exp(-1s) = " << res_toysCLs_calculator->GetExpectedUpperLimit(-1) << " CLs_exp(+1s) = " << res_toysCLs_calculator->GetExpectedUpperLimit(1) << endl ; /* // dump results string to output file ofstream outStream ; outStream.open(outFile,ios::app) ; outStream << "CLs = " << res_toysCLs_calculator->UpperLimit() << " CLs_exp = " << res_toysCLs_calculator->GetExpectedUpperLimit(0) << " CLs_exp(-1s) = " << res_toysCLs_calculator->GetExpectedUpperLimit(-1) << " CLs_exp(+1s) = " << res_toysCLs_calculator->GetExpectedUpperLimit(1) << endl ; outStream.close() ; */ cout << "End of frequentist " << time(NULL) << endl; return ; }
// implementation void TwoBinInstructional( void ){ // let's time this example TStopwatch t; t.Start(); // set RooFit random seed for reproducible results RooRandom::randomGenerator()->SetSeed(4357); // make model RooWorkspace * pWs = new RooWorkspace("ws"); // derived from data pWs->factory("xsec[0.2,0,2]"); // POI pWs->factory("bg_b[10,0,50]"); // data driven nuisance // predefined nuisances pWs->factory("lumi[100,0,1000]"); pWs->factory("eff_a[0.2,0,1]"); pWs->factory("eff_b[0.05,0,1]"); pWs->factory("tau[0,1]"); pWs->factory("xsec_bg_a[0.05]"); // constant pWs->var("xsec_bg_a")->setConstant(1); // channel a (signal): lumi*xsec*eff_a + lumi*bg_a + tau*bg_b pWs->factory("prod::sig_a(lumi,xsec,eff_a)"); pWs->factory("prod::bg_a(lumi,xsec_bg_a)"); pWs->factory("prod::tau_bg_b(tau, bg_b)"); pWs->factory("Poisson::pdf_a(na[14,0,100],sum::mu_a(sig_a,bg_a,tau_bg_b))"); // channel b (control): lumi*xsec*eff_b + bg_b pWs->factory("prod::sig_b(lumi,xsec,eff_b)"); pWs->factory("Poisson::pdf_b(nb[11,0,100],sum::mu_b(sig_b,bg_b))"); // nuisance constraint terms (systematics) pWs->factory("Lognormal::l_lumi(lumi,nom_lumi[100,0,1000],sum::kappa_lumi(1,d_lumi[0.1]))"); pWs->factory("Lognormal::l_eff_a(eff_a,nom_eff_a[0.20,0,1],sum::kappa_eff_a(1,d_eff_a[0.05]))"); pWs->factory("Lognormal::l_eff_b(eff_b,nom_eff_b[0.05,0,1],sum::kappa_eff_b(1,d_eff_b[0.05]))"); pWs->factory("Lognormal::l_tau(tau,nom_tau[0.50,0,1],sum::kappa_tau(1,d_tau[0.05]))"); //pWs->factory("Lognormal::l_bg_a(bg_a,nom_bg_a[0.05,0,1],sum::kappa_bg_a(1,d_bg_a[0.10]))"); // complete model PDF pWs->factory("PROD::model(pdf_a,pdf_b,l_lumi,l_eff_a,l_eff_b,l_tau)"); // Now create sets of variables. Note that we could use the factory to // create sets but in that case many of the sets would be duplicated // when the ModelConfig objects are imported into the workspace. So, // we create the sets outside the workspace, and only the needed ones // will be automatically imported by ModelConfigs // observables RooArgSet obs(*pWs->var("na"), *pWs->var("nb"), "obs"); // global observables RooArgSet globalObs(*pWs->var("nom_lumi"), *pWs->var("nom_eff_a"), *pWs->var("nom_eff_b"), *pWs->var("nom_tau"), "global_obs"); // parameters of interest RooArgSet poi(*pWs->var("xsec"), "poi"); // nuisance parameters RooArgSet nuis(*pWs->var("lumi"), *pWs->var("eff_a"), *pWs->var("eff_b"), *pWs->var("tau"), "nuis"); // priors (for Bayesian calculation) pWs->factory("Uniform::prior_xsec(xsec)"); // for parameter of interest pWs->factory("Uniform::prior_bg_b(bg_b)"); // for data driven nuisance parameter pWs->factory("PROD::prior(prior_xsec,prior_bg_b)"); // total prior // create data pWs->var("na")->setVal(14); pWs->var("nb")->setVal(11); RooDataSet * pData = new RooDataSet("data","",obs); pData->add(obs); pWs->import(*pData); //pData->Print(); // signal+background model ModelConfig * pSbModel = new ModelConfig("SbModel"); pSbModel->SetWorkspace(*pWs); pSbModel->SetPdf(*pWs->pdf("model")); pSbModel->SetPriorPdf(*pWs->pdf("prior")); pSbModel->SetParametersOfInterest(poi); pSbModel->SetNuisanceParameters(nuis); pSbModel->SetObservables(obs); pSbModel->SetGlobalObservables(globalObs); // set all but obs, poi and nuisance to const SetConstants(pWs, pSbModel); pWs->import(*pSbModel); // background-only model // use the same PDF as s+b, with xsec=0 // POI value under the background hypothesis Double_t poiValueForBModel = 0.0; ModelConfig* pBModel = new ModelConfig(*(RooStats::ModelConfig *)pWs->obj("SbModel")); pBModel->SetName("BModel"); pBModel->SetWorkspace(*pWs); pWs->import(*pBModel); // find global maximum with the signal+background model // with conditional MLEs for nuisance parameters // and save the parameter point snapshot in the Workspace // - safer to keep a default name because some RooStats calculators // will anticipate it RooAbsReal * pNll = pSbModel->GetPdf()->createNLL(*pData); RooAbsReal * pProfile = pNll->createProfile(RooArgSet()); pProfile->getVal(); // this will do fit and set POI and nuisance parameters to fitted values RooArgSet * pPoiAndNuisance = new RooArgSet(); if(pSbModel->GetNuisanceParameters()) pPoiAndNuisance->add(*pSbModel->GetNuisanceParameters()); pPoiAndNuisance->add(*pSbModel->GetParametersOfInterest()); cout << "\nWill save these parameter points that correspond to the fit to data" << endl; pPoiAndNuisance->Print("v"); pSbModel->SetSnapshot(*pPoiAndNuisance); delete pProfile; delete pNll; delete pPoiAndNuisance; // Find a parameter point for generating pseudo-data // with the background-only data. // Save the parameter point snapshot in the Workspace pNll = pBModel->GetPdf()->createNLL(*pData); pProfile = pNll->createProfile(poi); ((RooRealVar *)poi.first())->setVal(poiValueForBModel); pProfile->getVal(); // this will do fit and set nuisance parameters to profiled values pPoiAndNuisance = new RooArgSet(); if(pBModel->GetNuisanceParameters()) pPoiAndNuisance->add(*pBModel->GetNuisanceParameters()); pPoiAndNuisance->add(*pBModel->GetParametersOfInterest()); cout << "\nShould use these parameter points to generate pseudo data for bkg only" << endl; pPoiAndNuisance->Print("v"); pBModel->SetSnapshot(*pPoiAndNuisance); delete pProfile; delete pNll; delete pPoiAndNuisance; // inspect workspace pWs->Print(); // save workspace to file pWs->writeToFile("ws_twobin.root"); // clean up delete pWs; delete pData; delete pSbModel; delete pBModel; } // ----- end of tutorial ----------------------------------------
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 test_counting_experiment() { ////////////////////// MODEL BUILDING ///////////////////////////////// /////////////////////////////////////////////////////////////////////////// /* N_s = N_tot_theory(Mass,Xsec) * Acceptance_SR * Eff_AmBe_bin_i * mu N_b = N_Co_SR_bin_i * Norm_factor Xesec: considered 10^-40 cm^2 Norm_factor = N_Data_CR / N_Co_CR --> assuming no difference between Co and Data in CR and SR. N_tot_theory(Mass,Xsec): for 225 livedays, 45kg and considering Xsec. It is a constant, no uncertainty at the moment. ---Costraint Signal nuissance parameter = Acceptance_SR, Eff_AmBe_bin_i Gauss(Acceptance_SR_obs | Acceptance_SR, err.) Poisson(S0_i | S_tot_SR * Eff_AmBe_bin_i) ---Costraint Bkg nuissance parameter = N_Co_SR_bin_i, Norm_factor Gauss(Norm_factor_obs | Norm_factor, err) Poisson(B0_i | N_Co_SR_bin_i) ---- WARNING:: convergence problems: mu_hat should always be >> 1, too small values have problem in finding minimum because mu is set >0. ---> Try to fix Xsec in order to have mu_hat ~ 10 */ RooWorkspace w("w"); //gROOT->ProcessLine(".L retrieve_input_from_histo_NoSys.C+"); gROOT->ProcessLine(".L retrieve_input_from_histo.C+"); retrieve_input_from_histo(w); // Building the model ModelConfig mc("ModelConfig",&w); mc.SetPdf(*w.pdf("model")); mc.SetParametersOfInterest(*w.var("mu")); // Setting nuissance parameter mc.SetNuisanceParameters(*w.set("nuissance_parameter")); // need now to set the global observable mc.SetGlobalObservables(*w.set("g_observables")); mc.SetObservables(*w.set("observables")); // this is needed for the hypothesis tests mc.SetSnapshot(*w.var("mu")); // make data set with the number of observed events RooDataSet data("data","", *w.set("observables")); data.add(*w.set("observables")); // import data set in workspace and save it in a file w.import(data); // import model in the workspace w.import(mc); w.writeToFile("CountingModel.root", true); w.Print(); data.Print(); /* cout << w.var("S_i")->getValV() << endl;//<< " " << w.var("S_i_exp")->getValV() << endl; /////////////////////////////////////////////////////////////////////// ProfileLikelihoodCalculator pl(data,mc); pl.SetConfidenceLevel(0.95); LikelihoodInterval* interval = pl.GetInterval(); // find the iterval on the first Parameter of Interest RooRealVar* firstPOI = (RooRealVar*) mc.GetParametersOfInterest()->first(); double lowerLimit = interval->LowerLimit(*firstPOI); double upperLimit = interval->UpperLimit(*firstPOI); cout << "\n95% interval on " <<firstPOI->GetName()<<" is : ["<< lowerLimit << ", "<< upperLimit <<"] "<<endl; LikelihoodIntervalPlot * plot = new LikelihoodIntervalPlot(interval); // plot->SetRange(0,50); // possible eventually to change ranges //plot->SetNPoints(50); // do not use too many points, it could become very slow for some models plot->Draw(""); // use option TF1 if too slow (plot.Draw("tf1") */ ////////////////////////// hypo test // get the modelConfig (S+B) out of the file // and create the B model from the S+B model ModelConfig * sbModel = (ModelConfig*) mc.Clone(); sbModel->SetName("S+B Model"); RooRealVar* poi = (RooRealVar*) sbModel->GetParametersOfInterest()->first(); poi->setVal(1); // set POI snapshot in S+B model for expected significance sbModel->SetSnapshot(*poi); ModelConfig * bModel = (ModelConfig*) mc.Clone(); bModel->SetName("B Model"); RooRealVar* poi2 = (RooRealVar*) bModel->GetParametersOfInterest()->first(); poi2->setVal(0); bModel->SetSnapshot( *poi2 ); //------------------Limit calculation for N_th event expected = 10 AsymptoticCalculator ac(data, *bModel, *sbModel); //ac.SetOneSidedDiscovery(true); // for one-side discovery test // ac.SetOneSided(true); // for one-side tests (limits) ac.SetQTilde(true); ac.SetPrintLevel(2); // to suppress print level // create hypotest inverter // passing the desired calculator HypoTestInverter *calc = new HypoTestInverter(ac); // for asymptotic //HypoTestInverter calc(fc); // for frequentist calc->SetConfidenceLevel(0.90); //calc->UseCLs(false); calc->UseCLs(true); int npoints = 500; // number of points to scan //int npoints = 1000; // number of points to scan default 1000 // min and max (better to choose smaller intervals) double poimin = poi->getMin(); double poimax = poi->getMax(); //poimin = 0; poimax=10; std::cout << "Doing a fixed scan in interval : " << poimin << " , " << poimax << std::endl; calc->SetFixedScan(npoints,poimin,poimax); calc->SetVerbose(2); HypoTestInverterResult * r = calc->GetInterval(); double upperLimit = r->UpperLimit(); std::cout << "The computed Expected upper limit is: " << r->GetExpectedUpperLimit(0) << std::endl; //------------ Getting the interval as function of m --------------// /* ifstream in; in.open("integral_mass.dat"); vector <double> masses_v; vector <double> observed_v; vector <double> expected_v; vector <double> expected_gaud_v; vector <double> expected_S1_up_v; vector <double> expected_S1_dw_v; vector <double> expected_S2_up_v; vector <double> expected_S2_dw_v; double mass_itr =0.; double Nev_exp_th_itr =0.; double xsec_modifier = 10.; double N_tot_theory = w.var("N_tot_theory")->getValV(); while(mass_itr <1000.){ in >> mass_itr; in >> Nev_exp_th_itr; xsec_modifier = Nev_exp_th_itr * 225.009 * 34.; //225.009 livedays and 34 kg and 10^-40 cm2 Xsec. masses_v.push_back(mass_itr); observed_v.push_back( 1.e-40 * N_tot_theory / xsec_modifier * upperLimit ); expected_v.push_back( 1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(0) ); expected_gaud_v.push_back(7e-38 * 1.37590955945e-05 / Nev_exp_th_itr ); expected_S1_up_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(1)); expected_S2_up_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(2)); expected_S2_dw_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(-2)); expected_S1_dw_v.push_back(1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(-1)); cout << "Expected median limit for mass " << mass_itr << " GeV = " << 1.e-40 * N_tot_theory / xsec_modifier * r->GetExpectedUpperLimit(0) << " cm^2 " << endl; // observed_v.push_back( w.var("Xsec")->getValV() * w.var("K_m")->getValV()* upperLimit ); // expected_v.push_back( w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(0) ); // expected_S1_up_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(1)); // expected_S2_up_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(2)); // expected_S2_dw_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(-2)); // expected_S1_dw_v.push_back(w.var("Xsec")->getValV() * w.var("K_m")->getValV()* r->GetExpectedUpperLimit(-1)); } in.close(); const int n = masses_v.size(); double xe[n]; double mA[n]; double observed[n]; double expected[n]; double expected_gaudenz[n]; double exSigma1_l[n]; double exSigma1_u[n]; double exSigma2_l[n]; double exSigma2_u[n]; for(int k=0; k< n; k++){ mA[k] = masses_v[k]; observed[k] = observed_v[k]; expected[k] = expected_v[k]; expected_gaudenz[k] = expected_gaud_v[k]; exSigma1_l[k] =expected_v[k] - expected_S1_dw_v[k] ; exSigma1_u[k] = expected_S1_up_v[k] - expected_v[k]; exSigma2_l[k] = expected_v[k] - expected_S2_dw_v[k]; exSigma2_u[k] = expected_S2_up_v[k] - expected_v[k] ; } TGraphErrors *obs_limits = new TGraphErrors(n, mA, observed); TGraphErrors *Exp_limits = new TGraphErrors(n, mA, expected ); TGraphAsymmErrors *Exp_limitsS1 = new TGraphAsymmErrors(n, mA, expected ,xe, xe, exSigma1_l, exSigma1_u ); TGraphAsymmErrors *Exp_limitsS2 = new TGraphAsymmErrors(n, mA, expected ,xe, xe, exSigma2_l, exSigma2_u); TGraphErrors *Exp_limits_gaudenz = new TGraphErrors( n, mA, expected_gaudenz); //double expected_xmass[15] = {8e-36,7e-37, 2e-37, 1e-37, 8e-38, 6e-38, 5.5e-38, 5e-38, 4.3e-38, 5e-38, 6e-38, 7e-38, 9e-38, 1.2e-37, 1.5e-37}; //double m_xmass[15] = { 20, 30., 40., 50., 60., 70., 80., 90., 100., 200., 300., 400, 500.,700., 1000.}; TGraphErrors *Exp_limits_xmass = new TGraphErrors(16); Exp_limits_xmass->SetPoint(0,20,8e-36); Exp_limits_xmass->SetPointError(0,0,0); Exp_limits_xmass->SetPoint(1,29.8071,7.162923e-37); Exp_limits_xmass->SetPointError(1,0,0); Exp_limits_xmass->SetPoint(2,39.90202,2.027528e-37); Exp_limits_xmass->SetPointError(2,0,0); Exp_limits_xmass->SetPoint(3,53.41583,9.91722e-38); Exp_limits_xmass->SetPointError(3,0,0); Exp_limits_xmass->SetPoint(4,62.16429,7.461589e-38); Exp_limits_xmass->SetPointError(4,0,0); Exp_limits_xmass->SetPoint(5,69.85718,6.3506e-38); Exp_limits_xmass->SetPointError(5,0,0); Exp_limits_xmass->SetPoint(6,83.21777,5.354015e-38); Exp_limits_xmass->SetPointError(6,0,0); Exp_limits_xmass->SetPoint(7,90,5e-38); Exp_limits_xmass->SetPointError(7,0,0); Exp_limits_xmass->SetPoint(8,105.0887,4.600252e-38); Exp_limits_xmass->SetPointError(8,0,0); Exp_limits_xmass->SetPoint(9,200,5e-38); Exp_limits_xmass->SetPointError(9,0,0); Exp_limits_xmass->SetPoint(10,300,6e-38); Exp_limits_xmass->SetPointError(10,0,0); Exp_limits_xmass->SetPoint(11,388.2045,7.252295e-38); Exp_limits_xmass->SetPointError(11,0,0); Exp_limits_xmass->SetPoint(12,590.8438,9.823615e-38); Exp_limits_xmass->SetPointError(12,0,0); Exp_limits_xmass->SetPoint(13,746.1269,1.210266e-37); Exp_limits_xmass->SetPointError(13,0,0); Exp_limits_xmass->SetPoint(14,1000,1.5e-37); Exp_limits_xmass->SetPointError(14,0,0); Exp_limits_xmass->SetPoint(15,4244.204,4.354065e-37); Exp_limits_xmass->SetPointError(15,0,0); TCanvas *c1 = new TCanvas("limits", "limit", 600, 600); Exp_limitsS1->SetFillColor(3); Exp_limitsS1->SetLineColor(3); Exp_limitsS1->SetMarkerColor(3); Exp_limitsS1->SetMarkerSize(0); Exp_limitsS2->SetFillColor(5); Exp_limitsS2->SetLineColor(5); Exp_limitsS2->SetMarkerColor(5); Exp_limitsS2->SetMarkerSize(0); obs_limits->SetFillColor(0); obs_limits->SetLineWidth(3); obs_limits->SetMarkerSize(0); Exp_limits->SetFillColor(0); Exp_limits->SetMarkerSize(0); Exp_limits->SetLineStyle(7); Exp_limits->SetLineWidth(3); Exp_limits_gaudenz->SetFillColor(0); Exp_limits_gaudenz->SetMarkerSize(0); Exp_limits_gaudenz->SetLineWidth(3); Exp_limits_gaudenz->SetLineColor(4); Exp_limits_xmass->SetFillColor(0); Exp_limits_xmass->SetMarkerSize(0); Exp_limits_xmass->SetLineWidth(3); Exp_limits_xmass->SetLineColor(2); //Exp_limitsS2->GetYaxis()->SetTitle("#sigma#timesBR( #phi #rightarrow #tau#tau ) [pb]"); Exp_limitsS2->GetYaxis()->SetTitle("#sigma"); Exp_limitsS2->GetXaxis()->SetTitle("M [GeV]"); Exp_limitsS2->GetXaxis()->SetLimits(9.,1000.); Exp_limitsS2->GetYaxis()->SetRangeUser(1E-38,1E-30); Exp_limits->GetXaxis()->SetLimits(9.,1000.); Exp_limits->GetYaxis()->SetRangeUser(1E-38,1E-30); Exp_limitsS2->Draw("Al3"); Exp_limitsS1->Draw("sameL3"); Exp_limits->Draw("PL"); Exp_limits_gaudenz->Draw("PC"); Exp_limits_xmass->Draw("PC"); //obs_limits->Draw("PL"); TLegend* lego = new TLegend(0.2,0.9,0.5,0.7); lego->SetTextSize(0.033); lego->SetFillColor(0); lego->SetBorderSize(0); lego->AddEntry(obs_limits,"Observed 90\% CLs limit"); lego->AddEntry(Exp_limits_gaudenz, "Expected 90\% Gaudenz"); lego->AddEntry(Exp_limits_xmass, "Expected 90\% XMASS"); lego->AddEntry(Exp_limits, "Expected 90\% CLs limit"); lego->AddEntry(Exp_limitsS1,"1 #sigma","f"); lego->AddEntry(Exp_limitsS2,"2 #sigma","f"); lego->Draw(); gPad->SetLogy(); gPad->SetLogx(); gPad->RedrawAxis("g"); myText(0.4,0.86,2,"Test"); */ // now use the profile inspector ProfileInspector p; TList* list = p.GetListOfProfilePlots(data,&mc); // now make plots TCanvas* c1 = new TCanvas("c1","ProfileInspectorDemo",800,200); if(list->GetSize()>4){ double n = list->GetSize(); int nx = (int)sqrt(n) ; int ny = TMath::CeilNint(n/nx); nx = TMath::CeilNint( sqrt(n) ); c1->Divide(ny,nx); } else c1->Divide(list->GetSize()); for(int i=0; i<list->GetSize(); ++i){ c1->cd(i+1); list->At(i)->Draw("al"); } cout << endl; /* // plot now the result of the scan HypoTestInverterPlot *plot = new HypoTestInverterPlot("HTI_Result_Plot","HypoTest Scan Result",r); // plot in a new canvas with style TCanvas * c1 = new TCanvas("HypoTestInverter Scan"); c1->SetLogy(false); plot->Draw("2CL"); // plot also CLb and CLs+b //plot->Draw("OBS"); // plot only observed p-value */ // plot also in a new canvas the test statistics distributions // plot test statistics distributions for the two hypothesis /* // when distribution is generated (case of FrequentistCalculators) const int n = r->ArraySize(); if (n> 0 && r->GetResult(0)->GetNullDistribution() ) { TCanvas * c2 = new TCanvas("Test Statistic Distributions","",2); if (n > 1) { int ny = TMath::CeilNint( sqrt(n) ); int nx = TMath::CeilNint(double(n)/ny); c2->Divide( nx,ny); } for (int i=0; i<n; i++) { if (n > 1) c2->cd(i+1); SamplingDistPlot * pl = plot->MakeTestStatPlot(i); pl->SetLogYaxis(true); pl->Draw(); } } */ }
void significance(RooWorkspace& w ) { ModelConfig* mc = (ModelConfig*)w.obj("mc"); RooDataSet* data = (RooDataSet*)w.data("data"); //data->Print(); // define the S+B snapshot (this is used for computing the expected significance) ModelConfig* sbModel = mc->Clone(); sbModel->SetName("S+B Model"); RooRealVar* poi = (RooRealVar*) sbModel->GetParametersOfInterest()->first(); poi->setVal(50); sbModel->SetSnapshot(*poi); ModelConfig * bModel = (ModelConfig*) sbModel->Clone(); bModel->SetName("B model"); poi->setVal(0); bModel->SetSnapshot(*poi); vector<double> masses; vector<double> p0values; vector<double> p0valuesExpected; vector<double> sigvalues; double massMin = 200; double massMax = 2500; int nbins = 100; // loop on the mass values for ( double mass=massMin; mass<=massMax; mass += (massMax-massMin)/nbins ) { w.var("mass")->setVal( mass ); // create the AsymptoticCalculator from data,alt model, null model AsymptoticCalculator * ac = new AsymptoticCalculator(*data, *sbModel, *bModel); ac->SetOneSidedDiscovery(true); // for one-side discovery test AsymptoticCalculator::SetPrintLevel(-1); // run the calculator HypoTestResult* asymCalcResult = ac->GetHypoTest(); asymCalcResult->Print(); double pvalue = asymCalcResult->NullPValue(); double sigvalue = asymCalcResult->Significance(); double expectedP0 = AsymptoticCalculator::GetExpectedPValues(asymCalcResult->NullPValue(),asymCalcResult->AlternatePValue(), 0, false); masses.push_back(mass); p0values.push_back(pvalue); p0valuesExpected.push_back(expectedP0); sigvalues.push_back(sigvalue); std::cout << "** Mass = " << mass << " p0-value = " << expectedP0 << " p-value = " << pvalue << " significance = " << sigvalue << std::endl; } TGraph* graph1 = new TGraph(masses.size(),&masses[0],&p0values[0]); TGraph* graph2 = new TGraph(masses.size(),&masses[0],&p0valuesExpected[0]); TGraph* graph3 = new TGraph(masses.size(),&masses[0],&sigvalues[0]); TCanvas* c2 = new TCanvas("c2","Significance", 900, 700); c2->Divide(1,2); c2->cd(1); graph1->SetMarkerStyle(10); //graph1->Draw("APC"); graph1->Draw("AC"); graph2->SetLineStyle(2); graph2->Draw("C"); graph1->GetXaxis()->SetTitle("Mass [GeV]"); graph1->GetYaxis()->SetTitle("p0 value"); graph1->SetTitle("P-value vs Mass"); graph1->SetMinimum(graph2->GetMinimum()); graph1->SetLineColor(kBlue); graph2->SetLineColor(kRed); gPad->SetLogy(true); c2->cd(2); graph3->SetMarkerStyle(10); graph3->Draw("AC"); graph3->SetLineStyle(1); graph3->SetLineColor(kRed); graph3->GetXaxis()->SetTitle("Mass [GeV]"); graph3->GetYaxis()->SetTitle("Significance"); graph3->SetTitle("Significance vs Mass"); gPad->SetLogy(false); c2->SaveAs("significance.pdf"); c2->SaveAs("significance.png"); }
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(); } }
void HypoTestInvDemo(const char * fileName ="GausModel_b.root", const char * wsName = "w", const char * modelSBName = "model_sb", const char * modelBName = "model_b", const char * dataName = "data_obs", int type = 0, // calculator type int testStatType = 0, // test stat type int npoints = 10, int ntoys=1000, bool useCls = true ) { /* type = 0 Freq calculator type = 1 Hybrid testStatType = 0 LEP = 1 Tevatron = 2 PL */ if (fileName==0) { std::cout << "give input filename " << std::endl; return; } TFile * file = new TFile(fileName); RooWorkspace * w = dynamic_cast<RooWorkspace*>( file->Get(wsName) ); if (!w) { return; } w->Print(); RooAbsData * data = w->data(dataName); if (!data) { Error("HypoTestDemo","Not existing data %s",dataName); } // get models from WS // get the modelConfig out of the file ModelConfig* bModel = (ModelConfig*) w->obj(modelBName); ModelConfig* sbModel = (ModelConfig*) w->obj(modelSBName); SimpleLikelihoodRatioTestStat slrts(*bModel->GetPdf(),*sbModel->GetPdf()); slrts.SetNullParameters(*bModel->GetSnapshot()); slrts.SetAltParameters(*sbModel->GetSnapshot()); RatioOfProfiledLikelihoodsTestStat ropl(*bModel->GetPdf(), *sbModel->GetPdf(), sbModel->GetSnapshot()); ropl.SetSubtractMLE(false); ProfileLikelihoodTestStat profll(*sbModel->GetPdf()); profll.SetOneSided(0); TestStatistic * testStat = &slrts; if (testStatType == 1) testStat = &ropl; if (testStatType == 2) testStat = &profll; HypoTestCalculatorGeneric * hc = 0; if (type == 0) hc = new FrequentistCalculator(*data, *sbModel, *bModel); else new HybridCalculator(*data, *sbModel, *bModel); ToyMCSampler *toymcs = (ToyMCSampler*)hc->GetTestStatSampler(); //toymcs->SetNEventsPerToy(1); toymcs->SetTestStatistic(testStat); if (type == 1) { HybridCalculator *hhc = (HybridCalculator*) hc; hhc->SetToys(ntoys,ntoys); // hhc->ForcePriorNuisanceAlt(*pdfNuis); // hhc->ForcePriorNuisanceNull(*pdfNuis); } else ((FrequentistCalculator*) hc)->SetToys(ntoys,ntoys); // Get the result RooMsgService::instance().getStream(1).removeTopic(RooFit::NumIntegration); TStopwatch tw; tw.Start(); const RooArgSet * poiSet = sbModel->GetParametersOfInterest(); RooRealVar *poi = (RooRealVar*)poiSet->first(); // fit the data first sbModel->GetPdf()->fitTo(*data); double poihat = poi->getVal(); //poi->setVal(30); //poi->setError(10); HypoTestInverter calc(*hc); // GENA: for two-sided interval //calc.SetConfidenceLevel(0.95); // GENA: for 95% upper limit calc.SetConfidenceLevel(0.90); calc.UseCLs(useCls); calc.SetVerbose(true); // can spped up using proof ProofConfig pc(*w, 2, "workers=2", kFALSE); //ProofConfig pc(*w, 30, "localhost", kFALSE); //ToyMCSampler * toymcs = dynamic_cast<ToyMCSampler *> (calc.GetHypoTestCalculator()->GetTestStatSampler() ); // GENA: disable proof for now //toymcs->SetProofConfig(&pc); // enable proof if (npoints > 0) { // GENA double poimin = TMath::Max(poihat - 4 * poi->getError(), 0.0); //poimin = poihat; double poimax = poihat + 4 * poi->getError(); poimin = 0; poimax = 20; //double poimin = poi->getMin(); //double poimax = poi->getMax(); std::cout << "Doing a fixed scan in interval : " << poimin << " , " << poimax << std::endl; calc.SetFixedScan(npoints,poimin,poimax); } HypoTestInverterResult * r = calc.GetInterval(); // write to a file the results TString resultFileName = (useCls) ? "CLs_" : "Cls+b_"; resultFileName += fileName; // GENA //TFile * file = new TFile(resultFileName,"RECREATE"); file = new TFile(resultFileName,"RECREATE"); r->Write(); file->Close(); double ulError = r->UpperLimitEstimatedError(); double upperLimit = r->UpperLimit(); std::cout << "The computed upper limit is: " << upperLimit << std::endl; std::cout << "an estimated error on this upper limit is: " << ulError << std::endl; // check using interpolation // double interpLimit = r->FindInterpolatedLimit(1.-r->ConfidenceLevel() ); // cout << "The computer interpolated limits is " << interpLimit << endl; const int nEntries = r->ArraySize(); std::vector<Double_t> xArray(nEntries); std::vector<Double_t> yArray(nEntries); std::vector<Double_t> yErrArray(nEntries); for (int i=0; i<nEntries; i++) { xArray[i] = r->GetXValue(i); yArray[i] = r->GetYValue(i); yErrArray[i] = r->GetYError(i); std::cout << xArray[i] << " , " << yArray[i] << " err = " << yErrArray[i] << std::endl; } // see expected result (bands) TGraph * g0 = new TGraph(nEntries); TGraphAsymmErrors * g1 = new TGraphAsymmErrors(nEntries); TGraphAsymmErrors * g2l = new TGraphAsymmErrors(nEntries); TGraphAsymmErrors * g2u = new TGraphAsymmErrors(nEntries); double p[7]; double q[7]; p[0] = ROOT::Math::normal_cdf(-2); p[1] = ROOT::Math::normal_cdf(-1.5); p[2] = ROOT::Math::normal_cdf(-1); p[3] = 0.5; p[4] = ROOT::Math::normal_cdf(1); p[5] = ROOT::Math::normal_cdf(1.5); p[6] = ROOT::Math::normal_cdf(2); for (int i=0; i<nEntries; i++) { SamplingDistribution * s = r->GetExpectedDistribution(i); // GENA //const std::vector<double> & values = s->GetSamplingDistribution(); const std::vector<Double_t> & cValues = s->GetSamplingDistribution(); std::vector<Double_t> values; for (std::vector<Double_t>::const_iterator val = cValues.begin(); val != cValues.end(); ++val) values.push_back(*val); TMath::Quantiles(values.size(), 7, &values[0],q,p,false); double p0 = q[3]; double p2l = q[1]; double p2u = q[5]; g0->SetPoint(i, r->GetXValue(i), p0 ) ; g1->SetPoint(i, r->GetXValue(i), p0); g2l->SetPoint(i, r->GetXValue(i), p2l); g2u->SetPoint(i, r->GetXValue(i), p2u); //g2->SetPoint(i, r->GetXValue(i), s->InverseCDF(0.50)); g1->SetPointEYlow(i, q[3] - q[2]); // -1 sigma errorr g1->SetPointEYhigh(i, q[4] - q[3]);//+1 sigma error g2l->SetPointEYlow(i, q[1]-q[0]); // -2 -- -1 sigma error g2l->SetPointEYhigh(i, q[2]-q[1]); g2u->SetPointEYlow(i, q[5]-q[4]); g2u->SetPointEYhigh(i, q[6]-q[5]); if (plotHypoTestResult) { HypoTestResult * hr = new HypoTestResult(); hr->SetNullDistribution( r->GetBackgroundDistribution() ); hr->SetAltDistribution( r->GetSignalAndBackgroundDistribution(i) ); new TCanvas(); HypoTestPlot * pl = new HypoTestPlot(*hr); pl->Draw(); } } HypoTestInverterPlot *plot = new HypoTestInverterPlot("result","",r); TGraphErrors * g = plot->MakePlot(); g->Draw("APL"); g2l->SetFillColor(kYellow); g2l->Draw("3"); g2u->SetFillColor(kYellow); g2u->Draw("3"); g1->SetFillColor(kGreen); g1->Draw("3"); g0->SetLineColor(kBlue); g0->SetLineStyle(2); g0->SetLineWidth(2); g0->Draw("L"); //g1->Draw("P"); //g2->Draw("P"); g->SetLineWidth(2); g->Draw("PL"); // GENA: two-sided interval //double alpha = 1.-r->ConfidenceLevel(); // GENA: upper limit double alpha = (1.-r->ConfidenceLevel())/2.0; double x1 = g->GetXaxis()->GetXmin(); double x2 = g->GetXaxis()->GetXmax(); TLine * line = new TLine(x1, alpha, x2,alpha); line->SetLineColor(kRed); line->Draw(); // see the expected limit and -1 +1 sigma bands // SamplingDistribution * limits = r->GetUpperLimitDistribution(); // std::cout << " expected limit (median) " << limits->InverseCDF(0.50) << std::endl; // std::cout << " expected limit (-1 sig) " << limits->InverseCDF((ROOT::Math::normal_cdf(-1))) << std::endl; // std::cout << " expected limit (+1 sig) " << limits->InverseCDF((ROOT::Math::normal_cdf(+1))) << std::endl; tw.Print(); }
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(); }
// internal routine to run the inverter HypoTestInverterResult * RunInverter(RooWorkspace * w, const char * modelSBName, const char * modelBName, const char * dataName, int type, int testStatType, int npoints, double poimin, double poimax, int ntoys, bool useCls ) { std::cout << "Running HypoTestInverter on the workspace " << w->GetName() << std::endl; w->Print(); RooAbsData * data = w->data(dataName); if (!data) { Error("RA2bHypoTestDemo","Not existing data %s",dataName); return 0; } else std::cout << "Using data set " << dataName << std::endl; // get models from WS // get the modelConfig out of the file ModelConfig* bModel = (ModelConfig*) w->obj(modelBName); ModelConfig* sbModel = (ModelConfig*) w->obj(modelSBName); if (!sbModel) { Error("RA2bHypoTestDemo","Not existing ModelConfig %s",modelSBName); return 0; } // check the model if (!sbModel->GetPdf()) { Error("RA2bHypoTestDemo","Model %s has no pdf ",modelSBName); return 0; } if (!sbModel->GetParametersOfInterest()) { Error("RA2bHypoTestDemo","Model %s has no poi ",modelSBName); return 0; } if (!sbModel->GetParametersOfInterest()) { Error("RA2bHypoTestInvDemo","Model %s has no poi ",modelSBName); return 0; } if (!sbModel->GetSnapshot() ) { Info("RA2bHypoTestInvDemo","Model %s has no snapshot - make one using model poi",modelSBName); sbModel->SetSnapshot( *sbModel->GetParametersOfInterest() ); } if (!bModel || bModel == sbModel) { Info("RA2bHypoTestInvDemo","The background model %s does not exist",modelBName); Info("RA2bHypoTestInvDemo","Copy it from ModelConfig %s and set POI to zero",modelSBName); bModel = (ModelConfig*) sbModel->Clone(); bModel->SetName(TString(modelSBName)+TString("_with_poi_0")); RooRealVar * var = dynamic_cast<RooRealVar*>(bModel->GetParametersOfInterest()->first()); if (!var) return 0; double oldval = var->getVal(); var->setVal(0); bModel->SetSnapshot( RooArgSet(*var) ); var->setVal(oldval); } else { if (!bModel->GetSnapshot() ) { Info("RA2bHypoTestInvDemo","Model %s has no snapshot - make one using model poi and 0 values ",modelBName); RooRealVar * var = dynamic_cast<RooRealVar*>(bModel->GetParametersOfInterest()->first()); if (var) { double oldval = var->getVal(); var->setVal(0); bModel->SetSnapshot( RooArgSet(*var) ); var->setVal(oldval); } else { Error("RA2bHypoTestInvDemo","Model %s has no valid poi",modelBName); return 0; } } } SimpleLikelihoodRatioTestStat slrts(*sbModel->GetPdf(),*bModel->GetPdf()); if (sbModel->GetSnapshot()) slrts.SetNullParameters(*sbModel->GetSnapshot()); if (bModel->GetSnapshot()) slrts.SetAltParameters(*bModel->GetSnapshot()); // ratio of profile likelihood - need to pass snapshot for the alt RatioOfProfiledLikelihoodsTestStat ropl(*sbModel->GetPdf(), *bModel->GetPdf(), bModel->GetSnapshot()); ropl.SetSubtractMLE(false); //MyProfileLikelihoodTestStat profll(*sbModel->GetPdf()); ProfileLikelihoodTestStat profll(*sbModel->GetPdf()); if (testStatType == 3) profll.SetOneSided(1); if (optimize) profll.SetReuseNLL(true); TestStatistic * testStat = &slrts; if (testStatType == 1) testStat = &ropl; if (testStatType == 2 || testStatType == 3) testStat = &profll; HypoTestCalculatorGeneric * hc = 0; if (type == 0) hc = new FrequentistCalculator(*data, *bModel, *sbModel); else hc = new HybridCalculator(*data, *bModel, *sbModel); ToyMCSampler *toymcs = (ToyMCSampler*)hc->GetTestStatSampler(); //=== DEBUG ///// toymcs->SetWS( w ) ; //=== DEBUG toymcs->SetNEventsPerToy(1); toymcs->SetTestStatistic(testStat); if (optimize) toymcs->SetUseMultiGen(true); if (type == 1) { HybridCalculator *hhc = (HybridCalculator*) hc; hhc->SetToys(ntoys,ntoys); // check for nuisance prior pdf if (bModel->GetPriorPdf() && sbModel->GetPriorPdf() ) { hhc->ForcePriorNuisanceAlt(*bModel->GetPriorPdf()); hhc->ForcePriorNuisanceNull(*sbModel->GetPriorPdf()); } else { if (bModel->GetNuisanceParameters() || sbModel->GetNuisanceParameters() ) { Error("RA2bHypoTestInvDemo","Cannnot run Hybrid calculator because no prior on the nuisance parameter is specified"); return 0; } } } else ((FrequentistCalculator*) hc)->SetToys(ntoys,ntoys); // Get the result RooMsgService::instance().getStream(1).removeTopic(RooFit::NumIntegration); TStopwatch tw; tw.Start(); const RooArgSet * poiSet = sbModel->GetParametersOfInterest(); RooRealVar *poi = (RooRealVar*)poiSet->first(); // fit the data first sbModel->GetPdf()->fitTo(*data); double poihat = poi->getVal(); HypoTestInverter calc(*hc); calc.SetConfidenceLevel(0.95); calc.UseCLs(useCls); calc.SetVerbose(true); // can speed up using proof-lite if (useProof && nworkers > 1) { ProofConfig pc(*w, nworkers, "", kFALSE); toymcs->SetProofConfig(&pc); // enable proof } printf(" npoints = %d, poimin = %7.2f, poimax = %7.2f\n\n", npoints, poimin, poimax ) ; cout << flush ; if ( npoints==1 ) { std::cout << "Evaluating one point : " << poimax << std::endl; calc.RunOnePoint(poimax); } else if (npoints > 0) { if (poimin >= poimax) { // if no min/max given scan between MLE and +4 sigma poimin = int(poihat); poimax = int(poihat + 4 * poi->getError()); } std::cout << "Doing a fixed scan in interval : " << poimin << " , " << poimax << std::endl; calc.SetFixedScan(npoints,poimin,poimax); } else { //poi->setMax(10*int( (poihat+ 10 *poi->getError() )/10 ) ); std::cout << "Doing an automatic scan in interval : " << poi->getMin() << " , " << poi->getMax() << std::endl; } cout << "\n\n right before calc.GetInterval(), ntoys = " << ntoys << " \n\n" << flush ; HypoTestInverterResult * r = calc.GetInterval(); return r; }
result fit_toy(RooWorkspace* wspace, int n, const RooArgSet* globals) { RooRandom::randomGenerator()->SetSeed(0); // TFile f(filename); // RooWorkspace *wspace = (RooWorkspace*)f.Get("combined"); ModelConfig* model = (ModelConfig*)wspace->obj("ModelConfig"); RooAbsPdf* pdf; pdf = model->GetPdf(); RooAbsPdf* top_constraint = (RooAbsPdf*)wspace->obj("top_ratio_constraint"); RooAbsPdf* vv_constraint = (RooAbsPdf*)wspace->obj("vv_ratio_constraint"); RooAbsPdf* top_vv_constraint_sf = (RooAbsPdf*)wspace->obj("top_vv_ratio_sf_constraint"); RooAbsPdf* top_vv_constraint_of = (RooAbsPdf*)wspace->obj("top_vv_ratio_of_constraint"); // generate constraint global observables RooRealVar *nom_top_ratio = (RooRealVar*)wspace->obj("nom_top_ratio"); nom_top_ratio->setRange(0, 100); RooRealVar *nom_vv_ratio = (RooRealVar*)wspace->obj("nom_vv_ratio"); nom_vv_ratio->setRange(0,100); RooRealVar *nom_top_vv_ratio_sf = (RooRealVar*)wspace->obj("nom_top_vv_ratio_sf"); nom_top_vv_ratio_sf->setRange(0,100); RooRealVar *nom_top_vv_ratio_of = (RooRealVar*)wspace->obj("nom_top_vv_ratio_of"); nom_top_vv_ratio_of->setRange(0,100); RooDataSet *nom_top_generated = top_constraint->generateSimGlobal(RooArgSet(*nom_top_ratio), 1); nom_top_ratio->setVal(((RooRealVar*)nom_top_generated->get(0)->find("nom_top_ratio"))->getVal()); RooDataSet *nom_vv_generated = vv_constraint->generateSimGlobal(RooArgSet(*nom_vv_ratio), 1); nom_vv_ratio->setVal(((RooRealVar*)nom_vv_generated->get(0)->find("nom_vv_ratio"))->getVal()); RooDataSet *nom_top_vv_sf_generated = top_vv_constraint_sf->generateSimGlobal(RooArgSet(*nom_top_vv_ratio_sf), 1); nom_top_vv_ratio_sf->setVal(((RooRealVar*)nom_top_vv_sf_generated->get(0)->find("nom_top_vv_ratio_sf"))->getVal()); RooDataSet *nom_top_vv_of_generated = top_vv_constraint_of->generateSimGlobal(RooArgSet(*nom_top_vv_ratio_of), 1); nom_top_vv_ratio_of->setVal(((RooRealVar*)nom_top_vv_of_generated->get(0)->find("nom_top_vv_ratio_of"))->getVal()); NumEventsTestStat* dummy = new NumEventsTestStat(*pdf); ToyMCSampler* mc = new ToyMCSampler(*dummy, 1); mc->SetPdf(*pdf); mc->SetObservables(*model->GetObservables()); mc->SetGlobalObservables(*globals); mc->SetNuisanceParameters(*model->GetNuisanceParameters()); mc->SetParametersForTestStat(*model->GetParametersOfInterest()); mc->SetNEventsPerToy(n); RooArgSet constr; constr.add(*(model->GetNuisanceParameters())); RemoveConstantParameters(&constr); RooDataSet* toy_data = (RooDataSet*)mc->GenerateToyData(*const_cast<RooArgSet*>(model->GetSnapshot())); RooFitResult *res = pdf->fitTo(*toy_data, Constrain(constr), PrintLevel(0), Save(), Range("fitRange"), InitialHesse(), ExternalConstraints(RooArgSet(*top_constraint, *vv_constraint, *top_vv_constraint_sf, *top_vv_constraint_of))); result yield = get_results(wspace, res); yield.of.generated_sum.val = toy_data->sumEntries("(channelCat==channelCat::of) & (obs_x_of>120)"); yield.sf.generated_sum.val = toy_data->sumEntries("(channelCat==channelCat::sf) & (obs_x_sf>120)"); delete mc; delete dummy; // f.Close(); return yield; }
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 build_hbb_workspace1( const char* infile = "outputfiles/input-file.txt", const char* outfile = "outputfiles/ws.root" ) { //------------------------------------------------------------------------- //-- Create workspace and other RooStats things. printf("\n\n Creating workspace.\n\n") ; RooWorkspace workspace("ws") ; workspace.autoImportClassCode(true) ; globalObservables = new RooArgSet("globalObservables"); allNuisances = new RooArgSet("allNuisances"); allNuisancePdfs = new RooArgSet("allNuisancePdfs"); RooArgSet* observedParametersList = new RooArgSet("observables") ; //------------------------------------------------------------------------- printf("\n\n Reading input file: %s\n\n", infile ) ; float fileVal ; char pname[1000] ; char formula[1000] ; sprintf( pname, "bins_of_met" ) ; if ( !getFileValue( infile, pname, fileVal ) ) { printf("\n\n *** Error. Can't find %s\n\n", pname ) ; return ; } int bins_of_met = TMath::Nint( fileVal ) ; //-- save bins_of_met in the workspace for convenience. RooRealVar bom( "bins_of_met", "bins_of_met", bins_of_met, 0., 1000. ) ; bom.setConstant(kTRUE) ; workspace.import(bom) ; //-- save bins_of_nb in the workspace for convenience. RooRealVar bonb( "bins_of_nb", "bins_of_nb", bins_of_nb, 0., 1000. ) ; bonb.setConstant(kTRUE) ; workspace.import(bonb) ; RooRealVar* rv_N_msig[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooRealVar* rv_N_msb[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooRealVar* rv_smc_msig[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooRealVar* rv_smc_msb[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooAbsReal* rv_Rsigsb_corr[bins_of_nb][max_bins_of_met] ; for ( int nbi=0; nbi<bins_of_nb; nbi++ ) { for ( int mbi=0; mbi<bins_of_met; mbi++ ) { sprintf( pname, "N_%db_msig_met%d", nbi+2, mbi+1 ) ; if ( !getFileValue( infile, pname, fileVal ) ) { printf("\n\n *** Error. Can't find %s\n\n", pname ) ; return ; } rv_N_msig[nbi][mbi] = new RooRealVar( pname, pname, 0., 1.e6 ) ; rv_N_msig[nbi][mbi] -> setVal( TMath::Nint(fileVal) ) ; rv_N_msig[nbi][mbi] -> setConstant( kTRUE ) ; observedParametersList -> add( *rv_N_msig[nbi][mbi] ) ; sprintf( pname, "N_%db_msb_met%d", nbi+2, mbi+1 ) ; if ( !getFileValue( infile, pname, fileVal ) ) { printf("\n\n *** Error. Can't find %s\n\n", pname ) ; return ; } rv_N_msb[nbi][mbi] = new RooRealVar( pname, pname, 0., 1.e6 ) ; rv_N_msb[nbi][mbi] -> setVal( TMath::Nint(fileVal) ) ; rv_N_msb[nbi][mbi] -> setConstant( kTRUE ) ; observedParametersList -> add( *rv_N_msb[nbi][mbi] ) ; sprintf( pname, "smc_%db_msig_met%d", nbi+2, mbi+1 ) ; if ( !getFileValue( infile, pname, fileVal ) ) { printf("\n\n *** Error. Can't find %s\n\n", pname ) ; return ; } rv_smc_msig[nbi][mbi] = new RooRealVar( pname, pname, 0., 1.e6 ) ; rv_smc_msig[nbi][mbi] -> setVal( TMath::Nint(fileVal) ) ; rv_smc_msig[nbi][mbi] -> setConstant( kTRUE ) ; sprintf( pname, "smc_%db_msb_met%d", nbi+2, mbi+1 ) ; if ( !getFileValue( infile, pname, fileVal ) ) { printf("\n\n *** Error. Can't find %s\n\n", pname ) ; return ; } rv_smc_msb[nbi][mbi] = new RooRealVar( pname, pname, 0., 1.e6 ) ; rv_smc_msb[nbi][mbi] -> setVal( TMath::Nint(fileVal) ) ; rv_smc_msb[nbi][mbi] -> setConstant( kTRUE ) ; float corrVal, corrSyst ; sprintf( pname, "Rsigsb_syst_%db_met%d", nbi+2, mbi+1 ) ; if ( !getFileValue( infile, pname, corrSyst ) ) { printf("\n\n *** Error. Can't find %s\n\n", pname ) ; return ; } sprintf( pname, "Rsigsb_corr_%db_met%d", nbi+2, mbi+1 ) ; if ( !getFileValue( infile, pname, corrVal ) ) { printf("\n\n *** Error. Can't find %s\n\n", pname ) ; return ; } rv_Rsigsb_corr[nbi][mbi] = makeLognormalConstraint( pname, corrVal, corrSyst ) ; } // mbi. } // nbi. //-- Finished reading input from file. //------------------------------------------------------------------------- printf("\n\n Creating and importing dataset into workspace.\n\n") ; RooDataSet* dsObserved = new RooDataSet("hbb_observed_rds", "hbb observed data values", *observedParametersList ) ; dsObserved -> add( *observedParametersList ) ; workspace.import( *dsObserved ) ; //------------------------------------------------------------------------- //-- Define all floats. printf("\n\n Defining all unconstrained floats (Ratios, signal strength).\n\n") ; double R_msigmsb_initialval(0.15) ; RooRealVar* rv_R_msigmsb[50] ; for ( int mbi=0; mbi<bins_of_met; mbi++ ) { sprintf( pname, "R_msigmsb_met%d", mbi+1 ) ; printf( " %s\n", pname ) ; rv_R_msigmsb[mbi] = new RooRealVar( pname, pname, R_msigmsb_initialval, 0., 3. ) ; rv_R_msigmsb[mbi] -> setConstant( kFALSE ) ; rv_R_msigmsb[mbi] -> Print() ; } // mbi. printf("\n") ; sprintf( pname, "sig_strength" ) ; RooRealVar* rv_sig_strength = new RooRealVar( pname, pname, 1.0, 0., 10. ) ; rv_sig_strength -> setConstant(kFALSE) ; rv_sig_strength -> Print() ; printf(" %s\n\n", pname ) ; //------------------------------------------------------------------------- //-- Define all mu parameters. printf("\n\n Defining mu parameters.\n\n") ; RooAbsReal* rv_mu_bg_msig[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooAbsReal* rv_mu_bg_msb[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooAbsReal* rv_mu_sig_msig[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooAbsReal* rv_mu_sig_msb[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. for ( int nbi=0; nbi<bins_of_nb; nbi++ ) { for ( int mbi=0; mbi<bins_of_met; mbi++ ) { sprintf( pname, "mu_bg_%db_msb_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_mu_bg_msb[nbi][mbi] = new RooRealVar( pname, pname, rv_N_msb[nbi][mbi] -> getVal(), 0., 1.e6 ) ; rv_mu_bg_msb[nbi][mbi] -> Print() ; sprintf( formula, "@0 * @1 * @2" ) ; sprintf( pname, "mu_bg_%db_msig_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_mu_bg_msig[nbi][mbi] = new RooFormulaVar( pname, formula, RooArgSet( *rv_Rsigsb_corr[nbi][mbi], *rv_R_msigmsb[mbi], *rv_mu_bg_msb[nbi][mbi] ) ) ; rv_mu_bg_msig[nbi][mbi] -> Print() ; sprintf( formula, "@0 * @1" ) ; sprintf( pname, "mu_sig_%db_msig_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_mu_sig_msig[nbi][mbi] = new RooFormulaVar( pname, formula, RooArgSet( *rv_sig_strength, *rv_smc_msig[nbi][mbi] ) ) ; rv_mu_sig_msig[nbi][mbi] -> Print() ; sprintf( formula, "@0 * @1" ) ; sprintf( pname, "mu_sig_%db_msb_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_mu_sig_msb[nbi][mbi] = new RooFormulaVar( pname, formula, RooArgSet( *rv_sig_strength, *rv_smc_msb[nbi][mbi] ) ) ; rv_mu_sig_msb[nbi][mbi] -> Print() ; } // mbi. } // nbi. //-- Finished defining mu parameters. //------------------------------------------------------------------------- //-- Defining small n's printf("\n\n Defining small n's.\n\n") ; RooAbsReal* rv_n_msig[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooAbsReal* rv_n_msb[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. for ( int nbi=0; nbi<bins_of_nb; nbi++ ) { for ( int mbi=0; mbi<bins_of_met; mbi++ ) { sprintf( formula, "@0 + @1" ) ; sprintf( pname, "n_%db_msig_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_n_msig[nbi][mbi] = new RooFormulaVar( pname, formula, RooArgSet( *rv_mu_sig_msig[nbi][mbi], *rv_mu_bg_msig[nbi][mbi] ) ) ; rv_n_msig[nbi][mbi] -> Print() ; workspace.import( *rv_n_msig[nbi][mbi] ) ; sprintf( pname, "n_%db_msb_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_n_msb[nbi][mbi] = new RooFormulaVar( pname, formula, RooArgSet( *rv_mu_sig_msb[nbi][mbi], *rv_mu_bg_msb[nbi][mbi] ) ) ; rv_n_msb[nbi][mbi] -> Print() ; workspace.import( *rv_n_msb[nbi][mbi] ) ; } // mbi. } // nbi. //------------------------------------------------------------------------- //-- Define the Poisson pdfs for the observables. printf("\n\n Defining Poisson pdfs for the observables.\n\n") ; RooAbsReal* rv_pdf_msig[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooAbsReal* rv_pdf_msb[bins_of_nb][max_bins_of_met] ; // first index is number of btags, second is met bin. RooArgSet pdflist ; for ( int nbi=0; nbi<bins_of_nb; nbi++ ) { for ( int mbi=0; mbi<bins_of_met; mbi++ ) { sprintf( pname, "pdf_%db_msig_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_pdf_msig[nbi][mbi] = new RooPoisson( pname, pname, *rv_N_msig[nbi][mbi], *rv_n_msig[nbi][mbi] ) ; rv_pdf_msig[nbi][mbi] -> Print() ; pdflist.add( *rv_pdf_msig[nbi][mbi] ) ; sprintf( pname, "pdf_%db_msb_met%d", nbi+2, mbi+1 ) ; printf( " %s\n", pname ) ; rv_pdf_msb[nbi][mbi] = new RooPoisson( pname, pname, *rv_N_msb[nbi][mbi], *rv_n_msb[nbi][mbi] ) ; rv_pdf_msb[nbi][mbi] -> Print() ; pdflist.add( *rv_pdf_msb[nbi][mbi] ) ; } // mbi. } // nbi. //------------------------------------------------------------------------- //-- Build the likelihood. printf("\n\n Building the likelihood.\n\n") ; pdflist.add( *allNuisancePdfs ) ; pdflist.Print() ; printf("\n") ; RooProdPdf* likelihood = new RooProdPdf( "likelihood", "hbb likelihood", pdflist ) ; likelihood->Print() ; //------------------------------------------------------------------------- // printf("\n\n Running a test fit.\n\n") ; // dsObserved -> Print() ; // dsObserved -> printMultiline(cout, 1, kTRUE, "") ; // printf("\n\n =============================================\n\n") ; // likelihood -> fitTo( *dsObserved, PrintLevel(3), Hesse(0), Minos(0) ) ; // printf("\n\n =============================================\n\n") ; //-- Set up RooStats models. printf("\n\n Setting up S+B model.\n\n") ; RooArgSet poi( *rv_sig_strength, "poi" ) ; RooUniform signal_prior( "signal_prior", "signal_prior", *rv_sig_strength ) ; ModelConfig sbModel ("SbModel"); sbModel.SetWorkspace( workspace ) ; sbModel.SetPdf( *likelihood ) ; sbModel.SetParametersOfInterest( poi ); sbModel.SetPriorPdf(signal_prior); sbModel.SetObservables( *observedParametersList ); sbModel.SetNuisanceParameters( *allNuisances ); sbModel.SetGlobalObservables( *globalObservables ); workspace.Print() ; printf("\n\n Doing fit for S+B model.\n" ) ; fflush(stdout) ; RooAbsReal* pNll = sbModel.GetPdf()->createNLL(*dsObserved); RooAbsReal* pProfile = pNll->createProfile(RooArgSet()); pProfile->getVal(); RooArgSet* pPoiAndNuisance = new RooArgSet(); pPoiAndNuisance->add(*sbModel.GetParametersOfInterest()); if(sbModel.GetNuisanceParameters()) pPoiAndNuisance->add(*sbModel.GetNuisanceParameters()); printf("\n\n Will save these parameter points that correspond to the fit to data.\n\n") ; fflush(stdout) ; pPoiAndNuisance->Print("v"); sbModel.SetSnapshot(*pPoiAndNuisance); workspace.import (sbModel); delete pProfile ; delete pNll ; delete pPoiAndNuisance ; printf("\n\n Setting up BG-only model.\n\n") ; ModelConfig bModel (*(RooStats::ModelConfig *)workspace.obj("SbModel")); bModel.SetName("BModel"); bModel.SetWorkspace(workspace); printf("\n\n Doing fit for BG-only model.\n" ) ; fflush(stdout) ; pNll = bModel.GetPdf()->createNLL(*dsObserved); pProfile = pNll->createProfile(*bModel.GetParametersOfInterest()); ((RooRealVar *)(bModel.GetParametersOfInterest()->first()))->setVal(0.); pProfile->getVal(); pPoiAndNuisance = new RooArgSet(); pPoiAndNuisance->add(*bModel.GetParametersOfInterest()); if(bModel.GetNuisanceParameters()) pPoiAndNuisance->add(*bModel.GetNuisanceParameters()); printf("\n\n Should use these parameter points to generate pseudo data for bkg only.\n\n") ; fflush(stdout) ; pPoiAndNuisance->Print("v"); bModel.SetSnapshot(*pPoiAndNuisance); workspace.import (bModel); delete pProfile ; delete pNll ; delete pPoiAndNuisance ; workspace.Print() ; printf("\n\n Saving workspace in : %s\n\n", outfile ) ; gSystem->Exec(" mkdir -p outputfiles " ) ; workspace.writeToFile( outfile ) ; } // build_hbb_workspace1.
void StandardHypoTestDemo(const char* infile = "", const char* workspaceName = "combined", const char* modelSBName = "ModelConfig", const char* modelBName = "", const char* dataName = "obsData", int calcType = 0, // 0 freq 1 hybrid, 2 asymptotic int testStatType = 3, // 0 LEP, 1 TeV, 2 LHC, 3 LHC - one sided int ntoys = 5000, bool useNC = false, const char * nuisPriorName = 0) { /* Other Parameter to pass in tutorial apart from standard for filename, ws, modelconfig and data type = 0 Freq calculator type = 1 Hybrid calculator type = 2 Asymptotic calculator testStatType = 0 LEP = 1 Tevatron = 2 Profile Likelihood = 3 Profile Likelihood one sided (i.e. = 0 if mu < mu_hat) ntoys: number of toys to use useNumberCounting: set to true when using number counting events nuisPriorName: name of prior for the nnuisance. This is often expressed as constraint term in the global model It is needed only when using the HybridCalculator (type=1) If not given by default the prior pdf from ModelConfig is used. extra options are available as global paramwters of the macro. They major ones are: generateBinned generate binned data sets for toys (default is false) - be careful not to activate with a too large (>=3) number of observables nToyRatio ratio of S+B/B toys (default is 2) printLevel */ // disable - can cause some problems //ToyMCSampler::SetAlwaysUseMultiGen(true); SimpleLikelihoodRatioTestStat::SetAlwaysReuseNLL(true); ProfileLikelihoodTestStat::SetAlwaysReuseNLL(true); RatioOfProfiledLikelihoodsTestStat::SetAlwaysReuseNLL(true); //RooRandom::randomGenerator()->SetSeed(0); // to change minimizers // ROOT::Math::MinimizerOptions::SetDefaultStrategy(0); // ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2"); // ROOT::Math::MinimizerOptions::SetDefaultTolerance(1); ///////////////////////////////////////////////////////////// // 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; } ///////////////////////////////////////////////////////////// // Tutorial starts here //////////////////////////////////////////////////////////// // get the workspace out of the file RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName); if(!w){ cout <<"workspace not found" << endl; return; } w->Print(); // get the modelConfig out of the file ModelConfig* sbModel = (ModelConfig*) w->obj(modelSBName); // get the modelConfig out of the file RooAbsData* data = w->data(dataName); // make sure ingredients are found if(!data || !sbModel){ w->Print(); cout << "data or ModelConfig was not found" <<endl; return; } // make b model ModelConfig* bModel = (ModelConfig*) w->obj(modelBName); // 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 ) { 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("B_only")); RooRealVar * var = dynamic_cast<RooRealVar*>(bModel->GetParametersOfInterest()->first()); if (!var) return; double oldval = var->getVal(); var->setVal(0); //bModel->SetSnapshot( RooArgSet(*var, *w->var("lumi")) ); bModel->SetSnapshot( RooArgSet(*var) ); var->setVal(oldval); } if (!sbModel->GetSnapshot() || poiValue > 0) { Info("StandardHypoTestDemo","Model %s has no snapshot - make one using model poi",modelSBName); RooRealVar * var = dynamic_cast<RooRealVar*>(sbModel->GetParametersOfInterest()->first()); if (!var) return; double oldval = var->getVal(); if (poiValue > 0) var->setVal(poiValue); //sbModel->SetSnapshot( RooArgSet(*var, *w->var("lumi") ) ); sbModel->SetSnapshot( RooArgSet(*var) ); if (poiValue > 0) var->setVal(oldval); //sbModel->SetSnapshot( *sbModel->GetParametersOfInterest() ); } // part 1, hypothesis testing SimpleLikelihoodRatioTestStat * slrts = new SimpleLikelihoodRatioTestStat(*bModel->GetPdf(), *sbModel->GetPdf()); // null parameters must includes snapshot of poi plus the nuisance values RooArgSet nullParams(*bModel->GetSnapshot()); if (bModel->GetNuisanceParameters()) nullParams.add(*bModel->GetNuisanceParameters()); slrts->SetNullParameters(nullParams); RooArgSet altParams(*sbModel->GetSnapshot()); if (sbModel->GetNuisanceParameters()) altParams.add(*sbModel->GetNuisanceParameters()); slrts->SetAltParameters(altParams); ProfileLikelihoodTestStat * profll = new ProfileLikelihoodTestStat(*bModel->GetPdf()); RatioOfProfiledLikelihoodsTestStat * ropl = new RatioOfProfiledLikelihoodsTestStat(*bModel->GetPdf(), *sbModel->GetPdf(), sbModel->GetSnapshot()); ropl->SetSubtractMLE(false); if (testStatType == 3) profll->SetOneSidedDiscovery(1); profll->SetPrintLevel(printLevel); // profll.SetReuseNLL(mOptimize); // slrts.SetReuseNLL(mOptimize); // ropl.SetReuseNLL(mOptimize); AsymptoticCalculator::SetPrintLevel(printLevel); HypoTestCalculatorGeneric * hypoCalc = 0; // note here Null is B and Alt is S+B if (calcType == 0) hypoCalc = new FrequentistCalculator(*data, *sbModel, *bModel); else if (calcType == 1) hypoCalc= new HybridCalculator(*data, *sbModel, *bModel); else if (calcType == 2) hypoCalc= new AsymptoticCalculator(*data, *sbModel, *bModel); if (calcType == 0) ((FrequentistCalculator*)hypoCalc)->SetToys(ntoys, ntoys/nToysRatio); if (calcType == 1) ((HybridCalculator*)hypoCalc)->SetToys(ntoys, ntoys/nToysRatio); if (calcType == 2 ) { if (testStatType == 3) ((AsymptoticCalculator*) hypoCalc)->SetOneSidedDiscovery(true); if (testStatType != 2 && testStatType != 3) Warning("StandardHypoTestDemo","Only the PL test statistic can be used with AsymptoticCalculator - use by default a two-sided PL"); } // check for nuisance prior pdf in case of nuisance parameters if (calcType == 1 && (bModel->GetNuisanceParameters() || sbModel->GetNuisanceParameters() )) { RooAbsPdf * nuisPdf = 0; if (nuisPriorName) nuisPdf = w->pdf(nuisPriorName); // use prior defined first in bModel (then in SbModel) if (!nuisPdf) { Info("StandardHypoTestDemo","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("StandardHypoTestDemo","No nuisance pdf given - try to use %s that is defined as a prior pdf in the B model",nuisPdf->GetName()); } else { Error("StandardHypoTestDemo","Cannnot run Hybrid calculator because no prior on the nuisance parameter is specified or can be derived"); return; } } assert(nuisPdf); Info("StandardHypoTestDemo","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("StandardHypoTestDemo","Prior nuisance does not depend on nuisance parameters. They will be smeared in their full range"); } delete np; ((HybridCalculator*)hypoCalc)->ForcePriorNuisanceAlt(*nuisPdf); ((HybridCalculator*)hypoCalc)->ForcePriorNuisanceNull(*nuisPdf); } // hypoCalc->ForcePriorNuisanceAlt(*sbModel->GetPriorPdf()); // hypoCalc->ForcePriorNuisanceNull(*bModel->GetPriorPdf()); ToyMCSampler * sampler = (ToyMCSampler *)hypoCalc->GetTestStatSampler(); if (sampler && (calcType == 0 || calcType == 1) ) { // look if pdf is number counting or extended if (sbModel->GetPdf()->canBeExtended() ) { if (useNC) Warning("StandardHypoTestDemo","Pdf is extended: but number counting flag is set: ignore it "); } else { // for not extended pdf if (!useNC) { int nEvents = data->numEntries(); Info("StandardHypoTestDemo","Pdf is not extended: number of events to generate taken from observed data set is %d",nEvents); sampler->SetNEventsPerToy(nEvents); } else { Info("StandardHypoTestDemo","using a number counting pdf"); sampler->SetNEventsPerToy(1); } } if (data->isWeighted() && !generateBinned) { Info("StandardHypoTestDemo","Data set is weighted, nentries = %d and sum of weights = %8.1f but toy generation is unbinned - it would be faster to set generateBinned to true\n",data->numEntries(), data->sumEntries()); } if (generateBinned) sampler->SetGenerateBinned(generateBinned); // set the test statistic if (testStatType == 0) sampler->SetTestStatistic(slrts); if (testStatType == 1) sampler->SetTestStatistic(ropl); if (testStatType == 2 || testStatType == 3) sampler->SetTestStatistic(profll); } HypoTestResult * htr = hypoCalc->GetHypoTest(); htr->SetPValueIsRightTail(true); htr->SetBackgroundAsAlt(false); htr->Print(); // how to get meaningfull CLs at this point? delete sampler; delete slrts; delete ropl; delete profll; if (calcType != 2) { HypoTestPlot * plot = new HypoTestPlot(*htr,100); plot->SetLogYaxis(true); plot->Draw(); } else { std::cout << "Asymptotic results " << std::endl; } // look at expected significances // found median of S+B distribution if (calcType != 2) { SamplingDistribution * altDist = htr->GetAltDistribution(); HypoTestResult htExp("Expected Result"); htExp.Append(htr); // find quantiles in alt (S+B) distribution double p[5]; double q[5]; for (int i = 0; i < 5; ++i) { double sig = -2 + i; p[i] = ROOT::Math::normal_cdf(sig,1); } std::vector<double> values = altDist->GetSamplingDistribution(); TMath::Quantiles( values.size(), 5, &values[0], q, p, false); for (int i = 0; i < 5; ++i) { htExp.SetTestStatisticData( q[i] ); double sig = -2 + i; std::cout << " Expected p -value and significance at " << sig << " sigma = " << htExp.NullPValue() << " significance " << htExp.Significance() << " sigma " << std::endl; } } else { // case of asymptotic calculator for (int i = 0; i < 5; ++i) { double sig = -2 + i; // sigma is inverted here double pval = AsymptoticCalculator::GetExpectedPValues( htr->NullPValue(), htr->AlternatePValue(), -sig, false); std::cout << " Expected p -value and significance at " << sig << " sigma = " << pval << " significance " << ROOT::Math::normal_quantile_c(pval,1) << " sigma " << std::endl; } } }
void runQ(const char* inFileName, const char* wsName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData", const char* asimov0DataName = "asimovData_0", const char* conditional0Snapshot = "conditionalGlobs_0", const char* asimov1DataName = "asimovData_1", const char* conditional1Snapshot = "conditionalGlobs_1", const char* nominalSnapshot = "nominalGlobs", string smass = "130", string folder = "test") { double mass; stringstream massStr; massStr << smass; massStr >> mass; bool errFast = 0; bool goFast = 1; bool remakeData = 1; bool doRightSided = 1; bool doInj = 0; bool doObs = 1; bool doMedian = 1; TStopwatch timer; timer.Start(); TFile f(inFileName); RooWorkspace* ws = (RooWorkspace*)f.Get(wsName); if (!ws) { cout << "ERROR::Workspace: " << wsName << " doesn't exist!" << endl; return; } ModelConfig* mc = (ModelConfig*)ws->obj(modelConfigName); if (!mc) { cout << "ERROR::ModelConfig: " << modelConfigName << " doesn't exist!" << endl; return; } RooDataSet* data = (RooDataSet*)ws->data(dataName); if (!data) { cout << "ERROR::Dataset: " << dataName << " doesn't exist!" << endl; return; } mc->GetNuisanceParameters()->Print("v"); RooNLLVar::SetIgnoreZeroEntries(1); ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2"); ROOT::Math::MinimizerOptions::SetDefaultStrategy(0); ROOT::Math::MinimizerOptions::SetDefaultPrintLevel(1); cout << "Setting max function calls" << endl; //ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(20000); RooMinimizer::SetMaxFunctionCalls(10000); ws->loadSnapshot("conditionalNuis_0"); RooArgSet nuis(*mc->GetNuisanceParameters()); RooRealVar* mu = (RooRealVar*)mc->GetParametersOfInterest()->first(); if (string(mc->GetPdf()->ClassName()) == "RooSimultaneous" && remakeData) { RooSimultaneous* simPdf = (RooSimultaneous*)mc->GetPdf(); double min_mu; data = makeData(data, simPdf, mc->GetObservables(), mu, mass, min_mu); } RooDataSet* asimovData0 = (RooDataSet*)ws->data(asimov0DataName); if (!asimovData0) { cout << "Asimov data doesn't exist! Please, allow me to build one for you..." << endl; makeAsimovData(mc, true, ws, mc->GetPdf(), data, 1); ws->Print(); asimovData0 = (RooDataSet*)ws->data("asimovData_0"); } RooDataSet* asimovData1 = (RooDataSet*)ws->data(asimov1DataName); if (!asimovData1) { cout << "Asimov data doesn't exist! Please, allow me to build one for you..." << endl; makeAsimovData(mc, true, ws, mc->GetPdf(), data, 0); ws->Print(); asimovData1 = (RooDataSet*)ws->data("asimovData_1"); } if (!doRightSided) mu->setRange(0, 40); else mu->setRange(-40, 40); bool old = false; if (old) { mu->setVal(0); RooArgSet poi(*mu); ProfileLikelihoodTestStat_modified asimov_testStat_sig(*mc->GetPdf()); asimov_testStat_sig.SetRightSided(doRightSided); asimov_testStat_sig.SetNuis(&nuis); if (!doInj) asimov_testStat_sig.SetDoAsimov(true, 1); asimov_testStat_sig.SetWorkspace(ws); ProfileLikelihoodTestStat_modified testStat(*mc->GetPdf()); testStat.SetRightSided(doRightSided); testStat.SetNuis(&nuis); testStat.SetWorkspace(ws); //RooMinimizerFcn::SetOverrideEverything(true); double med_sig = 0; double med_testStat_val = 0; //gRandom->SetSeed(1); //RooRandom::randomGenerator()->SetSeed(1); RooNLLVar::SetIgnoreZeroEntries(1); if (asimov1DataName != "" && doMedian) { mu->setVal(0); if (!doInj) mu->setRange(0, 2); ws->loadSnapshot("conditionalNuis_0"); asimov_testStat_sig.SetLoadUncondSnapshot("conditionalNuis_1"); if (string(conditional1Snapshot) != "") ws->loadSnapshot(conditional1Snapshot); med_testStat_val = 2*asimov_testStat_sig.Evaluate(*asimovData1, poi); if (med_testStat_val < 0 && !doInj) { mu->setVal(0); med_testStat_val = 2*asimov_testStat_sig.Evaluate(*asimovData1, poi); // just try again } int sign = med_testStat_val != 0 ? med_testStat_val/fabs(med_testStat_val) : 0; med_sig = sign*sqrt(fabs(med_testStat_val)); if (string(nominalSnapshot) != "") ws->loadSnapshot(nominalSnapshot); if (!doRightSided) mu->setRange(0, 40); else mu->setRange(-40, 40); } RooNLLVar::SetIgnoreZeroEntries(0); //gRandom->SetSeed(1); //RooRandom::randomGenerator()->SetSeed(1); //RooMinimizerFcn::SetOverrideEverything(false); cout << "med test stat: " << med_testStat_val << endl; ws->loadSnapshot("nominalGlobs"); ws->loadSnapshot("conditionalNuis_0"); mu->setVal(0); testStat.SetWorkspace(ws); testStat.SetLoadUncondSnapshot("ucmles"); double obsTestStat_val = doObs ? 2*testStat.Evaluate(*data, poi) : 0; cout << "obs test stat: " << obsTestStat_val << endl; // obsTestStat_val = 2*testStat.Evaluate(*data, poi); // cout << "obs test stat: " << obsTestStat_val << endl; // obsTestStat_val = 2*testStat.Evaluate(*data, poi); // cout << "obs test stat: " << obsTestStat_val << endl; double obs_sig; int sign = obsTestStat_val == 0 ? 0 : obsTestStat_val / fabs(obsTestStat_val); if (!doRightSided && (obsTestStat_val < 0 && obsTestStat_val > -0.1 || mu->getVal() < 0.001)) obs_sig = 0; else obs_sig = sign*sqrt(fabs(obsTestStat_val)); if (obs_sig != obs_sig) //nan, do by hand { cout << "Obs test stat gave nan: try by hand" << endl; mu->setVal(0); mu->setConstant(1); mc->GetPdf()->fitTo(*data, Hesse(0), Minos(0), PrintLevel(-1), Constrain(*mc->GetNuisanceParameters())); mu->setConstant(0); double L_0 = mc->GetPdf()->getVal(); //mu->setVal(0); //mu->setConstant(1); mc->GetPdf()->fitTo(*data, Hesse(0), Minos(0), PrintLevel(-1), Constrain(*mc->GetNuisanceParameters())); //mu->setConstant(0); double L_muhat = mc->GetPdf()->getVal(); cout << "L_0: " << L_0 << ", L_muhat: " << L_muhat << endl; obs_sig = sqrt(-2*TMath::Log(L_0/L_muhat)); //still nan if (obs_sig != obs_sig && fabs(L_0 - L_muhat) < 0.000001) obs_sig = 0; } cout << "obs: " << obs_sig << endl; cout << "Observed significance: " << obs_sig << endl; if (med_sig) { cout << "Median test stat val: " << med_testStat_val << endl; cout << "Median significance: " << med_sig << endl; } f.Close(); stringstream fileName; fileName << "root_files/" << folder << "/" << mass << ".root"; system(("mkdir -vp root_files/" + folder).c_str()); TFile f2(fileName.str().c_str(),"recreate"); // stringstream fileName; // fileName << "results_sig/" << mass << ".root"; // system("mkdir results_sig"); // TFile f(fileName.str().c_str(),"recreate"); TH1D* h_hypo = new TH1D("hypo","hypo",2,0,2); h_hypo->SetBinContent(1, obs_sig); h_hypo->SetBinContent(2, med_sig); f2.Write(); f2.Close(); //mc->GetPdf()->fitTo(*data, PrintLevel(0)); timer.Stop(); timer.Print(); } else { RooAbsPdf* pdf = mc->GetPdf(); RooArgSet nuis_tmp1 = *mc->GetNuisanceParameters(); RooNLLVar* asimov_nll0 = (RooNLLVar*)pdf->createNLL(*asimovData0, Constrain(nuis_tmp1)); RooArgSet nuis_tmp2 = *mc->GetNuisanceParameters(); RooNLLVar* asimov_nll1 = (RooNLLVar*)pdf->createNLL(*asimovData1, Constrain(nuis_tmp2)); RooArgSet nuis_tmp3 = *mc->GetNuisanceParameters(); RooNLLVar* obs_nll = (RooNLLVar*)pdf->createNLL(*data, Constrain(nuis_tmp3)); //do asimov int status; //get sigma_b ws->loadSnapshot(conditional0Snapshot); status = ws->loadSnapshot("conditionalNuis_0"); if (status != 0 && goFast) errFast = 1; mu->setVal(0); mu->setConstant(1); status = goFast ? 0 : minimize(asimov_nll0, ws); if (status < 0) { cout << "Retrying" << endl; //ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll0, ws); if (status >= 0) cout << "Success!" << endl; } double asimov0_nll0 = asimov_nll0->getVal(); mu->setVal(1); ws->loadSnapshot("conditionalNuis_1"); status = minimize(asimov_nll0, ws); if (status < 0) { cout << "Retrying" << endl; //ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll0, ws); if (status >= 0) cout << "Success!" << endl; } double asimov0_nll1 = asimov_nll0->getVal(); double asimov0_q = 2*(asimov0_nll1 - asimov0_nll0); double sigma_b = sqrt(1./asimov0_q); ws->loadSnapshot(nominalSnapshot); //get sigma_sb ws->loadSnapshot(conditional1Snapshot); ws->loadSnapshot("conditionalNuis_0"); mu->setVal(0); mu->setConstant(1); status = minimize(asimov_nll1, ws); if (status < 0) { cout << "Retrying" << endl; //ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll1, ws); if (status >= 0) cout << "Success!" << endl; } double asimov1_nll0 = asimov_nll1->getVal(); mu->setVal(1); status = ws->loadSnapshot("conditionalNuis_1"); if (status != 0 && goFast) errFast = 1; status = goFast ? 0 : minimize(asimov_nll1, ws); if (status < 0) { cout << "Retrying" << endl; //ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll1, ws); if (status >= 0) cout << "Success!" << endl; } double asimov1_nll1 = asimov_nll1->getVal(); double asimov1_q = 2*(asimov1_nll1 - asimov1_nll0); double sigma_sb = sqrt(-1./asimov1_q); ws->loadSnapshot(nominalSnapshot); //do obs mu->setVal(0); status = ws->loadSnapshot("conditionalNuis_0"); if (status != 0 && goFast) errFast = 1; mu->setConstant(1); status = goFast ? 0 : minimize(obs_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(obs_nll, ws); if (status >= 0) cout << "Success!" << endl; } double obs_nll0 = obs_nll->getVal(); status = ws->loadSnapshot("conditionalNuis_1"); if (status != 0 && goFast) errFast = 1; mu->setVal(1); status = goFast ? 0 : minimize(obs_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(obs_nll, ws); if (status >= 0) cout << "Success!" << endl; } double obs_nll1 = obs_nll->getVal(); double obs_q = 2*(obs_nll1 - obs_nll0); double Zobs = (1./sigma_b/sigma_b - obs_q) / (2./sigma_b); double Zexp = (1./sigma_b/sigma_b - asimov1_q) / (2./sigma_b); double pb_obs = 1-ROOT::Math::gaussian_cdf(Zobs); double pb_exp = 1-ROOT::Math::gaussian_cdf(Zexp); cout << "asimov0_q = " << asimov0_q << endl; cout << "asimov1_q = " << asimov1_q << endl; cout << "obs_q = " << obs_q << endl; cout << "sigma_b = " << sigma_b << endl; cout << "sigma_sb = " << sigma_sb << endl; cout << "Z obs = " << Zobs << endl; cout << "Z exp = " << Zexp << endl; f.Close(); stringstream fileName; fileName << "root_files/" << folder << "/" << mass << ".root"; system(("mkdir -vp root_files/" + folder).c_str()); TFile f2(fileName.str().c_str(),"recreate"); TH1D* h_hypo = new TH1D("hypo_tev","hypo_tev",2,0,2); h_hypo->SetBinContent(1, pb_obs); h_hypo->SetBinContent(2, pb_exp); f2.Write(); f2.Close(); stringstream fileName3; fileName3 << "root_files/" << folder << "_llr/" << mass << ".root"; system(("mkdir -vp root_files/" + folder + "_llr").c_str()); TFile f3(fileName3.str().c_str(),"recreate"); TH1D* h_hypo3 = new TH1D("hypo_llr","hypo_llr",7,0,7); h_hypo3->SetBinContent(1, -obs_q); h_hypo3->SetBinContent(2, -asimov1_q); h_hypo3->SetBinContent(3, -asimov0_q); h_hypo3->SetBinContent(4, -asimov0_q-2*2/sigma_b); h_hypo3->SetBinContent(5, -asimov0_q-1*2/sigma_b); h_hypo3->SetBinContent(6, -asimov0_q+1*2/sigma_b); h_hypo3->SetBinContent(7, -asimov0_q+2*2/sigma_b); f3.Write(); f3.Close(); timer.Stop(); timer.Print(); } }
void compute_p0(const char* inFileName, const char* wsName = "combined", const char* modelConfigName = "ModelConfig", const char* dataName = "obsData", const char* asimov1DataName = "asimovData_1", const char* conditional1Snapshot = "conditionalGlobs_1", const char* nominalSnapshot = "nominalGlobs", string smass = "130", string folder = "test") { double mass; stringstream massStr; massStr << smass; massStr >> mass; double mu_profile_value = 1; // mu value to profile the obs data at wbefore generating the expected bool doConditional = 1; // do conditional expected data bool remakeData = 0; // handle unphysical pdf cases in H->ZZ->4l bool doUncap = 1; // uncap p0 bool doInj = 0; // setup the poi for injection study (zero is faster if you're not) bool doObs = 1; // compute median significance bool doMedian = 1; // compute observed significance TStopwatch timer; timer.Start(); TFile f(inFileName); RooWorkspace* ws = (RooWorkspace*)f.Get(wsName); if (!ws) { cout << "ERROR::Workspace: " << wsName << " doesn't exist!" << endl; return; } ModelConfig* mc = (ModelConfig*)ws->obj(modelConfigName); if (!mc) { cout << "ERROR::ModelConfig: " << modelConfigName << " doesn't exist!" << endl; return; } RooDataSet* data = (RooDataSet*)ws->data(dataName); if (!data) { cout << "ERROR::Dataset: " << dataName << " doesn't exist!" << endl; return; } mc->GetNuisanceParameters()->Print("v"); ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2"); ROOT::Math::MinimizerOptions::SetDefaultStrategy(0); ROOT::Math::MinimizerOptions::SetDefaultPrintLevel(1); cout << "Setting max function calls" << endl; ws->loadSnapshot("conditionalNuis_0"); RooArgSet nuis(*mc->GetNuisanceParameters()); RooRealVar* mu = (RooRealVar*)mc->GetParametersOfInterest()->first(); RooAbsPdf* pdf = mc->GetPdf(); string condSnapshot(conditional1Snapshot); RooArgSet nuis_tmp2 = *mc->GetNuisanceParameters(); RooNLLVar* obs_nll = doObs ? (RooNLLVar*)pdf->createNLL(*data, Constrain(nuis_tmp2)) : NULL; RooDataSet* asimovData1 = (RooDataSet*)ws->data(asimov1DataName); RooRealVar* emb = (RooRealVar*)mc->GetNuisanceParameters()->find("ATLAS_EMB"); if (!asimovData1 || (string(inFileName).find("ic10") != string::npos && emb)) { if (emb) emb->setVal(0.7); cout << "Asimov data doesn't exist! Please, allow me to build one for you..." << endl; string mu_str, mu_prof_str; asimovData1 = makeAsimovData(mc, doConditional, ws, obs_nll, 1, &mu_str, &mu_prof_str, mu_profile_value, true); condSnapshot="conditionalGlobs"+mu_prof_str; } if (!doUncap) mu->setRange(0, 40); else mu->setRange(-40, 40); RooAbsPdf* pdf = mc->GetPdf(); RooArgSet nuis_tmp1 = *mc->GetNuisanceParameters(); RooNLLVar* asimov_nll = (RooNLLVar*)pdf->createNLL(*asimovData1, Constrain(nuis_tmp1)); //do asimov mu->setVal(1); mu->setConstant(0); if (!doInj) mu->setConstant(1); int status,sign; double med_sig=0,obs_sig=0,asimov_q0=0,obs_q0=0; if (doMedian) { ws->loadSnapshot(condSnapshot.c_str()); if (doInj) ws->loadSnapshot("conditionalNuis_inj"); else ws->loadSnapshot("conditionalNuis_1"); mc->GetGlobalObservables()->Print("v"); mu->setVal(0); mu->setConstant(1); status = minimize(asimov_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll, ws); if (status >= 0) cout << "Success!" << endl; } double asimov_nll_cond = asimov_nll->getVal(); mu->setVal(1); if (doInj) ws->loadSnapshot("conditionalNuis_inj"); else ws->loadSnapshot("conditionalNuis_1"); if (doInj) mu->setConstant(0); status = minimize(asimov_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll, ws); if (status >= 0) cout << "Success!" << endl; } double asimov_nll_min = asimov_nll->getVal(); asimov_q0 = 2*(asimov_nll_cond - asimov_nll_min); if (doUncap && mu->getVal() < 0) asimov_q0 = -asimov_q0; sign = int(asimov_q0 != 0 ? asimov_q0/fabs(asimov_q0) : 0); med_sig = sign*sqrt(fabs(asimov_q0)); ws->loadSnapshot(nominalSnapshot); } if (doObs) { ws->loadSnapshot("conditionalNuis_0"); mu->setVal(0); mu->setConstant(1); status = minimize(obs_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(obs_nll, ws); if (status >= 0) cout << "Success!" << endl; } double obs_nll_cond = obs_nll->getVal(); mu->setConstant(0); status = minimize(obs_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(obs_nll, ws); if (status >= 0) cout << "Success!" << endl; } double obs_nll_min = obs_nll->getVal(); obs_q0 = 2*(obs_nll_cond - obs_nll_min); if (doUncap && mu->getVal() < 0) obs_q0 = -obs_q0; sign = int(obs_q0 == 0 ? 0 : obs_q0 / fabs(obs_q0)); if (!doUncap && (obs_q0 < 0 && obs_q0 > -0.1 || mu->getVal() < 0.001)) obs_sig = 0; else obs_sig = sign*sqrt(fabs(obs_q0)); } // Report results cout << "obs: " << obs_sig << endl; cout << "Observed significance: " << obs_sig << endl; cout << "Corresponding to a p-value of " << (1-ROOT::Math::gaussian_cdf( obs_sig )) << endl; if (med_sig) { cout << "Median test stat val: " << asimov_q0 << endl; cout << "Median significance: " << med_sig << endl; } f.Close(); stringstream fileName; fileName << "root-files/" << folder << "/" << mass << ".root"; system(("mkdir -vp root-files/" + folder).c_str()); TFile f2(fileName.str().c_str(),"recreate"); TH1D* h_hypo = new TH1D("hypo","hypo",2,0,2); h_hypo->SetBinContent(1, obs_sig); h_hypo->SetBinContent(2, med_sig); f2.Write(); f2.Close(); timer.Stop(); timer.Print(); }
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 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 new_RA4(){ // let's time this challenging example TStopwatch t; t.Start(); // set RooFit random seed for reproducible results RooRandom::randomGenerator()->SetSeed(4357); // make model RooWorkspace* wspace = new RooWorkspace("wspace"); wspace->factory("Gaussian::sigCons(prime_SigEff[0,-5,5], nom_SigEff[0,-5,5], 1)"); wspace->factory("expr::SigEff('1.0*pow(1.20,@0)',prime_SigEff)"); // // 1+-20%, 1.20=exp(20%) wspace->factory("Poisson::on(non[0,50], sum::splusb(prod::SigUnc(s[0,0,50],SigEff),mainb[8.8,0,50],dilep[0.9,0,20],tau[2.3,0,20],QCD[0.,0,10],MC[0.1,0,4]))"); wspace->factory("Gaussian::mcCons(prime_rho[0,-5,5], nom_rho[0,-5,5], 1)"); wspace->factory("expr::rho('1.0*pow(1.39,@0)',prime_rho)"); // // 1+-39% wspace->factory("Poisson::off(noff[0,200], prod::rhob(mainb,rho,mu_plus_e[0.74,0.01,10],1.08))"); wspace->factory("Gaussian::mcCons2(mu_plus_enom[0.74,0.01,4], mu_plus_e, sigmatwo[.05])"); wspace->factory("Gaussian::dilep_pred(dilep_nom[0.9,0,20], dilep, sigma3[2.2])"); wspace->factory("Gaussian::tau_pred(tau_nom[2.3,0,20], tau, sigma4[0.5])"); wspace->factory("Gaussian::QCD_pred(QCD_nom[0.0,0,10], QCD, sigma5[1.0])"); wspace->factory("Gaussian::MC_pred(MC_nom[0.1,0.01,4], MC, sigma7[0.14])"); wspace->factory("PROD::model(on,off,mcCons,mcCons2,sigCons,dilep_pred,tau_pred,QCD_pred,MC_pred)"); RooArgSet obs(*wspace->var("non"), *wspace->var("noff"), *wspace->var("mu_plus_enom"), *wspace->var("dilep_nom"), *wspace->var("tau_nom"), "obs"); obs.add(*wspace->var("QCD_nom")); obs.add(*wspace->var("MC_nom")); RooArgSet globalObs(*wspace->var("nom_SigEff"), *wspace->var("nom_rho"), "global_obs"); // fix global observables to their nominal values wspace->var("nom_SigEff")->setConstant(); wspace->var("nom_rho")->setConstant(); RooArgSet poi(*wspace->var("s"), "poi"); RooArgSet nuis(*wspace->var("mainb"), *wspace->var("prime_rho"), *wspace->var("prime_SigEff"), *wspace->var("mu_plus_e"), *wspace->var("dilep"), *wspace->var("tau"), "nuis"); nuis.add(*wspace->var("QCD")); nuis.add(*wspace->var("MC")); wspace->factory("Uniform::prior_poi({s})"); wspace->factory("Uniform::prior_nuis({mainb,mu_plus_e,dilep,tau,QCD,MC})"); wspace->factory("PROD::prior(prior_poi,prior_nuis)"); wspace->var("non")->setVal(8); //observed //wspace->var("non")->setVal(12); //expected observation wspace->var("noff")->setVal(7); //observed events in control region wspace->var("mu_plus_enom")->setVal(0.74); wspace->var("dilep_nom")->setVal(0.9); wspace->var("tau_nom")->setVal(2.3); wspace->var("QCD")->setVal(0.0); wspace->var("MC")->setVal(0.1); RooDataSet * data = new RooDataSet("data","",obs); data->add(obs); wspace->import(*data); ///////////////////////////////////////////////////// // Now the statistical tests // model config ModelConfig* pSbModel = new ModelConfig("SbModel"); pSbModel->SetWorkspace(*wspace); pSbModel->SetPdf(*wspace->pdf("model")); pSbModel->SetPriorPdf(*wspace->pdf("prior")); pSbModel->SetParametersOfInterest(poi); pSbModel->SetNuisanceParameters(nuis); pSbModel->SetObservables(obs); pSbModel->SetGlobalObservables(globalObs); wspace->import(*pSbModel); // set all but obs, poi and nuisance to const SetConstants(wspace, pSbModel); wspace->import(*pSbModel); Double_t poiValueForBModel = 0.0; ModelConfig* pBModel = new ModelConfig(*(RooStats::ModelConfig *)wspace->obj("SbModel")); pBModel->SetName("BModel"); pBModel->SetWorkspace(*wspace); wspace->import(*pBModel); RooAbsReal * pNll = pSbModel->GetPdf()->createNLL(*data); RooAbsReal * pProfile = pNll->createProfile(RooArgSet()); pProfile->getVal(); // this will do fit and set POI and nuisance parameters to fitted values RooArgSet * pPoiAndNuisance = new RooArgSet(); //if(pSbModel->GetNuisanceParameters()) // pPoiAndNuisance->add(*pSbModel->GetNuisanceParameters()); pPoiAndNuisance->add(*pSbModel->GetParametersOfInterest()); cout << "\nWill save these parameter points that correspond to the fit to data" << endl; pPoiAndNuisance->Print("v"); pSbModel->SetSnapshot(*pPoiAndNuisance); delete pProfile; delete pNll; delete pPoiAndNuisance; pNll = pBModel->GetPdf()->createNLL(*data); pProfile = pNll->createProfile(poi); ((RooRealVar *)poi.first())->setVal(poiValueForBModel); pProfile->getVal(); // this will do fit and set nuisance parameters to profiled values pPoiAndNuisance = new RooArgSet(); //if(pBModel->GetNuisanceParameters()) // pPoiAndNuisance->add(*pBModel->GetNuisanceParameters()); pPoiAndNuisance->add(*pBModel->GetParametersOfInterest()); cout << "\nShould use these parameter points to generate pseudo data for bkg only" << endl; pPoiAndNuisance->Print("v"); pBModel->SetSnapshot(*pPoiAndNuisance); delete pProfile; delete pNll; delete pPoiAndNuisance; // inspect workspace wspace->Print(); // save workspace to file wspace->writeToFile("tight.root"); //wspace->writeToFile("tight_median.root"); // clean up delete wspace; delete data; delete pSbModel; delete pBModel; }
/* * Prepares the workspace to be used by the hypothesis test calculator */ void workspace_preparer(char *signal_file_name, char *signal_hist_name_in_file, char *background_file_name, char *background_hist_name_in_file, char *data_file_name, char *data_hist_name_in_file, char *config_file) { // Include the config_reader class. TString path = gSystem->GetIncludePath(); path.Append(" -I/home/max/cern/cls/mario"); gSystem->SetIncludePath(path); gROOT->LoadMacro("config_reader.cxx"); // RooWorkspace used to store values. RooWorkspace * pWs = new RooWorkspace("ws"); // Create a config_reader (see source for details) to read the config // file. config_reader reader(config_file, pWs); // Read MR and RR bounds from the config file. double MR_lower = reader.find_double("MR_lower"); double MR_upper = reader.find_double("MR_upper"); double RR_lower = reader.find_double("RR_lower"); double RR_upper = reader.find_double("RR_upper"); double MR_initial = (MR_lower + MR_upper)/2; double RR_initial = (RR_lower + RR_upper)/2; // Define the Razor Variables RooRealVar MR = RooRealVar("MR", "MR", MR_initial, MR_lower, MR_upper); RooRealVar RR = RooRealVar("RSQ", "RSQ", RR_initial, RR_lower, RR_upper); // Argument lists RooArgList pdf_arg_list(MR, RR, "input_args_list"); RooArgSet pdf_arg_set(MR, RR, "input_pdf_args_set"); /***********************************************************************/ /* PART 1: IMPORTING SIGNAL AND BACKGROUND HISTOGRAMS */ /***********************************************************************/ /* * Get the signal's unextended pdf by converting the TH2D in the file * into a RooHistPdf */ TFile *signal_file = new TFile(signal_file_name); TH2D *signal_hist = (TH2D *)signal_file->Get(signal_hist_name_in_file); RooDataHist *signal_RooDataHist = new RooDataHist("signal_roodatahist", "signal_roodatahist", pdf_arg_list, signal_hist); RooHistPdf *unextended_sig_pdf = new RooHistPdf("unextended_sig_pdf", "unextended_sig_pdf", pdf_arg_set, *signal_RooDataHist); /* * Repeat this process for the background. */ TFile *background_file = new TFile(background_file_name); TH2D *background_hist = (TH2D *)background_file->Get(background_hist_name_in_file); RooDataHist *background_RooDataHist = new RooDataHist("background_roodatahist", "background_roodatahist", pdf_arg_list, background_hist); RooHistPdf *unextended_bkg_pdf = new RooHistPdf("unextended_bkg_pdf", "unextended_bkg_pdf", pdf_arg_set, *background_RooDataHist); /* * Now, we want to create the bprime variable, which represents the * integral over the background-only sample. We will perform the * integral automatically (that's why this is the only nuisance * parameter declared in this file - its value can be determined from * the input histograms). */ ostringstream bprime_string; ostringstream bprime_pdf_string; bprime_string << "bprime[" << background_hist->Integral() << ", 0, 999999999]"; bprime_pdf_string << "Poisson::bprime_pdf(bprime, " << background_hist->Integral() << ")"; pWs->factory(bprime_string.str().c_str()); pWs->factory(bprime_pdf_string.str().c_str()); /* * This simple command will create all values from the config file * with 'make:' at the beginning and a delimiter at the end (see config * _reader if you don't know what a delimiter is). In other * words, the luminosity, efficiency, transfer factors, and their pdfs * are created from this command. The declarations are contained in the * config file to be changed easily without having to modify this code. */ reader.factory_all(); /* * Now, we want to create the extended pdfs from the unextended pdfs, as * well as from the S and B values we manufactured in the config file. * S and B are the values by which the signal and background pdfs, * respectively, are extended. Recall that they were put in the * workspace in the reader.facotry_all() command. */ RooAbsReal *S = pWs->function("S"); RooAbsReal *B = pWs->function("B"); RooExtendPdf *signalpart = new RooExtendPdf("signalpart", "signalpart", *unextended_sig_pdf, *S); RooExtendPdf *backgroundpart = new RooExtendPdf("backgroundpart", "backgroundpart", *unextended_bkg_pdf, *B); RooArgList *pdf_list = new RooArgList(*signalpart, *backgroundpart, "list"); // Add the signal and background pdfs to make a TotalPdf RooAddPdf *TotalPdf = new RooAddPdf("TotalPdf", "TotalPdf", *pdf_list); RooArgList *pdf_prod_list = new RooArgList(*TotalPdf, *pWs->pdf("lumi_pdf"), *pWs->pdf("eff_pdf"), *pWs->pdf("rho_pdf"), *pWs->pdf("bprime_pdf")); // This creates the final model pdf. RooProdPdf *model = new RooProdPdf("model", "model", *pdf_prod_list); /* * Up until now, we have been using the workspace pWs to contain all of * our values. Now, all of our values that we require are in use in the * RooProdPdf called "model". So, we need to import "model" into a * RooWorkspace. To avoid recopying values into the rooworkspace, when * the values may already be present (which can cause problems), we will * simply create a new RooWorkspace to avoid confusion and problems. The * new RooWorkspace is created here. */ RooWorkspace *newworkspace = new RooWorkspace("newws"); newworkspace->import(*model); // Immediately delete pWs, so we don't accidentally use it again. delete pWs; // Show off the newworkspace newworkspace->Print(); // observables RooArgSet obs(*newworkspace->var("MR"), *newworkspace->var("RSQ"), "obs"); // global observables RooArgSet globalObs(*newworkspace->var("nom_lumi"), *newworkspace->var("nom_eff"), *newworkspace->var("nom_rho")); //fix global observables to their nominal values newworkspace->var("nom_lumi")->setConstant(); newworkspace->var("nom_eff")->setConstant(); newworkspace->var("nom_rho")->setConstant(); //Set Parameters of interest RooArgSet poi(*newworkspace->var("sigma"), "poi"); //Set Nuisnaces RooArgSet nuis(*newworkspace->var("prime_lumi"), *newworkspace->var("prime_eff"), *newworkspace->var("prime_rho"), *newworkspace->var("bprime")); // priors (for Bayesian calculation) newworkspace->factory("Uniform::prior_signal(sigma)"); // for parameter of interest newworkspace->factory("Uniform::prior_bg_b(bprime)"); // for data driven nuisance parameter newworkspace->factory("PROD::prior(prior_signal,prior_bg_b)"); // total prior //Observed data is pulled from histogram. //TFile *data_file = new TFile(data_file_name); TFile *data_file = new TFile(data_file_name); TH2D *data_hist = (TH2D *)data_file->Get(data_hist_name_in_file); RooDataHist *pData = new RooDataHist("data", "data", obs, data_hist); newworkspace->import(*pData); // Now, we will draw our data from a RooDataHist. /*TFile *data_file = new TFile(data_file_name); TTree *data_tree = (TTree *) data_file->Get(data_hist_name_in_file); RooDataSet *pData = new RooDataSet("data", "data", data_tree, obs); newworkspace->import(*pData);*/ // Craft the signal+background model ModelConfig * pSbModel = new ModelConfig("SbModel"); pSbModel->SetWorkspace(*newworkspace); pSbModel->SetPdf(*newworkspace->pdf("model")); pSbModel->SetPriorPdf(*newworkspace->pdf("prior")); pSbModel->SetParametersOfInterest(poi); pSbModel->SetNuisanceParameters(nuis); pSbModel->SetObservables(obs); pSbModel->SetGlobalObservables(globalObs); // set all but obs, poi and nuisance to const SetConstants(newworkspace, pSbModel); newworkspace->import(*pSbModel); // background-only model // use the same PDF as s+b, with sig=0 // POI value under the background hypothesis // (We will set the value to 0 later) Double_t poiValueForBModel = 0.0; ModelConfig* pBModel = new ModelConfig(*(RooStats::ModelConfig *)newworkspace->obj("SbModel")); pBModel->SetName("BModel"); pBModel->SetWorkspace(*newworkspace); newworkspace->import(*pBModel); // find global maximum with the signal+background model // with conditional MLEs for nuisance parameters // and save the parameter point snapshot in the Workspace // - safer to keep a default name because some RooStats calculators // will anticipate it RooAbsReal * pNll = pSbModel->GetPdf()->createNLL(*pData); RooAbsReal * pProfile = pNll->createProfile(RooArgSet()); pProfile->getVal(); // this will do fit and set POI and nuisance parameters to fitted values RooArgSet * pPoiAndNuisance = new RooArgSet(); if(pSbModel->GetNuisanceParameters()) pPoiAndNuisance->add(*pSbModel->GetNuisanceParameters()); pPoiAndNuisance->add(*pSbModel->GetParametersOfInterest()); cout << "\nWill save these parameter points that correspond to the fit to data" << endl; pPoiAndNuisance->Print("v"); pSbModel->SetSnapshot(*pPoiAndNuisance); delete pProfile; delete pNll; delete pPoiAndNuisance; // Find a parameter point for generating pseudo-data // with the background-only data. // Save the parameter point snapshot in the Workspace pNll = pBModel->GetPdf()->createNLL(*pData); pProfile = pNll->createProfile(poi); ((RooRealVar *)poi.first())->setVal(poiValueForBModel); pProfile->getVal(); // this will do fit and set nuisance parameters to profiled values pPoiAndNuisance = new RooArgSet(); if(pBModel->GetNuisanceParameters()) pPoiAndNuisance->add(*pBModel->GetNuisanceParameters()); pPoiAndNuisance->add(*pBModel->GetParametersOfInterest()); cout << "\nShould use these parameter points to generate pseudo data for bkg only" << endl; pPoiAndNuisance->Print("v"); pBModel->SetSnapshot(*pPoiAndNuisance); delete pProfile; delete pNll; delete pPoiAndNuisance; // save workspace to file newworkspace->writeToFile("ws_twobin.root"); // clean up delete newworkspace; delete pData; delete pSbModel; delete pBModel; } // ----- end of tutorial ----------------------------------------
double StandardFrequentistDiscovery( const char* infile = "", const char* workspaceName = "channel1", const char* modelConfigNameSB = "ModelConfig", const char* dataName = "obsData", int toys = 1000, double poiValueForBackground = 0.0, double poiValueForSignal = 1.0 ) { // The workspace contains the model for s+b. The b model is "autogenerated" // by copying s+b and setting the one parameter of interest to zero. // To keep the script simple, multiple parameters of interest or different // functional forms of the b model are not supported. // for now, assume there is only one parameter of interest, and these are // its values: ///////////////////////////////////////////////////////////// // 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_channel1_GammaExample_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 -1; #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 -1; } ///////////////////////////////////////////////////////////// // Tutorial starts here //////////////////////////////////////////////////////////// TStopwatch *mn_t = new TStopwatch; mn_t->Start(); // get the workspace out of the file RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName); if (!w) { cout << "workspace not found" << endl; return -1.0; } // get the modelConfig out of the file ModelConfig* mc = (ModelConfig*) w->obj(modelConfigNameSB); // get the data 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 -1.0; } RooRealVar* firstPOI = (RooRealVar*) mc->GetParametersOfInterest()->first(); firstPOI->setVal(poiValueForSignal); mc->SetSnapshot(*mc->GetParametersOfInterest()); // create null model ModelConfig *mcNull = mc->Clone("ModelConfigNull"); firstPOI->setVal(poiValueForBackground); mcNull->SetSnapshot(*(RooArgSet*)mcNull->GetParametersOfInterest()->snapshot()); // ---------------------------------------------------- // Configure a ProfileLikelihoodTestStat and a SimpleLikelihoodRatioTestStat // to use simultaneously with ToyMCSampler ProfileLikelihoodTestStat* plts = new ProfileLikelihoodTestStat(*mc->GetPdf()); plts->SetOneSidedDiscovery(true); plts->SetVarName( "q_{0}/2" ); // ---------------------------------------------------- // configure the ToyMCImportanceSampler with two test statistics ToyMCSampler toymcs(*plts, 50); // 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) { toymcs.SetNEventsPerToy(1); } else cout << "Not sure what to do about this model" << endl; } // We can use PROOF to speed things along in parallel // ProofConfig pc(*w, 2, "user@yourfavoriteproofcluster", false); ProofConfig pc(*w, 2, "", false); //toymcs.SetProofConfig(&pc); // enable proof // instantiate the calculator FrequentistCalculator freqCalc(*data, *mc, *mcNull, &toymcs); freqCalc.SetToys( toys,toys ); // null toys, alt toys // Run the calculator and print result HypoTestResult* freqCalcResult = freqCalc.GetHypoTest(); freqCalcResult->GetNullDistribution()->SetTitle( "b only" ); freqCalcResult->GetAltDistribution()->SetTitle( "s+b" ); freqCalcResult->Print(); double pvalue = freqCalcResult->NullPValue(); // stop timing mn_t->Stop(); cout << "total CPU time: " << mn_t->CpuTime() << endl; cout << "total real time: " << mn_t->RealTime() << endl; // plot TCanvas* c1 = new TCanvas(); HypoTestPlot *plot = new HypoTestPlot(*freqCalcResult, 100, -0.49, 9.51 ); plot->SetLogYaxis(true); // add chi2 to plot int nPOI = 1; TF1* f = new TF1("f", TString::Format("1*ROOT::Math::chisquared_pdf(2*x,%d,0)",nPOI), 0,20); f->SetLineColor( kBlack ); f->SetLineStyle( 7 ); plot->AddTF1( f, TString::Format("#chi^{2}(2x,%d)",nPOI) ); plot->Draw(); c1->SaveAs("standard_discovery_output.pdf"); return pvalue; }
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(); }
TH1D* runSig(RooWorkspace* ws, const char* modelConfigName = "ModelConfig", const char* dataName = "obsData", const char* asimov1DataName = "asimovData_1", const char* conditional1Snapshot = "conditionalGlobs_1", const char* nominalSnapshot = "nominalGlobs") { string defaultMinimizer = "Minuit"; // or "Minuit" int defaultStrategy = 2; // Minimization strategy. 0-2. 0 = fastest, least robust. 2 = slowest, most robust double mu_profile_value = 1; // mu value to profile the obs data at wbefore generating the expected bool doUncap = 1; // uncap p0 bool doInj = 0; // setup the poi for injection study (zero is faster if you're not) bool doMedian = 1; // compute median significance bool isBlind = 0; // Dont look at observed data bool doConditional = !isBlind; // do conditional expected data bool doObs = !isBlind; // compute observed significance TStopwatch timer; timer.Start(); if (!ws) { cout << "ERROR::Workspace is NULL!" << endl; return NULL; } ModelConfig* mc = (ModelConfig*)ws->obj(modelConfigName); if (!mc) { cout << "ERROR::ModelConfig: " << modelConfigName << " doesn't exist!" << endl; return NULL; } RooDataSet* data = (RooDataSet*)ws->data(dataName); if (!data) { cout << "ERROR::Dataset: " << dataName << " doesn't exist!" << endl; return NULL; } mc->GetNuisanceParameters()->Print("v"); //RooNLLVar::SetIgnoreZeroEntries(1); ROOT::Math::MinimizerOptions::SetDefaultMinimizer(defaultMinimizer.c_str()); ROOT::Math::MinimizerOptions::SetDefaultStrategy(defaultStrategy); ROOT::Math::MinimizerOptions::SetDefaultPrintLevel(-1); // cout << "Setting max function calls" << endl; //ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(20000); //RooMinimizer::SetMaxFunctionCalls(10000); ws->loadSnapshot("conditionalNuis_0"); RooArgSet nuis(*mc->GetNuisanceParameters()); RooRealVar* mu = (RooRealVar*)mc->GetParametersOfInterest()->first(); RooAbsPdf* pdf_temp = mc->GetPdf(); string condSnapshot(conditional1Snapshot); RooArgSet nuis_tmp2 = *mc->GetNuisanceParameters(); RooNLLVar* obs_nll = doObs ? (RooNLLVar*)pdf_temp->createNLL(*data, Constrain(nuis_tmp2)) : NULL; RooDataSet* asimovData1 = (RooDataSet*)ws->data(asimov1DataName); if (!asimovData1) { cout << "Asimov data doesn't exist! Please, allow me to build one for you..." << endl; string mu_str, mu_prof_str; asimovData1 = makeAsimovData(mc, doConditional, ws, obs_nll, 1, &mu_str, &mu_prof_str, mu_profile_value, true); condSnapshot="conditionalGlobs"+mu_prof_str; //makeAsimovData(mc, true, ws, mc->GetPdf(), data, 0); //ws->Print(); //asimovData1 = (RooDataSet*)ws->data("asimovData_1"); } if (!doUncap) mu->setRange(0, 40); else mu->setRange(-40, 40); RooAbsPdf* pdf = mc->GetPdf(); RooArgSet nuis_tmp1 = *mc->GetNuisanceParameters(); RooNLLVar* asimov_nll = (RooNLLVar*)pdf->createNLL(*asimovData1, Constrain(nuis_tmp1)); //do asimov mu->setVal(1); mu->setConstant(0); if (!doInj) mu->setConstant(1); int status,sign; double med_sig=0,obs_sig=0,asimov_q0=0,obs_q0=0; if (doMedian) { ws->loadSnapshot(condSnapshot.c_str()); if (doInj) ws->loadSnapshot("conditionalNuis_inj"); else ws->loadSnapshot("conditionalNuis_1"); mc->GetGlobalObservables()->Print("v"); mu->setVal(0); mu->setConstant(1); status = minimize(asimov_nll, ws); if (status >= 0) cout << "Success!" << endl; if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll, ws); if (status >= 0) cout << "Success!" << endl; } double asimov_nll_cond = asimov_nll->getVal(); mu->setVal(1); if (doInj) ws->loadSnapshot("conditionalNuis_inj"); else ws->loadSnapshot("conditionalNuis_1"); if (doInj) mu->setConstant(0); status = minimize(asimov_nll, ws); if (status >= 0) cout << "Success!" << endl; if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(asimov_nll, ws); if (status >= 0) cout << "Success!" << endl; } double asimov_nll_min = asimov_nll->getVal(); asimov_q0 = 2*(asimov_nll_cond - asimov_nll_min); if (doUncap && mu->getVal() < 0) asimov_q0 = -asimov_q0; sign = int(asimov_q0 != 0 ? asimov_q0/fabs(asimov_q0) : 0); med_sig = sign*sqrt(fabs(asimov_q0)); ws->loadSnapshot(nominalSnapshot); } if (doObs) { ws->loadSnapshot("conditionalNuis_0"); mu->setVal(0); mu->setConstant(1); status = minimize(obs_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(obs_nll, ws); if (status >= 0) cout << "Success!" << endl; } double obs_nll_cond = obs_nll->getVal(); //ws->loadSnapshot("ucmles"); mu->setConstant(0); status = minimize(obs_nll, ws); if (status < 0) { cout << "Retrying with conditional snapshot at mu=1" << endl; ws->loadSnapshot("conditionalNuis_0"); status = minimize(obs_nll, ws); if (status >= 0) cout << "Success!" << endl; } double obs_nll_min = obs_nll->getVal(); obs_q0 = 2*(obs_nll_cond - obs_nll_min); if (doUncap && mu->getVal() < 0) obs_q0 = -obs_q0; sign = int(obs_q0 == 0 ? 0 : obs_q0 / fabs(obs_q0)); if (!doUncap && ((obs_q0 < 0 && obs_q0 > -0.1) || mu->getVal() < 0.001)) obs_sig = 0; else obs_sig = sign*sqrt(fabs(obs_q0)); } cout << "obs: " << obs_sig << endl; cout << "Observed significance: " << obs_sig << endl; if (med_sig) { cout << "Median test stat val: " << asimov_q0 << endl; cout << "Median significance: " << med_sig << endl; } TH1D* h_hypo = new TH1D("hypo","hypo",2,0,2); h_hypo->SetBinContent(1, obs_sig); h_hypo->SetBinContent(2, med_sig); timer.Stop(); timer.Print(); return h_hypo; }