예제 #1
0
///
/// Store the errors as RooFit error into the observables
/// to have them easily available for the pull computation.
///
void PDF_Abs::storeErrorsInObs()
{
	if ( covMatrix==0 )
	{
		cout << "PDF_Abs::storeErrorsInObs() : ERROR : covMatrix not initialized." << endl;
		return;
	}

	for ( int i=0; i<nObs; i++ )
	{
		RooRealVar* pObs = (RooRealVar*)((RooArgList*)observables)->at(i);
		pObs->setError(sqrt(covMatrix[i][i]));
	}
}
예제 #2
0
void fitbkgdataCard(TString configCard="template.config", 
		    bool dobands  = true,  // create baerror bands for BG models
		    bool dosignal = false, // plot the signal model (needs to be present)
		    bool blinded  = true,  // blind the data in the plots?
		    bool verbose  = true  ) {
  
  gROOT->Macro("MitStyle.C");
  gStyle->SetErrorX(0); 
  gStyle->SetOptStat(0);
  gROOT->ForceStyle();  
  
  TString projectDir;

  std::vector<TString> catdesc;
  std::vector<TString> catnames;  
  std::vector<int>     polorder;

  double massmin = -1.;
  double massmax = -1.;

  double theCMenergy = -1.;

  bool readStatus = readFromConfigCard( configCard,
					projectDir,
					catnames,
					catdesc,
					polorder,
					massmin,
					massmax,
					theCMenergy
					);
  
  if( !readStatus ) {
    std::cerr<<" ERROR: Could not read from card > "<<configCard.Data()<<" <."<<std::endl;
    return;
  }
  
  TFile *fdata = new TFile(TString::Format("%s/CMS-HGG-data.root",projectDir.Data()),"READ");
  if( !fdata ) {
    std::cerr<<" ERROR: Could not open file "<<projectDir.Data()<<"/CMS-HGG-data.root."<<std::endl;
    return;
  }
  
  if( !gSystem->cd(TString::Format("%s/databkg/",projectDir.Data())) ) {
    std::cerr<<" ERROR: Could not change directory to "<<TString::Format("%s/databkg/",projectDir.Data()).Data()<<"."<<std::endl;
    return;
  }
  
  // ----------------------------------------------------------------------
  // load the input workspace....
  RooWorkspace* win = (RooWorkspace*)fdata->Get("cms_hgg_workspace_data");
  if( !win ) {
    std::cerr<<" ERROR: Could not load workspace > cms_hgg_workspace_data < from file > "<<TString::Format("%s/CMS-HGG-data.root",projectDir.Data()).Data()<<" <."<<std::endl;
    return;
  }

  RooRealVar *intLumi = win->var("IntLumi");
  RooRealVar *hmass   = win->var("CMS_hgg_mass");
  if( !intLumi || !hmass ) {
    std::cerr<<" ERROR: Could not load needed variables > IntLumi < or > CMS_hgg_mass < forom input workspace."<<std::endl;
    return;
  }

  //win->Print();

  hmass->setRange(massmin,massmax);
  hmass->setBins(4*(int)(massmax-massmin));
  hmass->SetTitle("m_{#gamma#gamma}");
  hmass->setUnit("GeV");
  hmass->setRange("fitrange",massmin,massmax);

  hmass->setRange("blind1",100.,110.);
  hmass->setRange("blind2",150.,180.);
  
  // ----------------------------------------------------------------------
  // some auxiliray vectro (don't know the meaning of all of them ... yet...
  std::vector<RooAbsData*> data_vec;
  std::vector<RooAbsPdf*>  pdfShape_vec;   // vector to store the NOT-EXTENDED PDFs (aka pdfshape)
  std::vector<RooAbsPdf*>  pdf_vec;        // vector to store the EXTENDED PDFs
  
  std::vector<RooAbsReal*> normu_vec;      // this holds the normalization vars for each Cat (needed in bands for combined cat)

  RooArgList               normList;       // list of range-limityed normalizations (needed for error bands on combined category)

  //std::vector<RooRealVar*> coeffv;
  //std::vector<RooAbsReal*> normu_vecv; // ???

  // ----------------------------------------------------------------------
  // define output works
  RooWorkspace *wOut = new RooWorkspace("wbkg","wbkg") ;
  
  // util;ities for the combined fit
  RooCategory     finalcat  ("finalcat",  "finalcat") ;  
  RooSimultaneous fullbkgpdf("fullbkgpdf","fullbkgpdf",finalcat);
  RooDataSet      datacomb  ("datacomb",  "datacomb",  RooArgList(*hmass,finalcat)) ;

  RooDataSet *datacombcat = new RooDataSet("data_combcat","",RooArgList(*hmass)) ;
  
  // add the 'combcat' to the list...if more than one cat
  if( catnames.size() > 1 ) {
    catnames.push_back("combcat");    
    catdesc.push_back("Combined");
  }
  
  for (UInt_t icat=0; icat<catnames.size(); ++icat) {
    TString catname = catnames.at(icat);
    finalcat.defineType(catname);
    
    // check if we're in a sub-cat or the comb-cat
    RooDataSet *data   = NULL;
    RooDataSet *inData = NULL;
    if( icat < (catnames.size() - 1) || catnames.size() == 1) { // this is NOT the last cat (which is by construction the combination)
      inData = (RooDataSet*)win->data(TString("data_mass_")+catname);
      if( !inData ) {
	std::cerr<<" ERROR: Could not find dataset > data_mass_"<<catname.Data()<<" < in input workspace."<<std::endl;
	return;
      }
      data = new RooDataSet(TString("data_")+catname,"",*hmass,Import(*inData));  // copy the dataset (why?)
      
      // append the data to the combined data...
      RooDataSet *datacat = new RooDataSet(TString("datacat")+catname,"",*hmass,Index(finalcat),Import(catname,*data)) ;
      datacomb.append(*datacat);
      datacombcat->append(*data);
      
      // normalization for this category
      RooRealVar *nbkg = new RooRealVar(TString::Format("CMS_hgg_%s_bkgshape_norm",catname.Data()),"",800.0,0.0,25e3);
      
      // we keep track of the normalizario vars only for N-1 cats, naming convetnions hystoric...
      if( catnames.size() > 2 && icat < (catnames.size() - 2) ) {
	RooRealVar* cbkg = new RooRealVar(TString::Format("cbkg%s",catname.Data()),"",0.0,0.0,1e3);
	cbkg->removeRange();
	normu_vec.push_back(cbkg);
	normList.add(*cbkg);
      }
      
      /// generate the Bernstrin polynomial (FIX-ME: add possibility ro create other models...)
      fstBernModel* theBGmodel = new fstBernModel(hmass, polorder[icat], icat, catname);            // using my dedicated class...
      
      std::cout<<" model name is "<<theBGmodel->getPdf()->GetName()<<std::endl;

      RooAbsPdf*    bkgshape   = theBGmodel->getPdf();                                              // the BG shape
      RooAbsPdf*    bkgpdf     = new RooExtendPdf(TString("bkgpdf")+catname,"",*bkgshape,*nbkg);    // the extended PDF
      
      // add the extedned PDF to the RooSimultaneous holding all models...
      fullbkgpdf.addPdf(*bkgpdf,catname);
      // store the NON-EXTENDED PDF for usgae to compute the error bands later..
      pdfShape_vec.push_back(bkgshape);
      pdf_vec     .push_back(bkgpdf);
      data_vec    .push_back(data);
      
    } else {
      data = datacombcat;   // we're looking at the last cat (by construction the combination)
      data_vec.push_back(data);
      
      // sum up all the cts PDFs for combined PDF
      RooArgList subpdfs;
      for (int ipdf=0; ipdf<pdf_vec.size(); ++ipdf) {
	subpdfs.add(*pdf_vec.at(ipdf));
      }
      RooAddPdf* bkgpdf = new RooAddPdf(TString("bkgpdf")+catname,"",subpdfs);
      pdfShape_vec.push_back(bkgpdf);      
      pdf_vec     .push_back(bkgpdf);  // I don't think this is really needed though....
    }
    
    // generate the binned dataset (to be put into the workspace... just in case...)
    RooDataHist *databinned = new RooDataHist(TString("databinned_")+catname,"",*hmass,*data);
    
    wOut->import(*data);
    wOut->import(*databinned);

  }
  
  std::cout<<" ***************** "<<std::endl;

  // fit the RooSimultaneous to the combined dataset -> (we could also fit each cat separately)
  fullbkgpdf.fitTo(datacomb,Strategy(1),Minos(kFALSE),Save(kTRUE));
  RooFitResult *fullbkgfitres = fullbkgpdf.fitTo(datacomb,Strategy(2),Minos(kFALSE),Save(kTRUE));
  
  // in principle we're done now, so store the results in the output workspace
  wOut->import(datacomb);  
  wOut->import(fullbkgpdf);
  wOut->import(*fullbkgfitres);

  std::cout<<" ***************** "<<std::endl;
  

  if( verbose ) wOut->Print();

  
  std::cout<<" ***************** "<<std::endl;

  wOut->writeToFile("bkgdatawithfit.root") ;  
  
  if( verbose ) {
    printf("IntLumi = %5f\n",intLumi->getVal());
    printf("ndata:\n");
    for (UInt_t icat=0; icat<catnames.size(); ++icat) {    
      printf("%i ",data_vec.at(icat)->numEntries());      
    }   
    printf("\n");
  } 
  
  // --------------------------------------------------------------------------------------------
  // Now comesd the plotting
  // chage the Statistics style...
  gStyle->SetOptStat(1110);
  
  // we want to plot in 1GeV bins (apparently...)
  UInt_t nbins = (UInt_t) (massmax-massmin);
  
  // here we'll store the curves for the bands...
  std::vector<RooCurve*> fitcurves;
  
  // loop again over the cats
  TCanvas **canbkg = new TCanvas*[catnames.size()];
  RooPlot** plot   = new RooPlot*[catnames.size()];

  TLatex** lat  = new TLatex*[catnames.size()];
  TLatex** lat2 = new TLatex*[catnames.size()];

  std::cout<<"  beofre plotting..."<<std::endl;
  

  for (UInt_t icat=0; icat<catnames.size(); ++icat) {
    TString catname = catnames.at(icat);
    

    std::cout<<" trying to plot #"<<icat<<std::endl;

    // plot the data and the fit 
    canbkg[icat] = new TCanvas;
    plot  [icat] = hmass->frame(Bins(nbins),Range("fitrange"));
    
    std::cout<<" trying to plot #"<<icat<<std::endl;

    // first plot the data invisibly... and put the fitted BG model on top...
    data_vec    .at(icat)->plotOn(plot[icat],RooFit::LineColor(kWhite),MarkerColor(kWhite),Invisible());
    pdfShape_vec.at(icat)->plotOn(plot[icat],RooFit::LineColor(kRed),Range("fitrange"),NormRange("fitrange"));
    
    std::cout<<" trying to plot #"<<icat<<std::endl;


    // if toggled on, plot also the Data visibly
    if( !blinded ) {
      data_vec.at(icat)->plotOn(plot[icat]);
    }
   
    std::cout<<" trying to plot #"<<icat<<std::endl;

    // some cosmetics...
    plot[icat]->SetTitle("");      
    plot[icat]->SetMinimum(0.0);
    plot[icat]->SetMaximum(1.40*plot[icat]->GetMaximum());
    plot[icat]->GetXaxis()->SetTitle("m_{#gamma#gamma} (GeV/c^{2})");
    plot[icat]->Draw();       
            

    std::cout<<" trying to plot #"<<icat<<std::endl;

    // legend....
    TLegend *legmc = new TLegend(0.68,0.70,0.97,0.90);
    legmc->AddEntry(plot[icat]->getObject(2),"Data","LPE");
    legmc->AddEntry(plot[icat]->getObject(1),"Bkg Model","L");
    
    // this part computes the 1/2-sigma bands.    
    TGraphAsymmErrors *onesigma = NULL;
    TGraphAsymmErrors *twosigma = NULL;
    
    std::cout<<" trying ***  to plot #"<<icat<<std::endl;

    RooAddition* sumcatsnm1 = NULL;

    if ( dobands ) { //&& icat == (catnames.size() - 1) ) {

      onesigma = new TGraphAsymmErrors();
      twosigma = new TGraphAsymmErrors();

      // get the PDF for this cat from the vector
      RooAbsPdf *thisPdf = pdfShape_vec.at(icat); 

      // get the nominal fir curve
      RooCurve *nomcurve = dynamic_cast<RooCurve*>(plot[icat]->getObject(1));
      fitcurves.push_back(nomcurve);

      bool iscombcat       = ( icat == (catnames.size() - 1) && catnames.size() > 1);
      RooAbsData *datanorm = ( iscombcat ? &datacomb : data_vec.at(icat) );

      // this si the nornmalization in the 'sliding-window' (i.e. per 'test-bin')
      RooRealVar *nlim = new RooRealVar(TString::Format("nlim%s",catnames.at(icat).Data()),"",0.0,0.0,10.0);
      nlim->removeRange();

      if( iscombcat ) {
	// ----------- HISTORIC NAMING  ----------------------------------------
	sumcatsnm1 = new RooAddition("sumcatsnm1","",normList);   // summing all normalizations epect the last Cat
	// this is the normlization of the last Cat
	RooFormulaVar *nlast = new RooFormulaVar("nlast","","TMath::Max(0.1,@0-@1)",RooArgList(*nlim,*sumcatsnm1));
	// ... and adding it ot the list of norms
	normu_vec.push_back(nlast);
      }

      //if (icat == 1 && catnames.size() == 2) continue; // only 1 cat, so don't need combination

      for (int i=1; i<(plot[icat]->GetXaxis()->GetNbins()+1); ++i) {
	
	// this defines the 'binning' we use for the error bands
        double lowedge = plot[icat]->GetXaxis()->GetBinLowEdge(i);
        double upedge = plot[icat]->GetXaxis()->GetBinUpEdge(i);
        double center = plot[icat]->GetXaxis()->GetBinCenter(i);
        
	// get the nominal value at the center of the bin
        double nombkg = nomcurve->interpolate(center);
        nlim->setVal(nombkg);
        hmass->setRange("errRange",lowedge,upedge);

	// this is the new extended PDF whith the normalization restricted to the bin-area
        RooAbsPdf *extLimPdf = NULL;
	if( iscombcat ) {
	  extLimPdf = new RooSimultaneous("epdf","",finalcat);
	  // loop over the cats and generate temporary extended PDFs
	  for (int jcat=0; jcat<(catnames.size()-1); ++jcat) {
            RooRealVar *rvar = dynamic_cast<RooRealVar*>(normu_vec.at(jcat));
            if (rvar) rvar->setVal(fitcurves.at(jcat)->interpolate(center));
            RooExtendPdf *ecpdf = new RooExtendPdf(TString::Format("ecpdf%s",catnames.at(jcat).Data()),"",*pdfShape_vec.at(jcat),*normu_vec.at(jcat),"errRange");
            static_cast<RooSimultaneous*>(extLimPdf)->addPdf(*ecpdf,catnames.at(jcat));
          }
	} else
	  extLimPdf = new RooExtendPdf("extLimPdf","",*thisPdf,*nlim,"errRange");

        RooAbsReal *nll = extLimPdf->createNLL(*datanorm,Extended(),NumCPU(1));
        RooMinimizer minim(*nll);
        minim.setStrategy(0);
        double clone = 1.0 - 2.0*RooStats::SignificanceToPValue(1.0);
        double cltwo = 1.0 - 2.0*RooStats::SignificanceToPValue(2.0);
	
        if (iscombcat) minim.setStrategy(2);
        
        minim.migrad();
	
        if (!iscombcat) { 
          minim.minos(*nlim);
        }
        else {
          minim.hesse();
          nlim->removeAsymError();
        }

	if( verbose ) 
	  printf("errlo = %5f, errhi = %5f\n",nlim->getErrorLo(),nlim->getErrorHi());
        
        onesigma->SetPoint(i-1,center,nombkg);
        onesigma->SetPointError(i-1,0.,0.,-nlim->getErrorLo(),nlim->getErrorHi());
        
	// to get the 2-sigma bands...
        minim.setErrorLevel(0.5*pow(ROOT::Math::normal_quantile(1-0.5*(1-cltwo),1.0), 2)); // the 0.5 is because qmu is -2*NLL
                          // eventually if cl = 0.95 this is the usual 1.92!      
        
        if (!iscombcat) { 
          minim.migrad();
          minim.minos(*nlim);
        }
        else {
          nlim->setError(2.0*nlim->getError());
          nlim->removeAsymError();          
        }
	
        twosigma->SetPoint(i-1,center,nombkg);
        twosigma->SetPointError(i-1,0.,0.,-nlim->getErrorLo(),nlim->getErrorHi());      
        
        // for memory clean-up
        delete nll;
        delete extLimPdf;
      }
      
      hmass->setRange("errRange",massmin,massmax);

      if( verbose )
	onesigma->Print("V");
      
      // plot[icat] the error bands
      twosigma->SetLineColor(kGreen);
      twosigma->SetFillColor(kGreen);
      twosigma->SetMarkerColor(kGreen);
      twosigma->Draw("L3 SAME");     
      
      onesigma->SetLineColor(kYellow);
      onesigma->SetFillColor(kYellow);
      onesigma->SetMarkerColor(kYellow);
      onesigma->Draw("L3 SAME");
      
      plot[icat]->Draw("SAME");
    
      // and add the error bands to the legend
      legmc->AddEntry(onesigma,"#pm1 #sigma","F");  
      legmc->AddEntry(twosigma,"#pm2 #sigma","F");  
    }
    
    std::cout<<" trying ***2  to plot #"<<icat<<std::endl;

    // rest of the legend ....
    legmc->SetBorderSize(0);
    legmc->SetFillStyle(0);
    legmc->Draw();   

    lat[icat]  = new TLatex(103.0,0.9*plot[icat]->GetMaximum(),TString::Format("#scale[0.7]{#splitline{CMS preliminary}{#sqrt{s} = %.1f TeV L = %.2f fb^{-1}}}",theCMenergy,intLumi->getVal()));
    lat2[icat] = new TLatex(103.0,0.75*plot[icat]->GetMaximum(),catdesc.at(icat));

    lat[icat] ->Draw();
    lat2[icat]->Draw();
    
    // -------------------------------------------------------    
    // save canvas in different formats
    canbkg[icat]->SaveAs(TString("databkg") + catname + TString(".pdf"));
    canbkg[icat]->SaveAs(TString("databkg") + catname + TString(".eps"));
    canbkg[icat]->SaveAs(TString("databkg") + catname + TString(".root"));              
  }
  
  return;
  
}
예제 #3
0
	void fitpeaks(int bin){
		switch (bin)
		{
			case 0:
				cut_="abs(upsRapidity)<2.4";
				//cut_="( (muPlusPt>3.5 && abs(muPlusEta)<1.6) || (muPlusPt>2.5 && abs(muPlusEta)>=1.6 && abs(muPlusEta)<2.4) ) && ( (muMinusPt>3.5 && abs(muMinusEta)<1.6) || (muMinusPt>2.5 && abs(muMinusEta)>=1.6 && abs(muMinusEta)<2.4) ) && abs(upsRapidity)<2.0";   //pp acceptance for Upsilon 
				suffix_="";
				f2Svs1S_pp->setVal(0.5569);
				//f2Svs1S_pp->setVal(0);
				f3Svs1S_pp->setVal(0.4140);
				//f3Svs1S_pp->setVal(0);
				break;
			case 1:
				cut_="abs(upsRapidity)>=0.0 && abs(upsRapidity)<1.2";
				suffix_="_eta0-12"; binw_=0.14;
				break;
			case 2:
				cut_="abs(upsRapidity)>=1.2 && abs(upsRapidity)<2.4";
				suffix_="_eta12-24"; binw_=0.14;
				break;
			case 3:
				cut_="Centrality>=0 && Centrality<2";
				suffix_="_cntr0-5"; binw_=0.14;
				break;
			case 4:
				cut_="Centrality>=2 && Centrality<4";
				suffix_="_cntr5-10"; binw_=0.14;
				break;
			case 5:
				cut_="Centrality>=4 && Centrality<8";
				suffix_="_cntr10-20"; binw_=0.14;
				break;
			case 6:
				cut_="Centrality>=8 && Centrality<12";
				suffix_="_cntr20-30"; binw_=0.14;
				break;
			case 7:
				cut_="Centrality>=12 && Centrality<16";
				suffix_="_cntr30-40"; binw_=0.14;
				break;
			case 8:
				cut_="Centrality>=16 && Centrality<20";
				suffix_="_cntr40-50"; binw_=0.14;
				break;
			case 9:
				cut_="Centrality>=20 && Centrality<50";
				suffix_="_cntr50-100"; binw_=0.14;
				break;
			case 10:
				cut_="Centrality>=20 && Centrality<24";
				suffix_="_cntr50-60"; binw_=0.14;
				break;
			case 11:
				cut_="Centrality>=0 && Centrality<8";
				suffix_="_cntr0-20"; binw_=0.1;
				break;
			case 12:
				cut_="Centrality>=16 && Centrality<50";
				suffix_="_cntr40-100"; binw_=0.14;
				break;
			case 13:
				cut_="Centrality>=8 && Centrality<50";
				suffix_="_cntr20-100"; binw_=0.1;
				break;
			default:
				cout<<"error in binning"<<endl;
				break;
		}

		cout << "oniafitter processing"
			<< "\n\tInput:  \t" << finput
			<< "\n\tresults:\t" << figs_
			<< endl;
		ofstream outfile("fitresults.out", ios_base::app);
		outfile<<endl<<"**********"<<suffix_<<"**********"<<endl<<endl;

		//read the data
		TFile f(finput,"read");
		gDirectory->Cd(finput+":/"+dirname_);
		TTree* theTree     = (TTree*)gROOT->FindObject("UpsilonTree");
		TTree* allsignTree     = (TTree*)gROOT->FindObject("UpsilonTree_allsign");
		if (PR_plot) {TRKROT = 1; PbPb=1;}
		if (TRKROT) TTree* trkRotTree = (TTree*)gROOT->FindObject("UpsilonTree_trkRot");

		RooRealVar* mass  = new RooRealVar("invariantMass","#mu#mu mass",mmin_,mmax_,"GeV/c^{2}");
		RooRealVar* upsPt  = new RooRealVar("upsPt","p_{T}(#Upsilon)",0,60,"GeV");
		RooRealVar* upsEta = new RooRealVar("upsEta",  "upsEta"  ,-7,7);
		RooRealVar* upsRapidity = new RooRealVar("upsRapidity",  "upsRapidity"  ,-2.4,2.4);
		RooRealVar* vProb = new RooRealVar("vProb",  "vProb"  ,0.05,1.00);
		RooRealVar* QQsign = new RooRealVar("QQsign",  "QQsign"  ,-1,5);
		RooRealVar* weight = new RooRealVar("weight",  "weight"  ,-2,2);
		if (PbPb) RooRealVar* Centrality = new RooRealVar("Centrality",  "Centrality"  ,0,40);
		RooRealVar* muPlusPt = new RooRealVar("muPlusPt","muPlusPt",muonpTcut,50);
		RooRealVar* muPlusEta = new RooRealVar("muPlusEta","muPlusEta",-2.5,2.5);
		RooRealVar* muMinusPt = new RooRealVar("muMinusPt","muMinusPt",muonpTcut,50);
		RooRealVar* muMinusEta = new RooRealVar("muMinusEta","muMinusEta",-2.5,2.5);


		//import unlike-sign data set
		RooDataSet* data0, *data, *likesignData0, *likesignData, *TrkRotData0, *TrkRotData;
		if (PbPb) data0 = new RooDataSet("data","data",theTree,RooArgSet(*mass,*upsRapidity,*vProb,*upsPt,*Centrality,*muPlusPt,*muMinusPt));
		//data0 = new RooDataSet("data","data",theTree,RooArgSet(*mass,*upsRapidity,*upsPt,*muPlusPt,*muMinusPt,*QQsign,*weight));
		else data0 = new RooDataSet("data","data",theTree,RooArgSet(*mass,*upsRapidity,*vProb,*upsPt,*muPlusPt,*muMinusPt,*muPlusEta,*muMinusEta));
		data0->Print();
		data = ( RooDataSet*) data0->reduce(Cut(cut_));
		data->Print();

		//import like-sign data set
		if (PbPb) likesignData0 = new RooDataSet("likesignData","likesignData",allsignTree,RooArgSet(*mass,*upsRapidity,*vProb,*upsPt,*Centrality,*muPlusPt,*muMinusPt,*QQsign));
		else likesignData0 = new RooDataSet("likesignData","likesignData",allsignTree,RooArgSet(*mass,*upsRapidity,*vProb,*upsPt,*muPlusPt,*muMinusPt,*QQsign));
		likesignData0->Print();
		likesignData = ( RooDataSet*) likesignData0->reduce(Cut(cut_+" && QQsign != 0"));
		likesignData->Print();


		//import track-rotation data set
		if (TRKROT) {
			if (PbPb) TrkRotData0 = new RooDataSet("TrkRotData","TrkRotData",trkRotTree,RooArgSet(*mass,*upsRapidity,*vProb,*upsPt,*Centrality,*muPlusPt,*muMinusPt,*QQsign));
			else TrkRotData0 = new RooDataSet("TrkRotData","TrkRotData",trkRotTree,RooArgSet(*mass,*upsRapidity,*upsPt,*vProb,*muPlusPt,*muMinusPt,*QQsign));
			TrkRotData0->Print();
			if (PR_plot && RAA) TrkRotData = ( RooDataSet*) TrkRotData0->reduce(Cut(cut_+" && upsPt < 8.1"));
			else if (PR_plot && !RAA) TrkRotData = ( RooDataSet*) TrkRotData0->reduce(Cut(cut_+" && upsPt < 7.07"));
			else TrkRotData = ( RooDataSet*) TrkRotData0->reduce(Cut(cut_+" && QQsign != 0"));
			TrkRotData->Print();
		}

		mass->setRange("R1",7.0,10.2);
		mass->setRange("R2",7,14);
		mass->setRange("R3",10.8,14);
		const double M1S = 9.46;   //upsilon 1S pgd mass value
		const double M2S = 10.02;  //upsilon 2S pgd mass value
		const double M3S = 10.35;  //upsilon 3S pgd mass value

		RooRealVar *mean    = new RooRealVar("#mu_{#Upsilon(1S)}","#Upsilon mean",M1S,M1S-0.1,M1S+0.1);
		RooRealVar *shift21 = new RooRealVar("shift2","mass diff #Upsilon(1,2S)",M2S-M1S);
		RooRealVar *shift31 = new RooRealVar("shift3","mass diff #Upsilon(1,3S)",M3S-M1S);
		RooRealVar *mscale  = new RooRealVar("mscale","mass scale factor",1.,0.7,1.3);
		mscale->setConstant(kTRUE); /* the def. parameter value is fixed in the fit */
		RooFormulaVar *mean1S = new RooFormulaVar("mean1S","@0",
				RooArgList(*mean));
		RooFormulaVar *mean2S = new RooFormulaVar("mean2S","@0+@1*@2",
				RooArgList(*mean,*mscale,*shift21));
		RooFormulaVar *mean3S = new RooFormulaVar("mean3S","@0+@1*@2",
				RooArgList(*mean,*mscale,*shift31));

		RooRealVar *sigma1 = new RooRealVar("sigma","Sigma_1",0.10,0.01,0.30);    //detector resolution
		RooRealVar *sigma2 = new RooRealVar("#sigma_{#Upsilon(1S)}","Sigma_1S",0.08,0.01,0.30); //Y(1S) resolution
		RooFormulaVar *reso1S = new RooFormulaVar("reso1S","@0"             ,RooArgList(*sigma2));
		RooFormulaVar *reso2S = new RooFormulaVar("reso2S","@0*10.023/9.460",RooArgList(*sigma2));
		RooFormulaVar *reso3S = new RooFormulaVar("reso3S","@0*10.355/9.460",RooArgList(*sigma2));

		/// to describe final state radiation tail on the left of the peaks
		RooRealVar *alpha  = new RooRealVar("alpha","tail shift",0.982,0,2.4);   // minbias fit value
		//RooRealVar *alpha  = new RooRealVar("alpha","tail shift",1.6,0.2,4);   // MC value
		RooRealVar *npow   = new RooRealVar("npow","power order",2.3,1,3);       // MC value
		npow ->setConstant(kTRUE);
		if (!fitMB) alpha->setConstant(kTRUE);
		// relative fraction of the two peak components 
		RooRealVar *sigmaFraction = new RooRealVar("sigmaFraction","Sigma Fraction",0.3,0.,1.);
		sigmaFraction->setVal(0);
		sigmaFraction->setConstant(kTRUE);

		/// Upsilon 1S
		//RooCBShape  *gauss1S1 = new RooCBShape ("gauss1S1", "FSR cb 1s",
		//                  *mass,*mean1S,*sigma1,*alpha,*npow);
		RooCBShape  *gauss1S2 = new RooCBShape ("gauss1S2", "FSR cb 1s",
				*mass,*mean1S,*reso1S,*alpha,*npow);
		//RooAddPdf *sig1S      = new RooAddPdf  ("sig1S","1S mass pdf",
		//                  RooArgList(*gauss1S1,*gauss1S2),*sigmaFraction);

		//mean->setVal(9.46);
		//mean->setConstant(kTRUE);
		sigma1->setVal(0);
		sigma1->setConstant(kTRUE);
		if (!fitMB) {
			sigma2->setVal(width_);        //fix the resolution
			sigma2->setConstant(kTRUE);
		}
		/// Upsilon 2S
		RooCBShape  *gauss2S1 = new RooCBShape ("gauss2S1", "FSR cb 2s", 
				*mass,*mean2S,*sigma1,*alpha,*npow); 
		RooCBShape  *gauss2S2 = new RooCBShape ("gauss2S2", "FSR cb 2s", 
				*mass,*mean2S,*reso2S,*alpha,*npow); 
		RooAddPdf *sig2S      = new RooAddPdf  ("sig2S","2S mass pdf",
				RooArgList(*gauss2S1,*gauss2S2),*sigmaFraction);

		/// Upsilon 3S
		RooCBShape  *gauss3S1 = new RooCBShape ("gauss3S1", "FSR cb 3s", 
				*mass,*mean3S,*sigma1,*alpha,*npow); 
		RooCBShape  *gauss3S2 = new RooCBShape ("gauss3S2", "FSR cb 3s", 
				*mass,*mean3S,*reso3S,*alpha,*npow); 
		RooAddPdf *sig3S      = new RooAddPdf  ("sig3S","3S mass pdf",
				RooArgList(*gauss3S1,*gauss3S2),*sigmaFraction);

		/// Background
		RooRealVar *bkg_a1  = new RooRealVar("bkg_{a1}", "background a1", 0, -2, 2);
		RooRealVar *bkg_a2  = new RooRealVar("bkg_{a2}", "background a2", 0, -1, 1);
		//RooRealVar *bkg_a3  = new RooRealVar("bkg_{a3}", "background a3", 0, -1, 1);
		RooAbsPdf  *bkgPdf  = new RooChebychev("bkg","background",
				*mass, RooArgList(*bkg_a1,*bkg_a2));
		//bkg_a1->setVal(0);
		//bkg_a1->setConstant(kTRUE);
		//bkg_a2->setVal(0);
		//bkg_a2->setConstant(kTRUE); //set constant for liner background

		// only sideband region pdf, using RooPolynomial instead of RooChebychev for multiple ranges fit
		RooRealVar *SB_bkg_a1  = new RooRealVar("SB bkg_{a1}", "background a1", 0, -1, 1);
		RooRealVar *SB_bkg_a2  = new RooRealVar("SB bkg_{a2}", "background a2", 0, -1, 1);
		RooAbsPdf  *SB_bkgPdf  = new RooPolynomial("SB_bkg","side-band background",
				*mass, RooArgList(*SB_bkg_a1,*SB_bkg_a2));
		//SB_bkg_a1->setVal(0);
		//SB_bkg_a1->setConstant(kTRUE);
		//SB_bkg_a2->setVal(0);
		//SB_bkg_a2->setConstant(kTRUE);

		/// Combined pdf
		int nt = 100000;
		//bool fitfraction = true;
		RooRealVar *nbkgd = new RooRealVar("N_{bkg}","nbkgd",nt*0.75,0,10*nt);
		RooRealVar *SB_nbkgd = new RooRealVar("SB N_{bkg}","SB_nbkgd",nt*0.75,0,10*nt);
		RooRealVar *nsig1f  = new RooRealVar("N_{#Upsilon(1S)}","nsig1S",nt*0.25,0,10*nt);
		/*
		//use the YIELDs of 2S and 3S as free parameters
		RooRealVar *nsig2f  = new RooRealVar("N_{#Upsilon(2S)}","nsig2S",   nt*0.25,-1*nt,10*nt);
		RooRealVar *nsig3f  = new RooRealVar("N_{#Upsilon(3S)}","nsig3S",   nt*0.25,-1*nt,10*nt);
		 */
		//use the RATIOs of 2S and 3S as free parameters
		RooRealVar *f2Svs1S = new RooRealVar("N_{2S}/N_{1S}","f2Svs1S",0.21,-0.1,1);
		//RooRealVar *f3Svs1S = new RooRealVar("N_{3S}/N_{1S}","f3Svs1S",0.0,-0.1,0.5);
		RooRealVar *f23vs1S = new RooRealVar("N_{2S+3S}/N_{1S}","f23vs1S",0.45,-0.1,1);
		RooFormulaVar *nsig2f = new RooFormulaVar("nsig2S","@0*@1", RooArgList(*nsig1f,*f2Svs1S));
		//RooFormulaVar *nsig3f = new RooFormulaVar("nsig3S","@0*@1", RooArgList(*nsig1f,*f3Svs1S));
		RooFormulaVar *nsig3f = new RooFormulaVar("nsig3S","@0*@2-@0*@1", RooArgList(*nsig1f,*f2Svs1S,*f23vs1S));

		//f3Svs1S->setConstant(kTRUE);

		//force the ratio to the pp value
		f2Svs1S_pp->setConstant(kTRUE);
		f3Svs1S_pp->setConstant(kTRUE);
		RooFormulaVar *nsig2f_ = new RooFormulaVar("nsig2S_pp","@0*@1", RooArgList(*nsig1f,*f2Svs1S_pp)); 
		RooFormulaVar *nsig3f_ = new RooFormulaVar("nsig3S_pp","@0*@1", RooArgList(*nsig1f,*f3Svs1S_pp)); 

		//only sideband region pdf, using RooPolynomial instead of RooChebychev for multiple ranges fit
		RooAbsPdf  *SB_pdf = new RooAddPdf ("SB_pdf","sideband background pdf",
				RooArgList(*SB_bkgPdf),
				RooArgList(*SB_nbkgd));
		//only signal region pdf, using RooPolynomial instead of RooChebychev for multiple ranges fit
		RooAbsPdf  *S_pdf   = new RooAddPdf ("S_pdf","total signal+background pdf",
				RooArgList(*gauss1S2,*sig2S,*sig3S,*SB_bkgPdf),
				RooArgList(*nsig1f,*nsig2f,*nsig3f,*SB_nbkgd));

		//parameters for likesign
		RooRealVar m0shift("turnOn","turnOn",8.6,0,20.) ;
		RooRealVar width("width","width",2.36,0,20.) ;
		RooRealVar par3("decay","decay",6.8, 0, 20.) ;
		RooGaussian* m0shift_constr;
		RooGaussian* width_constr;
		RooGaussian* par3_constr;

		RooRealVar *nLikesignbkgd = new RooRealVar("NLikesign_{bkg}","nlikesignbkgd",nt*0.75,0,10*nt);
		if (TRKROT) {
			nLikesignbkgd->setVal(TrkRotData->sumEntries());
			nLikesignbkgd->setError(sqrt(TrkRotData->sumEntries()));
		}
		else {
			nLikesignbkgd->setVal(likesignData->sumEntries());
			nLikesignbkgd->setError(sqrt(likesignData->sumEntries()));
		}

		if (LS_constrain) {
			RooGaussian* nLikesignbkgd_constr = new RooGaussian("nLikesignbkgd_constr","nLikesignbkgd_constr",*nLikesignbkgd,RooConst(nLikesignbkgd->getVal()),RooConst(nLikesignbkgd->getError()));
		}
		else nLikesignbkgd->setConstant(kTRUE);

		RooFormulaVar *nResidualbkgd = new RooFormulaVar("NResidual_{bkg}","@0-@1",RooArgList(*nbkgd,*nLikesignbkgd));

		switch (bkgdModel) {
			case 1 :  //use error function to fit the like-sign, then fix the shape and normailization, 
				RooGenericPdf *LikeSignPdf = new  RooGenericPdf("Like-sign","likesign","exp(-@0/decay)*(TMath::Erf((@0-turnOn)/width)+1)",RooArgList(*mass,m0shift,width,par3));
				if (TRKROT) RooFitResult* fit_1st = LikeSignPdf->fitTo(*TrkRotData,Save()) ;
				else RooFitResult* fit_1st = LikeSignPdf->fitTo(*likesignData,Save()) ; // likesign data
				//LikeSignPdf.fitTo(*data) ;       // unlikesign data    
				//fit_1st->Print();
				if (LS_constrain) {
					m0shift_constr = new RooGaussian("m0shift_constr","m0shift_constr",m0shift,RooConst(m0shift.getVal()),RooConst(m0shift.getError()));
					width_constr = new RooGaussian("width_constr","width_constr",width,RooConst(width.getVal()),RooConst(width.getError()));
					par3_constr = new RooGaussian("par3_constr","par3_constr",par3,RooConst(par3.getVal()),RooConst(par3.getError()));
					//m0shift_constr = new RooGaussian("m0shift_constr","m0shift_constr",m0shift,RooConst(7.9),RooConst(0.34*2));
					//width_constr = new RooGaussian("width_constr","width_constr",width,RooConst(2.77),RooConst(0.38*2));
					//par3_constr = new RooGaussian("par3_constr","par3_constr",par3,RooConst(6.3),RooConst(1.0*2));
				}
				else {
					m0shift.setConstant(kTRUE);
					width.setConstant(kTRUE);
					par3.setConstant(kTRUE);
				}
				RooAbsPdf  *pdf_combinedbkgd   = new RooAddPdf ("pdf_combinedbkgd","total combined background pdf",
						RooArgList(*bkgPdf,*LikeSignPdf),
						RooArgList(*nResidualbkgd,*nLikesignbkgd));
				//RooArgList(*LikeSignPdf),
				//RooArgList(*nbkgd));
				break;

			case 2 : //use RooKeysPdf to smooth the like-sign, then fix the shape and normailization
				if (TRKROT) RooKeysPdf *LikeSignPdf = new RooKeysPdf("Like-sign","likesign",*mass,*TrkRotData,3,1.5);
				else RooKeysPdf *LikeSignPdf = new RooKeysPdf("Like-sign","likesign",*mass,*likesignData,3,1.7);
				RooAbsPdf  *pdf_combinedbkgd   = new RooAddPdf ("pdf_combinedbkgd","total combined background pdf",
						RooArgList(*bkgPdf,*LikeSignPdf),
						RooArgList(*nResidualbkgd,*nLikesignbkgd));
				break;

			case 3 : //use error function to fit the unlike-sign directly
				RooGenericPdf *LikeSignPdf = new  RooGenericPdf("Like-sign","likesign","exp(-@0/decay)*(TMath::Erf((@0-turnOn)/width)+1)",RooArgList(*mass,m0shift,width,par3));
				RooAbsPdf  *pdf_combinedbkgd   = new RooAddPdf ("pdf_combinedbkgd","total combined background pdf",
						RooArgList(*LikeSignPdf),
						RooArgList(*nbkgd));
				break;

			case 4 : //use polynomial to fit the unlike-sign directly
				RooAbsPdf  *pdf_combinedbkgd   = new RooAddPdf ("pdf_combinedbkgd","total combined background pdf",
						RooArgList(*bkgPdf),
						RooArgList(*nbkgd));
				break;


			case 5 : //use ( error function + polynomial ) to fit the unlike-sign directly
				RooGenericPdf *LikeSignPdf = new  RooGenericPdf("Like-sign","likesign","exp(-@0/decay)*(TMath::Erf((@0-turnOn)/width)+1)",RooArgList(*mass,m0shift,width,par3));
				RooAbsPdf  *pdf_combinedbkgd   = new RooAddPdf ("pdf_combinedbkgd","total combined background pdf",
						RooArgList(*bkgPdf,*LikeSignPdf),
						RooArgList(*nResidualbkgd,*nLikesignbkgd));
				break;

			default :
				break;
		}

		//pdf with fixed ratio of the pp ratio
		RooAbsPdf  *pdf_pp   = new RooAddPdf ("pdf_pp","total signal+background pdf",
				RooArgList(*gauss1S2,*sig2S,*sig3S,*pdf_combinedbkgd),
				RooArgList(*nsig1f,*nsig2f_,*nsig3f_,*nbkgd));

		//the nominal fit with default pdf 
		if (LS_constrain) {
			RooAbsPdf  *pdf_unconstr   = new RooAddPdf ("pdf_unconstr","total signal+background pdf",
					RooArgList(*gauss1S2,*sig2S,*sig3S,*pdf_combinedbkgd),
					RooArgList(*nsig1f,*nsig2f,*nsig3f,*nbkgd));
			RooProdPdf *pdf  = new RooProdPdf ("pdf","total constr pdf",
					RooArgSet(*pdf_unconstr,*m0shift_constr,*width_constr,*par3_constr,*nLikesignbkgd_constr));
			RooFitResult* fit_2nd = pdf->fitTo(*data,Constrained(),Save(kTRUE),Extended(kTRUE),Minos(doMinos));
		}
		else {
			RooAbsPdf  *pdf   = new RooAddPdf ("pdf","total signal+background pdf",
					RooArgList(*gauss1S2,*sig2S,*sig3S,*pdf_combinedbkgd),
					RooArgList(*nsig1f,*nsig2f,*nsig3f,*nbkgd));
			RooFitResult* fit_2nd = pdf->fitTo(*data,Save(kTRUE),Extended(kTRUE),Minos(doMinos));
		}


		//plot
		TCanvas c; c.cd();
		int nbins = ceil((mmax_-mmin_)/binw_); 
		RooPlot* frame = mass->frame(Bins(nbins),Range(mmin_,mmax_));
		data->plotOn(frame,Name("theData"),MarkerSize(0.8));
		pdf->plotOn(frame,Name("thePdf"));
		if (plotLikeSign) {
			if (TRKROT) TrkRotData->plotOn(frame,Name("theLikeSignData"),MarkerSize(0.8),MarkerColor(kMagenta),MarkerStyle(22));
			else likesignData->plotOn(frame,Name("theLikeSignData"),MarkerSize(0.8),MarkerColor(kRed),MarkerStyle(24));
			//LikeSignPdf->plotOn(frame,Name("theLikeSign"),VisualizeError(*fit_1st,1),FillColor(kOrange));
			//LikeSignPdf->plotOn(frame,Name("theLikeSign"),LineColor(kRed));
		}
		RooArgSet * pars = pdf->getParameters(data);
		//RooArgSet * pars = LikeSignPdf->getParameters(likesignData);

		//calculate chi2 in a mass range
		float bin_Min = (8.2-mmin_)/binw_;
		float bin_Max = (10.8-mmin_)/binw_;
		int binMin = ceil(bin_Min);
		int binMax = ceil(bin_Max);
		int nfloatpars = pars->selectByAttrib("Constant",kFALSE)->getSize();
		float myndof = ceil((10.8-8.2)/binw_) - nfloatpars;
		cout<<binMin<<" "<<binMax<<" "<<nfloatpars<<" "<<myndof<<endl;
		double mychsq = frame->mychiSquare("thePdf","theData",nfloatpars,true,binMin,binMax)*myndof;
		//double mychsq = frame->mychiSquare("theLikeSign","theLikeSignData",nfloatpars,true,binMin,binMax)*myndof;

		/*
		   int nfloatpars = pars->selectByAttrib("Constant",kFALSE)->getSize();
		   float myndof = frame->GetNbinsX() - nfloatpars;
		   double mychsq = frame->chiSquare("theLikeSign","theLikeSignData",nfloatpars)*myndof;
		 */
		//plot parameters
		if(plotpars) {
			paramOn_ = "_paramOn";
			pdf->paramOn(frame,Layout(0.15,0.6,0.4),Layout(0.5,0.935,0.97),Label(Form("#chi^{2}/ndf = %2.1f/%2.0f", mychsq,myndof)));
		}

		/*
		   mass->setRange("R1S",8.8,9.7);
		   mass->setRange("R2S",9.8,10.2);
		//pdf_combinedbkgd->fitTo(*data,Range("R1,R3"),Constrained(),Save(kTRUE),Extended(kTRUE),Minos(doMinos));
		RooAbsReal* integral_1S = pdf_combinedbkgd->createIntegral(*mass,NormSet(*mass),Range("R1S")) ;
		cout << "1S bkgd integral = " << integral_1S->getVal() * (nbkgd->getVal()) << endl ;
		RooAbsReal* integral_2S = pdf_combinedbkgd->createIntegral(*mass,NormSet(*mass),Range("R2S")) ;
		cout << "2S bkgd integral = " << integral_2S->getVal() * (nbkgd->getVal()) << endl ;
		cout << "1S range count: " << data->sumEntries("invariantMass","R1S") <<endl;
		cout << "2S range count: " << data->sumEntries("invariantMass","R2S") <<endl;
		cout << "1S signal yield: " << data->sumEntries("invariantMass","R1S") - integral_1S->getVal() * (nbkgd->getVal()) << endl;
		cout << "2S signal yield: " << data->sumEntries("invariantMass","R2S") - integral_2S->getVal() * (nbkgd->getVal()) << endl;
		 */
		outfile<<"Y(1S) yield  : = "<<nsig1f->getVal()<<" +/- "<<nsig1f->getError()<<endl<<endl;
		outfile<<"free parameter = "<< nfloatpars << ", mychi2 = " << mychsq << ", ndof = " << myndof  << endl << endl;

		//draw the fit lines and save plots
		data->plotOn(frame,Name("theData"),MarkerSize(0.8));
		pdf->plotOn(frame,Components("bkg"),Name("theBkg"),LineStyle(5),LineColor(kGreen));
		pdf->plotOn(frame,Components("pdf_combinedbkgd"),LineStyle(kDashed));
		if (plotLikeSign) {
			if (TRKROT) pdf->plotOn(frame,Components("Like-sign"),Name("theLikeSign"),LineStyle(9),LineColor(kMagenta));
			else  pdf->plotOn(frame,Components("Like-sign"),Name("theLikeSign"),LineStyle(9),LineColor(kRed));
		}
		pdf->plotOn(frame,Name("thePdf"));
		data->plotOn(frame,MarkerSize(0.8));
		if (plotLikeSign) {
			if (TRKROT) TrkRotData->plotOn(frame,Name("theTrkRotData"),MarkerSize(0.8),MarkerColor(kMagenta),MarkerStyle(22));
			else likesignData->plotOn(frame,Name("theLikeSignData"),MarkerSize(0.8),MarkerColor(kRed),MarkerStyle(24));
		}   


		frame->SetTitle( "" );
		frame->GetXaxis()->SetTitle("m_{#mu^{+}#mu^{-}} (GeV/c^{2})");
		frame->GetXaxis()->CenterTitle(kTRUE);
		frame->GetYaxis()->SetTitleOffset(1.3);
		if (PR_plot && RAA) frame->GetYaxis()->SetRangeUser(0,1200);
		//frame->GetYaxis()->SetLabelSize(0.05);
		frame->Draw();


		//plot parameters
		if(!plotpars) {
			paramOn_ = ""; 
			TLatex latex1;
			latex1.SetNDC();
			if (PbPb) {
				latex1.DrawLatex(0.46,1.-0.05*3,"CMS PbPb  #sqrt{s_{NN}} = 2.76 TeV");
				latex1.DrawLatex(0.5,1.-0.05*4.9,"L_{int} = 150 #mub^{-1}"); 
				switch (bin) {  
					case 0: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 0-100%, |y| < 2.4"); break;
					case 3: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 0-5%, |y| < 2.4"); break;
					case 4: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 5-10%, |y| < 2.4"); break;
					case 5: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 10-20%, |y| < 2.4"); break;
					case 6: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 20-30%, |y| < 2.4"); break;
					case 7: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 30-40%, |y| < 2.4"); break;
					case 8: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 40-50%, |y| < 2.4"); break;
					case 9: latex1.DrawLatex(0.5,1.-0.05*6.2,"Cent. 50-100%, |y| < 2.4"); break;
							default; break;
				}   
			}
			else {