Beispiel #1
0
// ------------------------------------------------------------------------------------------------------//
// ------------------------------------------------------------------------------------------------------//
void bias_corr_stat_error(double Sa, double Sb, double Sc, double Sd,
		          double Qa, double Qb, double Qc, double Qd, 
		          double Scale, double *ret){
 
      	double ea = (Sa)/(Sa+Sb);
      	double ed = (Sd)/(Sd+Sc);
      	double ew = (Sa+Sb)/(Sa+Sb+Sd+Sc);
 	double st = Sa+Sb+Sc+Sd;
 
 	double na = (Qa + Sa);
      	double nb = (Qb + Sb);
      	double nc = (Qc + Sc);     		
      	double nd = (Qd + Sd);
 	
 	double S[4] = {0,0,0,0};
 	signal(na,nb,nc,nd,ea,ed,ew,S);
 	
 	double s1 = S[0];
 	double s2 = S[2];
 	
 	double cen1 = st/s1;
 	double cen2 = st/s2;
 	
      	TH1F *tmp_u = new TH1F("tmp_u","tmp_u",100,cen1*(1-0.01),cen1*(1+0.01)); 
      	TH1F *tmp_d = new TH1F("tmp_d","tmp_d",100,cen2*(1-0.01),cen2*(1+0.01));
      	
      	TRandom3 *rnd = new TRandom3();
      	      	
      	for(int i=0;i<50000; i++){
      	
      		double qa = Scale*rnd->Poisson((1./Scale)*Qa);
      		double qb = Scale*rnd->Poisson((1./Scale)*Qb);
      		double qc = Scale*rnd->Poisson((1./Scale)*Qc);
      		double qd = Scale*rnd->Poisson((1./Scale)*Qd);
      		
      		na = (qa + Sa);
      		nb = (qb + Sb);
      		nc = (qc + Sc);     		
      		nd = (qd + Sd);
      		
      		signal(na,nb,nc,nd,ea,ed,ew,S);

      		tmp_u->Fill(st/S[0]);      		     
      		tmp_d->Fill(st/S[2]);      		               	
          	
        }
        
	tmp_u->Fit("gaus","Q","Q");
	tmp_d->Fit("gaus","Q","Q");

	double val1 = tmp_u->GetFunction("gaus")->GetParameter(2);
	double val2 = tmp_d->GetFunction("gaus")->GetParameter(2);
	delete tmp_u;
	delete tmp_d;
	
	ret[0] = val1;
	ret[1] = val2;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    std::auto_ptr<TRint> application(new TRint("histInMemory", 0, 0));

    TH1F *hist1 = new TH1F("hist1", "hist1", 50, 0, 10);
    TH1F *hist2 = new TH1F("hist2", "hist2", 50, 0, 10);
    TH1F *hist3 = new TH1F("hist3", "hist3", 50, 0, 10);
    TH1F *hist4 = new TH1F("hist4", "hist4", 50, 0, 10);
    TH1F *hist5 = new TH1F("hist5", "hist5", 50, 0, 10);

    {
        TRandom3 *random = new TRandom3(1);
        for(int i = 0; 10000 > i; ++i)
        {
            hist1->Fill(random->Gaus(5, 1));
            hist2->Fill(random->Poisson(5));
            hist3->Fill(random->Uniform(0, 10));
            hist4->Fill(random->Gaus(4, 1));
            hist5->Fill(random->Poisson(3));
        }
        delete random;
    }

    TFile *output = new TFile("output.root", "RECREATE");
    TDirectory *group1 = output->mkdir("group1");
    group1->cd();

    hist1->Write();
    hist2->Write();

    TDirectory *group2 = output->mkdir("group2");
    group2->cd();

    hist3->Write();
    hist4->Write();
    hist5->Write();

    delete output;

    application->Run(true);

    delete hist1;
    delete hist2;
    delete hist3;
    delete hist4;
    delete hist5;

    return 0;
}
Beispiel #3
0
// ------------------------------------------------------------------------------------------------------//
// ------------------------------------------------------------------------------------------------------//
void frac_error(double a, double b, double *ret){

	double c = (b-a);
	gStyle->SetOptFit(0011);
	gStyle->SetOptStat(0); 
	TCanvas *can = new TCanvas("can","can",900,600);

	double frac = a/b;
	TH1F *h_    = new TH1F("h_","h_",100,frac*0.98,frac*1.02);
	TRandom3 *r  = new TRandom3();
	
	for(int i=0;i<50000;i++){
	 
	  double ap = r->Poisson(a);
	  double cp = r->Poisson(c);
	  h_->Fill((double)ap/(ap+cp));
	  
	}
	
	h_->Fit("gaus","Q","Q");
		
	h_->Draw();
	can->SaveAs("statEP.png");
	double val = h_->GetFunction("gaus")->GetParameter(2);
	delete h_;
	
	ret[0] = val;
}
int main()
{
	// Manual input:
	if (true)
	{
		vector<KLV> gen(4); // pt eta phi m
		gen[1].p4.SetCoordinates(30,  1.0, 0.5, 0);
		gen[3].p4.SetCoordinates(25, -1.0, 2.5, 0);
		gen[2].p4.SetCoordinates(15,  2.1, 1.1, 0);
		gen[0].p4.SetCoordinates(10,  2.3, 1.0, 0);
		vector<KLV> rec(3);
		rec[2].p4.SetCoordinates(20,  1.3, 0.4, 0);
		rec[0].p4.SetCoordinates(18, -0.9, 2.2, 0);
		rec[1].p4.SetCoordinates(13,  2.2, 1.1, 0);
		test(gen, rec);
	}

	// Automatic input
	TRandom3 rnd;
	for (size_t i = 0; i < 4; ++i)
	{
		vector<KLV> gen, rec;
		// GEN stuff
		for (size_t j = 0; j < (size_t)rnd.Poisson(10); ++j)
		{
			gen.push_back(KLV());
			gen.back().p4.SetCoordinates(rnd.Uniform(5, 100), rnd.Gaus(0, 5), rnd.Uniform(-M_PI, +M_PI), rnd.Gaus(0, 10));
			// RECO efficiency
			if (rnd.Uniform(0, 1) > 0.05)
			{
				rec.push_back(KLV());
				rec.back().p4.SetCoordinates(
					gen.back().p4.pt() * fabs(rnd.Gaus(0.8, 0.1)),
					gen.back().p4.eta() * fabs(rnd.Gaus(1, 0.1)),
					gen.back().p4.phi() + rnd.Uniform(0, 0.1),
					gen.back().p4.mass() * rnd.Gaus(1, 0.1));
			}
		}
		// RECO noise
		for (size_t j = 0; j < (size_t)rnd.Poisson(5); ++j)
		{
			rec.push_back(KLV());
			rec.back().p4.SetCoordinates(rnd.Uniform(1, 10), rnd.Gaus(0, 5), rnd.Uniform(-M_PI, +M_PI), rnd.Gaus(0, 10));
		}
		test(gen, rec);
	}
}
Beispiel #5
0
Int_t TwoBody::CreateDimuonToyMc( void ){
  //
  // generate a toy di-muon dataset with systematics
  // set mData accordingly
  //

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

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

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

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

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

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

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

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

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

  // debug
  std::cout << "!!!!!!!!!!!!!! _beta = " << _beta << std::endl;
  //std::cout << "!!!!!!!!!!!!!! _kappa = " << _kappa << std::endl;
  std::cout << "!!!!!!!!!!!!!! _nbkg_est = " << _nbkg_est << std::endl;
  std::cout << "!!!!!!!!!!!!!! _ntoy     = " << _ntoy << std::endl;
  std::cout << "!!!!!!!!!!!!!! _n        = " << _n    << std::endl;
  std::cout << "!!!!!!!!!!!!!! n_generated_entries = " << n_generated_entries    << std::endl;
  return n_generated_entries;
}
Beispiel #6
0
void randomize(TH1F* hist, unsigned int seed, unsigned int debug=0.)
{
  TRandom3* rnd = new TRandom3(seed); rnd->SetSeed();
  for(int idx=0; idx<hist->GetNbinsX(); ++idx){
    if(debug>0){
      std::cerr << "[" << idx+1 << "] : " << "mean=" << hist->GetBinContent(idx+1) << "  rnd=" << rnd->Poisson(hist->GetBinContent(idx+1)) << std::endl;  
    }
    float value = rnd->Poisson(hist->GetBinContent(idx+1));
    hist->SetBinContent(idx+1, value); hist->SetBinError(idx+1, TMath::Sqrt(value));
  }
  // Make sure there is no rounding error, and the total is truly an integer.
  hist->Scale(TMath::Nint(hist->Integral())/hist->Integral());
  delete rnd;
}
Beispiel #7
0
// Read in an event spectrum from a text file containing
// spectral data, and then generate some random events.
// This assumes that the input data file contains two columns,
// the first with (evenly spaced!) energy bins in units of eV, and the second
// with a number of events per kg per day per keV
void FillRecoilSpectrumFromFile(TH1F* recoilHisto, Double_t time, Double_t mass, const char* filename, Int_t seed)
{
	FILE* dataFile;
	dataFile = fopen(filename,"r");
	if (dataFile == NULL) {
		cout << "The file " << filename << " is not found!!! Quitting now." << endl;
		exit(1);
	}
	
	// Count the number of lines to set the array sizes
	fstream lineCountStream;
	lineCountStream.open(filename, fstream::in);
	Int_t lineCount = 0;
	while (lineCountStream.peek() != EOF) {
		lineCountStream.ignore(128, '\n');
		lineCount++;
	}
	lineCountStream.close();
	cout << "The file has " << lineCount << " lines." << endl;
	
	// Should add a section here to double check the formatting of the file
	
	// Warning message about units
	cout << "Reading data and filling histogram from " << filename << "..." << endl;
	cout << "I am assuming that the first column in the file is in units of MeV "
			 << "and that the second column is in units of 1/(kg day keV)!" << endl << endl;
	
	// Read the data
	const Int_t nLines = lineCount;
	Float_t energies[nLines];
	Float_t rates[nLines];
	for (Int_t thisLine = 0; thisLine < nLines; thisLine++)
		fscanf(dataFile, "%E %E", &energies[thisLine], &rates[thisLine]);
	fclose(dataFile);
	
	// Set up the source histogram
	TH1F SpectralDataHistogram("SpectralDataHistogram", "Spectrum of Events from File", nLines-1, energies);
	for (Int_t thisBin = 0; thisBin < (nLines - 1); thisBin++) {
		SpectralDataHistogram.SetBinContent(thisBin,rates[thisBin]);
	}
	
	// Fill the recoil histogram with the correct number
	// of events, randomly chosen from the source histogram.
	TRandom3* randGen = new TRandom3(seed);
	Float_t meanNEvents = time * mass * SpectralDataHistogram.ComputeIntegral();
	Int_t nEvents = randGen->Poisson(meanNEvents);
	cout << "nEvents = " << nEvents << endl;
	for (Int_t thisEvent; thisEvent<nEvents; thisEvent++)
		recoilHisto->Fill(SpectralDataHistogram.GetRandom());
}
Beispiel #8
0
// Generate the number of events for this run.
// This is just Poisson statistics and the cross section.
Int_t GenerateNumOfNuRecoils(Double_t time, Double_t detMass, Double_t distance, Double_t activity, Int_t nNeutrons, Int_t nProtons, TF1* RecoilSpectrum, Double_t SpectrumMin, Double_t SpectrumMax, UInt_t seed)
{
	// Set up the constants
	Double_t AvogadroConst = 6.022e23;
	Double_t NucleonMass = (nNeutrons * 939.565) + (nProtons * 938.272); // [MeV]
	Double_t molarMass = nNeutrons + nProtons;
	
	// Calculate mean number of events
	Double_t SpectrumWeightedCrossSection = RecoilSpectrum->Integral(SpectrumMin, SpectrumMax);
	Double_t MeanEvents = time * AvogadroConst * activity * detMass * SpectrumWeightedCrossSection / (4 * TMath::Pi() * molarMass * pow(distance,2));
	
	// Generate a random number of events from Poisson distribution
	TRandom3* randGen = new TRandom3(seed);
	Int_t nEvt = randGen->Poisson(MeanEvents);
	return nEvt;
}
void bins_chi2_n() {

//-------------------------------------------------
//Define here the luminosities for period 1 and 2
//-------------------------------------------------
    float l1 = 3.99;
    float l2 = 3.66;
    float ltot = l1+l2;


//-------------------------------------------------
//Define here the number of boxes (indepednant) and the yields
//-------------------------------------------------
//observed 27 - 36 | CR 88 - 54
///*
    int nbins = 2;
    float n1[] = {27,88};
    float n2[] = {36,54};
//*/

    //observed 31 - 13 | CR 59 - 43
    /*
    int nbins = 2;
    float n1[] = {31,59};
    float n2[] = {13,43};
    */
    float *ntot = new float[nbins];
    float *pred1 = new float[nbins];
    float *pred2 = new float[nbins];
    for(int i=0; i<nbins; i++) {
        ntot[i] = n1[i]+n2[i];
        pred1[i] = ntot[i]/ltot*l1;
        pred2[i] = ntot[i]/ltot*l2;
    }


    double prob = 1;
//max should be larger that the maximum yield
    int max = 200;
    for(int i=0; i<nbins; i++) {
        if(max<n1[i]) max = n1[i]*2;
        if(max<n2[i]) max = n2[i]*2;

    }
    double chi2=0;
    double like0 = 1;
    for(int i=0; i<nbins; i++) {
        TF1 f1("poiss1","TMath::PoissonI(x,[1])",0,max);
        TF1 f2("poiss1","TMath::PoissonI(x,[1])",0,max);
        f1.SetParameter(1,pred1[i]);
        f2.SetParameter(1,pred2[i]);
        if(f1.Integral(n1[i],max)<0.5)
            prob*=f1.Integral(n1[i],max);
        else
            prob*=f1.Integral(0,n1[i]);
        if(f2.Integral(n2[i],max)<0.5)
            prob*=f2.Integral(n2[i],max);
        else
            prob*=f2.Integral(0,n2[i]);

        //likelihood

        like0*=TMath::PoissonI(n1[i],pred1[i]);
        like0*=TMath::PoissonI(n2[i],pred2[i]);
        //chi2-test

        chi2+=pow((n1[i]-pred1[i]),2)/pred1[i];
        chi2+=pow((n2[i]-pred2[i]),2)/pred2[i];
        //prob *= f1.Integral(n1[i],max)*f2.Integral(n2[i],max);
    }
    cout<<"prob = "<<prob<<endl;
    cout<<"likelihood = "<<like0<<endl;
    cout<<"chi2 = "<<chi2<<" "<<TMath::Prob(chi2,1)<<endl;

//MC toys
    TRandom3 rand;
    int ntoys = 1000000;
    vector<double> vprob;
    for(int i=0; i<ntoys; i++) {
        double p = 1;
        double like = 1;
        for(int b=0; b<nbins; b++) {
            float v1 = rand.Poisson(pred1[b]);
            float v2 = rand.Poisson(pred2[b]);
            ///Compute prob
            like*=TMath::PoissonI(v1,pred1[b]);
            like*=TMath::PoissonI(v2,pred2[b]);

        }
        //vprob.push_back(prob);
        //cout<<like<<endl;
        vprob.push_back(like);
    }
//sort the vector
//std::sort(vprob.begin(),vprob.end(),myfunction);
//compute prob
    int count = 0;
    for(unsigned int x=0; x<vprob.size(); x++) {
        if(like0<vprob[x]) count++;
        // break;
    }
    cout<<count<<endl;
    double prob_toy = double(count)/vprob.size();
    cout<<"prob from MC toys = "<<prob_toy<<endl;


}
void createTBevents(int input){

  printf("Starting Simulation of data\n");

  //creating the output file
  char outputFileName[100] = {"OutputFile.root"};

  printf("Creating output file: %s \n",outputFileName);
  TFile * outputFile = new TFile(outputFileName,"RECREATE");


  //Counter for event number
  unsigned int eventNr;

  //Counter for total number of hits
  unsigned int hitsTotal = 0;

  
  short int col, row, adc;
  short int ladder = 2;
  short int mod = 3;
  short int disk = 2;
  short int blade = 2;
  short int panel = 2;
  
  //create the tree to store the data
  TTree *bpixTree[3];

  char title[30];
  for (int i=1; i<4; i++){
    sprintf(title,"BPIX_Digis_Layer%1d",i);
    bpixTree[i-1]= new TTree(title,title);
    bpixTree[i-1]->Branch("Event", &eventNr, "Event/i");           
    bpixTree[i-1]->Branch("Ladder", &ladder, "Ladder/S");      
    bpixTree[i-1]->Branch("Module", &mod, "Module/S");      
    bpixTree[i-1]->Branch("adc", &adc, "adc/S");       
    bpixTree[i-1]->Branch("col", &col, "col/S");       
    bpixTree[i-1]->Branch("row", &row, "row/S");
  }

  

  //Maximum number of events. Events does not correspond with Hits
  unsigned int maxEventNr = input;

  //Number of Hits per Event
  //This should be randomized later and be dependant on the rate
  double meanHitsPerEvent = 2;

  //Maximum particle flux [MHz cm^-2]
  int maxParticleFlux = 500;

  //number of hits in current event
  int hitsInEvent = -1; 

  //create a random number generator
  TRandom3 * random = new TRandom3();
  TRandom3 * randomrow = new TRandom3();
  TRandom3 * randomcol = new TRandom3();
  TRandom3 * randomadc = new TRandom3();

  //using custom function to distribute values
  //values used from http://ntucms1.cern.ch/pixel_dev/flux/v8/016031/fitspot_bin_11.pdf
  
  TF1 * fx = new TF1("xfunc", "[0]*exp(2.59349*exp(-0.5*((-x+3.24273/.15+[1]/.15)/7.07486*.15)**2)+2.07765*exp(-0.5*((-x+9.33060e-01/.15+[1]/.15)/2.24067*.15)**2)-4.21847)",0, 52);
  
  fx->SetParameters(1,337.0);
  fx->SetParameters(2,1.74);
  
  TF1 * fy = new TF1("yfunc", AsyGaus,0,80,4);
  
  fy->SetParNames("mean","sigma1","sigma2","amplitude");
  fy->SetParameter("mean",43);
  fy->SetParameter("sigma1",11.4);
  fy->SetParameter("sigma2",15.0);
  fy->SetParameter("amplitude",347.0);
  
  TF1 * fadc = new TF1("adcfunc", langaufun,0,400,4);
  fadc->SetParNames("scale","mpv","area","sigma");
  fadc->SetParameter("scale",19);
  fadc->SetParameter("mvp",220);
  fadc->SetParameter("area",10000);
  fadc->SetParameter("sigma",30);




  while (eventNr < maxEventNr){
    //printf("eventNr: %d \n",eventNr);
    //Function used for fitting according to Xin an Stefano
    
    //Start by generating the number of hits per event
    //following a poisson distribution
    random->SetSeed(0);
    hitsInEvent = random->Poisson(meanHitsPerEvent);
    //printf("hitsInEvent %d \n", hitsInEvent);

    hitsTotal += hitsInEvent;

    if(hitsInEvent < 0){
      printf("ERROR: Number of hits in event is negative!!!\n");
      break;
    }

    //distribute the hits in the event over the roc accorsing to gaus distribution
    /*
    for(int i = 0; i < hitsInEvent; ++i){

      //random row value
      randomrow->SetSeed(0);
      row = randomrow->Gaus(40,10);
      
      //random column value
      randomcol->SetSeed(0);
      col = randomcol->Gaus(25,8);

      //printf("row: %d | col: %d | adc: %d\n",row,col,adc);

      bpixTree[2]->Fill();

    }
    */


    for(int i = 0; i < hitsInEvent; ++i){

      //random row value
      row = fy->GetRandom();
      
      //random column value
      col = fx->GetRandom();

      //random adc value
      adc = fadc->GetRandom();

      //printf("row: %d | col: %d | adc: %d\n",row,col,adc);


      bpixTree[1]->Fill();

    }


    ++ eventNr;
  }


  printf("Total number of Hits: %d\n",hitsTotal);
  printf("Writing output file: %s \n", outputFileName);

  outputFile->cd();
  outputFile->Write();
  outputFile->Close();

  printf("DONE!\n");

}
//-------------------------------------------------------------
//Main macro for generating data and fitting
//=============================================================  
void FitMassPhotonResolutionSystematics(const string workspaceFile = "/afs/cern.ch/work/d/daan/public/releases/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/FitWorkspace_asdf.root", const string outputTree = "/afs/cern.ch/work/d/daan/public/releases/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/MassFitResults/MassFitTwoD_asdf.root", Int_t plotOption = 0, Int_t storeOption = 1, Int_t SystematicsUpOrDown = 1, Int_t NToys = 5000) {

  TRandom3 *randomnumber = new TRandom3(1200);
  TFile *wsFile = new TFile (workspaceFile.c_str(), "READ");
  RooWorkspace *ws = (RooWorkspace*)wsFile->Get("MassFitWorkspace");
  
  //Import variables from workspace
  RooAbsPdf *model2Dpdf = ws->pdf("model2Dpdf");
  RooRealVar *massBjet = ws->var("massBjet");
  RooRealVar *massPho = ws->var("massPho");
  RooRealVar *nsig = ws->var("N (Sig)"); RooRealVar constNsig(*nsig);
  RooRealVar *nres = ws->var("N (ResBkg)"); RooRealVar constNres(*nres);
  RooRealVar *nnonres = ws->var("N (NonResBkg)"); RooRealVar constNnonres(*nnonres);
  RooRealVar *expRateBjet = ws->var("expRateBjet"); RooRealVar constexpBjet(*expRateBjet);
  RooRealVar *expRatePho = ws->var("expRatePho"); RooRealVar constexpPho(*expRatePho);

  //Variables to set constant
  RooRealVar *sigMeanBjet = ws->var("sigMeanBjet"); sigMeanBjet->setConstant();
  RooRealVar *sigSigmaBjet = ws->var("sigSigmaBjet"); sigSigmaBjet->setConstant();
  RooRealVar *sigAlpha = ws->var("sigAlpha"); sigAlpha->setConstant();
  RooRealVar *sigPower = ws->var("sigPower"); sigPower->setConstant();
  RooRealVar *sigmaPho = ws->var("sigmaPho"); sigmaPho->setConstant();

  RooRealVar *resMeanBjet = ws->var("resMeanBjet"); resMeanBjet->setConstant();
  RooRealVar *resSigmaBjet = ws->var("resSigmaBjet"); resSigmaBjet->setConstant();
  RooRealVar *resAlpha = ws->var("resAlpha"); resAlpha->setConstant();
  RooRealVar *resPower = ws->var("resPower"); resPower->setConstant();
  RooRealVar *resExpo = ws->var("resExpo"); resExpo->setConstant();
  RooRealVar *nbbH = ws->var("nbbH"); nbbH->setConstant();
  RooRealVar *nOthers = ws->var("nOthers"); nOthers->setConstant();
  
  double inputSigmaPho = sigmaPho->getVal();

  //Create TTree to store the resulting yield data
  TFile *f = new TFile(outputTree.c_str(), "RECREATE");
  TTree *resultTree = new TTree("resultTree", "Parameter results from fitting");
  Float_t nsigOut, nresOut, nnonresOut;
  Float_t nsigStd, nresStd, nnonresStd;
  
  resultTree->Branch("nsigOut",&nsigOut, "nsigOut/F");
  resultTree->Branch("nresOut",&nresOut, "nresOut/F");
  resultTree->Branch("nnonresOut",&nnonresOut, "nnonresOut/F");
  resultTree->Branch("nsigStd",&nsigStd, "nsigStd/F");
  resultTree->Branch("nresStd",&nresStd, "nresStd/F");
  resultTree->Branch("nnonresStd",&nnonresStd, "nnonresStd/F");
  
  //Generate Toy MC experiment data and fits
  for(UInt_t t=0; t < NToys; ++t) {
    cout << "Toy #" << t << endl;
    nsig->setVal(constNsig.getVal()); nres->setVal(constNres.getVal()); nnonres->setVal(constNnonres.getVal());
    expRateBjet->setVal(constexpBjet.getVal()); expRatePho->setVal(constexpPho.getVal());
   
    //set jet energy resolutions to nominal
    sigmaPho->setVal(inputSigmaPho);

    cout << "Before: " << sigmaPho->getVal() << " | ";

    Float_t ran = randomnumber->Poisson(325.);
    RooDataSet *pseudoData2D = model2Dpdf->generate(RooArgList(*massBjet,*massPho), ran);

    //move jet energy resolution up/down
    if (SystematicsUpOrDown == 1) {
      sigmaPho->setVal(inputSigmaPho*1.15);
    } else if (SystematicsUpOrDown == -1) {
      sigmaPho->setVal(inputSigmaPho/1.15);
    }

    cout << "After: " << sigmaPho->getVal() << " \n";

    RooFitResult *fitResult2D = model2Dpdf->fitTo(*pseudoData2D, RooFit::Save(), RooFit::Extended(kTRUE), RooFit::Strategy(2));
//     if (t == 1763) {
//     	ws->import(*pseudoData2D, kTRUE);
//     	ws->import(*pseudoData2D, Rename("pseudoData2D"));
//     }
//     if (plotOption == 1) MakePlots(ws, fitResult2D);
    

    cout << "DEBUG: " << constexpBjet.getVal() << " , " << constexpPho.getVal() << " | " << expRateBjet->getVal() << " " << expRatePho->getVal() << "\n";


    //Store fit parameters into ROOT file
    if (storeOption == 1) {
      //Save variables into separate branches of root tree
  		nsigOut = nsig->getVal();
  		nresOut = nres->getVal();
  		nnonresOut = nnonres->getVal();
  		nsigStd = nsig->getPropagatedError(*fitResult2D);
  		nresStd = nres->getPropagatedError(*fitResult2D);
  		nnonresStd = nnonres->getPropagatedError(*fitResult2D);
  		//cout << "\n\n\n\n\n\n" << nsigOut << " | " << nresOut << " | " << nnonresOut << " | " << ran  << "\n\n\n\n\n" << endl;
  		resultTree->Fill();
    }
  }
  
  //Write to the TTree and close it
  resultTree->Write();
  f->Close();
}
Beispiel #12
0
int main (int argc, char** argv)
{
  // check number of inpt parameters
  if (argc < 2)
    {
      cerr << "Forgot to put the cfg file --> exit " << endl ;
      return 1 ;
    }
  if (gConfigParser) return 1 ;
  gConfigParser = new ConfigParser () ;
  
  TString config , runs;
  config.Form ("%s",argv[1]) ;
  runs.Form("%s",argv[2]);
  if (! (gConfigParser->init (config)))
    {
      cout << ">>> parseConfigFile::Could not open configuration file " << config << endl ;
      return -1 ;
    }

    int nruns=runs.Atoi();

  float lumi = gConfigParser->readFloatOption ("general::lumi") ;
  cout << "READING lumi " << lumi << endl ;

  int maxEvtsMC = -1;
  if (gConfigParser->isDefined ("general::maxEvtsMC"))
        maxEvtsMC = gConfigParser -> readIntOption ("general::maxEvtsMC");

  // get the samples to be analised
  // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

  // isolated samples
  // .... .... .... .... .... .... .... .... .... .... .... ....
  
  vector<string> sigSamplesList = gConfigParser->readStringListOption ("general::signals") ;
  vector<sample> sigSamples ;
  readSamples (sigSamples, sigSamplesList) ;

  vector<float> signalScales ;
  for (unsigned int i = 0 ; i < sigSamplesList.size () ; ++i)
    {
      string name = string ("samples::") + sigSamplesList.at (i) + string ("FACT") ;
      float scale = gConfigParser->readFloatOption (name.c_str ()) ;
      signalScales.push_back (scale) ;        
    }

  vector<string> bkgSamplesList = gConfigParser->readStringListOption ("general::backgrounds") ;
  vector<sample> bkgSamples ;
  readSamples (bkgSamples, bkgSamplesList) ;

  vector<string> DATASamplesList = gConfigParser->readStringListOption ("general::data") ;
  vector<sample> DATASamples ;
  readSamples (DATASamples, DATASamplesList) ;


  // get the selections to be applied
  // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

  vector<string> activeSelections = gConfigParser->readStringListOption ("selections::list") ;
  vector<pair <TString, TCut> > selections = readCutsFile (
      activeSelections,
      gConfigParser->readStringOption ("selections::selectionsFile")
    ) ;

  cout << "\n-====-====-====-====-====-====-====-====-====-====-====-====-====-\n\n" ;
  cout << "selections sequence: \n" ;
  for (unsigned int i = 0 ; i < selections.size () ; ++i)
    cout << selections.at (i).first << " : " << selections.at (i).second << endl ;

  // input selection must not have explicit iso on dau1, dau2 because QCD is relaxed and this selection is added here
  for (unsigned int i = 0 ; i < selections.size () ; ++i)
  {
    TString sel (selections.at (i).second);
    if ( sel.Contains("dau1_iso") || sel.Contains("dau2_iso") )
    {  
      cout << endl;
      cout << " ---------------------------------------------------------------------------------- " << endl;
      cout << " ** WARNING: selection " << selections.at(i).first << " explicitly contains iso cut" << endl; 
      cout << " ---------------------------------------------------------------------------------- " << endl;
      cout << endl;
    }
  }

  string sel_dau1_iso = gConfigParser->readStringOption ("selections::dau1iso");
  string sel_dau2_iso = gConfigParser->readStringOption ("selections::dau2iso");

  // ----------------------------------------
  // OS selections
  vector<pair <TString, TCut> > selections_OS = selections ;
  TCut dau1Cut = Form("dau1_iso < %s" , sel_dau1_iso.c_str());
  TCut dau2Cut = Form("dau2_iso < %s" , sel_dau2_iso.c_str());
  for (unsigned int i = 0 ; i < selections_OS.size () ; ++i)
    {
      selections_OS.at (i).first = TString ("OS_") + selections_OS.at (i).first ;
      selections_OS.at (i).second = selections_OS.at (i).second && TCut ("isOS != 0") && dau1Cut && dau2Cut;
    }
     
  // SS selections with tight iso (for QCD yield determination)
  vector<pair <TString, TCut> > selections_SS_tightIso = selections ;
  for (unsigned int i = 0 ; i < selections_SS_tightIso.size () ; ++i)
    {
      selections_SS_tightIso.at (i).first = TString ("SS_tightIso_") + selections_SS_tightIso.at (i).first ;
      selections_SS_tightIso.at (i).second = selections_SS_tightIso.at (i).second && TCut ("isOS == 0") && dau1Cut && dau2Cut;
    }
     
  // get the variables to be plotted
  // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

  vector<string> variablesList = gConfigParser->readStringListOption ("general::variables") ;
  vector<string> Buf_variables2DList(0);
  if (gConfigParser->isDefined ("general::2Dvariables")) Buf_variables2DList = gConfigParser->readStringListOption ("general::2Dvariables") ;
  
  vector<pair<string,string> > variables2DList ;
  for (unsigned int i = 0 ; i < Buf_variables2DList.size () ; ++i)
    {
      vector<string> dummy = split (Buf_variables2DList.at (i), ':') ;
      //cout << dummy.at (0) << " " << dummy.at (1) << " " << dummy.size () << endl ;
      variables2DList.push_back (make_pair(dummy.at (0), dummy.at (1)) ) ;
    }

    vector<pair <TString, TCut> > selections_SS = selections_SS_tightIso;

  // calculate the QCD in the SS region as data - other_bkg
  // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

  cout << "--- MAIN reading DATA and filling SS histos" << endl ;

  // get the same-sign distributions from data
  plotContainer SS_DATA_plots ("SS_DATA", variablesList, variables2DList, selections_SS, DATASamplesList, 2) ;
  counters SS_DATACount = fillHistos (DATASamples, SS_DATA_plots, 
              variablesList, variables2DList,
              selections_SS,
              lumi,
              vector<float> (0),
              true, false) ;
  SS_DATA_plots.AddOverAndUnderFlow () ;

  cout << "--- MAIN reading bkg and filling SS histos" << endl ;

  // get the same-sign distributions from bkg
  plotContainer SS_bkg_plots ("SS_bkg", variablesList, variables2DList, selections_SS, bkgSamplesList, 0) ;
  counters SS_bkgCount = fillHistos (bkgSamples, SS_bkg_plots, 
              variablesList, variables2DList,
              selections_SS,
              lumi,
              vector<float> (0),
              false, false, maxEvtsMC) ;
  SS_bkg_plots.AddOverAndUnderFlow () ;

  cout << "--- MAIN preparing to loop on variables and selections to calc SS QCD" << endl ;

  // the index in the stack is based on variable ID (iv) and selection ID (isel):
  // iHisto = iv + nVars * isel
  vector<string> QCDsample ;
  QCDsample.push_back ("QCD") ;
  plotContainer SS_QCD ("SS_QCD", variablesList, variables2DList, selections_SS, QCDsample, 0) ;
//  vector <TH1F *> SS_QCD ;
  vector<vector<float>> QCDyieldSSregionRLXiso (variablesList.size(), vector<float>(selections_SS.size()) ); // var, cut
  vector<TH1F*> QCDYields ;


  /* FIXME should we subtract signals as well? */
  /* NB if it has to be subtracted, it cannot be scaled! */

  // now get QCD yields with the non-relaxed selections

  cout << "--- MAIN reading bkg and filling SS histos with non-relaxed iso" << endl ;

  // get the same-sign distributions from bkg
  plotContainer SS_tightIso_bkg_plots ("SS_tightIso_bkg", variablesList, variables2DList, selections_SS_tightIso, bkgSamplesList, 0) ;
  counters SS_tightIso_bkgCount = fillHistos (bkgSamples, SS_tightIso_bkg_plots, 
              variablesList, variables2DList,
              selections_SS_tightIso,
              lumi,
              vector<float> (0),
              false, false, maxEvtsMC) ;
  SS_tightIso_bkg_plots.AddOverAndUnderFlow () ;


  plotContainer SS_QCD_tightIso ("SS_tightIso_QCD", variablesList, variables2DList, selections_SS_tightIso, QCDsample, 0) ;
//  vector <TH1F *> SS_QCD ;
  vector<vector<float>> QCDyieldSSregionTightIso (variablesList.size(), vector<float>(selections_SS_tightIso.size()) ); // var, cut


  cout << "--- MAIN reading DATA and filling SS histos with non-relaxed iso" << endl ;

  // get the same-sign distributions from data
  //plotContainer SS_tightIso_DATA_array[nruns];
  TRandom3 *g = new TRandom3();

    for (unsigned int icut = 0 ; icut < selections_SS_tightIso.size () ; ++icut)
    {
      TH1F *h =new TH1F(selections_SS_tightIso.at (icut).first.Data (),selections_SS_tightIso.at (icut).first.Data (),10000,1,10001);
      QCDYields.push_back(h);   
    }

    plotContainer SS_tightIso_DATA_plots ("SS_tightIso_DATA", variablesList, variables2DList, selections_SS_tightIso, DATASamplesList, 2) ;
    counters SS_tightIso_DATACount = fillHistos (DATASamples, SS_tightIso_DATA_plots, 
      variablesList, variables2DList,
      selections_SS_tightIso,
      lumi,
      vector<float> (0),
      true, false) ;
    SS_tightIso_DATA_plots.AddOverAndUnderFlow () ;  
    //SS_tightIso_DATA_array[irun] = SS_tightIso_DATA_plots;
  //}

  //cout << "--- MAIN preparing to loop on variables and selections to calc SS QCD yield with non-relaxed iso" << endl ;

  // the index in the stack is based on variable ID (iv) and selection ID (isel):
  // iHisto = iv + nVars * isel
  
  //vector<string> QCDsample ;
  //QCDsample.push_back ("QCD") ;
 
    for (unsigned int icut = 0 ; icut < selections_SS_tightIso.size () ; ++icut)
    {
      for (unsigned int ivar = 0 ; ivar < variablesList.size () ; ++ivar)
      {
        //plotContainer SS_tightIso_DATA_plots = SS_tightIso_DATA_array[irun]
        THStack * D_stack = SS_tightIso_DATA_plots.makeStack (variablesList.at (ivar),
          selections_SS_tightIso.at (icut).first.Data ()) ;
        TH1F * tempo = (TH1F *) D_stack->GetStack ()->Last () ;
        TH1F * orig = (TH1F*)tempo->Clone("original");
        THStack * b_stack = SS_tightIso_bkg_plots.makeStack (variablesList.at (ivar),
          selections_SS_tightIso.at (icut).first.Data ()) ;
        TH1F * h_bkg = (TH1F *) b_stack->GetStack ()->Last () ;
        int nbins = tempo->GetNbinsX();

        for(int irun =0;irun<nruns;irun++){
          //TString name; name.Form("%s%d",tempo->GetName (),irun) ;
          //tempo->SetName(name);
          //tempo->SetBinErrorOption(TH1::kPoisson);
          for(int ibin=1; ibin<=nbins;ibin++){
            tempo->SetBinContent(ibin,g->Poisson(orig->GetBinContent(ibin)));
            //cout<<tempo->GetBinContent(ibin)<<" "<<orig->GetBinContent(ibin)<<endl;
          }
        
        //name = TString ("DDQCD_tightIso_") + name ;
        //TH1F * dummy = (TH1F *) tempo->Clone (name) ;
        tempo->Add (h_bkg, -1) ;
        //cout<<"integral "<<tempo->Integral()<<endl;
        QCDYields.at(icut)->Fill(tempo->Integral());
      }
    }
  }

  //}
  // get the SS-to-OS scale factor and scale the QCD distributions
  // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


  // Save the histograms
  // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

  cout << "--- MAIN before saving" << endl ;
  TString outString ;
  outString.Form ("outPlotter.root") ;
  TFile * fOut = new TFile (outString.Data (), "RECREATE") ;

  fOut->cd();
  for(uint i=0; i<QCDYields.size();i++)QCDYields.at(i)->Write();
  fOut->Close () ;

  
  return 0 ;
}  
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");

}
Beispiel #14
0
TestProblem
AtlasDiJetMass(const int Nt,
               const int Nr,
               double tbins[],
               double rbins[],
               const double apar,
               const double bpar,
               const int nEvents,
               const double evtWeight)
{
  // From "Fully Bayesian Unfolding" by G. Choudalakis.
  // see arXiv:1201.4612v4
  // Recommended binning:
  // double bins[Nt+1] = {0};
  // for (int j=0; j<=Nt; j++)
  //   bins[j] = 500*TMath::Exp(0.15*j);

  static int id = 0; id++;
  TestProblem t;
  TRandom3 ran;

  // Mass distribution dN/dM
  TF1 *mass = new TF1("mass_dist",
                      "TMath::Power(1.-x/7000,6.0)/TMath::Power(x/7000,4.8)",
                      tbins[0], tbins[Nt]);

  // Generate test problem by MC convolution
  TH1D *hT   = new TH1D("hT",   "Truth mass dist. #hat{T}", Nt, tbins);
  TH1D *hTmc = new TH1D("hTmc", "MC Truth mass dist. #tilde{T}", Nt, tbins);
  TH1D *hD   = new TH1D("hD", "Measured mass dist.", Nr, rbins);
  TH2D *hM   = new TH2D("hM", "Migration matrix", Nr, rbins, Nt, tbins);
  hM->SetTitle(Form("%d x %d migration matrix M_{tr};"
                    "mass (observed);mass (true)", Nr, Nt));
  hT->SetLineWidth(2);
  hD->SetLineWidth(2);

  std::cout << Form("Generating test problem...") << std::flush;
  // Fill histos with MC events.
  // The response matrix gets more statistics than the data.
  double xt, xm, sigma;
  for (int i=0; i<nEvents; i++)
  {
    xt = mass->GetRandom();
    sigma = apar*TMath::Sqrt(xt) + bpar*xt;
    xm = xt + ran.Gaus(0, sigma);
    hM->Fill(xm, xt);
    hTmc->Fill(xt, evtWeight);
    hD->Fill(xm, evtWeight);
  }

  // Simulate Poisson fluctuations in real data (integer content, empty bins)
  for (int r=1; r<=Nr; r++)
    hD->SetBinContent(r, ran.Poisson(hD->GetBinContent(r)));

  // The true truth \hat{T}
  double totmass = mass->Integral(tbins[0],tbins[Nt]);
  for (int j=1; j<=Nt; j++)
  {
    hT->SetBinContent(j, evtWeight*nEvents*mass->Integral(tbins[j-1],
                      tbins[j])/totmass);
    hT->SetBinError(j, 0);
  }
  cout << "Done." << endl;

  // Projection of migration matrix to truth axis. hMt is the
  // numerator for efficiency. Bin contents should be counts
  // here. Elements are normalized to contain probabilities only after
  // projection & division by T-tilde.
  TH1D *hMt  = hM->ProjectionY("hMt",1,Nr);
  TH1D *heff = (TH1D *)hMt->Clone("heff");
  heff->Divide(hTmc);
  heff->Scale(evtWeight);
  hM->Scale(1./nEvents);
  hMt->Scale(1./nEvents);

  t.Response  = hM;
  t.xTruth    = hT;
  t.xTruthEst = hTmc;
  t.xIni      = hMt;
  t.bNoisy    = hD;
  t.eff       = heff;

  return t;
}
Beispiel #15
0
void higgsMassFit(const int& mH, const std::string& mode = "exclusion", const bool& drawPlots = false, const int& nToys = 10000)
{
  using namespace RooFit;
  RooMsgService::instance().deleteStream(0);
  RooMsgService::instance().deleteStream(1);
  
  
  
  std::string varName = "lepNuW_m";
  
  int step = 16;
  char treeName[50];
  sprintf(treeName, "ntu_%d", step);
  
  float lumi = 1000.;
  
  int nBins = 50;
  double xMin = 0.;
  double xMax = 1000.;
  double xMin_signal = 0.;
  double xMax_signal = 0.;
  SetXSignal(xMin_signal,xMax_signal,mH);
  
  RooRealVar x("x",varName.c_str(),xMin,xMax);
  x.setRange("low",   xMin,       xMin_signal);
  x.setRange("signal",xMin_signal,xMax_signal);
  x.setRange("high",  xMax_signal,xMax);
  
  RooRealVar w("w","weight",0.,1000000000.);
  
  char signalCut[50];
  sprintf(signalCut,"x > %f && x < %f",xMin_signal,xMax_signal);
  
  
  
  //-------------------
  // define the outfile
  char outFileName[50];
  sprintf(outFileName,"higgsMassFit_H%d_%s.root",mH,mode.c_str());
  TFile* outFile = new TFile(outFileName,"RECREATE");
  outFile -> cd();
  
  
  
  //-------------------
  // define the infiles
  char higgsMass[50];
  sprintf(higgsMass,"%d",mH);
  
  std::string BKGPath = "/grid_mnt/vol__vol1__u/llr/cms/abenagli/COLLISIONS7TeV/Fall10/VBFAnalysisPackage/data/VBFAnalysis_AK5PF_H" + 
                        std::string(higgsMass) + 
                        "_ET30_maxDeta_minDeta_Spring11_EGMu_noHiggsMassCut/";
  
  std::string WJetsFolder = "WJetsToLNu_TuneZ2_7TeV-madgraph-tauola_Spring11-PU_S1_START311_V1G1-v1/";
  std::string TTJetsFolder = "TTJets_TuneZ2_7TeV-madgraph-tauola_Spring11-PU_S1_START311_V1G1-v1/";
  //std::string ZJetsFolder = 
  //std::string GJets_HT40To100Folder 
  //std::string GJets_HT100To200Folder 
  //std::string GJets_HT200Folder 
  //std::string WWFolder 
  //std::string WZFolder 
  //std::string TJets_schannelFolder 
  //std::string TJets_tchannelFolder 
  //std::string TJets_tWchannelFolder 
  
  std::string GluGluHToLNuQQFolder   = "GluGluToHToWWToLNuQQ_M-"   + std::string(higgsMass) + "_7TeV-powheg-pythia6_Spring11-PU_S1_START311_V1G1-v1/";
  std::string GluGluHToTauNuQQFolder = "GluGluToHToWWToTauNuQQ_M-" + std::string(higgsMass) + "_7TeV-powheg-pythia6_Spring11-PU_S1_START311_V1G1-v1/";
  std::string VBFHToLNuQQFolder      = "VBF_HToWWToLNuQQ_M-"       + std::string(higgsMass) + "_7TeV-powheg-pythia6_Spring11-PU_S1_START311_V1G1-v1/";
  std::string VBFHToTauNuQQFolder    = "VBF_HToWWToTauNuQQ_M-"     + std::string(higgsMass) + "_7TeV-powheg-pythia6_Spring11-PU_S1_START311_V1G1-v1/";
  
  
  
  //---------------------------------------
  // define the background shape histograms
  int nBKG = 2;
  
  TH1F** BKGShapeHisto = new TH1F*[nBKG];
  TH1F* BKGTotShapeHisto = new TH1F("BKGTotShapeHisto","",nBins,xMin,xMax);
  THStack* BKGShapeStack = new THStack();
  RooDataSet** rooBKGDataSet = new RooDataSet*[nBKG];
  
  std::string* BKGNames = new std::string[nBKG];
  BKGNames[1]  = BKGPath+WJetsFolder+"VBFAnalysis_AK5PF.root";
  BKGNames[0]  = BKGPath+TTJetsFolder+"VBFAnalysis_AK5PF.root";
  //BKGNames[1]  = BKGPath+ZJetsFolder+"VBFAnalysis_AK5PF.root";
  //BKGNames[2]  = BKGPath+GJets_HT40To100Folder+"VBFAnalysis_AK5PF.root";
  //BKGNames[3]  = BKGPath+GJets_HT100To200Folder+"VBFAnalysis_AK5PF.root";
  //BKGNames[4]  = BKGPath+GJets_HT200Folder+"VBFAnalysis_AK5PF.root";
  //BKGNames[6]  = BKGPath+WWFolder+"VBFAnalysis_AK5PF.root";
  //BKGNames[7]  = BKGPath+WZFolder+"VBFAnalysis_AK5PF.root";
  //BKGNames[8]  = BKGPath+TJets_schannelFolder+"VBFAnalysis_AK5PF.root";
  //BKGNames[9]  = BKGPath+TJets_tchannelFolder+"VBFAnalysis_AK5PF.root";
  //BKGNames[10] = BKGPath+TJets_tWchannelFolder+"VBFAnalysis_AK5PF.root";
  
  std::string* BKGShortNames = new std::string[nBKG];
  BKGShortNames[1]  = "WJets";
  BKGShortNames[0]  = "TTJets";
  //BKGShortNames[1]  = "ZJets";
  //BKGShortNames[2]  = "GJets_HT40To100";
  //BKGShortNames[3]  = "GJets_HT100To200";
  //BKGShortNames[4]  = "GJets_HT200";
  //BKGShortNames[6]  = "WW";
  //BKGShortNames[7]  = "WZ";
  //BKGShortNames[8]  = "TJets_schannel";
  //BKGShortNames[9]  = "TJets_tchannel";
  //BKGShortNames[10] = "TJets_tWchannel";
  
  Color_t* BKGColors = new Color_t[nBKG];
  BKGColors[1]  = kOrange-708;
  BKGColors[0]  = kAzure-795;
  
  
  
  //-----------------------------------
  // define the signal shape histograms
  int nSIG = 2;
  
  TH1F* SIGShapeHisto = new TH1F("SIGShapeHisto","",4*nBins,xMin,xMax);
  SIGShapeHisto -> Sumw2();
  SIGShapeHisto -> SetLineWidth(1);
  SIGShapeHisto -> SetLineStyle(1);
  RooDataSet* rooSIGDataSet = new RooDataSet("rooSIGDataSet","",RooArgSet(x,w),WeightVar(w));
  
  std::string* SIGNames = new std::string[nSIG];
  SIGNames[0]  = BKGPath+GluGluHToLNuQQFolder+"VBFAnalysis_AK5PF.root";
  SIGNames[1]  = BKGPath+VBFHToLNuQQFolder+"VBFAnalysis_AK5PF.root";
  
  std::string* SIGShortNames = new std::string[nSIG];
  SIGShortNames[1]  = "ggH";
  SIGShortNames[0]  = "qqH";
  
  
  
  
  
  
  //----------------------
  // loop over backgrounds
  std::cout << "***********************************************************************" << std::endl;
  std::cout << ">>> Fill the background shapes" << std::endl;
    
  for(int i = 0; i < nBKG; ++i)
  {
    TFile* inFile_BKGShape = TFile::Open((BKGNames[i]).c_str());
    inFile_BKGShape -> cd();
    
    TTree* BKGShapeTree = (TTree*)(inFile_BKGShape -> Get(treeName));
    
    BKGShapeHisto[i] = new TH1F(("BKGShapeHisto_"+BKGShortNames[i]).c_str(),"",nBins,xMin,xMax);
    enum EColor color = (enum EColor)(BKGColors[i]);
    BKGShapeHisto[i] -> SetFillColor(color);
    BKGShapeHisto[i] -> Sumw2();
    
    rooBKGDataSet[i] = new RooDataSet(("rooBKGDataSet_"+BKGShortNames[i]).c_str(),"",RooArgSet(x,w),WeightVar(w)); 
    
    TH1F* eventsHisto;
    inFile_BKGShape -> GetObject("events", eventsHisto);
    float totEvents = eventsHisto -> GetBinContent(1);
    
    
    // set branch addresses
    float crossSection;
    float var;
    BKGShapeTree -> SetBranchAddress("crossSection", &crossSection);
    BKGShapeTree -> SetBranchAddress(varName.c_str(),&var);
    
    
    // loop over the entries
    for(int entry = 0; entry < BKGShapeTree->GetEntries(); ++entry)
    {
      BKGShapeTree -> GetEntry(entry);
      
      x = var;
      w = 1./totEvents*crossSection*lumi;
      
      BKGShapeHisto[i] -> Fill(var, 1./totEvents*crossSection*lumi);
      BKGTotShapeHisto    -> Fill(var, 1./totEvents*crossSection*lumi);
      rooBKGDataSet[i] -> add(RooArgSet(x,w));
    }
    
    BKGShapeStack -> Add(BKGShapeHisto[i]);
  }
  
  
  
  
  
  
  //------------------
  // loop over signals
  std::cout << ">>> Fill the signal shapes" << std::endl;
    
  for(int i = 0; i < nSIG; ++i)
  {
    TFile* inFile_SIGShape = TFile::Open((SIGNames[i]).c_str());
    inFile_SIGShape -> cd();
    
    TTree* SIGShapeTree = (TTree*)(inFile_SIGShape -> Get(treeName));
    
    TH1F* eventsHisto = (TH1F*)(inFile_SIGShape -> Get("events"));
    float totEvents = eventsHisto -> GetBinContent(1);
    
    
    // set branch addresses
    float crossSection;
    float var;
    SIGShapeTree -> SetBranchAddress("crossSection", &crossSection);
    SIGShapeTree -> SetBranchAddress(varName.c_str(),&var);
    
    
    // loop over the entries
    for(int entry = 0; entry < SIGShapeTree->GetEntries(); ++entry)
    {
      SIGShapeTree -> GetEntry(entry);
      
      x = var;
      w= 1./totEvents*crossSection*lumi;
      
      SIGShapeHisto -> Fill(var, 1./totEvents*crossSection*lumi);
      rooSIGDataSet -> add(RooArgSet(x,w));
    }
  }
  
  
  
  //-----------------------------------
  // draw the background + signal stack
  if( drawPlots )
  {
    TCanvas* c1 = new TCanvas("BKGShapeStack","BKGShapeStack");
    c1 -> SetGridx();
    c1 -> SetGridy();
    BKGShapeStack -> Draw("HIST");
    SIGShapeHisto -> Draw("HIST,same");  
    char pngFileName[50];
    sprintf(pngFileName,"BKGShapeStack_H%d_%s.png",mH,mode.c_str());
    c1 -> Print(pngFileName,"png");
  }  
  
  
  
  
  
  
  //---------------------------------
  // define the bkg shape with roofit
  std::cout << ">>> Define the background pdf" << std::endl;
    
  RooKeysPdf** rooBKGPdf = new RooKeysPdf*[nBKG];
  RooRealVar** rooNBKG = new RooRealVar*[nBKG];
  RooRealVar* rooNBKGTot = new RooRealVar("rooNBKGTot","",BKGTotShapeHisto->Integral(),0.,1000000.);
  
  for(int i = 0; i < nBKG; ++i)
  {  
    rooBKGPdf[i] = new RooKeysPdf(("rooBKGPdf_"+BKGShortNames[i]).c_str(),"",x,*rooBKGDataSet[i]);
    rooNBKG[i] = new RooRealVar(("rooNBKG_"+BKGShortNames[i]).c_str(),"",BKGShapeHisto[i]->Integral(),BKGShapeHisto[i]->Integral()),BKGShapeHisto[i]->Integral();
  }
  
  RooAddPdf* rooBKGTotPdf = new RooAddPdf("rooBKGTotPdf","",RooArgList(*rooBKGPdf[0],*rooBKGPdf[1]),RooArgList(*rooNBKG[0],*rooNBKG[1]));
  
  
  
  //---------------------------------
  // define the sig shape with roofit
  std::cout << ">>> Define the signal pdf" << std::endl;
    
  RooKeysPdf* rooSIGPdf = new RooKeysPdf("rooSIGPdf","",x,*rooSIGDataSet);
  RooRealVar* rooNSIG = new RooRealVar("rooNSIG","",1.,-1000000.,1000000.);
  
  
  
  //---------------------------------
  // define the tot shape with roofit
  std::cout << ">>> Define the total pdf" << std::endl;
  
  RooAddPdf* rooTotPdf = NULL;
  if( mode == "exclusion") rooTotPdf = new RooAddPdf("rooTotPdf","",RooArgList(*rooBKGTotPdf),RooArgList(*rooNBKGTot));
  if( mode == "discovery") rooTotPdf = new RooAddPdf("rooTotPdf","",RooArgList(*rooBKGTotPdf,*rooSIGPdf),RooArgList(*rooNBKGTot,*rooNSIG));
  
  
  
  
  
  
  //----
  // plot 
  if( drawPlots )
  {
    TCanvas* c2 = new TCanvas("rooTotPdf","rooTotPdf");
    c2 -> SetGridx();
    c2 -> SetGridy();
    
    RooPlot* rooBKGPlot = x.frame();
    rooBKGTotPdf -> plotOn(rooBKGPlot,LineColor(kBlack));
    enum EColor color = (enum EColor)(BKGColors[0]);
    rooBKGTotPdf -> plotOn(rooBKGPlot,Components(("rooBKGPdf_"+BKGShortNames[0]).c_str()),LineColor(color));
    color = (enum EColor)(BKGColors[1]);
    rooBKGTotPdf -> plotOn(rooBKGPlot,Components(("rooBKGPdf_"+BKGShortNames[1]).c_str()),LineColor(color));
    
    rooSIGPdf -> plotOn(rooBKGPlot,LineColor(kBlack),LineStyle(1),LineWidth(1));
    
    rooBKGPlot->Draw();
    
    TH1F* BKGShapeHistoNorm = (TH1F*) BKGTotShapeHisto -> Clone();
    BKGShapeHistoNorm -> Scale(1./BKGTotShapeHisto->Integral()/nBKG);
    BKGShapeHistoNorm -> Draw("HIST,same");

    char pngFileName[50];
    sprintf(pngFileName,"BKGShapeNorm_H%d_%s.png",mH,mode.c_str());
    c2 -> Print(pngFileName,"png");
  }
  
  
  
  
  
  
  //------------------------
  // generate toy experiment
  std::cout << "***********************************************************************" << std::endl;
  std::cout << ">>> 1st toy experiment - " << mode << " mode" << std::endl;  
  
  int NBKGToy = int(BKGTotShapeHisto->Integral());
  int NSIGToy = 0;
  if( mode == "discovery" ) NSIGToy = int(SIGShapeHisto->Integral());
  
  RooDataSet* rooBKGToyDataSet = rooBKGTotPdf->generate(RooArgSet(x),NBKGToy);
  RooDataSet* rooSIGToyDataSet = rooSIGPdf->generate(RooArgSet(x),NSIGToy);
  rooBKGToyDataSet -> append(*rooSIGToyDataSet);
  
  float NBKGToy_signal = rooBKGToyDataSet->sumEntries(signalCut);
  float NBKGToy_signal_fit = 0.;
  
  
  
  // fit
  if( mode == "exclusion" ) rooTotPdf -> fitTo(*rooBKGToyDataSet,Extended(kTRUE),PrintLevel(-1),Range("low,high"));
  if( mode == "discovery" ) rooTotPdf -> fitTo(*rooBKGToyDataSet,Extended(kTRUE),PrintLevel(-1));
  
  
  
  // count events
  if( mode == "exclusion" )
  {
    RooAbsReal* rooTotIntegral = rooTotPdf -> createIntegral(x,NormSet(x),Range("signal"));
    NBKGToy_signal_fit = rooTotIntegral->getVal() * rooNBKGTot->getVal();
    
    std::cout << ">>>>>> BKG toy events (true) in signal region in " << lumi << "/pb: " << NBKGToy_signal << std::endl;  
    std::cout << ">>>>>> BKG toy events (fit)  in signal region in " << lumi << "/pb: " << NBKGToy_signal_fit << std::endl;      
  }
  
  if( mode == "discovery" )
  {
    std::cout << ">>>>>> BKG toy events (true) in " << lumi << "/pb: " << NBKGToy << std::endl;  
    std::cout << ">>>>>> BKG toy events (fit)  in " << lumi << "/pb: " << rooNBKGTot->getVal() << std::endl;  
    std::cout << ">>>>>> SIG toy events (true) in " << lumi << "/pb: " << NSIGToy << std::endl;  
    std::cout << ">>>>>> SIG toy events (fit)  in " << lumi << "/pb: " << rooNSIG->getVal() << std::endl;  
  }
  
  if( drawPlots )
  {
    TCanvas* c3 = new TCanvas("TOY","TOY");
    c3 -> SetGridx();
    c3 -> SetGridy();
    
    RooPlot* rooTOYPlot = x.frame();
    rooBKGToyDataSet -> plotOn(rooTOYPlot,MarkerSize(0.7));
    rooTotPdf -> plotOn(rooTOYPlot, LineColor(kRed));
    rooTotPdf -> plotOn(rooTOYPlot, Components("rooSIGPdf"), LineColor(kRed));
    rooTOYPlot->Draw();
    
    char pngFileName[50];
    sprintf(pngFileName,"BKGToyFit_H%d_%s.png",mH,mode.c_str());
    c3 -> Print(pngFileName,"png");
  }
  
  
  
  
  
  
  //-------------------------
  // generate toy experiments
  
  TH1F* h_BKGRes = new TH1F("h_BKGRes","",200,-400,400);
  TH1F* h_SIGRes = new TH1F("h_SIGRes","",200,-400,400);
  
  TRandom3 B;
  TRandom3 S;
  for(int j = 0; j < nToys; ++j)
  {
    if( j%100 == 0 )
      std::cout << ">>>>>> generating toy experiment " << j << std::endl;
    
    NBKGToy = B.Poisson(BKGTotShapeHisto->Integral());
    NSIGToy = 0;
    if( mode == "discovery" ) NSIGToy = S.Poisson(SIGShapeHisto->Integral());
    
    rooBKGToyDataSet = rooBKGTotPdf->generate(RooArgSet(x),NBKGToy);
    rooSIGToyDataSet = rooSIGPdf->generate(RooArgSet(x),NSIGToy);
    rooBKGToyDataSet -> append(*rooSIGToyDataSet);
    
    NBKGToy_signal = rooBKGToyDataSet->sumEntries(signalCut);
    NBKGToy_signal_fit = 0.;
    
    
    
    // fit
    if( mode == "exclusion" ) rooTotPdf -> fitTo(*rooBKGToyDataSet,Extended(kTRUE),PrintLevel(-1),Range("low,high"));
    if( mode == "discovery" ) rooTotPdf -> fitTo(*rooBKGToyDataSet,Extended(kTRUE),PrintLevel(-1));    
    
    
    
    // count events
    if( mode == "exclusion" )
    {
      RooAbsReal* rooTotIntegral = rooTotPdf -> createIntegral(x,NormSet(x),Range("signal"));
      NBKGToy_signal_fit = rooTotIntegral->getVal() * rooNBKGTot->getVal();
      
      h_BKGRes -> Fill(NBKGToy_signal_fit - NBKGToy_signal);
      h_SIGRes -> Fill(0.);
    }
    
    if( mode == "discovery" )
    {
      h_BKGRes -> Fill(rooNBKGTot->getVal() - NBKGToy);
      h_SIGRes -> Fill(rooNSIG->getVal() - NSIGToy);
    }
    
  }
  
  
  
  outFile -> cd();
  
  h_BKGRes -> Write();
  h_SIGRes -> Write();
  
  outFile -> Close();
}