Esempio n. 1
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;

	}
// 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. 3
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;
	}

}
Esempio n. 4
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;
};