Esempio n. 1
0
void Initialize(const char* infile , const char* workspaceName, const char* modelConfigName, const char* ObsDataName) {

	// Load workspace, model and data
	TFile *file = TFile::Open(infile);
	if (!file) {
		cout << "The file " << infile << " is not found/created, will stop here." << endl;
		return;
   	}	
    	if(!(RooWorkspace*) file->Get(workspaceName)){
      		cout <<"workspace not found" << endl;
      		return;
    	}

    	w      = (RooWorkspace*) file->Get(workspaceName);
    	mc     = (ModelConfig*) w->obj(modelConfigName);
    	data   = w->data(ObsDataName);


    	w->SetName("w");
    	w->SetTitle("w");
    	// save snapshot before any fit has been done
	RooSimultaneous* pdf = (RooSimultaneous*) w->pdf("simPdf");
	RooArgSet* params = (RooArgSet*) pdf->getParameters(*data) ;
    	if(!w->loadSnapshot("snapshot_paramsVals_initial"))  w->saveSnapshot("snapshot_paramsVals_initial",*params);
    	else cout << endl << " Snapshot 'snapshot_paramsVals_initial' already exists in  workspace, will not overwrite it" << endl;
   	if(!data || !mc){
      		w->Print();
      		cout << "data or ModelConfig was not found" <<endl;
      		return;
    	}


}
Esempio n. 2
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));
}
Esempio n. 3
0
int main(int argc, char **argv)
{
	bool printSw = true;
	//TString massModel = "Gauss-m[5622]";
	string massModel = "DCB-m[5622]";
	TString effbase = "/afs/cern.ch/user/p/pluca/work/Lb/Lmumu/results/";
	bool printeff = false;
	TString dodata = "data";
	bool fitsingle = false;
	TString wstr = "physRate_polp006";
	TString decayToDo = "Lb2Lmumu";
	if(dodata=="genMC") wstr += "_noDecay";

	gROOT->ProcessLine(".x lhcbStyle.C");


	RooRealVar * cosThetaL = new RooRealVar("cosThetaL","cosThetaL",0.,-1.,1.);
	RooRealVar * cosThetaB = new RooRealVar("cosThetaB","cosThetaB",0.,-1.,1.);
	RooRealVar * nsig_sw = new RooRealVar("nsig_sw","nsig_sw",1,-1.e6,1.e6);
	RooRealVar * MCweight = new RooRealVar(wstr,wstr,1.,-1.e10,1.e10);
	RooRealVar * MM = new RooRealVar("Lb_MassConsLambda","Lb_MassConsLambda",5620.,5500.,5900.);
	TString datafilename = "/afs/cern.ch/user/p/pluca/work/Lb/Lmumu/candLb.root";
	if(dodata=="MC") datafilename = "/afs/cern.ch/user/p/pluca/work/Lb/Lmumu/candLb_MC.root";
	if(dodata=="genMC") datafilename = "/afs/cern.ch/work/p/pluca/weighted/Lmumu/"+(string)decayToDo+"_geomMC_Pythia8_NBweighted.root";
	TreeReader * data;
	if(dodata!="genMC") data = new TreeReader("cand"+decayToDo);
	else data = new TreeReader("MCtree");
	data->AddFile(datafilename);

	TFile * histFile = new TFile("Afb_hist.root","recreate");

	RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);

	int nbins = 1;//CutsDef::nq2bins;
	double q2min[] = {15.,11.0,15,16,18};//&CutsDef::q2min_highfirst[0];
	double q2max[] = {20.,12.5,16,18,20};//&CutsDef::q2max_highfirst[0];
	
	//int nbins = CutsDef::nq2bins
	//double *q2min = &CutsDef::q2min[0];
	//double *q2max = &CutsDef::q2max[0];


	TGraphErrors * Afb_vs_q2 = new TGraphErrors();
	TGraphErrors * AfbB_vs_q2 = new TGraphErrors();
	TGraphErrors * fL_vs_q2 = new TGraphErrors();
	TCanvas * ceff = new TCanvas();

	RooCategory * samples = new RooCategory("samples","samples");
	samples->defineType("DD");
	samples->defineType("LL");

	RooRealVar * afb = new RooRealVar("afb","afb",0.,-100,100);
	RooRealVar * fL = new RooRealVar("fL","fL",0.7,-1.,10.);
	//RooRealVar * afb = new RooRealVar("afb","afb",0.,-1.,1.);
	//RooRealVar * fL = new RooRealVar("fL","fL",0.7,0.,1.);
	RooRealVar * origafb = new RooRealVar("afb","afb",0.,-1.,1.);
	RooRealVar * origfL = new RooRealVar("fL","fL",0.7,-1.,10.);
	TString afbLpdf = "((3./8.)*(1.-fL)*(1 + TMath::Power(cosThetaL,2)) + afb*cosThetaL + (3./4.)*fL*(1 - TMath::Power(cosThetaL,2)))";
	RooRealVar * afbB = new RooRealVar("afbB","afbB",0.,-100,100);
	//RooRealVar * afbB = new RooRealVar("afbB","afbB",0.,-1.,1.);
	RooRealVar * origafbB = new RooRealVar("afbB","afbB",0.,-1.,1.);
	TString afbBpdf = "(1 + 2*afbB*cosThetaB)";

	vector< vector< double > > afb_errs, afbB_errs, fL_errs;
	TList * LLlist = new TList, * DDlist = new TList;

	TCanvas * cDD = new TCanvas();
	TCanvas * cLL = new TCanvas();
	TCanvas * cDDB = new TCanvas();
	TCanvas * cLLB = new TCanvas();

	for(int i = 0; i < nbins; i++)
	{
		//if(q2min[i] < 8) continue;
		TString q2name = ((TString)Form("q2_%4.2f_%4.2f",q2min[i],q2max[i])).ReplaceAll(".","");
		TString curq2cut = Form("TMath::Power(J_psi_1S_MM/1000,2) >= %e && TMath::Power(J_psi_1S_MM/1000,2) < %e",q2min[i],q2max[i]);	
		//TString curq2cut = Form("TMath::Power(J_psi_1S_MM/1000,2) >= %e && TMath::Power(J_psi_1S_MM/1000,2) < %e && (Lb_MassConsLambda > 5680 || Lb_MassConsLambda < 5590)",q2min[i],q2max[i]); 
		cout << "------------------- q2 bin: " << q2min[i] << " - " << q2max[i] << " -----------------------" << endl;

		TFile * effFile = NULL;
		TH1F * effDD = NULL, * effLL = NULL, * effLLB = NULL, * effDDB = NULL;
		if(q2min[i] == 15 && q2max[i] == 20)
		{
			effFile = TFile::Open(effbase+"LbeffvscosThetaL_DD.root");
			effDD  = (TH1F *)effFile->Get("htoteff");
			effFile = TFile::Open(effbase+"LbeffvscosThetaL_LL.root");
			effLL  = (TH1F *)effFile->Get("htoteff");
			effFile = TFile::Open(effbase+"LbeffvscosThetaB_DD.root");
			effDDB  = (TH1F *)effFile->Get("htot_nodet_eff");
			effFile = TFile::Open(effbase+"LbeffvscosThetaB_LL.root");
			effLLB  = (TH1F *)effFile->Get("htot_nodet_eff");
		}
		else
		{

			effFile = TFile::Open(effbase+"Lbeff2D_cosThetaL_vs_q2_DD.root");
			TH2F * effDD2D  = (TH2F *)effFile->Get("htot_eff");
			effDD = (TH1F*)GetSliceX(effDD2D,(q2max[i]+q2min[i])/2.);
			effFile = TFile::Open(effbase+"Lbeff2D_cosThetaL_vs_q2_LL.root");
			TH2F * effLL2D  = (TH2F *)effFile->Get("htot_eff");
			effLL = (TH1F*)GetSliceX(effLL2D,(q2max[i]+q2min[i])/2.);
			effFile = TFile::Open(effbase+"Lbeff2D_cosThetaB_vs_q2_DD.root");
			TH2F * effDDB2D  = (TH2F *)effFile->Get("hupper_eff");
			effDDB = (TH1F*)GetSliceX(effDDB2D,(q2max[i]+q2min[i])/2.);
			effFile = TFile::Open(effbase+"Lbeff2D_cosThetaB_vs_q2_LL.root");
			TH2F * effLLB2D  = (TH2F *)effFile->Get("hupper_eff");
			effLLB = (TH1F*)GetSliceX(effLLB2D,(q2max[i]+q2min[i])/2.);
		}

		ceff->cd();

		/**                    FIT EFFICIENCY                  **/

		RooDataHist * hLL = new RooDataHist("hLL","hLL",*cosThetaL,effLL);
		RooDataHist * hDD = new RooDataHist("hDD","hDD",*cosThetaL,effDD);
		RooRealVar * c1LL = new RooRealVar("c1LL","",0.,-1.,1);
		RooRealVar * c1DD = new RooRealVar("c1DD","",0.,-1.,1);
		RooRealVar * c2LL = new RooRealVar("c2LL","",0.,-1.,1);
		RooRealVar * c2DD = new RooRealVar("c2DD","",0.,-1.,1);
		TString effLLstr = "(1 + c1LL*cosThetaL + c2LL*TMath::Power(cosThetaL,2))";
		TString effDDstr = "(1 + c1DD*cosThetaL + c2DD*TMath::Power(cosThetaL,2))";
		RooAbsPdf * effLLpdf = new RooGenericPdf("effLLpdf", "", effLLstr, RooArgSet(*cosThetaL, *c1LL, *c2LL));
		RooAbsPdf * effDDpdf = new RooGenericPdf("effDDpdf", "", effDDstr, RooArgSet(*cosThetaL, *c1DD, *c2DD));
		effLLpdf->fitTo(*hLL,PrintLevel(-1));
		effDDpdf->fitTo(*hDD,PrintLevel(-1));
		fixParams(effLLpdf,cosThetaL);
		fixParams(effDDpdf,cosThetaL);	

		RooDataHist * hLLB = new RooDataHist("hLLB","hLLB",*cosThetaB,effLLB);
		RooDataHist * hDDB = new RooDataHist("hDDB","hDDB",*cosThetaB,effDDB);
		RooRealVar * cB1LL = new RooRealVar("cB1LL","",0,-1.,1);
		RooRealVar * cB1DD = new RooRealVar("cB1DD","",0,-1.,1);
		RooRealVar * cB2LL = new RooRealVar("cB2LL","",0,-1.,1);
		RooRealVar * cB2DD = new RooRealVar("cB2DD","",0,-1.,1);
		TString effLLBstr = "(1 + cB1LL*cosThetaB + cB2LL*TMath::Power(cosThetaB,2))";
		TString effDDBstr = "(1 + cB1DD*cosThetaB + cB2DD*TMath::Power(cosThetaB,2))";
		RooAbsPdf * effLLpdfB = new RooGenericPdf("effLLpdfB", "", effLLBstr, RooArgSet(*cosThetaB, *cB1LL, *cB2LL));
		RooAbsPdf * effDDpdfB = new RooGenericPdf("effDDpdfB", "", effDDBstr, RooArgSet(*cosThetaB, *cB1DD, *cB2DD));
		effLLpdfB->fitTo(*hLLB,PrintLevel(-1));
		effDDpdfB->fitTo(*hDDB,PrintLevel(-1));
		fixParams(effLLpdfB,cosThetaB);
		fixParams(effDDpdfB,cosThetaB);

		//cout << q2min[i] << " - " << q2max[i] << " LL cosThetaL -> " << c1LL->getVal() << "  " << c2LL->getVal() << endl;
		//cout << q2min[i] << " - " << q2max[i] << " DD cosThetaL -> " << c1DD->getVal() << "  " << c2DD->getVal() << endl;
		//cout << q2min[i] << " - " << q2max[i] << " LL cosThetaB -> " << cB1LL->getVal() << "  " << cB2LL->getVal() << endl;
		//cout << q2min[i] << " - " << q2max[i] << " DD cosThetaB -> " << cB1DD->getVal() << "  " << cB2DD->getVal() << endl;


		if(printeff) {
			GetFrame(cosThetaL, hLL,effLLpdf,"-nochi2",0,NULL,0,"cos#theta_{l}","Tot. eff.")->Draw();
			ceff->Print("DDeffFit"+q2name+".pdf");
			GetFrame(cosThetaL, hDD,effDDpdf,"-nochi2",0,NULL,0,"cos#theta_{l}","Tot. eff.")->Draw();
			ceff->Print("LLeffFit"+q2name+".pdf");
			GetFrame(cosThetaB, hLLB,effLLpdfB,"-nochi2",0,NULL,0,"cos#theta_{#Lambda}","Tot. eff.")->Draw();
			ceff->Print("DDeffFitB"+q2name+".pdf");
			GetFrame(cosThetaB, hDDB,effDDpdfB,"-nochi2",0,NULL,0,"cos#theta_{#Lambda}","Tot. eff.")->Draw();
			ceff->Print("LLeffFitB"+q2name+".pdf"); }

			/**                    FIT AFB                  **/


			afb->setVal(0);
			afbB->setVal(0);
			fL->setVal(0.7);

			TString LLnorm = "1./( 1. + (2./3.)*afb*c1LL + (2./5.)*c2LL - (1./5.)*c2LL*fL )*"+effLLstr;
			TString DDnorm = "1./( 1. + (2./3.)*afb*c1DD + (2./5.)*c2DD - (1./5.)*c2DD*fL )*"+effDDstr;
			RooAbsPdf * corrPdfLL = new RooGenericPdf(Form("corrPdfLL_%i",i),LLnorm+"*"+afbLpdf,RooArgSet(*cosThetaL, *afb, *fL, *c1LL, *c2LL) );
			RooAbsPdf * corrPdfDD = new RooGenericPdf(Form("corrPdfDD_%i",i),DDnorm+"*"+afbLpdf,RooArgSet(*cosThetaL, *afb, *fL, *c1DD, *c2DD) );

			TString LLnormB = "1./( (2./3.)*( 2*afbB*cB1LL + cB2LL + 3.) )*"+effLLBstr;
			TString DDnormB = "1./( (2./3.)*( 2*afbB*cB1DD + cB2DD + 3.) )*"+effDDBstr;
			RooAbsPdf * corrPdfLLB = new RooGenericPdf(Form("corrPdfLLB_%i",i),LLnormB+"*"+afbBpdf,RooArgSet(*cosThetaB, *afbB, *cB1LL, *cB2LL) );
			RooAbsPdf * corrPdfDDB = new RooGenericPdf(Form("corrPdfDDB_%i",i),DDnormB+"*"+afbBpdf,RooArgSet(*cosThetaB, *afbB, *cB1DD, *cB2DD) );

			TCut cutLL = CutsDef::LLcut + (TCut)curq2cut;
			TCut cutDD = CutsDef::DDcut + (TCut)curq2cut;

			if(dodata=="genMC")
			{
				corrPdfLLB = new RooGenericPdf("corrPdfLL",afbBpdf,RooArgSet(*cosThetaB, *afbB, *cB1LL, *cB2LL) );
				corrPdfDDB = new RooGenericPdf("corrPdfDD",afbBpdf,RooArgSet(*cosThetaB, *afbB, *cB1DD, *cB2DD) );
				corrPdfLL = new RooGenericPdf("corrPdfLL",afbLpdf,RooArgSet(*cosThetaL, *afb, *fL, *c1LL, *c2LL) );
				corrPdfDD = new RooGenericPdf("corrPdfDD",afbLpdf,RooArgSet(*cosThetaL, *afb, *fL, *c1DD, *c2DD) );
				cutLL = (TCut)curq2cut;
				cutDD = (TCut)curq2cut;
			}

			Analysis * anaLL = new Analysis(Form("LL_mass_%i",i),"Lb",data,&cutLL,MM);
			anaLL->AddVariable(cosThetaL);
			anaLL->AddVariable(cosThetaB);
			anaLL->AddVariable("J_psi_1S_MM");
			if(dodata!="data") anaLL->SetWeight(wstr);
			RooDataSet * dataLL = anaLL->GetDataSet("-recalc-docuts");

			Analysis * anaDD = new Analysis(Form("DD_mass_%i",i),"Lb",data,&cutDD,MM);
			anaDD->AddVariable(cosThetaL);
			anaDD->AddVariable(cosThetaB);
			anaDD->AddVariable("J_psi_1S_MM");
			if(dodata!="data") anaDD->SetWeight(wstr);
			RooDataSet * dataDD = anaDD->GetDataSet("-recalc-docuts");

			RooDataSet * sdataDD, * sdataLL;

			if(dodata=="data")
			{
				sdataLL = anaLL->CalcSweight("",massModel.c_str(),"Exp");

				if(printSw) {
					GetFrame(MM,NULL,sdataLL,"-nochi2",30,NULL,0,"M(#Lambda#mu#mu) (MeV/c^{2})")->Draw();
					ceff->Print("Mass_LL_sWeighted"+q2name+".pdf");
					GetFrame(cosThetaL,NULL,sdataLL,"-nochi2",6,NULL,0,"cos#theta_{l}")->Draw();
					ceff->Print("cosThetaL_LL_sWeighted"+q2name+".pdf");
					GetFrame(cosThetaL,NULL,dataLL,"-nochi2",6,NULL,0,"cos#theta_{l}")->Draw();
					ceff->Print("cosThetaL_LL_"+q2name+".pdf");
				}

				sdataDD = anaDD->CalcSweight("",massModel.c_str(),"Exp");

				if(printSw) {
					GetFrame(MM,NULL,sdataDD,"-nochi2",30,NULL,0,"M(#Lambda#mu#mu) (MeV/c^{2})")->Draw();
					ceff->Print("Mass_DD_sWeighted"+q2name+".pdf");
					GetFrame(cosThetaL,NULL,sdataDD,"-nochi2",10,NULL,0,"cos#theta_{l}")->Draw();
					ceff->Print("cosThetaL_DD_sWeighted"+q2name+".pdf");
					GetFrame(cosThetaL,NULL,dataDD,"-nochi2",10,NULL,0,"cos#theta_{l}")->Draw();
					ceff->Print("cosThetaL_DD_"+q2name+".pdf");
				}
			}		
			else { sdataLL = dataLL; sdataDD = dataDD; }

			histFile->cd();
			TTree * LLTree = (TTree*)sdataLL->tree();
			LLTree->SetName(Form("treeLL_%i",i));
			LLlist->Add(LLTree);
			TTree * DDTree = (TTree*)sdataDD->tree();
			DDTree->SetName(Form("treeDD_%i",i));
			DDlist->Add(DDTree);


			// CREATE COMBINED DATASET
			RooDataSet * combData;
			if(dodata=="data") combData = new RooDataSet(Form("combData_%i",i),"combined data",RooArgSet(*cosThetaL,*cosThetaB,*nsig_sw),Index(*samples),Import("DD",*sdataDD),Import("LL",*sdataLL),WeightVar("nsig_sw"));
			else combData = new RooDataSet(Form("combData_%i",i),"combined data",RooArgSet(*cosThetaL,*cosThetaB,*MCweight),Index(*samples),Import("DD",*sdataDD),Import("LL",*sdataLL),WeightVar(wstr));


			// FIT COS LEPTON
			RooSimultaneous * combModel = new RooSimultaneous(Form("combModel_%i",i),"",*samples);
			combModel->addPdf(*corrPdfLL,"LL");
			combModel->addPdf(*corrPdfDD,"DD");

			combModel->fitTo(*combData,PrintLevel(-1),Verbose(kFALSE),SumW2Error(kTRUE));

			if(fitsingle) corrPdfLL->fitTo(*sdataLL,PrintLevel(-1),Verbose(kFALSE),SumW2Error(kTRUE));
			GetFrame(cosThetaL,corrPdfLL,sdataLL,"-sumW2err-nochi2-noCost",6,NULL,0,"cos#theta_{l}")->Draw();
			ceff->Print("Afb_LL_"+q2name+".pdf");
			if(fitsingle) corrPdfDD->fitTo(*sdataDD,PrintLevel(-1),Verbose(kFALSE),SumW2Error(kTRUE));		
			GetFrame(cosThetaL,corrPdfDD,sdataDD,"-sumW2err-nochi2-noCost",10,NULL,0,"cos#theta_{l}")->Draw();
			ceff->Print("Afb_DD_"+q2name+".pdf");

			Afb_vs_q2->SetPoint(i,(q2max[i] + q2min[i])/2.,afb->getVal());
			Afb_vs_q2->SetPointError(i,(q2max[i] - q2min[i])/2.,afb->getError());
			fL_vs_q2->SetPoint(i,(q2max[i] + q2min[i])/2.,fL->getVal());
			fL_vs_q2->SetPointError(i,(q2max[i] - q2min[i])/2.,fL->getError());
				
			// FIT COS HADRON
			RooSimultaneous * combModelB = new RooSimultaneous(Form("combModelB_%i",i),"",*samples);
			combModelB->addPdf(*corrPdfLLB,"LL");
			combModelB->addPdf(*corrPdfDDB,"DD");

			combModelB->fitTo(*combData,PrintLevel(-1),Verbose(kFALSE),SumW2Error(kTRUE));

			if(fitsingle) corrPdfLLB->fitTo(*sdataLL,PrintLevel(-1),Verbose(kFALSE),SumW2Error(kTRUE));
			GetFrame(cosThetaB,corrPdfLLB,sdataLL,"-sumW2err-nochi2-noCost",6,NULL,0,"cos#theta_{#Lambda}")->Draw();
			ceff->Print("AfbB_LL_"+q2name+".pdf");
			if(fitsingle) corrPdfDDB->fitTo(*sdataDD,PrintLevel(-1),Verbose(kFALSE),SumW2Error(kTRUE));		
			GetFrame(cosThetaB,corrPdfDDB,sdataDD,"-sumW2err-nochi2-noCost",10,NULL,0,"cos#theta_{#Lambda}")->Draw();
			ceff->Print("AfbB_DD_"+q2name+".pdf");

			AfbB_vs_q2->SetPoint(i,(q2max[i] + q2min[i])/2.,afbB->getVal());
			AfbB_vs_q2->SetPointError(i,(q2max[i] - q2min[i])/2.,afbB->getError());
			
			cout << endl << fixed << setprecision(6) << "AfbB = " << afbB->getVal() << " +/- " << afbB->getError() << endl;
			cout << "Afb = " << afb->getVal() << " +/- " << afb->getError() << endl;
			cout << "fL = " << fL->getVal() << " +/- " << fL->getError() << endl;
			cout << endl;
			cout << "------------------------ FELDMAN AND COUSINS ------------------------" << endl;

			vector < RooDataSet * > datas;
			vector < RooAbsPdf * > pdfs, pdfsB;
			vector < TString > cat;
			cat.push_back("LL");
			cat.push_back("DD");
			datas.push_back(sdataLL);
			datas.push_back(sdataDD);

			RooArgSet * origPars = new RooArgSet();
			origPars->add(*origafb);
			origPars->add(*origfL);
			
			pdfs.push_back(corrPdfLL);
			pdfs.push_back(corrPdfDD);

			vector< double > afb_err, afbB_err, fL_err;
/*
			double fLval = fL->getVal(), fLerr = fL->getError();
			FeldmanCousins * FC = new FeldmanCousins(q2name,cat,datas,pdfs,cosThetaL,afb,"nsig_sw");
			//FC->SetNPointsToScan(20);
			//FC->SetNExp(1000);
			if(q2min[i]==18) afb_err = FC->ExtractLimits(origPars,-0.3,0.3);
			else if( (afb->getVal()-1.4*afb->getError()) > -1 && (afb->getVal()+1.4*afb->getError()) < 1 )
		       afb_err = FC->ExtractLimits(origPars,afb->getVal()-1.4*afb->getError(),afb->getVal()+1.4*afb->getError());
		    else afb_err = FC->ExtractLimits(origPars,-0.4,0.4);

			//FeldmanCousins * FCfL = new FeldmanCousins(q2name,cat,datas,pdfs,cosThetaL,fL,"nsig_sw");
			//if(q2min[i]==11) fL_err = FCfL->ExtractLimits(origPars,0.,0.6);
			//else if (q2min[i]==18) fL_err = FCfL->ExtractLimits(origPars,0.75,0.992);
			//( (fLval-1.3*fLerr) > 0 && (fLval+1.3*fLerr) <= 1 )
			//else fL_err = FCfL->ExtractLimits(origPars,fLval-1.3*fLerr,fLval+1.3*fLerr);

			afb_errs.push_back(afb_err);
			//fL_errs.push_back(fL_err);

 			RooArgSet * origParsB = new RooArgSet();
			origParsB->add(*origafbB);
			pdfsB.push_back(corrPdfLLB);
			pdfsB.push_back(corrPdfDDB);

			FeldmanCousins * FCB = new FeldmanCousins(q2name,cat,datas,pdfsB,cosThetaB,afbB,"nsig_sw");
			if( (afbB->getVal()-1.5*afbB->getError()) > -1 && (afbB->getVal()+1.5*afbB->getError()) < 1 )
			   afbB_err = FCB->ExtractLimits(origParsB,afbB->getVal()-1.5*afbB->getError(),afbB->getVal()+1.5*afbB->getError());
			else afbB_err = FCB->ExtractLimits(origParsB,-0.4,0.4);

			afbB_errs.push_back(afbB_err);
*/
			delete effDD;
			delete effLL;
			delete effLLB;
			delete effDDB;
	}

	cDD->Print("DDeff.pdf");
	cLL->Print("LLeff.pdf");
	cDDB->Print("DDBeff.pdf");
	cLLB->Print("LLBeff.pdf");


	Afb_vs_q2->GetXaxis()->SetTitle("q^{2}");
	Afb_vs_q2->GetYaxis()->SetTitle("Afb");
	Afb_vs_q2->SetMaximum(1);
	Afb_vs_q2->SetMinimum(-1);
	Afb_vs_q2->Draw("AP");
	ceff->Print("Afb_vs_q2.pdf");
	AfbB_vs_q2->GetXaxis()->SetTitle("q^{2}");
	AfbB_vs_q2->GetYaxis()->SetTitle("AfbB");
	AfbB_vs_q2->SetMaximum(1);
	AfbB_vs_q2->SetMinimum(-1);
	AfbB_vs_q2->Draw("AP");
	ceff->Print("AfbB_vs_q2.pdf");
	fL_vs_q2->GetXaxis()->SetTitle("q^{2}");
	fL_vs_q2->GetYaxis()->SetTitle("fL");
	fL_vs_q2->Draw("AP");
	ceff->Print("fL_vs_q2.pdf");

	for(int bb = 0; bb < Afb_vs_q2->GetN(); bb++)
	{
		double qq, qqerr, afbv, afbBv, fLv;
		Afb_vs_q2->GetPoint(bb,qq,afbv);
		qqerr = Afb_vs_q2->GetErrorX(bb);
		AfbB_vs_q2->GetPoint(bb,qq,afbBv);
		fL_vs_q2->GetPoint(bb,qq,fLv);
		cout << fixed << setprecision(1) << qq-qqerr << " - " << qq+qqerr;
		cout << fixed << setprecision(4); 
		//cout << " & $" << afbv << "_{-" << TMath::Abs(afb_errs[bb][0] - afbv) << "}^{+" << TMath::Abs(afb_errs[bb][1] - afbv)  << "} \\text{(stat)} \\pm \\text{(sys)}$ ";
		//cout << " & $" << afbBv << "_{-" << TMath::Abs(afbB_errs[bb][0] - afbBv) << "}^{+" << TMath::Abs(afbB_errs[bb][1]-afbBv) << "} \\text{(stat)} \\pm \\text{(sys)}$ " ;
		//cout << " & $" << fLv << "_{-" << TMath::Abs(fL_errs[bb][0] - fLv) << "}^{+" << TMath::Abs(fL_errs[bb][1] - fLv)  << "} \\text{(stat)} \\pm \\text{(sys)}$ ";
		cout << "  \\\\ " << endl;
	}

	histFile->cd();
	TTree * finalLLtree = (TTree*)TTree::MergeTrees(LLlist);
	TTree * finalDDtree = (TTree*)TTree::MergeTrees(DDlist);
	finalLLtree->SetName("LL_data");
	finalDDtree->SetName("DD_data");
	finalLLtree->Write();
	finalDDtree->Write();

	delete ceff;
	histFile->Write();
	delete histFile;

	}
Esempio n. 4
0
int main(int argc, char **argv)
{
	bool printeff = true;
	string fc = "none";
	
	gROOT->ProcessLine(".x lhcbStyle.C");

	if(argc > 1)
	{
		for(int a = 1; a < argc; a++)
		{
			string arg = argv[a];
			string str = arg.substr(2,arg.length()-2);

			if(arg.find("-E")!=string::npos) fc = str;
			if(arg=="-peff") printeff = true;
		}
	}
	
	int nexp = 100;
	int nbins = 6;
	double q2min[] = {8.,15.,11.0,15,16,18};
	double q2max[] = {11.,20.,12.5,16,18,20};

	TString datafilename = "/afs/cern.ch/work/p/pluca/weighted/Lmumu/candLb.root";
	TreeReader * data = new TreeReader("candLb2Lmumu");
	data->AddFile(datafilename);
	TreeReader * datajpsi = new TreeReader("candLb2JpsiL");
	datajpsi->AddFile(datafilename);

	TFile * histFile = new TFile("Afb_bkgSys.root","recreate");

	string options = "-quiet-noPlot-lin-stdAxis-XM(#Lambda#mu#mu) (MeV/c^{2})-noCost-noParams";
	Analysis::SetPrintLevel("s");

	RooRealVar * cosThetaL = new RooRealVar("cosThetaL","cosThetaL",0.,-1.,1.);
	RooRealVar * cosThetaB = new RooRealVar("cosThetaB","cosThetaB",0.,-1.,1.);
	RooRealVar * MM = new RooRealVar("Lb_MassConsLambda","Lb_MassConsLambda",5621.,5400.,6000.);
	MM->setRange("Signal",5600,5640);
	RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);

	//TGraphAsymmErrors * fL_vs_q2 = new TGraphAsymmErrors();
	//TCanvas * ceff = new TCanvas();

	RooCategory * samples = new RooCategory("samples","samples");
	samples->defineType("DD");
	samples->defineType("LL");

	RooRealVar * afb = new RooRealVar("afb","afb",0.,-0.75,0.75);
	RooRealVar * fL = new RooRealVar("fL","fL",0.6,0.,1.);
	TString afbLpdf = "((3./8.)*(1.-fL)*(1 + TMath::Power(cosThetaL,2)) + afb*cosThetaL + (3./4.)*fL*(1 - TMath::Power(cosThetaL,2)))";
	RooRealVar * afbB = new RooRealVar("afbB","afbB",0.,-0.5,0.5);
	TString afbBpdf = "(1 + 2*afbB*cosThetaB)";
	RooAbsPdf * teoPdf = new RooGenericPdf("teoPdf",afbLpdf,RooArgSet(*cosThetaL,*afb,*fL));
	RooAbsPdf * teoPdfB = new RooGenericPdf("teoPdfB",afbBpdf,RooArgSet(*cosThetaB,*afbB));

	TreeReader * mydata = datajpsi;
	Str2VarMap jpsiParsLL = getJpsiPars("LL", CutsDef::LLcut, histFile);
	Str2VarMap jpsiParsDD = getJpsiPars("DD", CutsDef::DDcut, histFile);

	vector<TH1 *> fLsysh, afbsysh, afbBsysh, fLsysh_frac, afbsysh_frac, afbBsysh_frac;

	for(int i = 0; i < nbins; i++)
	{
		TString q2name = ((TString)Form("q2_%4.2f_%4.2f",q2min[i],q2max[i])).ReplaceAll(".","");
		if(i>0) { mydata = data; MM->setRange(5400,6000); }
		else { q2name = "jpsi"; MM->setRange(5500,5850); }
		TString curq2cut = Form("TMath::Power(J_psi_1S_MM/1000,2) >= %e && TMath::Power(J_psi_1S_MM/1000,2) < %e",q2min[i],q2max[i]);	
		
		cout << "------------------- q2 bin: " << q2min[i] << " - " << q2max[i] << " -----------------------" << endl;

		/**               GET AND FIT EFFICIENCIES                  **/

		RooAbsPdf * effDDpdf = NULL, * effLLpdf = NULL, * effLLBpdf = NULL, * effDDBpdf = NULL;	
		getEfficiencies(q2min[i],q2max[i],&effLLpdf,&effDDpdf,&effLLBpdf,&effDDBpdf,printeff);
		cout << "Efficiencies extracted" << endl;
		histFile->cd();


		/**                    FIT AFB                  **/


		afb->setVal(0);
		afbB->setVal(-0.37);
		fL->setVal(0.6);

		RooAbsPdf * corrPdfLL = new RooProdPdf("sigPdfLL"+q2name,"corrPdfLL",*teoPdf,*effLLpdf);
		RooAbsPdf * corrPdfDD = new RooProdPdf("sigPdfDD"+q2name,"corrPdfDD",*teoPdf,*effDDpdf);
		RooAbsPdf * corrPdfLLB = new RooProdPdf("sigPdfLLB"+q2name,"corrPdfLLB",*teoPdfB,*effLLBpdf);
		RooAbsPdf * corrPdfDDB = new RooProdPdf("sigPdfDDB"+q2name,"corrPdfDDB",*teoPdfB,*effDDBpdf);

		TCut baseCut = "";
		TCut cutLL = CutsDef::LLcut + (TCut)curq2cut + baseCut;
		TCut cutDD = CutsDef::DDcut + (TCut)curq2cut + baseCut;

		histFile->cd();
		double fracDDv[2], fracLLv[2];
		double nsigDD, nsigLL;
		RooDataSet * dataLL = getDataAndFrac("LL",q2name,mydata,cutLL,MM,&fracLLv[0],jpsiParsLL,&nsigLL);
		RooDataSet * dataDD = getDataAndFrac("DD",q2name,mydata,cutDD,MM,&fracDDv[0],jpsiParsDD,&nsigDD);
		double nevts = nsigDD+nsigLL;

		cout << fixed << setprecision(3) << fracDDv[0] << "   " << fracDDv[1] << endl;
		RooRealVar * fracLL = new RooRealVar("fracLL","fracLL",fracLLv[0]);
		RooRealVar * fracDD = new RooRealVar("fracDD","fracDD",fracDDv[0]);

		RooAbsPdf * bkgLL = NULL, * bkgLLB = NULL, * bkgDD = NULL, * bkgDDB = NULL;
		buildBkgPdfs(q2min[i],q2max[i],"LL",CutsDef::LLcut,&bkgLL,&bkgLLB);
		buildBkgPdfs(q2min[i],q2max[i],"DD",CutsDef::DDcut,&bkgDD,&bkgDDB);
	
		cout << "Backgrounds extracted" << endl;

		RooAbsPdf * modelLL = new RooAddPdf("modelLL","modelLL",RooArgSet(*corrPdfLL,*bkgLL),*fracLL);
		RooAbsPdf * modelDD = new RooAddPdf("modelDD","modelDD",RooArgSet(*corrPdfDD,*bkgDD),*fracDD);
		RooAbsPdf * modelLLB = new RooAddPdf("modelLLB","modelLLB",RooArgSet(*corrPdfLLB,*bkgLLB),*fracLL);
		RooAbsPdf * modelDDB = new RooAddPdf("modelDDB","modelDDB",RooArgSet(*corrPdfDDB,*bkgDDB),*fracDD);

		// CREATE COMBINED DATASET
		RooDataSet * combData = new RooDataSet(Form("combData_%i",i),"combined data",RooArgSet(*MM,*cosThetaL,*cosThetaB),Index(*samples),Import("DD",*dataDD),Import("LL",*dataLL));

		Str2VarMap params;
		params["fL"] = fL;
		params["afb"] = afb;	
		Str2VarMap paramsB;
		paramsB["afbB"] = afbB;

		// FIT COS LEPTON
		RooSimultaneous * combModel = new RooSimultaneous(Form("combModel_%i",i),"",*samples);
		combModel->addPdf(*modelLL,"LL");
		combModel->addPdf(*modelDD,"DD");

		RooFitResult * res = safeFit(combModel,combData,params,&isInAllowedArea);	
	
		// FIT COS HADRON
		RooSimultaneous * combModelB = new RooSimultaneous(Form("combModelB_%i",i),"",*samples);
		combModelB->addPdf(*modelLLB,"LL");
		combModelB->addPdf(*modelDDB,"DD");

		RooFitResult * resB = safeFit(combModelB,combData,paramsB,&isInAllowedAreaB);

		cout << endl << fixed << setprecision(6) << "AfbB = " << afbB->getVal() << " +/- " << afbB->getError() << endl;
		cout << "Afb = " << afb->getVal() << " +/- " << afb->getError() << endl;
		cout << "fL = " << fL->getVal() << " +/- " << fL->getError() << endl;
		cout << endl;
		cout << "lepton:  " << res->edm() << "   "  << res->covQual() << endl;
		cout << "baryon:  " << resB->edm() << "   "  << resB->covQual() << endl;
		cout << endl;

		TH1F * fLsys = new TH1F(Form("fLsys_%i",i),"fLsys",40,-1,1);
		TH1F * afbsys = new TH1F(Form("afbsys_%i",i),"afbsys",40,-1,1);
		TH1F * afbBsys = new TH1F(Form("afbBsys_%i",i),"afbBsys",40,-1,1);
		TH1F * fLsys_frac = new TH1F(Form("fLsys_frac%i",i),"fLsys",40,-1,1);
		TH1F * afbsys_frac = new TH1F(Form("afbsys_frac%i",i),"afbsys",40,-1,1);
		TH1F * afbBsys_frac = new TH1F(Form("afbBsys_frac%i",i),"afbBsys",40,-1,1);


		RooAbsPdf * mybkgDD_2 = NULL, * mybkgDDB_2 = NULL;
		buildBkgPdfs(q2min[i],q2max[i],"DD",CutsDef::DDcut,&mybkgDD_2,&mybkgDDB_2,"RooKeyPdf");

		//cout << nevts << endl;
		//TRandom3 r(0);

		for(int e = 0; e < nexp; e++)
		{
			histFile->cd();
			RooAbsPdf * toypdf = (RooAbsPdf *)modelDD->Clone();
			Analysis * toy = new Analysis("toy",cosThetaL,modelDD,nevts);
			RooAbsPdf * toypdfB = (RooAbsPdf *)modelDDB->Clone();
			Analysis * toyB = new Analysis("toyB",cosThetaB,modelDDB,nevts);
			
			afb->setVal(0);
			afbB->setVal(-0.37);
			fL->setVal(0.6);

			safeFit(toypdf,toy->GetDataSet("-recalc"),params,&isInAllowedArea);
			safeFit(toypdfB,toyB->GetDataSet("-recalc"),paramsB,&isInAllowedAreaB);
			double def_afb = afb->getVal();
			double def_fL = fL->getVal();
			double def_afbB = afbB->getVal();

			afb->setVal(0);
			afbB->setVal(-0.37);
			fL->setVal(0.6);

			RooAbsPdf * modelDD_2 = new RooAddPdf("modelDD_2","modelDD",RooArgSet(*corrPdfDD,*mybkgDD_2),*fracDD);
			RooAbsPdf * modelDDB_2 = new RooAddPdf("modelDDB_2","modelDDB",RooArgSet(*corrPdfDDB,*mybkgDDB_2),*fracDD);
			safeFit(modelDD_2,toy->GetDataSet("-recalc"),params,&isInAllowedArea);
			safeFit(modelDDB_2,toyB->GetDataSet("-recalc"),paramsB,&isInAllowedAreaB);
			double oth_afb = afb->getVal();
			double oth_fL = fL->getVal();
			double oth_afbB = afbB->getVal();

			fLsys->Fill(oth_fL-def_fL);
			afbsys->Fill(oth_afb-def_afb);
			afbBsys->Fill(oth_afbB-def_afbB);
			

			afb->setVal(0.);
			afbB->setVal(-0.37);
			fL->setVal(0.6);

			//double rdm_frac = r.Gaus(fracDDv[0],fracDDv[1]);
			double rdm_frac = fracDDv[0] + fracDDv[1];
			RooRealVar * fracDD_2 = new RooRealVar("fracDD_2","fracDD_2",rdm_frac);	
			RooAbsPdf * modelDD_3 = new RooAddPdf("modelDD_3","modelDD",RooArgSet(*corrPdfDD,*bkgDD),*fracDD_2);
			RooAbsPdf * modelDDB_3 = new RooAddPdf("modelDDB_3","modelDDB",RooArgSet(*corrPdfDDB,*bkgDDB),*fracDD_2);
			safeFit(modelDD_3,toy->GetDataSet("-recalc"),params,&isInAllowedArea);
			safeFit(modelDDB_3,toyB->GetDataSet("-recalc"),paramsB,&isInAllowedAreaB);

			double frc_afb = afb->getVal();
			double frc_fL = fL->getVal();
			double frc_afbB = afbB->getVal();

			fLsys_frac->Fill(frc_fL-def_fL);
			afbsys_frac->Fill(frc_afb-def_afb);
			afbBsys_frac->Fill(frc_afbB-def_afbB);
			
		}

		afbsysh.push_back(afbsys);
		afbBsysh.push_back(afbBsys);
		fLsysh.push_back(fLsys);
		afbsysh_frac.push_back(afbsys_frac);
		afbBsysh_frac.push_back(afbBsys_frac);
		fLsysh_frac.push_back(fLsys_frac);

	}

	
	for(int q = 0; q < nbins; q++)
	{
		cout << fixed << setprecision(2) << "-------- Bin " << q2min[q] << "-" << q2max[q] << endl;
		cout << fixed << setprecision(5) << "fL sys = " << fLsysh[q]->GetMean() << " +/- " << fLsysh[q]->GetMeanError() << endl;
		cout << "Afb sys = " << afbsysh[q]->GetMean() << " +/- " << afbsysh[q]->GetMeanError() << endl;
		cout << "AfbB sys = " << afbBsysh[q]->GetMean() << " +/- " << afbBsysh[q]->GetMeanError() << endl;
	}

	cout << "#################################################################" << endl;
	for(int q = 0; q < nbins; q++)
	{
		cout << fixed << setprecision(2) << "-------- Bin " << q2min[q] << "-" << q2max[q] << endl;
		cout << fixed << setprecision(5) << "fL sys = " << fLsysh_frac[q]->GetMean() << " +/- " << fLsysh_frac[q]->GetMeanError() << endl;
		cout << "Afb sys = " << afbsysh_frac[q]->GetMean() << " +/- " << afbsysh_frac[q]->GetMeanError() << endl;
		cout << "AfbB sys = " << afbBsysh_frac[q]->GetMean() << " +/- " << afbBsysh_frac[q]->GetMeanError() << endl;
	}

	cout << "#################################################################" << endl;
	for(int q = 0; q < nbins; q++)
	{
		cout << fixed << setprecision(2) << "-------- Bin " << q2min[q] << "-" << q2max[q] << endl;
		cout << fixed << setprecision(5) << "fL sys = " << TMath::Sqrt(TMath::Power(fLsysh_frac[q]->GetMean(),2) + TMath::Power(fLsysh[q]->GetMean(),2) )  << endl;
		cout << "Afb sys = " << TMath::Sqrt(TMath::Power(afbsysh_frac[q]->GetMean(),2) + TMath::Power(afbsysh[q]->GetMean(),2) ) << endl;
		cout << "AfbB sys = " << TMath::Sqrt(TMath::Power(afbBsysh_frac[q]->GetMean(),2) + TMath::Power(afbBsysh[q]->GetMean(),2) ) << endl;
	}

}
void OneSidedFrequentistUpperLimitWithBands(const char* infile = "",
                                            const char* workspaceName = "combined",
                                            const char* modelConfigName = "ModelConfig",
                                            const char* dataName = "obsData") {



   double confidenceLevel=0.95;
   int nPointsToScan = 20;
   int nToyMC = 200;

   // -------------------------------------------------------
   // First part is just to access a user-defined file
   // or create the standard example file if it doesn't exist
   const char* filename = "";
   if (!strcmp(infile,"")) {
      filename = "results/example_combined_GaussExample_model.root";
      bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code
      // if file does not exists generate with histfactory
      if (!fileExist) {
#ifdef _WIN32
         cout << "HistFactory file cannot be generated on Windows - exit" << endl;
         return;
#endif
         // Normally this would be run on the command line
         cout <<"will run standard hist2workspace example"<<endl;
         gROOT->ProcessLine(".! prepareHistFactory .");
         gROOT->ProcessLine(".! hist2workspace config/example.xml");
         cout <<"\n\n---------------------"<<endl;
         cout <<"Done creating example input"<<endl;
         cout <<"---------------------\n\n"<<endl;
      }

   }
   else
      filename = infile;

   // Try to open the file
   TFile *file = TFile::Open(filename);

   // if input file was specified byt not found, quit
   if(!file ){
      cout <<"StandardRooStatsDemoMacro: Input file " << filename << " is not found" << endl;
      return;
   }


   // -------------------------------------------------------
   // Now get the data and workspace

   // get the workspace out of the file
   RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName);
   if(!w){
      cout <<"workspace not found" << endl;
      return;
   }

   // get the modelConfig out of the file
   ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName);

   // get the modelConfig out of the file
   RooAbsData* data = w->data(dataName);

   // make sure ingredients are found
   if(!data || !mc){
      w->Print();
      cout << "data or ModelConfig was not found" <<endl;
      return;
   }

   // -------------------------------------------------------
   // Now get the POI for convenience
   // you may want to adjust the range of your POI

   RooRealVar* firstPOI = (RooRealVar*) mc->GetParametersOfInterest()->first();
   /*  firstPOI->setMin(0);*/
   /*  firstPOI->setMax(10);*/

   // --------------------------------------------
   // Create and use the FeldmanCousins tool
   // to find and plot the 95% confidence interval
   // on the parameter of interest as specified
   // in the model config
   // REMEMBER, we will change the test statistic
   // so this is NOT a Feldman-Cousins interval
   FeldmanCousins fc(*data,*mc);
   fc.SetConfidenceLevel(confidenceLevel);
   /*  fc.AdditionalNToysFactor(0.25); // degrade/improve sampling that defines confidence belt*/
   /*  fc.UseAdaptiveSampling(true); // speed it up a bit, don't use for expected limits*/
   fc.SetNBins(nPointsToScan); // set how many points per parameter of interest to scan
   fc.CreateConfBelt(true); // save the information in the belt for plotting

   // -------------------------------------------------------
   // Feldman-Cousins is a unified limit by definition
   // but the tool takes care of a few things for us like which values
   // of the nuisance parameters should be used to generate toys.
   // so let's just change the test statistic and realize this is
   // no longer "Feldman-Cousins" but is a fully frequentist Neyman-Construction.
   /*  ProfileLikelihoodTestStatModified onesided(*mc->GetPdf());*/
   /*  fc.GetTestStatSampler()->SetTestStatistic(&onesided);*/
   /* ((ToyMCSampler*) fc.GetTestStatSampler())->SetGenerateBinned(true); */
   ToyMCSampler*  toymcsampler = (ToyMCSampler*) fc.GetTestStatSampler();
   ProfileLikelihoodTestStat* testStat = dynamic_cast<ProfileLikelihoodTestStat*>(toymcsampler->GetTestStatistic());
   testStat->SetOneSided(true);

   // Since this tool needs to throw toy MC the PDF needs to be
   // extended or the tool needs to know how many entries in a dataset
   // per pseudo experiment.
   // In the 'number counting form' where the entries in the dataset
   // are counts, and not values of discriminating variables, the
   // datasets typically only have one entry and the PDF is not
   // extended.
   if(!mc->GetPdf()->canBeExtended()){
      if(data->numEntries()==1)
         fc.FluctuateNumDataEntries(false);
      else
         cout <<"Not sure what to do about this model" <<endl;
   }

   // We can use PROOF to speed things along in parallel
   // However, the test statistic has to be installed on the workers
   // so either turn off PROOF or include the modified test statistic
   // in your `$ROOTSYS/roofit/roostats/inc` directory,
   // add the additional line to the LinkDef.h file,
   // and recompile root.
   if (useProof) {
      ProofConfig pc(*w, nworkers, "", false);
      toymcsampler->SetProofConfig(&pc); // enable proof
   }

   if(mc->GetGlobalObservables()){
      cout << "will use global observables for unconditional ensemble"<<endl;
      mc->GetGlobalObservables()->Print();
      toymcsampler->SetGlobalObservables(*mc->GetGlobalObservables());
   }


   // Now get the interval
   PointSetInterval* interval = fc.GetInterval();
   ConfidenceBelt* belt = fc.GetConfidenceBelt();

   // print out the interval on the first Parameter of Interest
   cout << "\n95% interval on " <<firstPOI->GetName()<<" is : ["<<
      interval->LowerLimit(*firstPOI) << ", "<<
      interval->UpperLimit(*firstPOI) <<"] "<<endl;

   // get observed UL and value of test statistic evaluated there
   RooArgSet tmpPOI(*firstPOI);
   double observedUL = interval->UpperLimit(*firstPOI);
   firstPOI->setVal(observedUL);
   double obsTSatObsUL = fc.GetTestStatSampler()->EvaluateTestStatistic(*data,tmpPOI);


   // Ask the calculator which points were scanned
   RooDataSet* parameterScan = (RooDataSet*) fc.GetPointsToScan();
   RooArgSet* tmpPoint;

   // make a histogram of parameter vs. threshold
   TH1F* histOfThresholds = new TH1F("histOfThresholds","",
                                       parameterScan->numEntries(),
                                       firstPOI->getMin(),
                                       firstPOI->getMax());
   histOfThresholds->GetXaxis()->SetTitle(firstPOI->GetName());
   histOfThresholds->GetYaxis()->SetTitle("Threshold");

   // loop through the points that were tested and ask confidence belt
   // what the upper/lower thresholds were.
   // For FeldmanCousins, the lower cut off is always 0
   for(Int_t i=0; i<parameterScan->numEntries(); ++i){
      tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp");
      //cout <<"get threshold"<<endl;
      double arMax = belt->GetAcceptanceRegionMax(*tmpPoint);
      double poiVal = tmpPoint->getRealValue(firstPOI->GetName()) ;
      histOfThresholds->Fill(poiVal,arMax);
   }
   TCanvas* c1 = new TCanvas();
   c1->Divide(2);
   c1->cd(1);
   histOfThresholds->SetMinimum(0);
   histOfThresholds->Draw();
   c1->cd(2);

   // -------------------------------------------------------
   // Now we generate the expected bands and power-constraint

   // First: find parameter point for mu=0, with conditional MLEs for nuisance parameters
   RooAbsReal* nll = mc->GetPdf()->createNLL(*data);
   RooAbsReal* profile = nll->createProfile(*mc->GetParametersOfInterest());
   firstPOI->setVal(0.);
   profile->getVal(); // this will do fit and set nuisance parameters to profiled values
   RooArgSet* poiAndNuisance = new RooArgSet();
   if(mc->GetNuisanceParameters())
      poiAndNuisance->add(*mc->GetNuisanceParameters());
   poiAndNuisance->add(*mc->GetParametersOfInterest());
   w->saveSnapshot("paramsToGenerateData",*poiAndNuisance);
   RooArgSet* paramsToGenerateData = (RooArgSet*) poiAndNuisance->snapshot();
   cout << "\nWill use these parameter points to generate pseudo data for bkg only" << endl;
   paramsToGenerateData->Print("v");


   RooArgSet unconditionalObs;
   unconditionalObs.add(*mc->GetObservables());
   unconditionalObs.add(*mc->GetGlobalObservables()); // comment this out for the original conditional ensemble

   double CLb=0;
   double CLbinclusive=0;

   // Now we generate background only and find distribution of upper limits
   TH1F* histOfUL = new TH1F("histOfUL","",100,0,firstPOI->getMax());
   histOfUL->GetXaxis()->SetTitle("Upper Limit (background only)");
   histOfUL->GetYaxis()->SetTitle("Entries");
   for(int imc=0; imc<nToyMC; ++imc){

      // set parameters back to values for generating pseudo data
      //    cout << "\n get current nuis, set vals, print again" << endl;
      w->loadSnapshot("paramsToGenerateData");
      //    poiAndNuisance->Print("v");

      RooDataSet* toyData = 0;
      // now generate a toy dataset
      if(!mc->GetPdf()->canBeExtended()){
         if(data->numEntries()==1)
            toyData = mc->GetPdf()->generate(*mc->GetObservables(),1);
         else
            cout <<"Not sure what to do about this model" <<endl;
      } else{
         //      cout << "generating extended dataset"<<endl;
         toyData = mc->GetPdf()->generate(*mc->GetObservables(),Extended());
      }

      // generate global observables
      // need to be careful for simpdf
      //    RooDataSet* globalData = mc->GetPdf()->generate(*mc->GetGlobalObservables(),1);

      RooSimultaneous* simPdf = dynamic_cast<RooSimultaneous*>(mc->GetPdf());
      if(!simPdf){
         RooDataSet *one = mc->GetPdf()->generate(*mc->GetGlobalObservables(), 1);
         const RooArgSet *values = one->get();
         RooArgSet *allVars = mc->GetPdf()->getVariables();
         *allVars = *values;
         delete allVars;
         delete values;
         delete one;
      } else {

         //try fix for sim pdf
         TIterator* iter = simPdf->indexCat().typeIterator() ;
         RooCatType* tt = NULL;
         while((tt=(RooCatType*) iter->Next())) {

            // Get pdf associated with state from simpdf
            RooAbsPdf* pdftmp = simPdf->getPdf(tt->GetName()) ;

            // Generate only global variables defined by the pdf associated with this state
            RooArgSet* globtmp = pdftmp->getObservables(*mc->GetGlobalObservables()) ;
            RooDataSet* tmp = pdftmp->generate(*globtmp,1) ;

            // Transfer values to output placeholder
            *globtmp = *tmp->get(0) ;

            // Cleanup
            delete globtmp ;
            delete tmp ;
         }
      }

      //    globalData->Print("v");
      //    unconditionalObs = *globalData->get();
      //    mc->GetGlobalObservables()->Print("v");
      //    delete globalData;
      //    cout << "toy data = " << endl;
      //    toyData->get()->Print("v");

      // get test stat at observed UL in observed data
      firstPOI->setVal(observedUL);
      double toyTSatObsUL = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI);
      //    toyData->get()->Print("v");
      //    cout <<"obsTSatObsUL " <<obsTSatObsUL << "toyTS " << toyTSatObsUL << endl;
      if(obsTSatObsUL < toyTSatObsUL) // not sure about <= part yet
         CLb+= (1.)/nToyMC;
      if(obsTSatObsUL <= toyTSatObsUL) // not sure about <= part yet
         CLbinclusive+= (1.)/nToyMC;


      // loop over points in belt to find upper limit for this toy data
      double thisUL = 0;
      for(Int_t i=0; i<parameterScan->numEntries(); ++i){
         tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp");
         double arMax = belt->GetAcceptanceRegionMax(*tmpPoint);
         firstPOI->setVal( tmpPoint->getRealValue(firstPOI->GetName()) );
         //   double thisTS = profile->getVal();
         double thisTS = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI);

         //   cout << "poi = " << firstPOI->getVal()
         // << " max is " << arMax << " this profile = " << thisTS << endl;
         //      cout << "thisTS = " << thisTS<<endl;
         if(thisTS<=arMax){
            thisUL = firstPOI->getVal();
         } else{
            break;
         }
      }



      /*
      // loop over points in belt to find upper limit for this toy data
      double thisUL = 0;
      for(Int_t i=0; i<histOfThresholds->GetNbinsX(); ++i){
         tmpPoint = (RooArgSet*) parameterScan->get(i)->clone("temp");
         cout <<"----------------  "<<i<<endl;
         tmpPoint->Print("v");
         cout << "from hist " << histOfThresholds->GetBinCenter(i+1) <<endl;
         double arMax = histOfThresholds->GetBinContent(i+1);
         // cout << " threhold from Hist = aMax " << arMax<<endl;
         // double arMax2 = belt->GetAcceptanceRegionMax(*tmpPoint);
         // cout << "from scan arMax2 = "<< arMax2 << endl; // not the same due to TH1F not TH1D
         // cout << "scan - hist" << arMax2-arMax << endl;
         firstPOI->setVal( histOfThresholds->GetBinCenter(i+1));
         //   double thisTS = profile->getVal();
         double thisTS = fc.GetTestStatSampler()->EvaluateTestStatistic(*toyData,tmpPOI);

         //   cout << "poi = " << firstPOI->getVal()
         // << " max is " << arMax << " this profile = " << thisTS << endl;
         //      cout << "thisTS = " << thisTS<<endl;

         // NOTE: need to add a small epsilon term for single precision vs. double precision
         if(thisTS<=arMax + 1e-7){
            thisUL = firstPOI->getVal();
         } else{
            break;
         }
      }
      */

      histOfUL->Fill(thisUL);

      // for few events, data is often the same, and UL is often the same
      //    cout << "thisUL = " << thisUL<<endl;

      delete toyData;
   }
   histOfUL->Draw();
   c1->SaveAs("one-sided_upper_limit_output.pdf");

   // if you want to see a plot of the sampling distribution for a particular scan point:
   /*
   SamplingDistPlot sampPlot;
   int indexInScan = 0;
   tmpPoint = (RooArgSet*) parameterScan->get(indexInScan)->clone("temp");
   firstPOI->setVal( tmpPoint->getRealValue(firstPOI->GetName()) );
   toymcsampler->SetParametersForTestStat(tmpPOI);
   SamplingDistribution* samp = toymcsampler->GetSamplingDistribution(*tmpPoint);
   sampPlot.AddSamplingDistribution(samp);
   sampPlot.Draw();
      */

   // Now find bands and power constraint
   Double_t* bins = histOfUL->GetIntegral();
   TH1F* cumulative = (TH1F*) histOfUL->Clone("cumulative");
   cumulative->SetContent(bins);
   double band2sigDown, band1sigDown, bandMedian, band1sigUp,band2sigUp;
   for(int i=1; i<=cumulative->GetNbinsX(); ++i){
      if(bins[i]<RooStats::SignificanceToPValue(2))
         band2sigDown=cumulative->GetBinCenter(i);
      if(bins[i]<RooStats::SignificanceToPValue(1))
         band1sigDown=cumulative->GetBinCenter(i);
      if(bins[i]<0.5)
         bandMedian=cumulative->GetBinCenter(i);
      if(bins[i]<RooStats::SignificanceToPValue(-1))
         band1sigUp=cumulative->GetBinCenter(i);
      if(bins[i]<RooStats::SignificanceToPValue(-2))
         band2sigUp=cumulative->GetBinCenter(i);
   }
   cout << "-2 sigma  band " << band2sigDown << endl;
   cout << "-1 sigma  band " << band1sigDown << " [Power Constraint)]" << endl;
   cout << "median of band " << bandMedian << endl;
   cout << "+1 sigma  band " << band1sigUp << endl;
   cout << "+2 sigma  band " << band2sigUp << endl;

   // print out the interval on the first Parameter of Interest
   cout << "\nobserved 95% upper-limit "<< interval->UpperLimit(*firstPOI) <<endl;
   cout << "CLb strict [P(toy>obs|0)] for observed 95% upper-limit "<< CLb <<endl;
   cout << "CLb inclusive [P(toy>=obs|0)] for observed 95% upper-limit "<< CLbinclusive <<endl;

   delete profile;
   delete nll;

}
void ZeeGammaMassFitSystematicStudy(string workspaceFile, const Int_t seed = 1234, 
                                    Int_t Option = 0, Int_t NToys = 1) {


  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================    
  TRandom3 *randomnumber = new TRandom3(seed);
//   RooRealVar m("m","mass",60,130);

  RooCategory sample("sample","");
  sample.defineType("Pass",1);
  sample.defineType("Fail",2);

  //--------------------------------------------------------------------------------------------------------------
  //Load Workspace
  //==============================================================================================================    
  TFile *f = new TFile (workspaceFile.c_str(), "READ");
  RooWorkspace *w = (RooWorkspace*)f->Get("MassFitWorkspace");

  //--------------------------------------------------------------------------------------------------------------
  //Setup output tree
  //==============================================================================================================    
  TFile *outputfile = new TFile (Form("EffToyResults_Option%d_Seed%d.root",Option, seed), "RECREATE");
  float varEff = 0;
  float varEffErrL = 0;
  float varEffErrH = 0;
  TTree *outTree = new TTree("eff","eff");
  outTree->Branch("eff",&varEff, "eff/F");
  outTree->Branch("efferrl",&varEffErrL, "efferrl/F");
  outTree->Branch("efferrh",&varEffErrH, "efferrh/F");
  
  //--------------------------------------------------------------------------------------------------------------
  //Load Model
  //==============================================================================================================    
  RooSimultaneous *totalPdf = (RooSimultaneous*)w->pdf("totalPdf");
  RooRealVar *m_default = (RooRealVar*)w->var("m");
  m_default->setRange("signalRange",85, 95);
  
  //get default models
  RooAddPdf *modelPass_default = (RooAddPdf*)w->pdf("modelPass");
  RooAddPdf *modelFail_default = (RooAddPdf*)w->pdf("modelFail");

  //get variables
  RooRealVar *Nsig = (RooRealVar*)w->var("Nsig");
  RooRealVar *eff = (RooRealVar*)w->var("eff");
  RooRealVar *NbkgFail = (RooRealVar*)w->var("NbkgFail");

  RooFormulaVar NsigPass("NsigPass","eff*Nsig",RooArgList(*eff,*Nsig));	 
  RooFormulaVar NsigFail("NsigFail","(1.0-eff)*Nsig",RooArgList(*eff,*Nsig));

  //get number of expected events
  Double_t npass = 100;
  Double_t nfail = 169;

  //*************************************************************************************
  //make alternative model
  //*************************************************************************************
  RooRealVar *tFail_default = (RooRealVar*)w->var("tFail");
  RooRealVar *fracFail_default = (RooRealVar*)w->var("fracFail");
 

  RooRealVar *meanFail_default = (RooRealVar*)w->var("meanFail");
  RooRealVar *sigmaFail_default = (RooRealVar*)w->var("sigmaFail");
  RooHistPdf *bkgFailTemplate_default = (RooHistPdf*)w->pdf("bkgHistPdfFail");
  RooFFTConvPdf *sigFail_default = (RooFFTConvPdf*)w->pdf("signalFail");
  RooFFTConvPdf *bkgFail_default = (RooFFTConvPdf*)w->pdf("bkgConvPdfFail");
  RooExtendPdf *esignalFail_default = (RooExtendPdf *)w->pdf("esignalFail");
  RooExtendPdf *ebackgroundFail_default = (RooExtendPdf *)w->pdf("ebackgroundFail");
  RooExponential *bkgexpFail_default = (RooExponential*)w->pdf("bkgexpFail");
  RooAddPdf *backgroundFail_default = (RooAddPdf*)w->pdf("backgroundFail");
  RooGaussian *bkggausFail_default = (RooGaussian*)w->pdf("bkggausFail");

  //shifted mean
  RooRealVar *meanFail_shifted = new RooRealVar("meanFail_shifted","meanFail_shifted", 0, -5, 5);
  meanFail_shifted->setVal(meanFail_default->getVal());
  if (Option == 1) meanFail_shifted->setVal(meanFail_default->getVal()-1.0);
  else if (Option == 2) meanFail_shifted->setVal(meanFail_default->getVal()+1.0);  
  else if (Option == 11) meanFail_shifted->setVal(meanFail_default->getVal()-2.0);
  else if (Option == 12) meanFail_shifted->setVal(meanFail_default->getVal()+2.0);  

  RooRealVar *sigmaFail_shifted = new RooRealVar("sigmaFail_shifted","sigmaFail_shifted", 0, -5, 5);
  sigmaFail_shifted->setVal(sigmaFail_default->getVal());
  if (Option == 3) sigmaFail_shifted->setVal(sigmaFail_default->getVal()*1.2);
  else if (Option == 4) sigmaFail_shifted->setVal(sigmaFail_default->getVal()*0.8);

  CMCBkgTemplateConvGaussianPlusExp *bkgFailModel = new CMCBkgTemplateConvGaussianPlusExp(*m_default,bkgFailTemplate_default,false,meanFail_shifted,sigmaFail_shifted, "shifted");
  bkgFailModel->t->setVal(tFail_default->getVal());
  bkgFailModel->frac->setVal(fracFail_default->getVal());

  cout << "mean : " << meanFail_default->getVal() << " - " << meanFail_shifted->getVal() << endl;
  cout << "sigma : " << sigmaFail_default->getVal() << " - " << sigmaFail_shifted->getVal() << endl;
  cout << "t: " << tFail_default->getVal() << " - " << bkgFailModel->t->getVal() << endl;
  cout << "frac: " << fracFail_default->getVal() << " - " << bkgFailModel->frac->getVal() << endl;
  
  cout << "eff: " << eff->getVal() << " : " << NsigPass.getVal() << " / " << (NsigPass.getVal() + NsigFail.getVal()) << endl;
  cout << "NbkgFail: " << NbkgFail->getVal() << endl;


  //make alternative fail model
  RooAddPdf *modelFail=0;
  RooExtendPdf *esignalFail=0, *ebackgroundFail=0;
  ebackgroundFail = new RooExtendPdf("ebackgroundFail_shifted","ebackgroundFail_shifted",*(bkgFailModel->model),*NbkgFail,"signalRange");
  modelFail       = new RooAddPdf("modelFail","Model for FAIL sample", RooArgList(*esignalFail_default,*ebackgroundFail));



  cout << "*************************************\n";
  ebackgroundFail->Print();
  cout << "*************************************\n";
  ebackgroundFail_default->Print();
  cout << "*************************************\n";
  modelFail->Print();
  cout << "*************************************\n";
  modelFail_default->Print();
  cout << "*************************************\n";

  TCanvas *cv = new TCanvas("cv","cv",800,600);

  RooPlot *mframeFail_default = m_default->frame(Bins(Int_t(130-60)/2));
  modelFail_default->plotOn(mframeFail_default);
  modelFail_default->plotOn(mframeFail_default,Components("ebackgroundFail"),LineStyle(kDashed),LineColor(kRed));
  modelFail_default->plotOn(mframeFail_default,Components("bkgexpFail"),LineStyle(kDashed),LineColor(kGreen+2));
  mframeFail_default->GetYaxis()->SetTitle("");
  mframeFail_default->GetYaxis()->SetTitleOffset(1.2);
  mframeFail_default->GetXaxis()->SetTitle("m_{ee#gamma} [GeV/c^{2}]");
  mframeFail_default->GetXaxis()->SetTitleOffset(1.05);
  mframeFail_default->SetTitle("");
  mframeFail_default->Draw();

  cv->SaveAs("DefaultModel.gif");

  RooPlot *mframeFail = m_default->frame(Bins(Int_t(130-60)/2));
  modelFail->plotOn(mframeFail);
  modelFail->plotOn(mframeFail,Components("ebackgroundFail_shifted"),LineStyle(kDashed),LineColor(kRed));
  modelFail->plotOn(mframeFail,Components("bkgexpFail_shifted"),LineStyle(kDashed),LineColor(kGreen+2));
  mframeFail->GetYaxis()->SetTitle("");
  mframeFail->GetYaxis()->SetTitleOffset(1.2);
  mframeFail->GetXaxis()->SetTitle("m_{ee#gamma} [GeV/c^{2}]");
  mframeFail->GetXaxis()->SetTitleOffset(1.05);
  mframeFail->SetTitle("");
  mframeFail->Draw();
  cv->SaveAs(Form("ShiftedModel_%d.gif",Option));


  //*************************************************************************************
  //Do Toys
  //*************************************************************************************
  for(uint t=0; t < NToys; ++t) {

    RooDataSet *pseudoData_pass    = modelPass_default->generate(*m_default, randomnumber->Poisson(npass));
    RooDataSet *pseudoData_fail  = 0;
    pseudoData_fail    = modelFail->generate(*m_default, randomnumber->Poisson(nfail));
    RooDataSet *pseudoDataCombined = new RooDataSet("pseudoDataCombined","pseudoDataCombined",RooArgList(*m_default),
                                                    RooFit::Index(sample),
                                                    RooFit::Import("Pass",*pseudoData_pass),
                                                    RooFit::Import("Fail",*pseudoData_fail));

    pseudoDataCombined->write(Form("toy%d.txt",t));

    RooFitResult *fitResult=0;
    fitResult = totalPdf->fitTo(*pseudoDataCombined,
                                RooFit::Extended(),
                                RooFit::Strategy(2),
                                //RooFit::Minos(RooArgSet(eff)),
                                RooFit::Save());

    cout << "\n\n";
    cout << "Eff Fit: " << eff->getVal() << " -" << fabs(eff->getErrorLo()) << " +" << eff->getErrorHi() << endl;

    //Fill Tree
    varEff = eff->getVal();
    varEffErrL = fabs(eff->getErrorLo());
    varEffErrH = eff->getErrorHi();
    outTree->Fill();


//   //*************************************************************************************
//   //Plot Toys
//   //*************************************************************************************
//   TCanvas *cv = new TCanvas("cv","cv",800,600);
//   char pname[50];
//   char binlabelx[100];
//   char binlabely[100];
//   char yield[50];
//   char effstr[100];
//   char nsigstr[100];
//   char nbkgstr[100];
//   char chi2str[100];

//   //
//   // Plot passing probes
//   //

//   RooPlot *mframeFail_default = m.frame(Bins(Int_t(130-60)/2));
//   modelFail_default->plotOn(mframeFail_default);
//   modelFail_default->plotOn(mframeFail_default,Components("ebackgroundFail"),LineStyle(kDashed),LineColor(kRed));
//   modelFail_default->plotOn(mframeFail_default,Components("bkgexpFail"),LineStyle(kDashed),LineColor(kGreen+2));
//   mframeFail_default->Draw();
//   cv->SaveAs("DefaultModel.gif");





//   RooPlot *mframeFail = m.frame(Bins(Int_t(130-60)/2));
//   modelFail->plotOn(mframeFail);
//   modelFail->plotOn(mframeFail,Components("ebackgroundFail_shifted"),LineStyle(kDashed),LineColor(kRed));
//   modelFail->plotOn(mframeFail,Components("bkgexpFail_shifted"),LineStyle(kDashed),LineColor(kGreen+2));

//   sprintf(yield,"%u Events",(Int_t)passTree->GetEntries());
//   sprintf(nsigstr,"N_{sig} = %.1f #pm %.1f",NsigPass.getVal(),NsigPass.getPropagatedError(*fitResult));
//     plotPass.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);    
//   plotPass.AddTextBox(effstr,0.70,0.85,0.94,0.90,0,kBlack,-1);
//     plotPass.AddTextBox(0.70,0.73,0.94,0.83,0,kBlack,-1,1,nsigstr);//,chi2str);

//   mframeFail->Draw();
//   cv->SaveAs(Form("ShiftedModel_%d.gif",Option));


 
//   //
//   // Plot failing probes
//   //
//   sprintf(pname,"fail%s_%i",name.Data(),ibin);
//   sprintf(yield,"%u Events",(Int_t)failTree->GetEntries());
//   sprintf(nsigstr,"N_{sig} = %.1f #pm %.1f",NsigFail.getVal(),NsigFail.getPropagatedError(*fitResult));
//   sprintf(nbkgstr,"N_{bkg} = %.1f #pm %.1f",NbkgFail.getVal(),NbkgFail.getPropagatedError(*fitResult));
//   sprintf(chi2str,"#chi^{2}/DOF = %.3f",mframePass->chiSquare(nflfail));
//   CPlot plotFail(pname,mframeFail,"Failing probes","tag-probe mass [GeV/c^{2}]","Events / 2.0 GeV/c^{2}");
//   plotFail.AddTextBox(binlabelx,0.21,0.85,0.51,0.90,0,kBlack,-1);
//   if((name.CompareTo("etapt")==0) || (name.CompareTo("etaphi")==0)) {
//     plotFail.AddTextBox(binlabely,0.21,0.80,0.51,0.85,0,kBlack,-1);    
//     plotFail.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);    
//   } else {
//     plotFail.AddTextBox(yield,0.21,0.81,0.51,0.85,0,kBlack,-1);
//   }
//   plotFail.AddTextBox(effstr,0.70,0.85,0.94,0.90,0,kBlack,-1);  
//   plotFail.AddTextBox(0.70,0.68,0.94,0.83,0,kBlack,-1,2,nsigstr,nbkgstr);//,chi2str);
//   plotFail.Draw(cfail,kTRUE,format);  




  } //for loop over all toys
  



  //*************************************************************************************
  //Save To File
  //*************************************************************************************
  outputfile->WriteTObject(outTree, outTree->GetName(), "WriteDelete");

}
// total PDF
void makeTotalPdf( RooWorkspace *w ) {

  // constrain the bs->phikst / bd->phikst ratio
  w->factory( "yield_ratio_bs2phikst_o_bd2phikst[0.,1.]" );
  w->factory( "Gaussian::yield_ratio_bs2phikst_o_bd2phikst_constraint( yield_ratio_bs2phikst_o_bd2phikst, 0.113, 0.0287 )" );
  // constrain the bd->rhokst / bd->phikst ratio
  w->factory("yield_ratio_bd2rhokst_o_bd2phikst[0.,1.]" );
  w->factory( "Gaussian::yield_ratio_bd2rhokst_o_bd2phikst_constraint( yield_ratio_bd2rhokst_o_bd2phikst, 0.390, 0.130 )" ); // PDG err is 0.130 (relax this for eff)

  // make a yield for each category
  RooCategory *cat = (RooCategory*)w->cat("DataCat");
  for ( int i=0; i < cat->numTypes(); i++ ) {
    cat->setIndex(i);
    w->factory( Form("bkg_y_%s[200,400e3]",       cat->getLabel()));
    w->factory( Form("part_reco_y_%s[100,200e3]", cat->getLabel()));
    w->factory( Form("bs2kstkst_y_%s[0,20e3]", cat->getLabel()));
    w->factory( Form("bd2kstkst_y_%s[0,3000]", cat->getLabel()));
    w->factory( Form("bd2phikst_y_%s[10,5000]", cat->getLabel()));
    // add bs2phikst yield as constrained ratio
    w->factory( Form("prod::bs2phikst_y_%s( yield_ratio_bs2phikst_o_bd2phikst, bd2phikst_y_%s )", cat->getLabel(), cat->getLabel()) );
    //w->factory( Form("bs2phikst_y_%s[10,5000]", cat->getLabel()));
    // add bd2rhokst yield as constrained ratio
    w->factory( Form("prod::bd2rhokst_y_%s( yield_ratio_bd2rhokst_o_bd2phikst, bd2phikst_y_%s )", cat->getLabel(), cat->getLabel()) );
    //w->factory( Form("bd2rhokst_y_%s[5,250]", cat->getLabel()));
    w->factory( Form("lb2pkpipi_y_%s[0,4000]", cat->getLabel()));
    w->factory( Form("lb2ppipipi_y_%s[0,4000]", cat->getLabel()));
  }

  // construct the pdf for each category
  for ( int i=0; i < cat->numTypes(); i++ ) {
    cat->setIndex(i);

    RooArgList *yields = new RooArgList();
    yields->add(*w->var( Form("bkg_y_%s"      , cat->getLabel()) ));
    yields->add(*w->var( Form("part_reco_y_%s", cat->getLabel()) ));
    yields->add(*w->var( Form("bs2kstkst_y_%s", cat->getLabel()) ));
    yields->add(*w->var( Form("bd2kstkst_y_%s", cat->getLabel()) ));
    yields->add(*w->var( Form("bd2phikst_y_%s", cat->getLabel()) ));
    yields->add(*w->function( Form("bs2phikst_y_%s", cat->getLabel()) ));
    //yields->add(*w->var( Form("bs2phikst_y_%s", cat->getLabel()) ));
    yields->add(*w->function( Form("bd2rhokst_y_%s", cat->getLabel()) ));
    //yields->add(*w->var( Form("bd2rhokst_y_%s", cat->getLabel()) ));
    yields->add(*w->var( Form("lb2pkpipi_y_%s", cat->getLabel()) ));
    //yields->add(*w->var( Form("lb2ppipipi_y_%s", cat->getLabel()) )); // this guy we scrap

    RooArgList *pdfs   = new RooArgList();
    pdfs->add(*w->pdf( Form("bkg_pdf_%s", cat->getLabel()) ));
    pdfs->add(*w->pdf("part_reco_pdf" ));
    pdfs->add(*w->pdf("bs2kstkst_mc_pdf"  ));
    pdfs->add(*w->pdf("bd2kstkst_mc_pdf" ));
    pdfs->add(*w->pdf("bd2phikst_mc_pdf" ));
    pdfs->add(*w->pdf("bs2phikst_mc_pdf" ));
    pdfs->add(*w->pdf("bd2rhokst_mc_pdf" ));
    pdfs->add(*w->pdf("lb2pkpipi_mc_pdf" ));
    //pdfs->add(*w->pdf("lb2ppipipi_mc_pdf")); // this guy we scrap

    RooAddPdf *pdf = new RooAddPdf( Form("pdf_%s",cat->getLabel()), "pdf" , *pdfs, *yields);
    w->import(*pdf);
    delete pdf;

    // then make the constrained pdf
    RooArgSet *prodpdfs = new RooArgSet();
    prodpdfs->add( *w->pdf(Form("pdf_%s",cat->getLabel())) );
    prodpdfs->add( *w->pdf("yield_ratio_bs2phikst_o_bd2phikst_constraint") );
    prodpdfs->add( *w->pdf("yield_ratio_bd2rhokst_o_bd2phikst_constraint") );
    RooProdPdf *cpdf = new RooProdPdf( Form("constrained_pdf_%s",cat->getLabel()), "constrained_pdf", *prodpdfs );
    w->import(*cpdf);
    delete cpdf;

    w->defineSet(Form("pdf_%s_yield_params",cat->getLabel()), *yields);
    w->defineSet(Form("constrained_pdf_%s_yield_params",cat->getLabel()), *yields);
  }

  // now make simultaneous pdf
  RooSimultaneous *cpdf = new RooSimultaneous( "constrained_pdf", "constrained_pdf", *w->cat("DataCat") );
  RooSimultaneous *pdf = new RooSimultaneous( "pdf", "pdf", *w->cat("DataCat") );
  for ( int i=0; i < cat->numTypes(); i++ ) {
    cat->setIndex(i);
    cpdf->addPdf( *w->pdf( Form("constrained_pdf_%s", cat->getLabel() )), cat->getLabel() );
    pdf->addPdf( *w->pdf( Form("pdf_%s", cat->getLabel() )), cat->getLabel() );
  }
  w->import(*cpdf);
  w->import(*pdf);

  delete pdf;
  delete cpdf;

}
Esempio n. 8
0
RooSimultaneous *SignalPDFs(TString url="EventSummaries.root",TString chSelector="")
{
  gStyle->SetOptStat(0);
  TCanvas *c = new TCanvas("signalpdfs","Signal PDFs");

  //the mass points
  typedef std::pair<TString,Float_t> MassPoint_t;
  std::vector<MassPoint_t> MassPointCollection;
  MassPointCollection.push_back( MassPoint_t("TTJets_mass_161v5",161.5) );
  MassPointCollection.push_back( MassPoint_t("TTJets_mass_163v5",163.5) );
  //  MassPointCollection.push_back( MassPoint_t("TTJets_mass_166v5",166.5) );
  MassPointCollection.push_back( MassPoint_t("TTJets_mass_169v5",169.5) ); 
  MassPointCollection.push_back( MassPoint_t("TTJets",           172.5) );
  MassPointCollection.push_back( MassPoint_t("TTJets_mass_175v5",175.5) );
  MassPointCollection.push_back( MassPoint_t("TTJets_mass_178v5",178.5) );
  MassPointCollection.push_back( MassPoint_t("TTJets_mass181v5", 181.5) );
  MassPointCollection.push_back( MassPoint_t("TTJets_mass184v5", 184.5) );

  std::map<std::string,TH1*> hmap;
  
  //get pdfs from file
  RooCategory sample("signal","") ;
  TFile *f = TFile::Open(url);
  for(size_t ipt=0; ipt<MassPointCollection.size(); ipt++)
    {
      TString sName("m"); sName += (ipt+1);      

      TString tname=MassPointCollection[ipt].first + "/data";
      TTree *t = (TTree *) f->Get(tname);
      if(t==0) continue;

      t->Draw("evmeasurements[0]>>hmass(80,100,500)","evmeasurements[0]>0" + chSelector);
      TH1D *h = (TH1D*) gDirectory->Get("hmass");
      if(h==0) continue;
      
      h = (TH1D *) h->Clone(sName);
      h->SetDirectory(0);
      h->GetYaxis()->SetTitle("Events / (5 GeV/c^{2})");
      h->GetXaxis()->SetTitle("Mass [GeV/c^{2}]");
      h->GetXaxis()->SetTitleOffset(0.8);
      h->GetYaxis()->SetTitleOffset(0.8);
      char titbuf[20];
      sprintf(titbuf,"m=%3.1lf",MassPointCollection[ipt].second);
      h->SetTitle(titbuf);

      sample.defineType(TString(sName));
      hmap[sName.Data()] = h;
    }    
  f->Close();
  delete c;

  // divide the binned data in categories according to the generated top quark mass
  RooRealVar mass("m","Mass", 100, 500);
  RooDataHist combData("combData", "combined data",mass, sample, hmap );

  //the parameters to fit and the variable
  RooRealVar g_mean_slope("#mu_{G}(slope)","g_mean_slope",0.01,0.,1.);    
  RooRealVar g_mean_shift("#mu_{G}(intercept)","g_mean_shift",162,100,180); 
  RooRealVar g_sigma_slope("#sigma_{G}(slope)","g_sigma_slope",0.01,0.,1.);
  RooRealVar g_sigma_shift("#sigma_{G}(intercept)","g_sigma_shift",10,0.,25);
  RooRealVar l_mean_slope("mpv_{L}(slope)","l_mean_slope",0.,0.,1.);//1,0,10);
  RooRealVar l_mean_shift("mpv_{L}(intercept)","l_mean_shift",212,150,250); 
  RooRealVar l_sigma_slope("#sigma_{L}(slope)","l_sigma_slope",0.,0.,1.);//1,0,10);
  RooRealVar l_sigma_shift("#sigma_{L}(intercept)","l_sigma_shift",10,0,25);
  RooRealVar massfrac_slope("#alpha(slope)","massfrac_slope",0,0,0.01);
  RooRealVar massfrac_shift("#alpha(intercept)","massfrac_shift",0.38,0.,1.);

  //build the prototype pdf
  RooRealVar    topmass( "mtop","mtop",100,300);
  RooFormulaVar g_mean(  "g_mean",  "(@0-172)*@1+@2",   RooArgSet(topmass,g_mean_slope,g_mean_shift));
  RooFormulaVar g_sigma( "g_sigma", "(@0-172)*@1+@2", RooArgSet(topmass,g_sigma_slope,g_sigma_shift)); 
  RooGaussian gaus("gaus", "Mass component 1", mass, g_mean, g_sigma);
  RooFormulaVar l_mean(  "l_mean",  "(@0-172)*@1+@2",   RooArgSet(topmass,l_mean_slope,l_mean_shift));
  RooFormulaVar l_sigma( "l_sigma", "(@0-172)*@1+@2", RooArgSet(topmass,l_sigma_slope,l_sigma_shift)); 
  RooLandau lan("lan", "Mass component 2", mass, l_mean, l_sigma);  
  RooFormulaVar massfrac( "#alpha", "(@0-172)*@1+@2", RooArgSet(topmass,massfrac_slope,massfrac_shift)); 
  RooAddPdf massmodel("model","Model",RooArgList(lan,gaus),massfrac);
  //RooNumConvPdf massmodel("model","Model",topmass,lan,gaus);

  //now split per categories
  RooSimPdfBuilder builder(massmodel) ;
  RooArgSet* config = builder.createProtoBuildConfig() ;
  config->setStringValue("physModels","model");     // Name of the PDF we are going to work with
  config->setStringValue("splitCats","signal");     // Category used to differentiate sub-datasets
  config->setStringValue("model","signal : mtop");  // Prescription to taylor PDF parameters mtop for each subset in signal
  RooSimultaneous* simPdf = builder.buildPdf(*config,&combData) ;
  config = simPdf->getParameters(combData);
  for(size_t ipt=0; ipt<MassPointCollection.size(); ipt++)
    {
      TString sName("m"); sName+=(ipt+1);
      Float_t imass=MassPointCollection[ipt].second;
      (((RooRealVar &)(*config)["mtop_"+sName])).setRange(imass,imass);
      (((RooRealVar &)(*config)["mtop_"+sName])).setVal(imass);
    }
  
  //fit to data
  simPdf->fitTo(combData,Range(100.,400.));
 
  //display
  for(size_t ipt=0; ipt<MassPointCollection.size(); ipt++)
    {
      if(ipt%5==0)
	{
	  TString name("SignalPDFs_");  name+=ipt;
	  c = new TCanvas(name,name);
	  c->SetBorderSize(0);
	  c->SetFillStyle(0);
	  c->SetFillColor(0);
	  c->SetWindowSize(1750,350);
	  c->Clear();
	  c->Divide(5,1);	  
	}
      
      TPad *p = (TPad *)c->cd(ipt%5+1);
      p->SetGridx();
      p->SetGridy();
      TString procName("m"); procName += (ipt+1);
      char buf[100];
      sprintf(buf,"m_{t}=%3.1lf GeV/c^{2}",MassPointCollection[ipt].second);
      RooPlot* frame = mass.frame(Title(buf));
      RooDataSet* dataslice = (RooDataSet *)combData.reduce("signal==signal::"+procName);
      dataslice->plotOn(frame,DataError(RooAbsData::SumW2));
      RooCategory newCat(procName,procName);
      simPdf->plotOn(frame,Slice(newCat),ProjWData(mass,*dataslice));
      frame->GetYaxis()->SetTitleOffset(1.0);
      frame->GetYaxis()->SetTitle("Events");
      frame->GetXaxis()->SetTitleOffset(0.8);
      frame->GetXaxis()->SetTitle("Reconstructed Mass [GeV/c^{2}]");
      frame->Draw();
             
      TPaveText *pt = new TPaveText(0.75,0.85,0.97,0.95,"brNDC");
      pt->SetBorderSize(0);
      pt->SetFillColor(0);
      pt->SetFillStyle(0);
      char buf2[50];
      sprintf(buf2,"%3.1lf GeV/c^{2}",MassPointCollection[ipt].second);
      pt->AddText(buf2);
      pt->Draw();
    }


  return simPdf;
}
void StandardHistFactoryPlotsWithCategories(const char* infile = "",
                                            const char* workspaceName = "combined",
                                            const char* modelConfigName = "ModelConfig",
                                            const char* dataName = "obsData"){


   double nSigmaToVary=5.;
   double muVal=0;
   bool doFit=false;

   // -------------------------------------------------------
   // First part is just to access a user-defined file
   // or create the standard example file if it doesn't exist
   const char* filename = "";
   if (!strcmp(infile,"")) {
      filename = "results/example_combined_GaussExample_model.root";
      bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code
                                                           // if file does not exists generate with histfactory
      if (!fileExist) {
#ifdef _WIN32
         cout << "HistFactory file cannot be generated on Windows - exit" << endl;
         return;
#endif
         // Normally this would be run on the command line
         cout <<"will run standard hist2workspace example"<<endl;
         gROOT->ProcessLine(".! prepareHistFactory .");
         gROOT->ProcessLine(".! hist2workspace config/example.xml");
         cout <<"\n\n---------------------"<<endl;
         cout <<"Done creating example input"<<endl;
         cout <<"---------------------\n\n"<<endl;
      }

   }
   else
      filename = infile;

   // Try to open the file
   TFile *file = TFile::Open(filename);

   // if input file was specified byt not found, quit
   if(!file ){
      cout <<"StandardRooStatsDemoMacro: Input file " << filename << " is not found" << endl;
      return;
   }

   // -------------------------------------------------------
   // Tutorial starts here
   // -------------------------------------------------------

   // get the workspace out of the file
   RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName);
   if(!w){
      cout <<"workspace not found" << endl;
      return;
   }

   // get the modelConfig out of the file
   ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName);

   // get the modelConfig out of the file
   RooAbsData* data = w->data(dataName);

   // make sure ingredients are found
   if(!data || !mc){
      w->Print();
      cout << "data or ModelConfig was not found" <<endl;
      return;
   }

   // -------------------------------------------------------
   // now use the profile inspector

   RooRealVar* obs = (RooRealVar*)mc->GetObservables()->first();
   TList* list = new TList();


   RooRealVar * firstPOI = dynamic_cast<RooRealVar*>(mc->GetParametersOfInterest()->first());

   firstPOI->setVal(muVal);
   //  firstPOI->setConstant();
   if(doFit){
      mc->GetPdf()->fitTo(*data);
   }

   // -------------------------------------------------------


   mc->GetNuisanceParameters()->Print("v");
   int  nPlotsMax = 1000;
   cout <<" check expectedData by category"<<endl;
   RooDataSet* simData=NULL;
   RooSimultaneous* simPdf = NULL;
   if(strcmp(mc->GetPdf()->ClassName(),"RooSimultaneous")==0){
      cout <<"Is a simultaneous PDF"<<endl;
      simPdf = (RooSimultaneous *)(mc->GetPdf());
   } else {
      cout <<"Is not a simultaneous PDF"<<endl;
   }



   if(doFit) {
      RooCategory* channelCat = (RooCategory*) (&simPdf->indexCat());
      TIterator* iter = channelCat->typeIterator() ;
      RooCatType* tt = NULL;
      tt=(RooCatType*) iter->Next();
      RooAbsPdf* pdftmp = ((RooSimultaneous*)mc->GetPdf())->getPdf(tt->GetName()) ;
      RooArgSet* obstmp = pdftmp->getObservables(*mc->GetObservables()) ;
      obs = ((RooRealVar*)obstmp->first());
      RooPlot* frame = obs->frame();
      cout <<Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())<<endl;
      cout << tt->GetName() << " " << channelCat->getLabel() <<endl;
      data->plotOn(frame,MarkerSize(1),Cut(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())),DataError(RooAbsData::None));

      Double_t normCount = data->sumEntries(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())) ;

      pdftmp->plotOn(frame,LineWidth(2.),Normalization(normCount,RooAbsReal::NumEvent)) ;
      frame->Draw();
      cout <<"expected events = " << mc->GetPdf()->expectedEvents(*data->get()) <<endl;
      return;
   }



   int nPlots=0;
   if(!simPdf){

      TIterator* it = mc->GetNuisanceParameters()->createIterator();
      RooRealVar* var = NULL;
      while( (var = (RooRealVar*) it->Next()) != NULL){
         RooPlot* frame = obs->frame();
         frame->SetYTitle(var->GetName());
         data->plotOn(frame,MarkerSize(1));
         var->setVal(0);
         mc->GetPdf()->plotOn(frame,LineWidth(1.));
         var->setVal(1);
         mc->GetPdf()->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(1));
         var->setVal(-1);
         mc->GetPdf()->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(1));
         list->Add(frame);
         var->setVal(0);
      }


   } else {
      RooCategory* channelCat = (RooCategory*) (&simPdf->indexCat());
      //    TIterator* iter = simPdf->indexCat().typeIterator() ;
      TIterator* iter = channelCat->typeIterator() ;
      RooCatType* tt = NULL;
      while(nPlots<nPlotsMax && (tt=(RooCatType*) iter->Next())) {

         cout << "on type " << tt->GetName() << " " << endl;
         // Get pdf associated with state from simpdf
         RooAbsPdf* pdftmp = simPdf->getPdf(tt->GetName()) ;

         // Generate observables defined by the pdf associated with this state
         RooArgSet* obstmp = pdftmp->getObservables(*mc->GetObservables()) ;
         //      obstmp->Print();


         obs = ((RooRealVar*)obstmp->first());

         TIterator* it = mc->GetNuisanceParameters()->createIterator();
         RooRealVar* var = NULL;
         while(nPlots<nPlotsMax && (var = (RooRealVar*) it->Next())){
            TCanvas* c2 = new TCanvas("c2");
            RooPlot* frame = obs->frame();
            frame->SetName(Form("frame%d",nPlots));
            frame->SetYTitle(var->GetName());

            cout <<Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())<<endl;
            cout << tt->GetName() << " " << channelCat->getLabel() <<endl;
            data->plotOn(frame,MarkerSize(1),Cut(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())),DataError(RooAbsData::None));

            Double_t normCount = data->sumEntries(Form("%s==%s::%s",channelCat->GetName(),channelCat->GetName(),tt->GetName())) ;

            if(strcmp(var->GetName(),"Lumi")==0){
               cout <<"working on lumi"<<endl;
               var->setVal(w->var("nominalLumi")->getVal());
               var->Print();
            } else{
               var->setVal(0);
            }
            // w->allVars().Print("v");
            // mc->GetNuisanceParameters()->Print("v");
            // pdftmp->plotOn(frame,LineWidth(2.));
            // mc->GetPdf()->plotOn(frame,LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data));
            //pdftmp->plotOn(frame,LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data));
            normCount = pdftmp->expectedEvents(*obs);
            pdftmp->plotOn(frame,LineWidth(2.),Normalization(normCount,RooAbsReal::NumEvent)) ;

            if(strcmp(var->GetName(),"Lumi")==0){
               cout <<"working on lumi"<<endl;
               var->setVal(w->var("nominalLumi")->getVal()+0.05);
               var->Print();
            } else{
               var->setVal(nSigmaToVary);
            }
            // pdftmp->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2));
            // mc->GetPdf()->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data));
            //pdftmp->plotOn(frame,LineColor(kRed),LineStyle(kDashed),LineWidth(2.),Slice(*channelCat,tt->GetName()),ProjWData(*data));
            normCount = pdftmp->expectedEvents(*obs);
            pdftmp->plotOn(frame,LineWidth(2.),LineColor(kRed),LineStyle(kDashed),Normalization(normCount,RooAbsReal::NumEvent)) ;

            if(strcmp(var->GetName(),"Lumi")==0){
               cout <<"working on lumi"<<endl;
               var->setVal(w->var("nominalLumi")->getVal()-0.05);
               var->Print();
            } else{
               var->setVal(-nSigmaToVary);
            }
            // pdftmp->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2));
            // mc->GetPdf()->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2),Slice(*channelCat,tt->GetName()),ProjWData(*data));
            //pdftmp->plotOn(frame,LineColor(kGreen),LineStyle(kDashed),LineWidth(2),Slice(*channelCat,tt->GetName()),ProjWData(*data));
            normCount = pdftmp->expectedEvents(*obs);
            pdftmp->plotOn(frame,LineWidth(2.),LineColor(kGreen),LineStyle(kDashed),Normalization(normCount,RooAbsReal::NumEvent)) ;



            // set them back to normal
            if(strcmp(var->GetName(),"Lumi")==0){
               cout <<"working on lumi"<<endl;
               var->setVal(w->var("nominalLumi")->getVal());
               var->Print();
            } else{
               var->setVal(0);
            }

            list->Add(frame);

            // quit making plots
            ++nPlots;

            frame->Draw();
            c2->SaveAs(Form("%s_%s_%s.pdf",tt->GetName(),obs->GetName(),var->GetName()));
            delete c2;
         }
      }
   }



   // -------------------------------------------------------


   // now make plots
   TCanvas* c1 = new TCanvas("c1","ProfileInspectorDemo",800,200);
   if(list->GetSize()>4){
      double n = list->GetSize();
      int nx = (int)sqrt(n) ;
      int ny = TMath::CeilNint(n/nx);
      nx = TMath::CeilNint( sqrt(n) );
      c1->Divide(ny,nx);
   } else
      c1->Divide(list->GetSize());
   for(int i=0; i<list->GetSize(); ++i){
      c1->cd(i+1);
      list->At(i)->Draw();
   }





}
Esempio n. 10
0
bool fitCharmoniaMassModel( RooWorkspace& myws,            // Local Workspace
                            const RooWorkspace& inputWorkspace,  // Workspace with all the input RooDatasets
                            struct KinCuts& cut,           // Variable containing all kinematic cuts
                            map<string, string>&  parIni,  // Variable containing all initial parameters
                            struct InputOpt& opt,          // Variable with run information (kept for legacy purpose)
                            string outputDir,              // Path to output directory
                            // Select the type of datasets to fit
                            string DSTAG,                  // Specifies the type of datasets: i.e, DATA, MCJPSINP, ...
                            bool isPbPb      = false,      // isPbPb = false for pp, true for PbPb
                            bool importDS    = true,       // Select if the dataset is imported in the local workspace
                            // Select the type of object to fit
                            bool incJpsi     = true,       // Includes Jpsi model
                            bool incPsi2S    = true,       // Includes Psi(2S) model
                            bool incBkg      = true,       // Includes Background model
                            // Select the fitting options
                            bool doFit       = true,       // Flag to indicate if we want to perform the fit
                            bool cutCtau     = false,      // Apply prompt ctau cuts
                            bool doConstrFit   = false,    // Do constrained fit
                            bool doSimulFit  = false,      // Do simultaneous fit
                            bool wantPureSMC = false,      // Flag to indicate if we want to fit pure signal MC
                            const char* applyCorr ="",     // Flag to indicate if we want corrected dataset and which correction
                            uint loadFitResult = false,    // Load previous fit results
                            string inputFitDir = "",       // Location of the fit results
                            int  numCores    = 2,          // Number of cores used for fitting
                            // Select the drawing options
                            bool setLogScale = true,       // Draw plot with log scale
                            bool incSS       = false,      // Include Same Sign data
                            bool zoomPsi     = false,      // Zoom Psi(2S) peak on extra pad
                            double  binWidth = 0.05,       // Bin width used for plotting
                            bool getMeanPT   = false       // Compute the mean PT (NEED TO FIX)
                            )  
{

  if (DSTAG.find("_")!=std::string::npos) DSTAG.erase(DSTAG.find("_"));

  // Check if input dataset is MC
  bool isMC = false;
  if (DSTAG.find("MC")!=std::string::npos) {
    if (incJpsi && incPsi2S) { 
      cout << "[ERROR] We can only fit one type of signal using MC" << endl; return false; 
    }
    isMC = true;
  }
  wantPureSMC = (isMC && wantPureSMC);
  bool cutSideBand = (incBkg && (!incPsi2S && !incJpsi));
  bool applyWeight_Corr = ( strcmp(applyCorr,"") );
  
  // Define the mass range
  setMassCutParameters(cut, incJpsi, incPsi2S, isMC);
  parIni["invMassNorm"] = Form("RooFormulaVar::%s('( -1.0 + 2.0*( @0 - @1 )/( @2 - @1) )', {%s, mMin[%.6f], mMax[%.6f]})", "invMassNorm", "invMass", cut.dMuon.M.Min, cut.dMuon.M.Max );
  // Apply the ctau cuts to reject non-prompt charmonia
  if (cutCtau) { setCtauCuts(cut, isPbPb); }
  
  string COLL = (isPbPb ? "PbPb" : "PP" );
  string plotLabelPbPb,  plotLabelPP;

  if (doSimulFit || !isPbPb) {
    // Set models based on initial parameters
    struct OniaModel model;
    if (!setMassModel(model, parIni, false, incJpsi, incPsi2S, incBkg)) { return false; }

    // Import the local datasets
    double numEntries = 1000000;
    string label = ((DSTAG.find("PP")!=std::string::npos) ? DSTAG.c_str() : Form("%s_%s", DSTAG.c_str(), "PP"));
    if (wantPureSMC) label += "_NoBkg";
    if (applyWeight_Corr) label += Form("_%s",applyCorr);
    string dsName = Form("dOS_%s", label.c_str());
    if (importDS) {
      if ( !(myws.data(dsName.c_str())) ) {
        int importID = importDataset(myws, inputWorkspace, cut, label, cutSideBand);
        if (importID<0) { return false; }
        else if (importID==0) { doFit = false; }
      }
      numEntries = myws.data(dsName.c_str())->sumEntries(); if (numEntries<=0) { doFit = false; }
    }
    else if (doFit && !(myws.data(dsName.c_str()))) { cout << "[ERROR] No local dataset was found to perform the fit!" << endl; return false; }
    if (myws.data(dsName.c_str())) numEntries = myws.data(dsName.c_str())->sumEntries();

    // Set global parameters
    setMassGlobalParameterRange(myws, parIni, cut, incJpsi, incPsi2S, incBkg, wantPureSMC);

    // Build the Fit Model
    if (!buildCharmoniaMassModel(myws, model.PP, parIni, false, doConstrFit, doSimulFit, incBkg, incJpsi, incPsi2S, numEntries))  { return false; }

    // Define plot names
    if (incJpsi)  { plotLabelPP += Form("_Jpsi_%s", parIni["Model_Jpsi_PP"].c_str());   } 
    if (incPsi2S) { plotLabelPP += Form("_Psi2S_%s", parIni["Model_Psi2S_PP"].c_str()); }
    if (incBkg)   { plotLabelPP += Form("_Bkg_%s", parIni["Model_Bkg_PP"].c_str());     }
    if (wantPureSMC) plotLabelPP +="_NoBkg";
    if (applyWeight_Corr) plotLabelPP +=Form("_%s",applyCorr);
  }

  if (doSimulFit || isPbPb) {
    // Set models based on initial parameters
    struct OniaModel model;
    if (!setMassModel(model, parIni, true, incJpsi, incPsi2S, incBkg)) { return false; }

    // Import the local datasets
    double numEntries = 1000000;
    string label = ((DSTAG.find("PbPb")!=std::string::npos) ? DSTAG.c_str() : Form("%s_%s", DSTAG.c_str(), "PbPb"));
    if (wantPureSMC) label += "_NoBkg";
    if (applyWeight_Corr) label += Form("_%s",applyCorr);
    string dsName = Form("dOS_%s", label.c_str());
    if (importDS) {
      if ( !(myws.data(dsName.c_str())) ) {
        int importID = importDataset(myws, inputWorkspace, cut, label, cutSideBand);
        if (importID<0) { return false; }
        else if (importID==0) { doFit = false; }
      }
      numEntries = myws.data(dsName.c_str())->sumEntries(); if (numEntries<=0) { doFit = false; }
    }
    else if (doFit && !(myws.data(dsName.c_str()))) { cout << "[ERROR] No local dataset was found to perform the fit!" << endl; return false; }
    if (myws.data(dsName.c_str())) numEntries = myws.data(dsName.c_str())->sumEntries();
      
    // Set global parameters
    setMassGlobalParameterRange(myws, parIni, cut, incJpsi, incPsi2S, incBkg, wantPureSMC);

    // Build the Fit Model
    if (!buildCharmoniaMassModel(myws, model.PbPb, parIni, true, doConstrFit, doSimulFit, incBkg, incJpsi, incPsi2S, numEntries))  { return false; }

    // Define plot names
    if (incJpsi)  { plotLabelPbPb += Form("_Jpsi_%s", parIni["Model_Jpsi_PbPb"].c_str());   } 
    if (incPsi2S) { plotLabelPbPb += Form("_Psi2S_%s", parIni["Model_Psi2S_PbPb"].c_str()); }
    if (incBkg)   { plotLabelPbPb += Form("_Bkg_%s", parIni["Model_Bkg_PbPb"].c_str());     }
    if (wantPureSMC) plotLabelPbPb += "_NoBkg";
    if (applyWeight_Corr) plotLabelPbPb += Form("_%s",applyCorr);
  }

  if (doSimulFit) {
    // Create the combided datasets
    RooCategory* sample = new RooCategory("sample","sample"); sample->defineType("PbPb"); sample->defineType("PP");
    RooDataSet*  combData = new RooDataSet("combData","combined data", *myws.var("invMass"), Index(*sample),
                                           Import("PbPb", *((RooDataSet*)myws.data("dOS_DATA_PbPb"))),
                                           Import("PP",   *((RooDataSet*)myws.data("dOS_DATA_PP")))
                                           );
    myws.import(*sample);

    // Create the combided models
    RooSimultaneous* simPdf = new RooSimultaneous("simPdf", "simultaneous pdf", *sample);
    simPdf->addPdf(*myws.pdf("pdfMASS_Tot_PbPb"), "PbPb"); simPdf->addPdf(*myws.pdf("pdfMASS_Tot_PP"), "PP");
    myws.import(*simPdf);

    // check if we have already done this fit. If yes, do nothing and return true.
    string FileName = "";
    setMassFileName(FileName, (inputFitDir=="" ? outputDir : inputFitDir), DSTAG, (plotLabelPP + plotLabelPbPb), cut, isPbPb, cutSideBand, doSimulFit);
    if (gSystem->AccessPathName(FileName.c_str()) && inputFitDir!="") {
      cout << "[WARNING] User Input File : " << FileName << " was not found!" << endl;
      if (loadFitResult) return false;
      setMassFileName(FileName, outputDir, DSTAG, (plotLabelPP + plotLabelPbPb), cut, isPbPb, cutSideBand, doSimulFit);
    }
    bool found =  true; bool skipFit = !doFit;
    RooArgSet *newpars = myws.pdf("simPdf")->getParameters(*(myws.var("invMass")));
    myws.saveSnapshot("simPdf_parIni", *newpars, kTRUE);
    found = found && isFitAlreadyFound(newpars, FileName, "simPdf");
    if (loadFitResult) {
      if ( loadPreviousFitResult(myws, FileName, DSTAG, false, (!isMC && !cutSideBand && loadFitResult==1), loadFitResult==1) ) { skipFit = true; } else { skipFit = false; }
      if ( loadPreviousFitResult(myws, FileName, DSTAG, true, (!isMC && !cutSideBand && loadFitResult==1), loadFitResult==1)  ) { skipFit = true; } else { skipFit = false; }
      if (skipFit) { cout << "[INFO] This simultaneous mass fit was already done, so I'll load the fit results." << endl; }
      myws.saveSnapshot("simPdf_parLoad", *newpars, kTRUE);
    } else if (found) {
      cout << "[INFO] This simultaneous mass fit was already done, so I'll just go to the next one." << endl;
      return true;
    }

    // Do the simultaneous fit
    if (skipFit==false) {
      RooFitResult* fitResult = simPdf->fitTo(*combData, Offset(kTRUE), Extended(kTRUE), NumCPU(numCores), Range("MassWindow"), Save()); //, Minimizer("Minuit2","Migrad")
      fitResult->Print("v");
      myws.import(*fitResult, "fitResult_simPdf"); 
      // Create the output files
      int nBins = min(int( round((cut.dMuon.M.Max - cut.dMuon.M.Min)/binWidth) ), 1000);
      drawMassPlot(myws, outputDir, opt, cut, parIni, plotLabelPP, DSTAG, false, incJpsi, incPsi2S, incBkg, cutCtau, doSimulFit, false, setLogScale, incSS, zoomPsi, nBins, getMeanPT);
      drawMassPlot(myws, outputDir, opt, cut, parIni, plotLabelPbPb, DSTAG, true, incJpsi, incPsi2S, incBkg, cutCtau, doSimulFit, false, setLogScale, incSS, zoomPsi, nBins, getMeanPT);
      // Save the results
      string FileName = ""; setMassFileName(FileName, outputDir, DSTAG, (plotLabelPP + plotLabelPbPb), cut, isPbPb, cutSideBand, doSimulFit);
      myws.saveSnapshot("simPdf_parFit", *newpars, kTRUE);
      saveWorkSpace(myws, Form("%smass%s/%s/result", outputDir.c_str(), (cutSideBand?"SB":""), DSTAG.c_str()), FileName);
      // Delete the objects used during the simultaneous fit
      delete sample; delete combData; delete simPdf;
    }
  }
  else {
    // Define pdf and plot names
    string pdfName = Form("pdfMASS_Tot_%s", COLL.c_str());
    string plotLabel = (isPbPb ? plotLabelPbPb : plotLabelPP);

    // Import the local datasets
    string label = ((DSTAG.find(COLL.c_str())!=std::string::npos) ? DSTAG.c_str() : Form("%s_%s", DSTAG.c_str(), COLL.c_str()));
    if (wantPureSMC) label += "_NoBkg";
    if (applyWeight_Corr) label += Form("_%s",applyCorr);
    string dsName = Form("dOS_%s", label.c_str());
      
    // check if we have already done this fit. If yes, do nothing and return true.
    string FileName = "";
    setMassFileName(FileName, (inputFitDir=="" ? outputDir : inputFitDir), DSTAG, plotLabel, cut, isPbPb, cutSideBand);
    if (gSystem->AccessPathName(FileName.c_str()) && inputFitDir!="") {
      cout << "[WARNING] User Input File : " << FileName << " was not found!" << endl;
      if (loadFitResult) return false;
      setMassFileName(FileName, outputDir, DSTAG, plotLabel, cut, isPbPb, cutSideBand);
    }
    bool found =  true; bool skipFit = !doFit;
    RooArgSet *newpars = myws.pdf(pdfName.c_str())->getParameters(*(myws.var("invMass")));
    found = found && isFitAlreadyFound(newpars, FileName, pdfName.c_str());
    if (loadFitResult) {
      if ( loadPreviousFitResult(myws, FileName, DSTAG, isPbPb, (!isMC && !cutSideBand && loadFitResult==1), loadFitResult==1) ) { skipFit = true; } else { skipFit = false; } 
      if (skipFit) { cout << "[INFO] This mass fit was already done, so I'll load the fit results." << endl; }
      myws.saveSnapshot(Form("%s_parLoad", pdfName.c_str()), *newpars, kTRUE);
    } else if (found) {
      cout << "[INFO] This mass fit was already done, so I'll just go to the next one." << endl;
      return true;
    }

    // Fit the Datasets
    if (skipFit==false) {
      bool isWeighted = myws.data(dsName.c_str())->isWeighted();
      RooFitResult* fitResult(0x0);
      if (doConstrFit)
      {
        cout << "[INFO] Performing constrained fit" << endl;
        
        if (isPbPb) {
          cout << "[INFO] Constrained variables: alpha, n, ratio of sigmas" << endl;
          fitResult = myws.pdf(pdfName.c_str())->fitTo(*myws.data(dsName.c_str()), Extended(kTRUE), SumW2Error(isWeighted), Range(cutSideBand ? parIni["BkgMassRange_FULL_Label"].c_str() : "MassWindow"), ExternalConstraints(RooArgSet(*(myws.pdf("sigmaAlphaConstr")),*(myws.pdf("sigmaNConstr")),*(myws.pdf("sigmaRSigmaConstr")))), NumCPU(numCores), Save());
        }
        else {
          cout << "[INFO] Constrained variables: alpha, n, ratio of sigmas" << endl;
          fitResult = myws.pdf(pdfName.c_str())->fitTo(*myws.data(dsName.c_str()), Extended(kTRUE), SumW2Error(isWeighted), Range(cutSideBand ? parIni["BkgMassRange_FULL_Label"].c_str() : "MassWindow"), ExternalConstraints(RooArgSet(*(myws.pdf("sigmaAlphaConstr")),*(myws.pdf("sigmaNConstr")))), NumCPU(numCores), Save());
        }
      }
      else
      {
       fitResult = myws.pdf(pdfName.c_str())->fitTo(*myws.data(dsName.c_str()), Extended(kTRUE), SumW2Error(isWeighted), Range(cutSideBand ? parIni["BkgMassRange_FULL_Label"].c_str() : "MassWindow"), NumCPU(numCores), Save());
      }
      fitResult->Print("v"); 
      myws.import(*fitResult, Form("fitResult_%s", pdfName.c_str())); 
      // Create the output files
      int nBins = min(int( round((cut.dMuon.M.Max - cut.dMuon.M.Min)/binWidth) ), 1000);
      drawMassPlot(myws, outputDir, opt, cut, parIni, plotLabel, DSTAG, isPbPb, incJpsi, incPsi2S, incBkg, cutCtau, doSimulFit, wantPureSMC, setLogScale, incSS, zoomPsi, nBins, getMeanPT);
      // Save the results
      string FileName = ""; setMassFileName(FileName, outputDir, DSTAG, plotLabel, cut, isPbPb, cutSideBand);
      myws.saveSnapshot(Form("%s_parFit", pdfName.c_str()), *newpars, kTRUE);
      saveWorkSpace(myws, Form("%smass%s/%s/result", outputDir.c_str(), (cutSideBand?"SB":""), DSTAG.c_str()), FileName);
    }
  }

  return true;
};