예제 #1
0
파일: dimuon.C 프로젝트: neumeist/twobody
RooAbsData * TwoBody::SetObservableRange( double peak, Double_t window_width, UInt_t minEvents ){
  //
  // Reduce the observable range so ~400 events are used
  // for the full combined dataset
  //

  std::string legend = "[TwoBody::SetObservableRange]: ";

  std::map<std::string, double> _range;

  _range = GetDataRange( data, peak, minEvents, window_width );
  char buf[256];

  // Should not change the range!
  //ws->var("mass")->setRange(_range["low"], _range["high"]);
  //ws->var("mass")->Print();

  // replace data
  //int iTotal = (int)data->sumEntries();
  sprintf(buf, "mass>%f && mass<%f", _range["low"], _range["high"]);
  RooAbsData * _data = data->reduce( RooFit::Cut(buf) );
  // correct the nbkg constraint accordingly
  //double _nbkg = ws->var("nbkg_est_dimuon")->getVal();
  //ws->var("nbkg_est_dimuon")->setVal(_nbkg*_data->sumEntries()/(double)(iTotal));
  //ws->var("nbkg_est_dimuon")->Print();

  data->Print();
  _data->Print();
  delete data;
  return _data;
}
pair<double,double> bkgEvPerGeV(RooWorkspace *work, int m_hyp, int cat, int spin=false){
  
  RooRealVar *mass = (RooRealVar*)work->var("CMS_hgg_mass");
  if (spin) mass = (RooRealVar*)work->var("mass");
  mass->setRange(100,180);
  RooAbsPdf *pdf = (RooAbsPdf*)work->pdf(Form("pdf_data_pol_model_8TeV_cat%d",cat));
  RooAbsData *data = (RooDataSet*)work->data(Form("data_mass_cat%d",cat));
  RooPlot *tempFrame = mass->frame();
  data->plotOn(tempFrame,Binning(80));
  pdf->plotOn(tempFrame);
  RooCurve *curve = (RooCurve*)tempFrame->getObject(tempFrame->numItems()-1);
  double nombkg = curve->Eval(double(m_hyp));
 
  RooRealVar *nlim = new RooRealVar(Form("nlim%d",cat),"",0.,0.,1.e5);
  //double lowedge = tempFrame->GetXaxis()->GetBinLowEdge(FindBin(double(m_hyp)));
  //double upedge  = tempFrame->GetXaxis()->GetBinUpEdge(FindBin(double(m_hyp)));
  //double center  = tempFrame->GetXaxis()->GetBinUpCenter(FindBin(double(m_hyp)));

  nlim->setVal(nombkg);
  mass->setRange("errRange",m_hyp-0.5,m_hyp+0.5);
  RooAbsPdf *epdf = 0;
  epdf = new RooExtendPdf("epdf","",*pdf,*nlim,"errRange");
		
  RooAbsReal *nll = epdf->createNLL(*data,Extended(),NumCPU(4));
  RooMinimizer minim(*nll);
  minim.setStrategy(0);
  minim.setPrintLevel(-1);
  minim.migrad();
  minim.minos(*nlim);
  
  double error = (nlim->getErrorLo(),nlim->getErrorHi())/2.;
  data->Print(); 
  return pair<double,double>(nombkg,error); 
}
예제 #3
0
 virtual Double_t Evaluate(RooAbsData& data, RooArgSet& /*nullPOI*/) {
   // This is the main method in the interface
   Double_t value = 0.0;
   for(int i=0; i < data.numEntries(); i++) {
     value += data.get(i)->getRealValue(fColumnName.c_str());
   }
   return value;
     }
예제 #4
0
//____________________________________
void MakePlots(RooWorkspace* wks) {

  // Make plots of the data and the best fit model in two cases:
  // first the signal+background case
  // second the background-only case.

  // get some things out of workspace
  RooAbsPdf* model = wks->pdf("model");
  RooAbsPdf* sigModel = wks->pdf("sigModel");
  RooAbsPdf* zjjModel = wks->pdf("zjjModel");
  RooAbsPdf* qcdModel = wks->pdf("qcdModel");

  RooRealVar* mu = wks->var("mu");
  RooRealVar* invMass = wks->var("invMass");
  RooAbsData* data = wks->data("data");


  //////////////////////////////////////////////////////////
  // Make plots for the Alternate hypothesis, eg. let mu float

  mu->setConstant(kFALSE);

  model->fitTo(*data,Save(kTRUE),Minos(kFALSE), Hesse(kFALSE),PrintLevel(-1));

  //plot sig candidates, full model, and individual componenets
  new TCanvas();
  RooPlot* frame = invMass->frame() ;
  data->plotOn(frame ) ;
  model->plotOn(frame) ;
  model->plotOn(frame,Components(*sigModel),LineStyle(kDashed), LineColor(kRed)) ;
  model->plotOn(frame,Components(*zjjModel),LineStyle(kDashed),LineColor(kBlack)) ;
  model->plotOn(frame,Components(*qcdModel),LineStyle(kDashed),LineColor(kGreen)) ;

  frame->SetTitle("An example fit to the signal + background model");
  frame->Draw() ;
  //  cdata->SaveAs("alternateFit.gif");

  //////////////////////////////////////////////////////////
  // Do Fit to the Null hypothesis.  Eg. fix mu=0

  mu->setVal(0); // set signal fraction to 0
  mu->setConstant(kTRUE); // set constant

  model->fitTo(*data, Save(kTRUE), Minos(kFALSE), Hesse(kFALSE),PrintLevel(-1));

  // plot signal candidates with background model and components
  new TCanvas();
  RooPlot* xframe2 = invMass->frame() ;
  data->plotOn(xframe2, DataError(RooAbsData::SumW2)) ;
  model->plotOn(xframe2) ;
  model->plotOn(xframe2, Components(*zjjModel),LineStyle(kDashed),LineColor(kBlack)) ;
  model->plotOn(xframe2, Components(*qcdModel),LineStyle(kDashed),LineColor(kGreen)) ;

  xframe2->SetTitle("An example fit to the background-only model");
  xframe2->Draw() ;
  //  cbkgonly->SaveAs("nullFit.gif");

}
예제 #5
0
void JetTagBin::generateData()
{
  if ( jtData_ ) delete jtData_;
  int nToGen = (int) nevt()+.5;
  int nToGenPoisson = RooRandom::randomGenerator()->Poisson(nToGen) ;
  jtData_ = jtPdf_->generateBinned( RooArgList(*jtBinVar_), nToGenPoisson, Verbose(1));
  if ( verbose ) cout << "Generated data histogram with " << jtData_->numEntries() << " bins and " 
                      << jtData_->sumEntries() << " events" << endl
                      << "Using seed: " << RooRandom::randomGenerator()->GetSeed() << endl;
}
//#include "/uscms_data/d3/cvernier/DiH_13TeV/CMSSW_7_1_5/src/HiggsAnalysis/CombinedLimit/interface/RooMultiPdf.h"
//#include "HiggsAnalysis/CombinedLimit/interface/RooMultiPdf.h"
void makeRooMultiPdfWorkspace(){

   // Load the combine Library 
   gSystem->Load("libHiggsAnalysisCombinedLimit.so");

   // Open the dummy H->gg workspace 
   TFile *f_hgg = TFile::Open("w_background_Bern.root");
   RooWorkspace *w_hgg = (RooWorkspace*)f_hgg->Get("HbbHbb");
   // The observable (CMS_hgg_mass in the workspace)
   RooRealVar *mass =  w_hgg->var("x");

   // Get three of the functions inside, exponential, linear polynomial, power law
   RooAbsPdf *pdf_exp = w_hgg->pdf("bg_exp");
   RooAbsPdf *pdf_pol = w_hgg->pdf("bg");


   // Fit the functions to the data to set the "prefit" state (note this can and should be redone with combine when doing 
   // bias studies as one typically throws toys from the "best-fit"
   RooAbsData *data = w_hgg->data("data_obs");
   pdf_exp->fitTo(*data);  // index 0
   pdf_pol->fitTo(*data);   // index 2

   // Make a plot (data is a toy dataset)
   RooPlot *plot = mass->frame();   data->plotOn(plot);
   pdf_exp->plotOn(plot,RooFit::LineColor(kBlue));
   pdf_pol->plotOn(plot,RooFit::LineColor(kRed));
   plot->SetTitle("PDF fits to toy data");
   plot->Draw();

   // Make a RooCategory object. This will control which of the pdfs is "active"
   RooCategory cat("pdf_index","Index of Pdf which is active");

   // Make a RooMultiPdf object. The order of the pdfs will be the order of their index, ie for below 
   // 0 == exponential
   // 1 == linear function
   // 2 == powerlaw
   RooArgList mypdfs;
   mypdfs.add(*pdf_exp);
   mypdfs.add(*pdf_pol);
   
   RooMultiPdf multipdf("roomultipdf","All Pdfs",cat,mypdfs);
   
   // As usual make an extended term for the background with _norm for freely floating yield
   RooRealVar norm("roomultipdf_norm","Number of background events",0,10000);
   
   // Save to a new workspace
   TFile *fout = new TFile("background_pdfs.root","RECREATE");
   RooWorkspace wout("backgrounds","backgrounds");
   wout.import(cat);
   wout.import(norm);
   wout.import(multipdf);
   wout.Print();
   wout.Write();

}
예제 #7
0
파일: dimuon.C 프로젝트: neumeist/twobody
Int_t TwoBody::CreateDimuonToyMc( void ){
  //
  // generate a toy di-muon dataset with systematics
  // set mData accordingly
  //

  // generate expected number of events from its uncertainty
  //RooDataSet * _ds = ws->pdf("syst_nbkg_dimuon")->generate(*ws->var("beta_nbkg_dimuon"), 1);
  //Double_t _ntoy = ((RooRealVar *)(_ds->get(0)->first()))->getVal() * (ws->var("nbkg_est_dimuon")->getVal());
  //delete _ds;

  Double_t _beta = GetRandom("syst_nbkg_dimuon", "beta_nbkg_dimuon");
  //  Double_t _kappa = ws->var("nbkg_kappa_dimuon")->getVal();
  Double_t _nbkg_est = ws->var("nbkg_est_dimuon")->getVal();
  //Double_t _ntoy = pow(_kappa,_beta) * _nbkg_est;
  Double_t _ntoy = _beta * _nbkg_est;
 
  Int_t _n = r.Poisson(_ntoy);
  // all nuisance parameters:
  //   beta_nsig_dimuon, 
  //   beta_nbkg_dimuon,
  //   lumi_nuis

  // create dataset
  RooRealVar * _mass = ws->var("mass");
  RooArgSet _vars(*_mass);

  RooAbsPdf * _pdf = ws->pdf("bkgpdf_dimuon");

  RooAbsPdf::GenSpec * _spec = _pdf->prepareMultiGen(_vars,
						     Name("toys"),
						     NumEvents(_n),
						     Extended(kFALSE),
						     Verbose(kTRUE));

  //RooPlot* xframe = _mass->frame(Title("Gaussian p.d.f.")) ;
  //realdata->plotOn(xframe,LineColor(kRed),MarkerColor(kRed));

  delete data;
  data = _pdf->generate(*_spec); // class member
  delete _spec;

  //data->plotOn(xframe);
  //TCanvas* c = new TCanvas("test","rf101_basics",800,400) ;
  //gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.6) ; xframe->Draw() ;
  //c->SaveAs("test.pdf");

  Int_t n_generated_entries = (Int_t)(data->sumEntries());

  // debug
  std::cout << "!!!!!!!!!!!!!! _beta = " << _beta << std::endl;
  //std::cout << "!!!!!!!!!!!!!! _kappa = " << _kappa << std::endl;
  std::cout << "!!!!!!!!!!!!!! _nbkg_est = " << _nbkg_est << std::endl;
  std::cout << "!!!!!!!!!!!!!! _ntoy     = " << _ntoy << std::endl;
  std::cout << "!!!!!!!!!!!!!! _n        = " << _n    << std::endl;
  std::cout << "!!!!!!!!!!!!!! n_generated_entries = " << n_generated_entries    << std::endl;
  return n_generated_entries;
}
void rs500b_PrepareWorkspace_Poisson_withSystematics( TString fileName = "WS_Poisson_withSystematics.root", int type = 1 )
{

  // use a RooWorkspace to store the pdf models, prior informations, list of parameters,...
  RooWorkspace myWS("myWS");

  // Observable
  myWS.factory("x[0,0,1]") ;

  // Pdf in observable,
  myWS.factory("Uniform::sigPdf(x)") ;
  myWS.factory("Uniform::bkgPdf(x)") ;
  myWS.factory("SUM::model(S[100,0,1500]*sigPdf,B[1000,0,3000]*bkgPdf)") ;

  // Background only pdf
  myWS.factory("ExtendPdf::modelBkg(bkgPdf,B)") ;

  // Priors
  myWS.factory("Gaussian::priorNuisance(B,1000,200)") ;
  myWS.factory("Uniform::priorPOI(S)") ;

  // Definition of observables and parameters of interest
  myWS.defineSet("observables","x");
  myWS.defineSet("POI","S");
  myWS.defineSet("parameters","B") ;

  // Generate data
  RooAbsData* data = 0;
  // binned data with fixed number of events
  if (type ==0) data = myWS.pdf("model")->generateBinned(*myWS.set("observables"),myWS.var("S")->getVal(),Name("data"));
  // binned data with Poisson fluctuations
  if (type ==1) data = myWS.pdf("model")->generateBinned(*myWS.set("observables"),Extended(),Name("data"));
  // Asimov data: binned data without any fluctuations (average case)
  if (type == 2)  data = myWS.pdf("model")->generateBinned(*myWS.set("observables"),Name("data"),ExpectedData());
  myWS.import(*data) ;

  myWS.writeToFile(fileName);
  std::cout << "\nRooFit model initialized and stored in " << fileName << std::endl;

  // control plot of the generated data
  RooPlot* plot = myWS.var("x")->frame();
  data->plotOn(plot);
  plot->DrawClone();

}
예제 #9
0
파일: dimuon.C 프로젝트: neumeist/twobody
double TwoBody::GetPoiUpperSimple(std::string channel, Double_t peak){
  //
  // Estimate a good value for the upper boundary of the range of POI
  // using just data in a window corresponding to the signal region
  //

  std::string legend = "[TwoBody::GetPoiUpperSimple]: ";

  char buf[128];

  // special handling needed for single-channel workspaces
  bool b_single_channel;
  if (channel.size()==0) b_single_channel = true;  else b_single_channel = false;

  double _range = 1.0;

  // get data yield under the signal peak
  ws->var("peak")->setVal(peak);

  if (b_single_channel) sprintf(buf,"width");
  else sprintf(buf,"width_%s",channel.c_str());
  double _width = 0;//ws->function(buf)->getVal();

  if (b_single_channel) sprintf(buf,"sigma");
  else sprintf(buf,"sigma_%s",channel.c_str());
  double _sigma = ws->function(buf)->getVal();

  double c_min = peak - sqrt(_width*_width + _sigma*_sigma);
  double c_max = peak + sqrt(_width*_width + _sigma*_sigma);

  sprintf(buf, "mass>=%f && mass<=%f", c_min, c_max);
  double n_count = data->sumEntries( buf );

  // ad-hoc fix when there are no events in window
  if (n_count < 0.3) n_count = 0.3;
  std::cout << legend << "event yield in data in the window: "
	    << n_count << std::endl;

  // compute the corresponding POI range
  if (b_single_channel) sprintf(buf,"nsig_scale");
  else sprintf(buf,"nsig_scale_%s",channel.c_str());
  double _nsig_scale = ws->var(buf)->getVal();

  if (b_single_channel) sprintf(buf,"nz");
  else sprintf(buf,"nz_%s",channel.c_str());
  double _nz = ws->var(buf)->getVal();

  if (b_single_channel) sprintf(buf,"eff");
  else sprintf(buf,"eff_%s",channel.c_str());
  double _eff = ws->function(buf)->getVal();

  double n_excess = 3.0 * sqrt(n_count)/0.68; // let signal excess be ~ uncertainty on BG
  _range = n_excess / _nsig_scale / _nz / _eff;

  return _range;
}
예제 #10
0
void MakeSpinPlots::PlotSignalFits(TString tag, TString mcName,TString cosThetaBin){
  TCanvas cv;
  TString cat=tag;
  if(cosThetaBin!="") tag = tag+"_"+cosThetaBin;

  float mean = ws->var(Form("%s_FIT_%s_mean",mcName.Data(),tag.Data()))->getVal();
  RooPlot *frame = ws->var("mass")->frame(105,140,70);//mean-10,mean+10,40);
  RooAbsData *d = ws->data(mcName+"_Combined")->reduce(TString("evtcat==evtcat::")+cat);
  if(cosThetaBin!=""){
    TObjArray *arr = cosThetaBin.Tokenize("_");
    float low  = atof(arr->At(1)->GetName());
    float high = atof(arr->At(2)->GetName());
    d = d->reduce( Form("cosT < %0.2f && cosT >= %0.2f",high,low) );
    delete arr;
  }

  d->plotOn(frame);
  RooFitResult *res = (RooFitResult*)ws->obj(Form("%s_FIT_%s_fitResult",mcName.Data(),tag.Data()));
  RooAbsPdf * pdf = ws->pdf(Form("%s_FIT_%s",mcName.Data(),tag.Data())); //signal model
  std::cout << pdf << "\t" << res << std::endl;
  pdf->plotOn(frame,RooFit::FillColor(kGreen),RooFit::VisualizeError(*res,2.0));
  pdf->plotOn(frame,RooFit::FillColor(kYellow),RooFit::VisualizeError(*res,1.0));
  pdf->plotOn(frame,RooFit::LineColor(kRed));
  d->plotOn(frame); //data
  
  tPair lbl(mcName,tag);

  TLatex *prelim = new TLatex(0.18,0.9,"CMS Preliminary Simulation");
  TLatex *sigL  = new TLatex(0.18,0.6,Form("#sigma_{eff} = %0.2f GeV",fitSigEff[lbl].first,fitSigEff[lbl].second));
  prelim->SetNDC();
  sigL->SetNDC();
  prelim->SetTextSize(0.05);
  sigL->SetTextSize(0.05);
  
  frame->addObject(prelim);
  frame->addObject(sigL);
  frame->Draw();
  cv.SaveAs(basePath+Form("/signalModels/sig_%s_%s_%s.png",mcName.Data(),outputTag.Data(),tag.Data()));
  cv.SaveAs(basePath+Form("/signalModels/C/sig_%s_%s_%s.C",mcName.Data(),outputTag.Data(),tag.Data()));
  cv.SaveAs(basePath+Form("/signalModels/sig_%s_%s_%s.pdf",mcName.Data(),outputTag.Data(),tag.Data()));

}
예제 #11
0
RooAbsData * Tprime::GetPseudoData( void ) {
    //
    // Generate pseudo data, return a pointer.
    // Class member pointer data set to point to the dataset.
    // Caller does not take ownership.
    //

    static int n_toys = 0;

    // legend for printouts
    std::string legend = "[Tprime::GetPseudoData()]: ";

    delete data;

    // We will use ToyMCSampler to generate pseudo-data (and test statistic, eventually)
    // We are responsible for randomizing nuisances and global observables,
    // ToyMCSampler only generates observables (as of ROOT 5.30.00-rc1 and before)

    // MC sampler and test statistic
    if(n_toys == 0) { // on first entry
        // get B model config from workspace
        RooStats::ModelConfig * pBModel = (RooStats::ModelConfig *)pWs->obj("BModel");
        pBModel->SetWorkspace(*pWs);

        // get parameter of interest set
        //const RooArgSet * poi = pSbModel->GetParametersOfInterest();

        //RooStats::TestStatistic * pTestStatistic = new RooStats::ProfileLikelihoodTestStat(*pBModel->GetPdf());
        //RooStats::ToyMCSampler toymcs(*pTestStatistic, 1);
        pTestStatistic = new RooStats::ProfileLikelihoodTestStat(*pBModel->GetPdf());
        pToyMcSampler = new RooStats::ToyMCSampler(*pTestStatistic, 1);
        pToyMcSampler->SetPdf(*pBModel->GetPdf());
        pToyMcSampler->SetObservables(*pBModel->GetObservables());
        pToyMcSampler->SetParametersForTestStat(*pBModel->GetParametersOfInterest()); // just POI
        pToyMcSampler->SetGlobalObservables(*pBModel->GetGlobalObservables());
    }

    // load parameter point
    pWs->loadSnapshot("parametersToGenerateData");

    RooArgSet dummySet;
    data = pToyMcSampler->GenerateToyData(dummySet);
    std::cout << legend << "generated the following background-only pseudo-data:" << std::endl;
    data->Print();

    // count number of generated toys
    ++n_toys;

    return data;
}
예제 #12
0
void JetTagBin::plotOn( RooPlot * frame )
{
  if ( verbose ) cout << "Plotting data and combined pdf" << endl;
  jtData_->plotOn(frame);
  jtPdf_ ->plotOn(frame);
  vector<Template*>::iterator i = jtTemplates_.begin(), iend = jtTemplates_.end();
  int color=1;
  for ( ; i != iend ; ++i ) {
    color++;
    if (color == 5) color++;  // only dead yellow is good yellow
    if ( verbose ) cout << "Plotting component " << (*i)->epdf()->GetName()
                        << " with color " << color << endl;
    jtPdf_->plotOn(frame,Components((*i)->epdf()->GetName()),LineColor(color));
  }                                                               
}
예제 #13
0
파일: dimuon.C 프로젝트: neumeist/twobody
Int_t TwoBody::AddWorkspace(std::string filename,
			    std::string ws_name,
			    std::string channel_name,
			    std::string shared_vars){
  //
  // Load a single channel model and data from a workspace
  //

  std::string _legend = "[TwoBody::AddWorkspace]: ";

   // load workspace from a file
  TFile _file(filename.c_str(), "read");
  RooWorkspace * _ws = (RooWorkspace *)_file.Get( ws_name.c_str() );

  // get the single channel model PDF
  RooAbsPdf * _model = _ws->pdf("model"),
            * _prior = _ws->pdf("prior");

  // import the channel model PDF into the combined workspace
  // add prefix channel_name to all nodes except shared_vars
  ws->import( RooArgSet(*_model,*_prior),
     	      RooFit::RenameAllNodes( channel_name.c_str() ),
    	      RooFit::RenameAllVariablesExcept(channel_name.c_str(), shared_vars.c_str()) );
  delete data; 
  data = new RooDataSet( *(RooDataSet *) _ws->data("data") );
  data->changeObservableName("vertex_m","mass");

  //realdata = new RooDataSet( *(RooDataSet *) data );
  //new RooDataSet( *(RooDataSet *) ws->data("data") );
  //realdata->SetName("RealData");
  //realdata->changeObservableName("vertex_m","mass");

  ws->import( *data );

  ws->Print();
  //  for (int i=0; i!=100; ++i){
  //  RooRealVar * _var = (RooRealVar *)(data->get(i)->first());
  //  cerr<<_var->getVal()<<",";
  //}
  _file.Close();

  return 0;
}
예제 #14
0
double getChisq(RooAbsData &dat, RooAbsPdf &pdf, RooRealVar &var, bool prt=false) {

    // Find total number of events
    double nEvt;
    double nTot=0.0;

    for(int j=0; j<dat.numEntries(); j++) {
        dat.get(j);
        nEvt=dat.weight();
        nTot+=nEvt;
    }

    // Find chi-squared equivalent 2NLL
    //RooRealVar *var=(RooRealVar*)(pdf.getParameters(*dat)->find("CMS_hgg_mass"));
    double totNLL=0.0;
    double prbSum=0.0;

    for(int j=0; j<dat.numEntries(); j++) {
        double m=dat.get(j)->getRealValue(var.GetName());
        if ( m < var.getMin() || m > var.getMax())  continue;
        // Find probability density and hence probability
        var.setVal(m);
        double prb = var.getBinWidth(0)*pdf.getVal(var);
        prbSum+=prb;

        dat.get(j);
        nEvt=dat.weight();

        double mubin=nTot*prb;
        double contrib(0.);
        if (nEvt < 1) contrib = mubin;
        else contrib=mubin-nEvt+nEvt*log(nEvt/mubin);
        totNLL+=contrib;

        if(prt) cout << "Bin " << j << " prob = " << prb << " nEvt = " << nEvt << ", mu = " << mubin << " contribution " << contrib << endl;
    }

    totNLL*=2.0;
    if(prt) cout << pdf.GetName() << " nTot = " << nTot << " 2NLL constant = " << totNLL << endl;

    return totNLL;
}
예제 #15
0
void draw_data_mgg(TString folderName,bool blind=true,float min=103,float max=160)
{
  TFile inputFile(folderName+"/data.root");
  
  const int nCat = 5;
  TString cats[5] = {"HighPt","Hbb","Zbb","HighRes","LowRes"};

  TCanvas cv;

  for(int iCat=0; iCat < nCat; iCat++) {

    RooWorkspace *ws  = (RooWorkspace*)inputFile.Get(cats[iCat]+"_mgg_workspace");
    RooFitResult* res = (RooFitResult*)ws->obj("fitresult_pdf_data");

    RooRealVar * mass = ws->var("mgg");
    mass->setRange("all",min,max);
    mass->setRange("blind",121,130);
    mass->setRange("low",106,121);
    mass->setRange("high",130,160);

    mass->setUnit("GeV");
    mass->SetTitle("m_{#gamma#gamma}");
    
    RooAbsPdf * pdf = ws->pdf("pdf");
    RooPlot *plot = mass->frame(min,max,max-min);
    plot->SetTitle("");
    
    RooAbsData* data = ws->data("data")->reduce(Form("mgg > %f && mgg < %f",min,max));
    double nTot = data->sumEntries();
    if(blind) data = data->reduce("mgg < 121 || mgg>130");
    double nBlind = data->sumEntries();
    double norm = nTot/nBlind; //normalization for the plot
    
    data->plotOn(plot);
    pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::Range("Full"),RooFit::LineWidth(0.1) );
    plot->Print();

    //add the fix error band
    RooCurve* c = plot->getCurve("pdf_Norm[mgg]_Range[Full]_NormRange[Full]");
    const int Nc = c->GetN();
    //TGraphErrors errfix(Nc);
    //TGraphErrors errfix2(Nc);
    TGraphAsymmErrors errfix(Nc);
    TGraphAsymmErrors errfix2(Nc);
    Double_t *x = c->GetX();
    Double_t *y = c->GetY();
    double NtotalFit = ws->var("Nbkg1")->getVal()*ws->var("Nbkg1")->getVal() + ws->var("Nbkg2")->getVal()*ws->var("Nbkg2")->getVal();
    for( int i = 0; i < Nc; i++ )
      {
	errfix.SetPoint(i,x[i],y[i]);
	errfix2.SetPoint(i,x[i],y[i]);
	mass->setVal(x[i]);      
	double shapeErr = pdf->getPropagatedError(*res)*NtotalFit;
	//double totalErr = TMath::Sqrt( shapeErr*shapeErr + y[i] );
	//total normalization error
	double totalErr = TMath::Sqrt( shapeErr*shapeErr + y[i]*y[i]/NtotalFit ); 
	if ( y[i] - totalErr > .0 )
	  {
	    errfix.SetPointError(i, 0, 0, totalErr, totalErr );
	  }
	else
	  {
	    errfix.SetPointError(i, 0, 0, y[i] - 0.01, totalErr );
	  }
	//2sigma
	if ( y[i] -  2.*totalErr > .0 )
	  {
	    errfix2.SetPointError(i, 0, 0, 2.*totalErr,  2.*totalErr );
	  }
	else
	  {
	    errfix2.SetPointError(i, 0, 0, y[i] - 0.01,  2.*totalErr );
	  }
	/*
	std::cout << x[i] << " " << y[i] << " "
		  << " ,pdf get Val: " << pdf->getVal()
		  << " ,pdf get Prop Err: " << pdf->getPropagatedError(*res)*NtotalFit
		  << " stat uncertainty: " << TMath::Sqrt(y[i]) << " Ntot: " << NtotalFit <<  std::endl;
	*/
      }
    errfix.SetFillColor(kYellow);
    errfix2.SetFillColor(kGreen);


    //pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::FillColor(kGreen),RooFit::Range("Full"), RooFit::VisualizeError(*res,2.0,kFALSE));
    //pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::FillColor(kYellow),RooFit::Range("Full"), RooFit::VisualizeError(*res,1.0,kFALSE));
    //pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::FillColor(kGreen),RooFit::Range("Full"), RooFit::VisualizeError(*res,2.0,kTRUE));
    //pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::FillColor(kYellow),RooFit::Range("Full"), RooFit::VisualizeError(*res,1.0,kTRUE));
    plot->addObject(&errfix,"4");
    plot->addObject(&errfix2,"4");
    plot->addObject(&errfix,"4");
    data->plotOn(plot);
    TBox blindBox(121,plot->GetMinimum()-(plot->GetMaximum()-plot->GetMinimum())*0.015,130,plot->GetMaximum());
    blindBox.SetFillColor(kGray);
    if(blind) {
      plot->addObject(&blindBox);
      pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::FillColor(kGreen),RooFit::Range("Full"), RooFit::VisualizeError(*res,2.0,kTRUE));
      pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::FillColor(kYellow),RooFit::Range("Full"), RooFit::VisualizeError(*res,1.0,kTRUE));
    }
    //plot->addObject(&errfix,"4");
    //data->plotOn(plot);

    //pdf->plotOn(plot,RooFit::Normalization( norm ) );
    //pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::Range("Full"),RooFit::LineWidth(1.5) );
    pdf->plotOn(plot,RooFit::NormRange( "low,high" ),RooFit::Range("Full"), RooFit::LineWidth(1));
    data->plotOn(plot);
    /*
    pdf->plotOn(plot,RooFit::Normalization(norm),RooFit::Range("all"),RooFit::LineWidth(0.8) );
    //pdf->plotOn(plot,RooFit::Normalization(norm),RooFit::FillColor(kGreen),RooFit::Range("all"), RooFit::VisualizeError(*res,2.0,kFALSE));
    //pdf->plotOn(plot,RooFit::Normalization(norm),RooFit::FillColor(kYellow),RooFit::Range("all"), RooFit::VisualizeError(*res,1.0,kFALSE));
    pdf->plotOn(plot,RooFit::Normalization(norm),RooFit::FillColor(kGreen),RooFit::Range("all"), RooFit::VisualizeError(*res,2.0,kTRUE));
    pdf->plotOn(plot,RooFit::Normalization(norm),RooFit::FillColor(kYellow),RooFit::Range("all"), RooFit::VisualizeError(*res,1.0,kTRUE));
    data->plotOn(plot);
    pdf->plotOn(plot,RooFit::Normalization(norm),RooFit::Range("all"),RooFit::LineWidth(0.8) );
    */
    TLatex lbl0(0.1,0.96,"CMS Preliminary");
    lbl0.SetNDC();
    lbl0.SetTextSize(0.042);
    plot->addObject(&lbl0);
    
    TLatex lbl(0.4,0.96,Form("%s Box",cats[iCat].Data()));
    lbl.SetNDC();
    lbl.SetTextSize(0.042);
    plot->addObject(&lbl);

    TLatex lbl2(0.6,0.96,"#sqrt{s}=8 TeV  L = 19.78 fb^{-1}");
    lbl2.SetNDC();
    lbl2.SetTextSize(0.042);
    plot->addObject(&lbl2);


    int iObj=-1;
    TNamed *obj;
    while( (obj = (TNamed*)plot->getObject(++iObj)) ) {
      obj->SetName(Form("Object_%d",iObj));
    }

    plot->Draw();
    TString tag = (blind ? "_BLIND" : "");
    cv.SaveAs(folderName+"/figs/mgg_data_"+cats[iCat]+tag+TString(Form("_%0.0f_%0.0f",min,max))+".png");
    cv.SaveAs(folderName+"/figs/mgg_data_"+cats[iCat]+tag+TString(Form("_%0.0f_%0.0f",min,max))+".pdf");
    cv.SaveAs(folderName+"/figs/mgg_data_"+cats[iCat]+tag+TString(Form("_%0.0f_%0.0f",min,max))+".C");
      
  }
  
}
예제 #16
0
//put very small data entries in a binned dataset to avoid unphysical pdfs, specifically for H->ZZ->4l
RooDataSet* makeData(RooDataSet* orig, RooSimultaneous* simPdf, const RooArgSet* observables, RooRealVar* firstPOI, double mass, double& mu_min)
{

  double max_soverb = 0;

  mu_min = -10e9;

  map<string, RooDataSet*> data_map;
  firstPOI->setVal(0);
  RooCategory* cat = (RooCategory*)&simPdf->indexCat();
  TList* datalist = orig->split(*(RooAbsCategory*)cat, true);
  TIterator* dataItr = datalist->MakeIterator();
  RooAbsData* ds;
  RooRealVar* weightVar = new RooRealVar("weightVar","weightVar",1);
  while ((ds = (RooAbsData*)dataItr->Next()))
  {
    string typeName(ds->GetName());
    cat->setLabel(typeName.c_str());
    RooAbsPdf* pdf = simPdf->getPdf(typeName.c_str());
    cout << "pdf: " << pdf << endl;
    RooArgSet* obs = pdf->getObservables(observables);
    cout << "obs: " << obs << endl;

    RooArgSet obsAndWeight(*obs, *weightVar);
    obsAndWeight.add(*cat);
    stringstream datasetName;
    datasetName << "newData_" << typeName;
    RooDataSet* thisData = new RooDataSet(datasetName.str().c_str(),datasetName.str().c_str(), obsAndWeight, WeightVar(*weightVar));

    RooRealVar* firstObs = (RooRealVar*)obs->first();
    //int ibin = 0;
    int nrEntries = ds->numEntries();
    for (int ib=0;ib<nrEntries;ib++)
    {
      const RooArgSet* event = ds->get(ib);
      const RooRealVar* thisObs = (RooRealVar*)event->find(firstObs->GetName());
      firstObs->setVal(thisObs->getVal());

      firstPOI->setVal(0);
      double b = pdf->expectedEvents(*firstObs)*pdf->getVal(obs);
      firstPOI->setVal(1);
      double s = pdf->expectedEvents(*firstObs)*pdf->getVal(obs) - b;

      if (s > 0)
      {
	mu_min = max(mu_min, -b/s);
	double soverb = s/b;
	if (soverb > max_soverb)
	{
	  max_soverb = soverb;
	  cout << "Found new max s/b: " << soverb << " in pdf " << pdf->GetName() << " at m = " << thisObs->getVal() << endl;
	}
      }

      if (b == 0 && s != 0)
      {
	cout << "Expecting non-zero signal and zero bg at m=" << firstObs->getVal() << " in pdf " << pdf->GetName() << endl;
      }
      if (s+b <= 0) 
      {
	cout << "expecting zero" << endl;
	continue;
      }


      double weight = ds->weight();
      if ((typeName.find("ATLAS_H_4mu") != string::npos || 
	   typeName.find("ATLAS_H_4e") != string::npos ||
	   typeName.find("ATLAS_H_2mu2e") != string::npos ||
	   typeName.find("ATLAS_H_2e2mu") != string::npos) && fabs(firstObs->getVal() - mass) < 10 && weight == 0)
      {
	cout << "adding event: " << firstObs->getVal() << endl;
	thisData->add(*event, pow(10., -9.));
      }
      else
      {
	//weight = max(pow(10.0, -9), weight);
	thisData->add(*event, weight);
      }
    }



    data_map[string(ds->GetName())] = (RooDataSet*)thisData;
  }

  
  RooDataSet* newData = new RooDataSet("newData","newData",RooArgSet(*observables, *weightVar), 
				       Index(*cat), Import(data_map), WeightVar(*weightVar));

  orig->Print();
  newData->Print();
  //newData->tree()->Scan("*");
  return newData;

}
void 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;

}
예제 #18
0
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();

}
예제 #19
0
void Raa3S_Workspace(const char* name_pbpb="chad_ws_fits/centFits/ws_PbPbData_262548_263757_0cent10_0.0pt50.0_0.0y2.4.root", const char* name_pp="chad_ws_fits/centFits/ws_PPData_262157_262328_-1cent1_0.0pt50.0_0.0y2.4.root", const char* name_out="fitresult_combo.root"){

   //TFile File(filename);

   //RooWorkspace * ws = test_combine(name_pbpb, name_pp);

   TFile *f = new TFile("fitresult_combo_333.root") ;
   RooWorkspace * ws1 = (RooWorkspace*) f->Get("wcombo");

   //File.GetObject("wcombo", ws);
   ws1->Print();
   RooAbsData * data = ws1->data("data"); //dataOS, dataSS

   // RooDataSet * US_data = (RooDataSet*) data->reduce( "QQsign == QQsign::PlusMinus");
   // US_data->SetName("US_data");
   // ws->import(* US_data);
   // RooDataSet * hi_data = (RooDataSet*) US_data->reduce("dataCat == dataCat::hi");
   // hi_data->SetName("hi_data");
   // ws->import(* hi_data);
   // hi_data->Print();

   RooRealVar* raa3 = new RooRealVar("raa3","R_{AA}(#Upsilon (3S))",0.5,-1,1);
   RooRealVar* leftEdge = new RooRealVar("leftEdge","leftEdge",0);
   RooRealVar* rightEdge = new RooRealVar("rightEdge","rightEdge",1);
   RooGenericPdf step("step", "step", "(@0 >= @1) && (@0 < @2)", RooArgList(*raa3, *leftEdge, *rightEdge));
   ws1->import(step);
   ws1->factory( "Uniform::flat(raa3)" );

   //pp Luminosities, Taa and efficiency ratios Systematics

   ws1->factory( "Taa_hi[5.662e-9]" );
   ws1->factory( "Taa_kappa[1.062]" ); // was 1.057
   ws1->factory( "expr::alpha_Taa('pow(Taa_kappa,beta_Taa)',Taa_kappa,beta_Taa[0,-5,5])" );
   ws1->factory( "prod::Taa_nom(Taa_hi,alpha_Taa)" );
   ws1->factory( "Gaussian::constr_Taa(beta_Taa,glob_Taa[0,-5,5],1)" );

   ws1->factory( "lumipp_hi[5.4]" );
   ws1->factory( "lumipp_kappa[1.037]" ); // was 1.06
   ws1->factory( "expr::alpha_lumipp('pow(lumipp_kappa,beta_lumipp)',lumipp_kappa,beta_lumipp[0,-5,5])" );
   ws1->factory( "prod::lumipp_nom(lumipp_hi,alpha_lumipp)" );
   ws1->factory( "Gaussian::constr_lumipp(beta_lumipp,glob_lumipp[0,-5,5],1)" );

   // ws->factory( "effRat1[1]" );
   // ws->factory( "effRat2[1]" );
   ws1->factory( "effRat3_hi[0.95]" );
   ws1->factory( "effRat_kappa[1.054]" );
   ws1->factory( "expr::alpha_effRat('pow(effRat_kappa,beta_effRat)',effRat_kappa,beta_effRat[0,-5,5])" );
   // ws->factory( "prod::effRat1_nom(effRat1_hi,alpha_effRat)" );
   ws1->factory( "Gaussian::constr_effRat(beta_effRat,glob_effRat[0,-5,5],1)" );
   // ws->factory( "prod::effRat2_nom(effRat2_hi,alpha_effRat)" );
   ws1->factory( "prod::effRat3_nom(effRat3_hi,alpha_effRat)" );
   //  
   ws1->factory("Nmb_hi[1.161e9]");
   ws1->factory("prod::denominator(Taa_nom,Nmb_hi)");
   ws1->factory( "expr::lumiOverTaaNmbmodified('lumipp_nom/denominator',lumipp_nom,denominator)");
   RooAbsReal *lumiOverTaaNmbmodified = ws1->function("lumiOverTaaNmbmodified"); //RooFormulaVar *lumiOverTaaNmbmodified = ws->function("lumiOverTaaNmbmodified");
   //  
   //  RooRealVar *raa1 = ws->var("raa1");
   //  RooRealVar* nsig1_pp = ws->var("nsig1_pp");
   //  RooRealVar* effRat1 = ws->function("effRat1_nom");
   //  RooRealVar *raa2 = ws->var("raa2");
   //  RooRealVar* nsig2_pp = ws->var("nsig2_pp");
   //  RooRealVar* effRat2 = ws->function("effRat2_nom");
   RooRealVar* nsig3_pp = ws1->var("R_{#frac{3S}{1S}}_pp"); //RooRealVar* nsig3_pp = ws->var("N_{#Upsilon(3S)}_pp");
   cout << nsig3_pp << endl;
   RooAbsReal* effRat3 = ws1->function("effRat3_nom"); //RooRealVar* effRat3 = ws->function("effRat3_nom");
   //  
   //  RooFormulaVar nsig1_hi_modified("nsig1_hi_modified", "@0*@1*@3/@2", RooArgList(*raa1, *nsig1_pp, *lumiOverTaaNmbmodified, *effRat1));
   //  ws->import(nsig1_hi_modified);
   //  RooFormulaVar nsig2_hi_modified("nsig2_hi_modified", "@0*@1*@3/@2", RooArgList(*raa2, *nsig2_pp, *lumiOverTaaNmbmodified, *effRat2));
   //  ws->import(nsig2_hi_modified);
   RooFormulaVar nsig3_hi_modified("nsig3_hi_modified", "@0*@1*@3/@2", RooArgList(*raa3, *nsig3_pp, *lumiOverTaaNmbmodified, *effRat3));
   ws1->import(nsig3_hi_modified);

   //  // background yield with systematics
   ws1->factory( "nbkg_hi_kappa[1.10]" );
   ws1->factory( "expr::alpha_nbkg_hi('pow(nbkg_hi_kappa,beta_nbkg_hi)',nbkg_hi_kappa,beta_nbkg_hi[0,-5,5])" );
   ws1->factory( "SUM::nbkg_hi_nom(alpha_nbkg_hi*bkgPdf_hi)" );
   ws1->factory( "Gaussian::constr_nbkg_hi(beta_nbkg_hi,glob_nbkg_hi[0,-5,5],1)" );
   RooAbsPdf* sig1S_hi = ws1->pdf("sig1S_hi"); //RooAbsPdf* sig1S_hi = ws->pdf("cbcb_hi");
   RooAbsPdf* sig2S_hi = ws1->pdf("sig2S_hi");
   RooAbsPdf* sig3S_hi = ws1->pdf("sig3S_hi");
   RooAbsPdf* LSBackground_hi = ws1->pdf("nbkg_hi_nom");
   RooRealVar* nsig1_hi = ws1->var("N_{#Upsilon(1S)}_hi");
   RooRealVar* nsig2_hi = ws1->var("R_{#frac{2S}{1S}}_hi");
   RooAbsReal* nsig3_hi = ws1->function("nsig3_hi_modified"); //RooFormulaVar* nsig3_hi = ws->function("nsig3_hi_modified");
   cout << nsig1_hi << " " << nsig2_hi << " " << nsig3_pp << endl;
   RooRealVar* norm_nbkg_hi = ws1->var("n_{Bkgd}_hi");

   RooArgList pdfs_hi( *sig1S_hi,*sig2S_hi,*sig3S_hi, *LSBackground_hi);
   RooArgList norms_hi(*nsig1_hi,*nsig2_hi,*nsig3_hi, *norm_nbkg_hi);

   ////////////////////////////////////////////////////////////////////////////////

   ws1->factory( "nbkg_pp_kappa[1.03]" );
   ws1->factory( "expr::alpha_nbkg_pp('pow(nbkg_pp_kappa,beta_nbkg_pp)',nbkg_pp_kappa,beta_nbkg_pp[0,-5,5])" );
   ws1->factory( "SUM::nbkg_pp_nom(alpha_nbkg_pp*bkgPdf_pp)" );
   ws1->factory( "Gaussian::constr_nbkg_pp(beta_nbkg_pp,glob_nbkg_pp[0,-5,5],1)" );
   RooAbsPdf* sig1S_pp = ws1->pdf("sig1S_pp"); //RooAbsPdf* sig1S_pp = ws1->pdf("cbcb_pp");
   RooAbsPdf* sig2S_pp = ws1->pdf("sig2S_pp");
   RooAbsPdf* sig3S_pp = ws1->pdf("sig3S_pp");
   RooAbsPdf* LSBackground_pp = ws1->pdf("nbkg_pp_nom");
   RooRealVar* nsig1_pp = ws1->var("N_{#Upsilon(1S)}_pp");
   RooRealVar* nsig2_pp = ws1->var("R_{#frac{2S}{1S}}_pp"); //RooRealVar* nsig2_pp = ws1->var("N_{#Upsilon(2S)}_pp");
   // RooRealVar* nsig3_pp = ws1->var("N_{#Upsilon(3S)}_pp");
   RooRealVar* norm_nbkg_pp = ws1->var("n_{Bkgd}_pp");

   RooArgList pdfs_pp( *sig1S_pp,*sig2S_pp,*sig3S_pp, *LSBackground_pp);
   RooArgList norms_pp( *nsig1_pp,*nsig2_pp,*nsig3_pp,*norm_nbkg_pp);

   RooAddPdf model_num("model_num", "model_num", pdfs_hi,norms_hi); 
   ws1->import(model_num);
   ws1->factory("PROD::model_hi(model_num, constr_nbkg_hi,constr_lumipp,constr_Taa,constr_effRat)");

   RooAddPdf model_den("model_den", "model_den", pdfs_pp,norms_pp); 
   ws1->import(model_den);
   ws1->factory("PROD::model_pp(model_den, constr_nbkg_pp)");

   ws1->factory("SIMUL::joint(dataCat,hi=model_hi,pp=model_pp)");



   /////////////////////////////////////////////////////////////////////
   RooRealVar * pObs = ws1->var("invariantMass"); // get the pointer to the observable
   RooArgSet obs("observables");
   obs.add(*pObs);
   obs.add( *ws1->cat("dataCat"));    
   //  /////////////////////////////////////////////////////////////////////
   ws1->var("glob_lumipp")->setConstant(true);
   ws1->var("glob_Taa")->setConstant(true);
   ws1->var("glob_effRat")->setConstant(true);
   ws1->var("glob_nbkg_pp")->setConstant(true);
   ws1->var("glob_nbkg_hi")->setConstant(true);
   RooArgSet globalObs("global_obs");
   globalObs.add( *ws1->var("glob_lumipp") );
   globalObs.add( *ws1->var("glob_Taa") );
   globalObs.add( *ws1->var("glob_effRat") );
   globalObs.add( *ws1->var("glob_nbkg_hi") );
   globalObs.add( *ws1->var("glob_nbkg_pp") );
   cout << "66666" << endl;

   // ws1->Print();

   RooArgSet poi("poi");
   poi.add( *ws1->var("raa3") );



   cout << "77777" << endl;
   // create set of nuisance parameters
   RooArgSet nuis("nuis");
   nuis.add( *ws1->var("beta_lumipp") );
   nuis.add( *ws1->var("beta_nbkg_hi") );
   nuis.add( *ws1->var("beta_nbkg_pp") );
   nuis.add( *ws1->var("beta_Taa") );
   nuis.add( *ws1->var("beta_effRat") );

   cout << "88888" << endl;
   ws1->var("#alpha_{CB}_hi")->setConstant(true);
   ws1->var("#alpha_{CB}_pp")->setConstant(true);
   ws1->var("#sigma_{CB1}_hi")->setConstant(true);
   ws1->var("#sigma_{CB1}_pp")->setConstant(true);
   ws1->var("#sigma_{CB2}/#sigma_{CB1}_hi")->setConstant(true);
   ws1->var("#sigma_{CB2}/#sigma_{CB1}_pp")->setConstant(true);
   //ws1->var("Centrality")->setConstant(true); //delete
   ws1->var("N_{#varUpsilon(1S)}_hi")->setConstant(true);
   ws1->var("N_{#varUpsilon(1S)}_pp")->setConstant(true);
   //ws1->var("N_{#Upsilon(2S)}_hi")->setConstant(true);
   //ws1->var("N_{#Upsilon(2S)}_pp")->setConstant(true);
   //ws1->var("N_{#Upsilon(3S)}_pp")->setConstant(true);

   ws1->var("R_{#frac{2S}{1S}}_hi")->setConstant(true); //new
   ws1->var("R_{#frac{2S}{1S}}_pp")->setConstant(true); //new
   ws1->var("R_{#frac{3S}{1S}}_hi")->setConstant(true); //new
   ws1->var("R_{#frac{3S}{1S}}_pp")->setConstant(true); //new

   ws1->var("Nmb_hi")->setConstant(true);
   // ws1->var("QQsign")->setConstant(true);
   ws1->var("Taa_hi")->setConstant(true);
   ws1->var("Taa_kappa")->setConstant(true);
   // ws1->var("beta_Taa")->setConstant(true);
   // ws1->var("beta_effRat")->setConstant(true);
   // ws1->var("beta_lumipp")->setConstant(true);
   // ws1->var("beta_nbkg_hi")->setConstant(true);
   // ws1->var("beta_nbkg_pp")->setConstant(true);
   // ws1->var("dataCat")->setConstant(true);
   ws1->var("decay_hi")->setConstant(true);
   ws1->var("decay_pp")->setConstant(true);
   ws1->var("effRat3_hi")->setConstant(true);
   ws1->var("effRat_kappa")->setConstant(true);
   // ws1->var("glob_Taa")->setConstant(true);
   // ws1->var("glob_effRat")->setConstant(true);
   // ws1->var("glob_lumipp")->setConstant(true);
   // ws1->var("glob_nbkg_hi")->setConstant(true);
   // ws1->var("glob_nbkg_pp")->setConstant(true);
   // ws1->var("invariantMass")->setConstant(true);
   ws1->var("leftEdge")->setConstant(true);
   ws1->var("lumipp_hi")->setConstant(true);
   ws1->var("lumipp_kappa")->setConstant(true);
   ws1->var("m_{ #varUpsilon(1S)}_hi")->setConstant(true); //ws1->var("mass1S_hi")->setConstant(true);
   ws1->var("m_{ #varUpsilon(1S)}_pp")->setConstant(true); //ws1->var("mass1S_pp")->setConstant(true);
   ws1->var("muMinusPt")->setConstant(true);
   ws1->var("muPlusPt")->setConstant(true);
   ws1->var("n_{Bkgd}_hi")->setConstant(true);
   ws1->var("n_{Bkgd}_pp")->setConstant(true);
   ws1->var("nbkg_hi_kappa")->setConstant(true);
   ws1->var("nbkg_pp_kappa")->setConstant(true);
   //ws1->var("n_{CB}")->setConstant(true); //ws1->var("n_{CB}")->setConstant(true); //ws1->var("npow")->setConstant(true);
   ws1->var("n_{CB}_hi")->setConstant(true); //ws1->var("n_{CB}")->setConstant(true); //ws1->var("npow")->setConstant(true);
   ws1->var("n_{CB}_pp")->setConstant(true); //ws1->var("n_{CB}")->setConstant(true); //ws1->var("npow")->setConstant(true);
   // ws1->var("raa3")->setConstant(true);
   ws1->var("rightEdge")->setConstant(true);
   ws1->var("sigmaFraction_hi")->setConstant(true);
   ws1->var("sigmaFraction_pp")->setConstant(true);
   ws1->var("turnOn_hi")->setConstant(true);
   ws1->var("turnOn_pp")->setConstant(true);
   ws1->var("dimuPt")->setConstant(true); //ws1->var("upsPt")->setConstant(true);
   ws1->var("dimuRapidity")->setConstant(true); //ws1->var("upsRapidity")->setConstant(true);
   ws1->var("vProb")->setConstant(true);
   ws1->var("width_hi")->setConstant(true);
   ws1->var("width_pp")->setConstant(true);
   // ws1->var("x3raw")->setConstant(true);
   //  RooArgSet fixed_again("fixed_again");
   //  fixed_again.add( *ws1->var("leftEdge") );
   //  fixed_again.add( *ws1->var("rightEdge") );
   //  fixed_again.add( *ws1->var("Taa_hi") );
   //  fixed_again.add( *ws1->var("Nmb_hi") );
   //  fixed_again.add( *ws1->var("lumipp_hi") );
   //  fixed_again.add( *ws1->var("effRat1_hi") );
   //  fixed_again.add( *ws1->var("effRat2_hi") );
   //  fixed_again.add( *ws1->var("effRat3_hi") );
   //  fixed_again.add( *ws1->var("nsig3_pp") );
   //  fixed_again.add( *ws1->var("nsig1_pp") );
   //  fixed_again.add( *ws1->var("nbkg_hi") );
   //  fixed_again.add( *ws1->var("alpha") );
   //  fixed_again.add( *ws1->var("nbkg_kappa") );
   //  fixed_again.add( *ws1->var("Taa_kappa") );
   //  fixed_again.add( *ws1->var("lumipp_kappa") );
   // fixed_again.add( *ws1->var("mean_hi") );
   // fixed_again.add( *ws1->var("mean_pp") );
   // fixed_again.add( *ws1->var("width_hi") );
   // fixed_again.add( *ws1->var("turnOn_hi") );
   // fixed_again.add( *ws1->var("bkg_a1_pp") );
   // fixed_again.add( *ws1->var("bkg_a2_pp") );
   // fixed_again.add( *ws1->var("decay_hi") );
   // fixed_again.add( *ws1->var("raa1") );
   // fixed_again.add( *ws1->var("raa2") );
   //  fixed_again.add( *ws1->var("nsig2_pp") );
   // fixed_again.add( *ws1->var("sigma1") );
   //  fixed_again.add( *ws1->var("nbkg_pp") );
   // fixed_again.add( *ws1->var("npow") );
   // fixed_again.add( *ws1->var("muPlusPt") );
   // fixed_again.add( *ws1->var("muMinusPt") );
   // fixed_again.add( *ws1->var("mscale_hi") );
   // fixed_again.add( *ws1->var("mscale_pp") );
   //  
   // ws1->Print();
   cout << "99999" << endl;

   // create signal+background Model Config
   RooStats::ModelConfig sbHypo("SbHypo");
   sbHypo.SetWorkspace( *ws1 );
   sbHypo.SetPdf( *ws1->pdf("joint") );
   sbHypo.SetObservables( obs );
   sbHypo.SetGlobalObservables( globalObs );
   sbHypo.SetParametersOfInterest( poi );
   sbHypo.SetNuisanceParameters( nuis );
   sbHypo.SetPriorPdf( *ws1->pdf("step") ); // this is optional

   // ws1->Print();
   /////////////////////////////////////////////////////////////////////
   RooAbsReal * pNll = sbHypo.GetPdf()->createNLL( *data,NumCPU(10) );
   cout << "111111" << endl;
   RooMinuit(*pNll).migrad(); // minimize likelihood wrt all parameters before making plots
   cout << "444444" << endl;
   RooPlot *framepoi = ((RooRealVar *)poi.first())->frame(Bins(10),Range(0.,0.2),Title("LL and profileLL in raa3"));
   cout << "222222" << endl;
   pNll->plotOn(framepoi,ShiftToZero());
   cout << "333333" << endl;
   
   RooAbsReal * pProfile = pNll->createProfile( globalObs ); // do not profile global observables
   pProfile->getVal(); // this will do fit and set POI and nuisance parameters to fitted values
   pProfile->plotOn(framepoi,LineColor(kRed));
   framepoi->SetMinimum(0);
   framepoi->SetMaximum(3);
   TCanvas *cpoi = new TCanvas();
   cpoi->cd(); framepoi->Draw();
   cpoi->SaveAs("cpoi.pdf");

   ((RooRealVar *)poi.first())->setMin(0.);
   RooArgSet * pPoiAndNuisance = new RooArgSet("poiAndNuisance");
   // pPoiAndNuisance->add(*sbHypo.GetNuisanceParameters());
   // pPoiAndNuisance->add(*sbHypo.GetParametersOfInterest());
   pPoiAndNuisance->add( nuis );
   pPoiAndNuisance->add( poi );
   sbHypo.SetSnapshot(*pPoiAndNuisance);

   RooPlot* xframeSB = pObs->frame(Title("SBhypo"));
   data->plotOn(xframeSB,Cut("dataCat==dataCat::hi"));
   RooAbsPdf *pdfSB = sbHypo.GetPdf();
   RooCategory *dataCat = ws1->cat("dataCat");
   pdfSB->plotOn(xframeSB,Slice(*dataCat,"hi"),ProjWData(*dataCat,*data));
   TCanvas *c1 = new TCanvas();
   c1->cd(); xframeSB->Draw();
   c1->SaveAs("c1.pdf");

   delete pProfile;
   delete pNll;
   delete pPoiAndNuisance;
   ws1->import( sbHypo );
   /////////////////////////////////////////////////////////////////////
   RooStats::ModelConfig bHypo = sbHypo;
   bHypo.SetName("BHypo");
   bHypo.SetWorkspace(*ws1);
   pNll = bHypo.GetPdf()->createNLL( *data,NumCPU(2) );
   RooArgSet poiAndGlobalObs("poiAndGlobalObs");
   poiAndGlobalObs.add( poi );
   poiAndGlobalObs.add( globalObs );
   pProfile = pNll->createProfile( poiAndGlobalObs ); // do not profile POI and global observables
   ((RooRealVar *)poi.first())->setVal( 0 );  // set raa3=0 here
   pProfile->getVal(); // this will do fit and set nuisance parameters to profiled values
   pPoiAndNuisance = new RooArgSet( "poiAndNuisance" );
   pPoiAndNuisance->add( nuis );
   pPoiAndNuisance->add( poi );
   bHypo.SetSnapshot(*pPoiAndNuisance);

   RooPlot* xframeB = pObs->frame(Title("Bhypo"));
   data->plotOn(xframeB,Cut("dataCat==dataCat::hi"));
   RooAbsPdf *pdfB = bHypo.GetPdf();
   pdfB->plotOn(xframeB,Slice(*dataCat,"hi"),ProjWData(*dataCat,*data));
   TCanvas *c2 = new TCanvas();
   c2->cd(); xframeB->Draw();
   c2->SaveAs("c2.pdf");

   delete pProfile;
   delete pNll;
   delete pPoiAndNuisance;

   // import model config into workspace
   bHypo.SetWorkspace(*ws1);
   ws1->import( bHypo );
   /////////////////////////////////////////////////////////////////////
   ws1->Print();
   bHypo.Print();
   sbHypo.Print();

   // save workspace to file
   ws1 -> SaveAs(name_out);

   return;
}
예제 #20
0
void combinedWorkspace_4WS(const char* name_pbpb_pass="******", const char* name_pbpb_fail="fitresult_pbpb_fail.root", const char* name_pp_pass="******", const char* name_pp_fail="fitresult_pp_fail.root", const char* name_out="fitresult_combo.root", const float systval = 0., const char* subDirName ="wsTest", int nCPU=2){
   // subdir: Directory to save workspaces under currentPATH/CombinedWorkspaces/subDir/

   // set things silent
   gErrorIgnoreLevel=kError;
   RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);
  
   bool dosyst = (systval > 0.);

   TString nameOut(name_out);
  
   RooWorkspace * ws = test_combine_4WS(name_pbpb_pass, name_pp_pass, name_pbpb_fail, name_pp_fail, false, nCPU);
   RooAbsData * data = ws->data("dOS_DATA");

   RooRealVar* RFrac2Svs1S_PbPbvsPP_P = ws->var("RFrac2Svs1S_PbPbvsPP_P");
   RooRealVar* leftEdge = new RooRealVar("leftEdge","leftEdge",-10);
   RooRealVar* rightEdge = new RooRealVar("rightEdge","rightEdge",10);
   RooGenericPdf step("step", "step", "(@0 >= @1) && (@0 < @2)", RooArgList(*RFrac2Svs1S_PbPbvsPP_P, *leftEdge, *rightEdge));
   ws->import(step);
   ws->factory( "Uniform::flat(RFrac2Svs1S_PbPbvsPP_P)" );

   // systematics
   if (dosyst) {
     ws->factory( Form("kappa_syst[%f]",systval) );
     ws->factory( "expr::alpha_syst('kappa_syst*beta_syst',kappa_syst,beta_syst[0,-5,5])" );
     ws->factory( "Gaussian::constr_syst(beta_syst,glob_syst[0,-5,5],1)" );
     
     // add systematics into the double ratio
     ws->factory( "expr::RFrac2Svs1S_PbPbvsPP_P_syst('@0+@1',RFrac2Svs1S_PbPbvsPP_P,alpha_syst)" );
     
     // build the pbpb pdf
     RooRealVar* effjpsi_pp_P = (RooRealVar*)ws->var("effjpsi_pp_P");
     RooRealVar* effpsip_pp_P = (RooRealVar*)ws->var("effpsip_pp_P");
     RooRealVar* effjpsi_pp_NP = (RooRealVar*)ws->var("effjpsi_pp_NP");
     Double_t Npsi2SPbPbPass = npsip_pbpb_pass_from_doubleratio_prompt(ws, RooArgList(*effjpsi_pp_P,*effpsip_pp_P,*effjpsi_pp_NP),true); // Create and import N_Psi2S_PbPb_pass_syst
     
     ws->factory( "SUM::pdfMASS_Tot_PbPb_pass_syst(N_Jpsi_PbPb_pass * pdfMASS_Jpsi_PbPb_pass, N_Psi2S_PbPb_pass_syst * pdfMASS_Psi2S_PbPb_pass, N_Bkg_PbPb_pass * pdfMASS_Bkg_PbPb_pass)" );
     ws->factory( "PROD::pdfMASS_Tot_PbPb_pass_constr(pdfMASS_Tot_PbPb_pass_syst,constr_syst)" );
     
     // build the combined pdf
     ws->factory("SIMUL::simPdf_syst_noconstr(sample,PbPb_pass=pdfMASS_Tot_PbPb_pass_syst,PbPb_fail=pdfMASS_Tot_PbPb_fail,PP_pass=pdfMASS_Tot_PP_pass,PP_fail=pdfMASS_Tot_PP_fail)");
     RooSimultaneous *simPdf = (RooSimultaneous*) ws->pdf("simPdf_syst_noconstr");
     RooGaussian *constr_syst = (RooGaussian*) ws->pdf("constr_syst");
     RooProdPdf *simPdf_constr = new RooProdPdf("simPdf_syst","simPdf_syst",RooArgSet(*simPdf,*constr_syst));
     ws->import(*simPdf_constr);
     
   } else {
      ws->factory("SIMUL::simPdf_syst(sample,PbPb_pass=pdfMASS_Tot_PbPb_pass,PbPb_fail=pdfMASS_Tot_PbPb_fail,PP_pass=pdfMASS_Tot_PP_pass,PP_fail=pdfMASS_Tot_PP_fail)");
   }

   ws->Print();

   if (dosyst) ws->var("beta_syst")->setConstant(kFALSE);


   /////////////////////////////////////////////////////////////////////
   RooRealVar * pObs = ws->var("invMass"); // get the pointer to the observable
   RooArgSet obs("observables");
   obs.add(*pObs);
   obs.add( *ws->cat("sample"));    
   //  /////////////////////////////////////////////////////////////////////

   if (dosyst) ws->var("glob_syst")->setConstant(true);
   RooArgSet globalObs("global_obs");
   if (dosyst) globalObs.add( *ws->var("glob_syst") );

   // ws->Print();

   RooArgSet poi("poi");
   poi.add( *ws->var("RFrac2Svs1S_PbPbvsPP_P") );



   // create set of nuisance parameters
   RooArgSet nuis("nuis");
   if (dosyst) nuis.add( *ws->var("beta_syst") );

   // set parameters constant
   RooArgSet allVars = ws->allVars();
   TIterator* it = allVars.createIterator();
   RooRealVar *theVar = (RooRealVar*) it->Next();
   while (theVar) {
      TString varname(theVar->GetName());
//      if (varname != "RFrac2Svs1S_PbPbvsPP"
//            && varname != "invMass"
//            && varname != "sample"
//            )
//         theVar->setConstant();
     if ( varname.Contains("f_Jpsi_PP") || varname.Contains("f_Jpsi_PbPb") ||
           varname.Contains("rSigma21_Jpsi_PP") || 
           varname.Contains("m_Jpsi_PP") || varname.Contains("m_Jpsi_PbPb") || 
           varname.Contains("sigma1_Jpsi_PP") || varname.Contains("sigma1_Jpsi_PbPb") || 
           (varname.Contains("lambda")) ||
           (varname.Contains("_fail") && !varname.Contains("RFrac2Svs1S")))
         {
           theVar->setConstant();
         }
      if (varname=="glob_syst"
            || varname=="beta_syst"
         ) {
         cout << varname << endl;
         theVar->setConstant(!dosyst);
      }
      theVar = (RooRealVar*) it->Next();
   }

   // create signal+background Model Config
   RooStats::ModelConfig sbHypo("SbHypo");
   sbHypo.SetWorkspace( *ws );
   sbHypo.SetPdf( *ws->pdf("simPdf_syst") );
   sbHypo.SetObservables( obs );
   sbHypo.SetGlobalObservables( globalObs );
   sbHypo.SetParametersOfInterest( poi );
   sbHypo.SetNuisanceParameters( nuis );
   sbHypo.SetPriorPdf( *ws->pdf("step") ); // this is optional


   /////////////////////////////////////////////////////////////////////
   RooAbsReal * pNll = sbHypo.GetPdf()->createNLL( *data,NumCPU(nCPU) );
   RooMinuit(*pNll).migrad(); // minimize likelihood wrt all parameters before making plots
  
   if (controlPlots)
   {
     RooPlot *framepoi = ((RooRealVar *)poi.first())->frame(Bins(10),Range(0.,1),Title("LL and profileLL in RFrac2Svs1S_PbPbvsPP_P"));
     pNll->plotOn(framepoi,ShiftToZero());
     framepoi->SetMinimum(0);
     framepoi->SetMaximum(10);
     TCanvas *cpoi = new TCanvas();
     cpoi->cd(); framepoi->Draw();
     cpoi->SaveAs("cpoi.pdf");
   }
  
   ((RooRealVar *)poi.first())->setMin(0.);
   RooArgSet * pPoiAndNuisance = new RooArgSet("poiAndNuisance");
   pPoiAndNuisance->add( nuis );
   pPoiAndNuisance->add( poi );
   sbHypo.SetSnapshot(*pPoiAndNuisance);
  
   if (controlPlots)
   {
     RooPlot* xframeSB_PP_pass = pObs->frame(Title("SBhypo_PP_pass"));
     data->plotOn(xframeSB_PP_pass,Cut("sample==sample::PP_pass"));
     RooAbsPdf *pdfSB_PP_pass = sbHypo.GetPdf();
     RooCategory *sample = ws->cat("sample");
     pdfSB_PP_pass->plotOn(xframeSB_PP_pass,Slice(*sample,"PP_pass"),ProjWData(*sample,*data));
     TCanvas *c1 = new TCanvas();
     c1->cd(); xframeSB_PP_pass->Draw();
     c1->SaveAs("c1.pdf");
    
     RooPlot* xframeSB_PP_fail = pObs->frame(Title("SBhypo_PP_fail"));
     data->plotOn(xframeSB_PP_fail,Cut("sample==sample::PP_fail"));
     RooAbsPdf *pdfSB_PP_fail = sbHypo.GetPdf();
     pdfSB_PP_fail->plotOn(xframeSB_PP_fail,Slice(*sample,"PP_fail"),ProjWData(*sample,*data));
     TCanvas *c2 = new TCanvas();
     c2->cd(); xframeSB_PP_fail->Draw();
     c2->SaveAs("c1.pdf");
    
     RooPlot* xframeB_PbPb_pass = pObs->frame(Title("SBhypo_PbPb_pass"));
     data->plotOn(xframeB_PbPb_pass,Cut("sample==sample::PbPb_pass"));
     RooAbsPdf *pdfB_PbPb_pass = sbHypo.GetPdf();
     pdfB_PbPb_pass->plotOn(xframeB_PbPb_pass,Slice(*sample,"PbPb_pass"),ProjWData(*sample,*data));
     TCanvas *c3 = new TCanvas();
     c3->cd(); xframeB_PbPb_pass->Draw();
     c3->SetLogy();
     c3->SaveAs("c2.pdf");
    
     RooPlot* xframeB_PbPb_fail = pObs->frame(Title("SBhypo_PbPb_fail"));
     data->plotOn(xframeB_PbPb_fail,Cut("sample==sample::PbPb_fail"));
     RooAbsPdf *pdfB_PbPb_fail = sbHypo.GetPdf();
     pdfB_PbPb_fail->plotOn(xframeB_PbPb_fail,Slice(*sample,"PbPb_fail"),ProjWData(*sample,*data));
     TCanvas *c4 = new TCanvas();
     c4->cd(); xframeB_PbPb_fail->Draw();
     c4->SetLogy();
     c4->SaveAs("c2.pdf");
   }
  
   delete pNll;
   delete pPoiAndNuisance;
   ws->import( sbHypo );
  
   /////////////////////////////////////////////////////////////////////
   RooStats::ModelConfig bHypo = sbHypo;
   bHypo.SetName("BHypo");
   bHypo.SetWorkspace(*ws);
   pNll = bHypo.GetPdf()->createNLL( *data,NumCPU(nCPU) );
   // RooMinuit(*pNll).migrad(); // minimize likelihood wrt all parameters before making plots
   RooArgSet poiAndGlobalObs("poiAndGlobalObs");
   poiAndGlobalObs.add( poi );
   poiAndGlobalObs.add( globalObs );
   RooAbsReal * pProfile = pNll->createProfile( poiAndGlobalObs ); // do not profile POI and global observables
   ((RooRealVar *)poi.first())->setVal( 0 );  // set RFrac2Svs1S_PbPbvsPP=0 here
   pProfile->getVal(); // this will do fit and set nuisance parameters to profiled values
   pPoiAndNuisance = new RooArgSet( "poiAndNuisance" );
   pPoiAndNuisance->add( nuis );
   pPoiAndNuisance->add( poi );
   bHypo.SetSnapshot(*pPoiAndNuisance);


   delete pNll;
   delete pPoiAndNuisance;

   // import model config into workspace
   bHypo.SetWorkspace(*ws);
   ws->import( bHypo );
  
   /////////////////////////////////////////////////////////////////////
   ws->Print();
   bHypo.Print();
   sbHypo.Print();

   // save workspace to file
   string mainDIR = gSystem->ExpandPathName(gSystem->pwd());
   string wsDIR = mainDIR + "/CombinedWorkspaces/";
   string ssubDirName="";
   if (subDirName) ssubDirName.append(subDirName);
   string subDIR = wsDIR + ssubDirName;
  
   void * dirp = gSystem->OpenDirectory(wsDIR.c_str());
   if (dirp) gSystem->FreeDirectory(dirp);
   else gSystem->mkdir(wsDIR.c_str(), kTRUE);

   void * dirq = gSystem->OpenDirectory(subDIR.c_str());
   if (dirq) gSystem->FreeDirectory(dirq);
   else gSystem->mkdir(subDIR.c_str(), kTRUE);
  
   const char* saveName = Form("%s/%s",subDIR.c_str(),nameOut.Data());
   ws->writeToFile(saveName);
}
예제 #21
0
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; 
         
      }
   }

}
예제 #22
0
void rf610_visualerror()
{
   // S e t u p   e x a m p l e   f i t 
   // ---------------------------------------

   // Create sum of two Gaussians p.d.f. with factory
   RooRealVar x("x","x",-10,10) ;
   
   RooRealVar m("m","m",0,-10,10) ;
   RooRealVar s("s","s",2,1,50) ;
   RooGaussian sig("sig","sig",x,m,s) ;

   RooRealVar m2("m2","m2",-1,-10,10) ;
   RooRealVar s2("s2","s2",6,1,50) ;
   RooGaussian bkg("bkg","bkg",x,m2,s2) ;

   RooRealVar fsig("fsig","fsig",0.33,0,1) ;
   RooAddPdf model("model","model",RooArgList(sig,bkg),fsig) ;

   // Create binned dataset
   x.setBins(25) ;  
   RooAbsData* d = model.generateBinned(x,1000) ;

   // Perform fit and save fit result
   RooFitResult* r = model.fitTo(*d,Save()) ;


   // V i s u a l i z e   f i t   e r r o r 
   // -------------------------------------

   // Make plot frame
   RooPlot* frame = x.frame(Bins(40),Title("P.d.f with visualized 1-sigma error band")) ;
   d->plotOn(frame) ;

   // Visualize 1-sigma error encoded in fit result 'r' as orange band using linear error propagation
   // This results in an error band that is by construction symmetric
   //
   // The linear error is calculated as
   // error(x) = Z* F_a(x) * Corr(a,a') F_a'(x)
   //
   // where     F_a(x) = [ f(x,a+da) - f(x,a-da) ] / 2, 
   // 
   //         with f(x) = the plotted curve 
   //              'da' = error taken from the fit result
   //        Corr(a,a') = the correlation matrix from the fit result
   //                Z = requested significance 'Z sigma band'
   //
   // The linear method is fast (required 2*N evaluations of the curve, where N is the number of parameters), 
   // but may not be accurate in the presence of strong correlations (~>0.9) and at Z>2 due to linear and 
   // Gaussian approximations made
   //
   model.plotOn(frame,VisualizeError(*r,1),FillColor(kOrange)) ;


   // Calculate error using sampling method and visualize as dashed red line. 
   //
   // In this method a number of curves is calculated with variations of the parameter values, as sampled 
   // from a multi-variate Gaussian p.d.f. that is constructed from the fit results covariance matrix. 
   // The error(x) is determined by calculating a central interval that capture N% of the variations 
   // for each valye of x, where N% is controlled by Z (i.e. Z=1 gives N=68%). The number of sampling curves 
   // is chosen to be such that at least 100 curves are expected to be outside the N% interval, and is minimally 
   // 100 (e.g. Z=1->Ncurve=356, Z=2->Ncurve=2156)) Intervals from the sampling method can be asymmetric, 
   // and may perform better in the presence of strong correlations, but may take (much) longer to calculate
   model.plotOn(frame,VisualizeError(*r,1,kFALSE),DrawOption("L"),LineWidth(2),LineColor(kRed)) ;
   
   // Perform the same type of error visualization on the background component only.
   // The VisualizeError() option can generally applied to _any_ kind of plot (components, asymmetries, efficiencies etc..)
   model.plotOn(frame,VisualizeError(*r,1),FillColor(kOrange),Components("bkg")) ;
   model.plotOn(frame,VisualizeError(*r,1,kFALSE),DrawOption("L"),LineWidth(2),LineColor(kRed),Components("bkg"),LineStyle(kDashed)) ;

   // Overlay central value
   model.plotOn(frame) ;
   model.plotOn(frame,Components("bkg"),LineStyle(kDashed)) ;
   d->plotOn(frame) ;
   frame->SetMinimum(0) ;


   // V i s u a l i z e   p a r t i a l   f i t   e r r o r 
   // ------------------------------------------------------

   // Make plot frame
   RooPlot* frame2 = x.frame(Bins(40),Title("Visualization of 2-sigma partial error from (m,m2)")) ;
   
   // Visualize partial error. For partial error visualization the covariance matrix is first reduced as follows
   //        ___                   -1
   // Vred = V22  = V11 - V12 * V22   * V21
   //
   // Where V11,V12,V21,V22 represent a block decomposition of the covariance matrix into observables that
   // are propagated (labeled by index '1') and that are not propagated (labeled by index '2'), and V22bar
   // is the Shur complement of V22, calculated as shown above  
   //
   // (Note that Vred is _not_ a simple sub-matrix of V)

   // Propagate partial error due to shape parameters (m,m2) using linear and sampling method
   model.plotOn(frame2,VisualizeError(*r,RooArgSet(m,m2),2),FillColor(kCyan)) ;
   model.plotOn(frame2,Components("bkg"),VisualizeError(*r,RooArgSet(m,m2),2),FillColor(kCyan)) ;
   
   model.plotOn(frame2) ;
   model.plotOn(frame2,Components("bkg"),LineStyle(kDashed)) ;
   frame2->SetMinimum(0) ;
   

   // Make plot frame
   RooPlot* frame3 = x.frame(Bins(40),Title("Visualization of 2-sigma partial error from (s,s2)")) ;
   
   // Propagate partial error due to yield parameter using linear and sampling method
   model.plotOn(frame3,VisualizeError(*r,RooArgSet(s,s2),2),FillColor(kGreen)) ;
   model.plotOn(frame3,Components("bkg"),VisualizeError(*r,RooArgSet(s,s2),2),FillColor(kGreen)) ;
   
   model.plotOn(frame3) ;
   model.plotOn(frame3,Components("bkg"),LineStyle(kDashed)) ;
   frame3->SetMinimum(0) ;


   // Make plot frame
   RooPlot* frame4 = x.frame(Bins(40),Title("Visualization of 2-sigma partial error from fsig")) ;
   
   // Propagate partial error due to yield parameter using linear and sampling method
   model.plotOn(frame4,VisualizeError(*r,RooArgSet(fsig),2),FillColor(kMagenta)) ;
   model.plotOn(frame4,Components("bkg"),VisualizeError(*r,RooArgSet(fsig),2),FillColor(kMagenta)) ;
   
   model.plotOn(frame4) ;
   model.plotOn(frame4,Components("bkg"),LineStyle(kDashed)) ;
   frame4->SetMinimum(0) ;


   
   TCanvas* c = new TCanvas("rf610_visualerror","rf610_visualerror",800,800) ;
   c->Divide(2,2) ;
   c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4)  ; frame->Draw() ;
   c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.6) ; frame2->Draw() ;
   c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.6) ; frame3->Draw() ;
   c->cd(4) ; gPad->SetLeftMargin(0.15) ; frame4->GetYaxis()->SetTitleOffset(1.6) ; frame4->Draw() ;
}
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;
}
예제 #24
0
int GetBayesianInterval( std::string filename = "workspace.root",
			  std::string wsname = "myWS" ){
  //
  // this function loads a workspace and computes
  // a Bayesian upper limit
  //

  // open file with workspace for reading
  TFile * pInFile = new TFile(filename.c_str(), "read");

  // load workspace
  RooWorkspace * pWs = (RooWorkspace *)pInFile->Get(wsname.c_str());
  if (!pWs){
    std::cout << "workspace " << wsname 
	      << " not found" << std::endl;
    return -1;
  }

  // printout workspace content
  pWs->Print();

  // load and print data from workspace
  RooAbsData * data = pWs->data("data");
  data->Print();
  
  // load and print S+B Model Config
  RooStats::ModelConfig * pSbHypo = (RooStats::ModelConfig *)pWs->obj("SbHypo");
  pSbHypo->Print();

  // create RooStats Bayesian MCMC calculator and set parameters

  // Metropolis-Hastings algorithm needs a proposal function
  RooStats::SequentialProposal sp(10.0);
  
  RooStats::MCMCCalculator mcmc( *data, *pSbHypo );
  mcmc.SetConfidenceLevel(0.95);
  mcmc.SetNumIters(100000);          // Metropolis-Hastings algorithm iterations
  mcmc.SetProposalFunction(sp);
  mcmc.SetNumBurnInSteps(500); // first N steps to be ignored as burn-in
  mcmc.SetLeftSideTailFraction(0.0);
  mcmc.SetNumBins(40); // for plotting only - does not affect limit calculation

      
  // estimate credible interval
  // NOTE: unfortunate notation: the UpperLimit() name refers
  //       to the upper boundary of an interval,
  //       NOT to the upper limit on the parameter of interest
  //       (it just happens to be the same for the one-sided
  //       interval starting at 0)
  RooStats::MCMCInterval * pMcmcInt = mcmc.GetInterval();
  double upper_bound = pMcmcInt->UpperLimit( *pWs->var("xsec") );
  double lower_bound = pMcmcInt->LowerLimit( *pWs->var("xsec") );

  std::cout << "one-sided 95%.C.L. bayesian credible interval for xsec: "
	    << "[" << lower_bound << ", " << upper_bound << "]"
	    << std::endl;

  // make posterior PDF plot for POI
  TCanvas c1("posterior");
  RooStats::MCMCIntervalPlot plot(*pMcmcInt);
  plot.Draw();
  c1.SaveAs("bayesian_mcmc_posterior.pdf");

  // make scatter plots to visualise the Markov chain
  TCanvas c2("xsec_vs_alpha_lumi");
  plot.DrawChainScatter( *pWs->var("xsec"), *pWs->var("alpha_lumi"));
  c2.SaveAs("scatter_mcmc_xsec_vs_alpha_lumi.pdf");

  TCanvas c3("xsec_vs_alpha_efficiency");
  plot.DrawChainScatter( *pWs->var("xsec"), *pWs->var("alpha_efficiency"));
  c3.SaveAs("scatter_mcmc_xsec_vs_alpha_efficiency.pdf");

  TCanvas c4("xsec_vs_alpha_nbkg");
  plot.DrawChainScatter( *pWs->var("xsec"), *pWs->var("alpha_nbkg"));
  c4.SaveAs("scatter_mcmc_xsec_vs_alpha_nbkg.pdf");

  // clean up a little
  delete pMcmcInt;

  return 0;
}
예제 #25
0
void Plot_BG(TString wsname)
{
	//get the stuff from the workspace:
	
	TFile* file=TFile::Open(wsname);
	RooWorkspace* ws = (RooWorkspace*)file->Get("combined");
	mc = (ModelConfig*)ws->obj("ModelConfig");
	data = ws->data("obsData");
	RooSimultaneous* simPdf=(RooSimultaneous*)(mc->GetPdf());
	RooAbsReal* nll=simPdf->createNLL(*data);
	
	//run on channels
	
	RooCategory* chanCat = (RooCategory*) (&simPdf->indexCat());
        TIterator* iterat = chanCat->typeIterator() ;
        RooCatType* ttype;
	bool stop = kFALSE;
	while ((ttype = (RooCatType*) iterat->Next())&&!stop)
	{
		// bool toggle to run on one channel or all	
		stop = kTRUE;
		RooAbsPdf  *pdf_state  = simPdf->getPdf(ttype->GetName()) ;
		RooArgSet  *obstmp  = pdf_state->getObservables( *mc->GetObservables() ) ;
        	RooAbsData *datatmp = data->reduce(Form("%s==%s::%s",chanCat->GetName(),chanCat->GetName(),ttype->GetName()));
		RooRealVar *obs     = ((RooRealVar*) obstmp->first());
		TString chanName(ttype->GetName());

		// get data
		TH1* hdata = datatmp->createHistogram("Data "+chanName,*obs);
		// set errors to gaussian
        	for (int ib=0 ; ib<hdata->GetNbinsX()+1 ; ib++) hdata->SetBinError(ib, sqrt(hdata->GetBinContent(ib)));
		
		// get initial BG
		TH1* h_initial_BG = pdf_state->createHistogram("initial_BG_"+chanName,*obs);
	
		// get initial gammas
		int nbins = h_initial_BG->GetNbinsX();
        	double InitGamma[nbins];
        	for (int i=0; i<nbins; i++)
        	{
                	TString varname = "gamma_B0_0j_l1pt0_bin_"+NumberToString(i);
                	InitGamma[i] = ws->var(varname)->getVal();
                	cout << "initial gamma"+NumberToString(i)+" = " << InitGamma[i] << endl;
        	}
        	double InitFpt = ws->var("fl1pt_l1pt0")->getVal();
        	cout << "initial fpt_l1pt0 = " << InitFpt <<  endl;

		TCanvas* c1 = new TCanvas("BG and Data "+chanName,"BG and Data "+chanName,600,600);
		h_initial_BG->Draw();
		//hdata->DrawNormalized("sames E1");

		// DO THE GLOBAL FIT
		
		RooMinimizer minim(*nll);
        	//set some options:
        	minim.setPrintLevel(0);
        	minim.optimizeConst(1);
        	minim.setOffsetting(true);
        	minim.setMinimizerType("Minuit2");
        	minim.minimize("Minuit2");
        	minim.setStrategy(3); //0-3 where 0 is the fastest
        	minim.migrad();
        
		// get gammas after fit
		double FinalGamma[nbins];
		TH1* h_initBG_times_gamma = (TH1*)h_initial_BG->Clone("initBG_times_gamma");
		for (int i=0; i<nbins; i++)
        	{
                	TString varname = "gamma_B0_0j_l1pt0_bin_"+NumberToString(i);
                	FinalGamma[i] = ws->var(varname)->getVal();
                	cout << "Final gamma in bin "+NumberToString(i)+" = " << FinalGamma[i] << endl;
        		h_initBG_times_gamma->SetBinContent(i+1,h_initial_BG->GetBinContent(i+1)*FinalGamma[i]);
		}
		double FinalFpt = ws->var("fl1pt_l1pt0")->getVal();
		cout << "initial fpt_l1pt0 = " << InitFpt <<  endl;
		cout << "final fpt_l1pt0 = " << FinalFpt <<  endl;
	
		TH1* h_final_BG = pdf_state->createHistogram("final_BG_"+chanName,*obs);
        	//TCanvas* cf = new TCanvas("final BG","final BG",600,600);
		h_final_BG->Draw("sames");
		h_initBG_times_gamma->Draw("sames");
		TH1* h_ratio = (TH1*)h_initial_BG->Clone("h_ratio");
		h_ratio->Divide(h_final_BG);
		//h_ratio->Draw();
		cout << "channel name = " << chanName << endl;	
		for ( int j=1; j<=nbins; j++)
		{
			double init = h_initial_BG->GetBinContent(j);
			double fina = h_final_BG->GetBinContent(j);
			double r = (fina)/init;
			cout << "in bin " << j << ", initial B = " << init << ", final B = " << fina << ", ratio = " << r << ", Gamma = " << FinalGamma[j-1] << endl;
		}	
	}


}
예제 #26
0
void results2tree(
      const char* workDirName, 
      bool isMC=false,
      const char* thePoiNames="RFrac2Svs1S,N_Jpsi,f_Jpsi,m_Jpsi,sigma1_Jpsi,alpha_Jpsi,n_Jpsi,sigma2_Jpsi,MassRatio,rSigma21_Jpsi,lambda1_Bkg,lambda2_Bkg,lambda3_Bkg,lambda4_Bkg,lambda5__Bkg,N_Bkg"
      ) {
   // workDirName: usual tag where to look for files in Output
   // thePoiNames: comma-separated list of parameters to store ("par1,par2,par3"). Default: all

   TFile *f = new TFile(treeFileName(workDirName,isMC),"RECREATE");
   TTree *tr = new TTree("fitresults","fit results");


   // bin edges
   float ptmin, ptmax, ymin, ymax, centmin, centmax;
   // model names
   Char_t jpsiName[128], psipName[128], bkgName[128];
   // collision system
   Char_t collSystem[8];
   // goodness of fit
   float nll, chi2, normchi2; int npar, ndof;
   // parameters to store: make it a vector
   vector<poi> thePois;
   TString thePoiNamesStr(thePoiNames);
   TString t; Int_t from = 0;
   while (thePoiNamesStr.Tokenize(t, from , ",")) {
      poi p; strcpy(p.name, t.Data());
      cout << p.name << endl;
      thePois.push_back(p);
   }

   // create tree branches
   tr->Branch("ptmin",&ptmin,"ptmin/F");
   tr->Branch("ptmax",&ptmax,"ptmax/F");
   tr->Branch("ymin",&ymin,"ymin/F");
   tr->Branch("ymax",&ymax,"ymax/F");
   tr->Branch("centmin",&centmin,"centmin/F");
   tr->Branch("centmax",&centmax,"centmax/F");
   tr->Branch("jpsiName",jpsiName,"jpsiName/C");
   tr->Branch("psipName",psipName,"psipName/C");
   tr->Branch("bkgName",bkgName,"bkgName/C");
   tr->Branch("collSystem",collSystem,"collSystem/C");
   tr->Branch("nll",&nll,"nll/F");
   tr->Branch("chi2",&chi2,"chi2/F");
   tr->Branch("normchi2",&normchi2,"normchi2/F");
   tr->Branch("npar",&npar,"npar/I");
   tr->Branch("ndof",&ndof,"ndof/I");

   for (vector<poi>::iterator it=thePois.begin(); it!=thePois.end(); it++) {
      tr->Branch(Form("%s_val",it->name),&(it->val),Form("%s_val/F",it->name));
      tr->Branch(Form("%s_err",it->name),&(it->err),Form("%s_err/F",it->name));
   }

   // list of files
   vector<TString> theFiles = fileList(workDirName,"",isMC);

   int cnt=0;
   for (vector<TString>::const_iterator it=theFiles.begin(); it!=theFiles.end(); it++) {
      cout << "Parsing file " << cnt << " / " << theFiles.size() << ": " << *it << endl;

      // parse the file name to get info
      anabin thebin = binFromFile(*it);
      ptmin = thebin.ptbin().low();
      ptmax = thebin.ptbin().high();
      ymin = thebin.rapbin().low();
      ymax = thebin.rapbin().high();
      centmin = thebin.centbin().low();
      centmax = thebin.centbin().high();
      strcpy(collSystem, (it->Index("PbPb")>0) ? "PbPb" : "PP");

      // get the model names
      from = 0;
      bool catchjpsi=false, catchpsip=false, catchbkg=false;
      while (it->Tokenize(t, from, "_")) {
         if (catchjpsi) {strcpy(jpsiName, t.Data()); catchjpsi=false;}
         if (catchpsip) {strcpy(psipName, t.Data()); catchpsip=false;}
         if (catchbkg) {strcpy(bkgName, t.Data()); catchbkg=false;}
         if (t=="Jpsi") catchjpsi=true;
         if (t=="Psi2S") catchpsip=true;
         if (t=="Bkg") catchbkg=true;
      }

      TFile *f = new TFile(*it); RooWorkspace *ws = NULL;
      if (!f) {
         cout << "Error, file " << *it << " does not exist." << endl;
      } else {
         ws = (RooWorkspace*) f->Get("workspace");
         if (!ws) {
            cout << "Error, workspace not found in " << *it << "." << endl;
         }
      }

      nll=0; chi2=0; npar=0; ndof=0;
      if (f && ws) {
         // get the model for nll and npar
         RooAbsPdf *model = pdfFromWS(ws, Form("_%s",collSystem), "pdfMASS_Tot");
         if (model) {
            RooAbsData *dat = dataFromWS(ws, Form("_%s",collSystem), "dOS_DATA");
            if (dat) {
               RooAbsReal *NLL = model->createNLL(*dat);
               if (NLL) nll = NLL->getVal();
               npar = model->getParameters(dat)->selectByAttrib("Constant",kFALSE)->getSize();

               // compute the chi2 and the ndof
               RooPlot* frame = ws->var("invMass")->frame(Bins(nBins));
               dat->plotOn(frame);
               model->plotOn(frame);
               TH1 *hdatact = dat->createHistogram("hdatact", *(ws->var("invMass")), Binning(nBins));
               RooHist *hpull = frame->pullHist(0,0, true);
               double* ypulls = hpull->GetY();
               unsigned int nFullBins = 0;
               for (int i = 0; i < nBins; i++) {
                  if (hdatact->GetBinContent(i+1) > 0.0) {
                     chi2 += ypulls[i]*ypulls[i];
                     nFullBins++;
                  }
               }
               ndof = nFullBins - npar;
               normchi2 = chi2/ndof;
            }
         }

         // get the POIs
         for (vector<poi>::iterator itpoi=thePois.begin(); itpoi!=thePois.end(); itpoi++) {
            RooRealVar *thevar = poiFromWS(ws, Form("_%s",collSystem), itpoi->name);
            itpoi->val = thevar ? thevar->getVal() : 0;
            itpoi->err = thevar ? thevar->getError() : 0;
         }

         f->Close();
         delete f;
      } else {
         for (vector<poi>::iterator itpoi=thePois.begin(); itpoi!=thePois.end(); itpoi++) {
            itpoi->val = 0;
            itpoi->err = 0;
         }
      }

      // fill the tree
      tr->Fill();
      cnt++;
   } // loop on the files

   f->Write();
   f->Close();
}
예제 #27
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;
}
예제 #28
0
파일: MakeAICFits.C 프로젝트: vlambert/AIC
MakeAICFits::MakeAICFits() {
  //RooRandom::randomGenerator()->SetSeed(314159);
  TFile *f = TFile::Open("/mnt/hadoop/store/user/amott/Hgg2013/Hgg/workspaces/hgg_22Jan2013_R9_CIC.root");
  RooWorkspace *w = (RooWorkspace*) f->Get("cms_hgg_spin_workspace");
  RooAbsData *d = w->data("Data_Combined");
  RooCategory* cat = (RooCategory*)cms_hgg_spin_workspace->obj("evtcat");
  RooAbsData *dc = d->reduce("evtcat==evtcat::cat4");
  //RooAbsData *dc = w->data("Data_Combined")->reduce("evtcar==evtcat::cat0");
  RooRealVar *mass = w->var("mass");

  const Int_t nToys = 1;

  std::cout<<"==========  Data Set Made    ==========="<<std::endl;
  
  Double_t LogLikelihood[8] = {0,0,0,0,0,0,0,0};
  Double_t AIC_bkg_array[8] = {0,0,0,0,0,0,0,0};
  Double_t AICc_bkg_array[8] = {0,0,0,0,0,0,0,0};
  Int_t avgcov[8] = {0,0,0,0,0,0,0};
  std::cout<<"======================   Starting Toys  ==============="<<std::endl;
  for (Int_t i=0; i<nToys; i++) {
    if (i%10==0) {
      std::cout<<">> Processing Toy Trial " << i << "/" << nToys << std::endl;
    }
    int SampleSize = dc->sumEntries();
    RooPlot* frame = mass->frame();
    TLegend *leg = new TLegend(0.55,0.55,0.9,0.9, NULL, "NDC");
    dc->plotOn(frame);
    leg->AddEntry(dc,"Hgg Background Cat 4", "lep");

    for (int type=0; type<7; type++) {
      std::cout<<type<<endl;
    }
    int display = 7;
    for (int type=0; type<display; type++) {
      RooAbsPdf* ModelShape;
      if (type<7) {
	//std::cout<<"Model Shape:    "<<type<<std::endl;
	ModelShape = MakeAICFits::getBackgroundPdf(type,mass);
	//std::cout<<"Model Shape made"<<std::endl;
	int k = MakeAICFits::Num_Params(type);
	//std::cout<<"Params counted"<<std::endl;
      }
      if (type==7) {
	RooAbsPdf* Model1 = MakeAICFits::getBackgroundPdf(0,mass);
	RooAbsPdf* Model2 = MakeAICFits::getBackgroundPdf(1,mass);
	RooAbsPdf* Model3 = MakeAICFits::getBackgroundPdf(2,mass);
	RooAbsPdf* Model4 = MakeAICFits::getBackgroundPdf(3,mass);
	RooAbsPdf* Model5 = MakeAICFits::getBackgroundPdf(4,mass);
	int k = MakeAICFits::Num_Params(3);
	k+= MakeAICFits::Num_Params(1);
	k+= MakeAICFits::Num_Params(0);
	//k+= MakeAICFits::Num_Params(3);
	//k+= MakeAICFits::Num_Params(4);
	RooRealVar* modratio1 = new RooRealVar("modrat1", "modrat1", 0.62, 0.6, 0.7);
	RooRealVar* modratio2 = new RooRealVar("modrat2", "modrat2", 0.29, 0.25, 0.35);
	RooRealVar* modratio3 = new RooRealVar("modrat3", "modrat3", 0.01);
	//RooRealVar* modratio4 = new RooRealVar("modrat4", "modrat4", 0.25);
	ModelShape = new RooAddPdf("Composite", "Background Model", RooArgList(*Model1, *Model4, *Model2), RooArgList(*modratio1, *modratio2));
      }
      RooRealVar *Nbkg = new RooRealVar("Nbkg","N Background Events", SampleSize,0,1e9);
      RooExtendPdf *BkgModel = new RooExtendPdf("BKGFIT_bkgModel", "Background Model", *ModelShape, *Nbkg);
      TH1F* Model = new TH1F("Model", "Model", 100,0,100);
 
      RooFitResult *bkg_databkg = BkgModel->fitTo(*dc, RooFit::Save(kTRUE), RooFit::Optimize(0));
      if (type == 0) {
	BkgModel->plotOn(frame, RooFit::LineColor(kBlue));
	Model->SetLineColor(kBlue);
	leg->AddEntry(Model, "Exponential Model", "l");
      }
      if (type == 4) { 
	BkgModel->plotOn(frame, RooFit::LineColor(kRed));
	Model->SetLineColor(kRed);
	leg->AddEntry(Model, "Polynomial Model", "l");
      }
      if (type == 5) { 
	BkgModel->plotOn(frame, RooFit::LineColor(kGreen));
	Model->SetLineColor(kGreen);
	leg->AddEntry(Model, "Power Model", "l");
      }
      if (type == 7) {
	BkgModel->plotOn(frame, RooFit::LineColor(kMagenta));
	Model->SetLineColor(kMagenta);
	leg->AddEntry(Model, "Composite Model", "l");
      }
      Double_t bkg_databkg_Nll = bkg_databkg->minNll();
      Int_t covariance = bkg_databkg->covQual();
      avgcov[type] += covariance;
      //assert (covariance == 3);
      // Calculate AIC for each model
      LogLikelihood[type] += -bkg_databkg_Nll;
      AICc_bkg_array[type] += 2.*(k + k*(k + 1.)/(SampleSize - (k + 1.)) + bkg_databkg_Nll);
      AIC_bkg_array[type] += 2.*(k + bkg_databkg_Nll);
      // Clean up objects
      delete bkg_databkg;
      bkg_databkg_Nll = 0.;
    }
    //delete databkg;
    TCanvas *c = new TCanvas("", "", 800, 600);
    frame->Draw();
    leg->Draw();
    c->Update();
    c->Print("HggData_cat4.pdf");
  }
  
  std::cout<<"Printing AIC Values" << std::endl;
  //std::cout<<"Log Likelihood Data :    " << LogLikelihood_data <<std::endl;
  int display = 7;
  for (int type = 0; type<display; type++) {
    avgcov[type] = avgcov[type]/nToys;
    LogLikelihood[type] = LogLikelihood[type]/nToys;
    AIC_bkg_array[type] = AIC_bkg_array[type]/nToys;
    AICc_bkg_array[type] = AICc_bkg_array[type]/nToys;
    std::cout<<"average covariance quality" << type <<" ===" << avgcov[type] <<std::endl;
    std::cout<<"Log Likelihood for Model " << type << " ==== " << LogLikelihood[type] <<std::endl;
    std::cout<<"AICc Value for Model: " << type << " ==== " << AICc_bkg_array[type] <<std::endl;
    std::cout<<"AIC Value for Model: " << type << " ==== " << AIC_bkg_array[type]  << std::endl;
  }
  double minAIC = 10000000000.;
  for (int type = 0; type<display; type++) {
    if (AICc_bkg_array[type] < minAIC) {
      minAIC = AICc_bkg_array[type];
    }
  }
  std::cout<<"Minimum AIC: " << minAIC << std::endl;
  double DeltaIA[8];
  double sumExpA=0;
  int bestmodelA;
  for (int type = 0; type<display; type++) {
    DeltaIA[type] = AICc_bkg_array[type] - minAIC;
    if (DeltaIA[type] == 0) {
      bestmodelA = type;
    }
    std::cout<<"Delta AIC values : " << type << " ====" << DeltaIA[type] <<std::endl;
    sumExpA+= exp(-DeltaIA[type]/2);
  }
  double AICweights[8];
  for (int type = 0; type<display; type++) {
    AICweights[type] = exp(-DeltaIA[type]/2)/sumExpA;
    std::cout<<"Relative Likelihood AIC " << type << " ==== " <<exp(-DeltaIA[type]/2)<<std::endl;
    std::cout<<"AIC Weights  : " << type << " =====" << AICweights[type] <<std::endl;
  }
  for (int type2 = 0; type2<display; type2++) {
    std::cout<< "AIC Ratio for:  " << "Model " << bestmodelA << " / " << "Model " << type2 << "  =  " << AICweights[bestmodelA]/AICweights[type2] <<std::endl;
  }
}
예제 #29
0
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));
}
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;

}