Пример #1
0
PolyFit::PolyFit(double p0, double p1, double p2, double p3, double sigma) :
  _theTFile(new TFile("test/myFit.root","RECREATE")),
  _sigma(sigma)
{

  // Display parameters for test distribution 

  std::cout << std::endl;
  /*Info <<"Set p0 as "<< p0 << endmsg;
  Info <<"Set p1 as "<< p1 << endmsg;
  Info <<"Set p2 as "<< p2 << endmsg;
  Info <<"Set p3 as "<< p3 << endmsg;
  Info <<"Set sigma as "<< sigma << endmsg;*/
  std::cout <<"Set p0 as "<< p0 << std::endl;
  std::cout <<"Set p1 as "<< p1 << std::endl;
  std::cout <<"Set p2 as "<< p2 << std::endl;
  std::cout <<"Set p3 as "<< p3 << std::endl;
  std::cout <<"Set sigma as "<< sigma << std::endl;

  // Generate test distribution and smear them with a gaussian
  TRandom randomNumber;
  randomNumber.SetSeed(1773);
  for(int i=0; i<1000; i++) {
    double tmpXvalue=static_cast<double>((rand() % 10000 + 1)) / 100;
    double tmpYvalue=randomNumber.Gaus(p0 + p1 * tmpXvalue + p2 * tmpXvalue * tmpXvalue + p3 * tmpXvalue * tmpXvalue * tmpXvalue, _sigma);
    _xValue.push_back(tmpXvalue);
    _yValue.push_back(tmpYvalue);
  }

}
Пример #2
0
void FitterUtils::initiateParams(int nGenSignalZeroGamma, int nGenSignalOneGamma, int nGenSignalTwoGamma, RooRealVar const& expoConstGen, RooRealVar& nSignal, RooRealVar& nPartReco, 
      RooRealVar& nComb, RooRealVar& fracZero, RooRealVar& fracOne, RooRealVar& expoConst, RooRealVar&  nJpsiLeak, bool constPartReco, RooRealVar const& fracPartRecoSigma)
{
   TRandom rand;
   rand.SetSeed();

   int nGenSignal = nGenSignalZeroGamma + nGenSignalOneGamma + nGenSignalTwoGamma;

   double nGenSignal2;
   double nGenPartReco2;
   if(!constPartReco)
   {
      nGenSignal2 = rand.Uniform(nGenSignal-5*sqrt(nGenSignal), nGenSignal+5*sqrt(nGenSignal));
      nGenPartReco2 = rand.Uniform(nGenPartReco-5*sqrt(nGenPartReco), nGenPartReco+5*sqrt(nGenPartReco));
   }
   if(constPartReco)
   { 
      double nGenSigPartReco( nGenSignal+nGenPartReco );
      double nGenSigPartReco2( rand.Uniform( nGenSigPartReco-5*sqrt(nGenSigPartReco), nGenSigPartReco+5*sqrt(nGenSigPartReco) ) );
      double fracPartReco1( nGenPartReco/(1.*nGenSignal));
      double fracPartReco2( rand.Uniform(fracPartReco1-5*fracPartRecoSigma.getVal(), fracPartReco1+5*fracPartRecoSigma.getVal()) ); 

      nGenPartReco2 = fracPartReco2*nGenSigPartReco2 / (1+fracPartReco2); 
      nGenSignal2 = nGenSigPartReco2 / (1+fracPartReco2); 
   }
   double nGenComb2 = rand.Uniform(nGenComb-5*sqrt(nGenComb), nGenComb+5*sqrt(nGenComb));
   double nGenJpsiLeak2 = rand.Uniform(nGenJpsiLeak-5*sqrt(nGenJpsiLeak), nGenJpsiLeak+5*sqrt(nGenJpsiLeak));


   nSignal.setVal(nGenSignal2);
   nSignal.setRange(TMath::Max(0.,nGenSignal2-10.*sqrt(nGenSignal)) , nGenSignal2+10*sqrt(nGenSignal));

   nPartReco.setVal(nGenPartReco2);
   nPartReco.setRange(TMath::Max(0.,nGenPartReco2-10.*sqrt(nGenPartReco)), nGenPartReco2+10*sqrt(nGenPartReco));


   nComb.setVal(nGenComb2);
   nComb.setRange(TMath::Max(0.,nGenComb2-10.*sqrt(nGenComb)), nGenComb2+10*sqrt(nGenComb));

   nJpsiLeak.setVal(nGenJpsiLeak2);
   nJpsiLeak.setRange(TMath::Max(0., nGenJpsiLeak2-10*sqrt(nGenJpsiLeak)), nGenJpsiLeak2+10*sqrt(nGenJpsiLeak));

   double fracGenZero(nGenSignalZeroGamma/(1.*nGenSignal));
   double fracGenOne(nGenSignalOneGamma/(1.*nGenSignal));

   fracZero.setVal(rand.Gaus(fracGenZero, sqrt(nGenSignalZeroGamma)/(1.*nGenSignal))) ;
   fracZero.setRange(0., 1.);
   fracOne.setVal(rand.Gaus(fracGenOne, sqrt(nGenSignalOneGamma)/(1.*nGenSignal))) ;
   fracOne.setRange(0., 1.);

   expoConst.setVal(rand.Uniform( expoConstGen.getVal() - 5*expoConstGen.getError(), expoConstGen.getVal() + 5*expoConstGen.getError() ) );
   expoConst.setRange( expoConstGen.getVal() - 10*expoConstGen.getError(), expoConstGen.getVal() + 10*expoConstGen.getError() );
}
Пример #3
0
void makeDecalibCDB(Int_t firstRun, Int_t lastRun, Float_t decalib = 0.065)
{
  //Generates a random decalibration factors O(1)
  //to be applied in the anchor run simulations with raw:// .
  //If decalib<0, no decalibration generated, all factors=1.
  
  //Run range is [firstRun,lastRun] and gaussian sigma = decalib.
  //Author: Boris Polishchuk.
  
  AliCDBManager::Instance()->SetDefaultStorage("raw://");
  AliCDBManager::Instance()->SetRun(firstRun);

  TString emcPath("PHOS/Calib/EmcGainPedestals");
  AliCDBEntry* entryEmc = AliCDBManager::Instance()->Get(emcPath.Data(),-1);

  AliPHOSEmcCalibData* clb=0;

  if(entryEmc) clb = (AliPHOSEmcCalibData*)entryEmc->GetObject();
  else { printf("CDB entry not found. Exit.\n"); return; }
  
  if(!clb) { printf("Calibration parameters for PHOS EMC not found.\n"); return; }
  
  printf("\t\tEMC calibration object found: FirstRun=%d LastRun=%d Version=%d SubVersion=%d\n",
         entryEmc->GetId().GetFirstRun(), entryEmc->GetId().GetLastRun(),
         entryEmc->GetId().GetVersion(),entryEmc->GetId().GetSubVersion());
  
  
  TRandom rn;
  rn.SetSeed(0); //the seed is set to the current  machine clock

  Float_t adcChannelEmc;

  for(Int_t module=1; module<6; module++) {
    for(Int_t column=1; column<57; column++) {
      for(Int_t row=1; row<65; row++) {

	if(decalib<0.) adcChannelEmc = 1.;
	else
	  adcChannelEmc =rn.Gaus(1.,decalib);

        clb->SetADCchannelEmcDecalib(module,column,row,adcChannelEmc);
      }
    }
  }

  AliCDBManager::Instance()->SetDefaultStorage("local://./");
  AliCDBStorage* storage = AliCDBManager::Instance()->GetDefaultStorage();
  
  AliCDBMetaData *md = new AliCDBMetaData();
  AliCDBId id(emcPath.Data(),firstRun,lastRun);
  storage->Put(clb,id, md);

}
Пример #4
0
void JEC_fit_Uncertainty(int N)
{
  TF1 *func[1000];
  TFile *inf = new TFile("L3Graphs_test_Icone5.root");
  TGraphErrors *g = (TGraphErrors*)inf->Get("Correction_vs_CaloPt");
  TGraphErrors *vg[1000];
  int i,k;
  double x[20],y[20],ex[20],ey[20];
  double vx[20],vy[20],vex[20],vey[20];
  for(i=0;i<g->GetN();i++)
    {
      g->GetPoint(i,x[i],y[i]);
      ex[i]=g->GetErrorX(i);
      ey[i]=g->GetErrorY(i); 
    }  
  TRandom *rnd = new TRandom();
  rnd->SetSeed(0);
  for(k=0;k<N;k++)
    {
      for(i=0;i<g->GetN();i++)
        {	
          vx[i] = rnd->Gaus(x[i],ex[i]);
          //vx[i] = x[i];
          vy[i] = rnd->Gaus(y[i],ey[i]);
          vex[i] = ex[i];
          vey[i] = ey[i];
        }
      vg[k] = new TGraphErrors(g->GetN(),vx,vy,vex,vey);
      func[k] = new TF1("func","[0]+[1]/(pow(log10(x),[2])+[3])",1,2000);
      func[k]->SetParameters(1,3,6,5);
      vg[k]->Fit(func[k],"RQ");     	
    }
  
  TCanvas *c = new TCanvas("c","c");
  gPad->SetLogx();
  g->SetMarkerStyle(20);
  g->SetMaximum(3.5);
  g->Draw("AP");
  for(k=0;k<N;k++)
    {
      func[k]->SetLineColor(5);
      func[k]->SetLineWidth(1);
      cout<<func[k]->GetChisquare()<<endl;
      vg[k]->SetMarkerColor(2);
      vg[k]->SetLineColor(2);
      vg[k]->SetMarkerStyle(21);
      //if (func[k]->GetChisquare()<0.1)
        //vg[k]->Draw("sameP");
      func[k]->Draw("same");  
    }  	 
}  
double error(double a, double b) {

 TRandom rndm;
 rndm.SetSeed(12345);
 
 if (a<=0.000000001) return 0.;

 double eff = a/b;
 int n0 = rndm.Poisson((a+b));
 // int n1 = rndm.Binomial(n0,eff);

 double err=sqrt(eff*(1-eff)/n0);

 return err;
}
Пример #6
0
Файл: fmpmt.c Проект: ekawa/test
void fmpmt(void){

  TTree *t = new TTree("tree","fine mesh");
  double adc;
  t->Branch("adc",&adc,"adc/D");

  double Mult(double seed){
    do{
      double _fac=2.79360;
      TRandom _rand;
      _rand.SetSeed(0);
      double _judge = _rand.Uniform(0,1);
      double _x = _rand.Uniform(0.001,10);
    } while (TMath::Gaus(_x, _fac, _fac/20) < _judge);
    return seed*_x;
  }


  double prob = 0.7;
  double npe = 0.1;
  double judge, tmp;
  TRandom rand;
  rand.SetSeed(0);

  for(int i=0; i<4000; ++i){
    if(i%100==0){
      cout<<"=====  "<<i<<"  ====="<<endl;
    }
    do{
      tmp = rand.Uniform(0,4);
      judge = rand.Uniform(0,1);
    } while (TMath::Poisson(tmp, npe) < judge);
    for(int j=0; j<19; ++j){
      if(j==0){
        judge = rand.Uniform(0,1);
        if(judge>prob){
          continue;
        }
      }
      tmp=Mult(tmp);
    }
    adc=tmp;
    t->Fill();
  }
  t->Draw("adc");


}
Пример #7
0
Int_t foam_kanwa(){
  cout<<"--- kanwa started ---"<<endl;
  TH2D  *hst_xy = new TH2D("hst_xy" ,  "x-y plot", 50,0,1.0, 50,0,1.0);
  Double_t *MCvect =new Double_t[2]; // 2-dim vector generated in the MC run
  //
  TRandom     *PseRan   = new TRandom3();  // Create random number generator
  PseRan->SetSeed(4357);
  TFoam   *FoamX    = new TFoam("FoamX");   // Create Simulator
  FoamX->SetkDim(2);         // No. of dimensions, obligatory!
  FoamX->SetnCells(500);     // Optionally No. of cells, default=2000
  FoamX->SetRhoInt(Camel2);  // Set 2-dim distribution, included below
  FoamX->SetPseRan(PseRan);  // Set random number generator
  FoamX->Initialize();       // Initialize simulator, may take time...
  //
  // visualising generated distribution
  TCanvas *cKanwa = new TCanvas("cKanwa","Canvas for plotting",600,600);
  cKanwa->cd();
  // From now on FoamX is ready to generate events
  int nshow=5000;
  for(long loop=0; loop<100000; loop++){
    FoamX->MakeEvent();            // generate MC event
    FoamX->GetMCvect( MCvect);     // get generated vector (x,y)
    Double_t x=MCvect[0];
    Double_t y=MCvect[1];
    if(loop<10) cout<<"(x,y) =  ( "<< x <<", "<< y <<" )"<<endl;
    hst_xy->Fill(x,y);
    // live plot
    if(loop == nshow){
      nshow += 5000;
      hst_xy->Draw("lego2");
      cKanwa->Update();
    }
  }// loop
  //
  hst_xy->Draw("lego2");  // final plot
  cKanwa->Update();
  //
  Double_t MCresult, MCerror;
  FoamX->GetIntegMC( MCresult, MCerror);  // get MC integral, should be one
  cout << " MCresult= " << MCresult << " +- " << MCerror <<endl;
  cout<<"--- kanwa ended ---"<<endl;

  return 0;
}//kanwa
Пример #8
0
void ThrowTheDices() {

  TH1S* dices = new TH1S("dices","Throw with 3 dices;Pips;Count rate", 20,0.5,20.5);

  TRandom* die = new TRandom();
  die->SetSeed(0);

  Float_t* value = new Float_t[3];

  for (Int_t i=0; i<10000;++i) {
    die->RndmArray(3,value);
    Int_t sum = static_cast<Int_t>((value[0]*6) + 1) +
                static_cast<Int_t>((value[1]*6) + 1) +
                static_cast<Int_t>((value[2]*6) + 1);
    dices->Fill(sum);
  }

  dices->Draw();

}
void FitterUtilsSimultaneousExpOfPolyTimesX::initiateParams(int nGenSignalZeroGamma, int nGenSignalOneGamma, int nGenSignalTwoGamma,
      RooRealVar& nKemu, RooRealVar& nSignal, RooRealVar& nPartReco,
      RooRealVar& nComb, RooRealVar& fracZero, RooRealVar& fracOne,
      RooRealVar&  nJpsiLeak, bool constPartReco, RooRealVar const& fracPartRecoSigma,
      RooRealVar& l1Kee, RooRealVar& l2Kee, RooRealVar& l3Kee, RooRealVar& l4Kee, RooRealVar& l5Kee,
      RooRealVar& l1Kemu, RooRealVar& l2Kemu, RooRealVar& l3Kemu, RooRealVar& l4Kemu, RooRealVar& l5Kemu,
      RooRealVar const& l1KeeGen, RooRealVar const& l2KeeGen, RooRealVar const& l3KeeGen, RooRealVar const& l4KeeGen, RooRealVar const& l5KeeGen 

      )
{
  FitterUtilsExpOfPolyTimesX::initiateParams(nGenSignalZeroGamma, nGenSignalOneGamma, nGenSignalTwoGamma,
           nSignal, nPartReco, nComb, fracZero, fracOne, nJpsiLeak, constPartReco, fracPartRecoSigma,
           l1Kee, l2Kee, l3Kee, l4Kee, l5Kee,
           l1KeeGen, l2KeeGen, l3KeeGen, l4KeeGen, l5KeeGen ); 



  TRandom rand;
  rand.SetSeed();

  nKemu.setVal(rand.Uniform(nGenKemu-5*sqrt(nGenKemu), nGenKemu+5*sqrt(nGenKemu)));
  nKemu.setRange(nGenKemu-10*sqrt(nGenKemu), nGenKemu+10*sqrt(nGenKemu));

  l1Kemu.setVal(rand.Uniform( l1KeeGen.getVal() - 5*l1KeeGen.getError(), l1KeeGen.getVal() + 5*l1KeeGen.getError() ) );
  l1Kemu.setRange( l1KeeGen.getVal() - 10*l1KeeGen.getError(), l1KeeGen.getVal() + 10*l1KeeGen.getError() );

  l2Kemu.setVal(rand.Uniform( l2KeeGen.getVal() - 5*l2KeeGen.getError(), l2KeeGen.getVal() + 5*l2KeeGen.getError() ) );
  l2Kemu.setRange( l2KeeGen.getVal() - 10*l2KeeGen.getError(), l2KeeGen.getVal() + 10*l2KeeGen.getError() );

  l3Kemu.setVal(rand.Uniform( l3KeeGen.getVal() - 5*l3KeeGen.getError(), l3KeeGen.getVal() + 5*l3KeeGen.getError() ) );
  l3Kemu.setRange( l3KeeGen.getVal() - 10*l3KeeGen.getError(), l3KeeGen.getVal() + 10*l3KeeGen.getError() );

  l4Kemu.setVal(rand.Uniform( l4KeeGen.getVal() - 5*l4KeeGen.getError(), l4KeeGen.getVal() + 5*l4KeeGen.getError() ) );
  l4Kemu.setRange( l4KeeGen.getVal() - 10*l4KeeGen.getError(), l4KeeGen.getVal() + 10*l4KeeGen.getError() );

  l5Kemu.setVal(rand.Uniform( l5KeeGen.getVal() - 5*l5KeeGen.getError(), l5KeeGen.getVal() + 5*l5KeeGen.getError() ) );
  l5Kemu.setRange( l5KeeGen.getVal() - 10*l5KeeGen.getError(), l5KeeGen.getVal() + 10*l5KeeGen.getError() );

}
Пример #10
0
void FitBias(TString CAT,TString CUT,float SIG,float BKG,int NTOYS)
{
  gROOT->ForceStyle();
  
  RooMsgService::instance().setSilentMode(kTRUE);
  RooMsgService::instance().setStreamStatus(0,kFALSE);
  RooMsgService::instance().setStreamStatus(1,kFALSE);
  
  // -----------------------------------------
  TFile *fTemplates = TFile::Open("templates_"+CUT+"_"+CAT+"_workspace.root");
  RooWorkspace *wTemplates = (RooWorkspace*)fTemplates->Get("w");
  RooRealVar *x            = (RooRealVar*)wTemplates->var("mTop");
  RooAbsPdf *pdf_signal    = (RooAbsPdf*)wTemplates->pdf("ttbar_pdf_Nominal");
  RooAbsPdf *pdf_bkg       = (RooAbsPdf*)wTemplates->pdf("qcdCor_pdf"); 
  TRandom *rnd = new TRandom();
  rnd->SetSeed(0);
  x->setBins(250);   
  RooPlot *frame;

  TFile *outf;

  if (NTOYS > 1) { 
    outf = TFile::Open("FitBiasToys_"+CUT+"_"+CAT+".root","RECREATE");
  }

  float nSigInj,nBkgInj,nSigFit,nBkgFit,eSigFit,eBkgFit,nll;

  TTree *tr = new TTree("toys","toys");
  
  tr->Branch("nSigInj",&nSigInj,"nSigInj/F");
  tr->Branch("nSigFit",&nSigFit,"nSigFit/F");
  tr->Branch("nBkgInj",&nBkgInj,"nBkgInj/F");
  tr->Branch("nBkgFit",&nBkgFit,"nBkgFit/F");
  tr->Branch("eSigFit",&eSigFit,"eSigFit/F");
  tr->Branch("eBkgFit",&eBkgFit,"eBkgFit/F");
  tr->Branch("nll"    ,&nll    ,"nll/F");

  for(int itoy=0;itoy<NTOYS;itoy++) {
    // generate pseudodataset
    nSigInj = rnd->Poisson(SIG);
    nBkgInj = rnd->Poisson(BKG);
    RooRealVar *nSig = new RooRealVar("nSig","nSig",nSigInj);
    RooRealVar *nBkg = new RooRealVar("nBkg","nBkg",nBkgInj);
    RooAddPdf *model = new RooAddPdf("model","model",RooArgList(*pdf_signal,*pdf_bkg),RooArgList(*nSig,*nBkg)); 
    RooDataSet *data = model->generate(*x,nSigInj+nBkgInj);
    
    RooDataHist *roohist = new RooDataHist("roohist","roohist",RooArgList(*x),*data);
    // build fit model
    RooRealVar *nFitSig = new RooRealVar("nFitSig","nFitSig",SIG,0,10*SIG);
    RooRealVar *nFitBkg = new RooRealVar("nFitBkg","nFitBkg",BKG,0,10*BKG);
    RooAddPdf *modelFit = new RooAddPdf("modelFit","modelFit",RooArgList(*pdf_signal,*pdf_bkg),RooArgList(*nFitSig,*nFitBkg)); 
    // fit the pseudo dataset
    RooFitResult *res = modelFit->fitTo(*roohist,RooFit::Save(),RooFit::Extended(kTRUE));
    //res->Print();
    nSigFit = nFitSig->getVal();
    nBkgFit = nFitBkg->getVal();
    eSigFit = nFitSig->getError();
    eBkgFit = nFitBkg->getError();
    nll     = res->minNll();
    tr->Fill();
    if (itoy % 100 == 0) {
      cout<<"Toy #"<<itoy<<": injected = "<<nSigInj<<", fitted = "<<nSigFit<<", error = "<<eSigFit<<endl;
    }
    if (NTOYS == 1) {
      frame = x->frame();
      roohist->plotOn(frame); 
      model->plotOn(frame);
    }
  }
  if (NTOYS == 1) {
    TCanvas *can = new TCanvas("Toy","Toy",900,600);
    frame->Draw();
  }  
  else {
    outf->cd();
    tr->Write();
    outf->Close();
    fTemplates->Close();
  }  
}
int main( int argc, char* argv[] ) {

  DrawTools::setStyle();

  std::string runName = "precalib_BGO_pedestal_noSource";
  if( argc>1 ) {
    std::string runName_str(argv[1]);
    runName = runName_str;
  }

  NORDERS = 6;
  if( argc>2 ) {
    NORDERS = atoi(argv[2]);
    std::cout << "-> NORDER is set to: " << NORDERS << std::endl;
  }


  std::string fileName = "../PositionAnalysis/data/run_" + runName + ".root";
  TFile* file = TFile::Open(fileName.c_str());
  
  
  if( argc>1 ) {
    std::string runName_str(argv[1]);
    runName = runName_str;
  }
  if( file==0 ) {
    std::cout << "ERROR! Din't find file " << fileName << std::endl;
    std::cout << "Exiting." << std::endl;
    exit(11);
  }
  
  TTree* tree = (TTree*)file->Get("eventRawData");
  UInt_t evtNumber;
  tree->SetBranchAddress( "evtNumber", &evtNumber );
  UInt_t adcData[40];
  tree->SetBranchAddress( "adcData", adcData );
  UInt_t adcBoard[40];
  tree->SetBranchAddress( "adcBoard", adcBoard );
  UInt_t adcChannel[40];
  tree->SetBranchAddress( "adcChannel", adcChannel );
  
  int nentries = tree->GetEntries();

  std::string outfileName = "calibAn_" + runName + ".root";
  TFile* outFile = TFile::Open( outfileName.c_str(), "RECREATE" );

  TH1D* h1_cef3_0   = new TH1D("cef3_0",   "", 400, 0., 400.);
  TH1D* h1_cef3_1   = new TH1D("cef3_1",   "", 400, 0., 400.);
  TH1D* h1_cef3_2   = new TH1D("cef3_2",   "", 400, 0., 400.);
  TH1D* h1_cef3_3   = new TH1D("cef3_3",   "", 400, 0., 400.);
  TH1D* h1_cef3_tot = new TH1D("cef3_tot", "", 400, 0., 4.*400.);

  TH1D* h1_cef3_corr_0   = new TH1D("cef3_corr_0",   "", 400, 0., 400.);
  TH1D* h1_cef3_corr_1   = new TH1D("cef3_corr_1",   "", 385, 0., 400.4);
  TH1D* h1_cef3_corr_2   = new TH1D("cef3_corr_2",   "", 400, 0., 404.);
  TH1D* h1_cef3_corr_3   = new TH1D("cef3_corr_3",   "", 400, 0., 400.);
  TH1D* h1_cef3_corr_tot = new TH1D("cef3_corr_tot", "", 400, 0., 4.*400.);

  TH1D* h1_cef3_pedSubtracted_0   = new TH1D("cef3_pedSubtracted_0",   "", 400, 0., 400.);
  TH1D* h1_cef3_pedSubtracted_1   = new TH1D("cef3_pedSubtracted_1",   "", 400, 0., 400.);
  TH1D* h1_cef3_pedSubtracted_2   = new TH1D("cef3_pedSubtracted_2",   "", 400, 0., 400.);
  TH1D* h1_cef3_pedSubtracted_3   = new TH1D("cef3_pedSubtracted_3",   "", 400, 0., 400.);

  TH1D* h1_cef3_pedSubtracted_corr_0   = new TH1D("cef3_pedSubtracted_corr_0",   "", 400, 0., 400.*1.11228);
  TH1D* h1_cef3_pedSubtracted_corr_1   = new TH1D("cef3_pedSubtracted_corr_1",   "", 400, 0., 400.*0.855333);
  TH1D* h1_cef3_pedSubtracted_corr_2   = new TH1D("cef3_pedSubtracted_corr_2",   "", 400, 0., 400.*0.97973);
  TH1D* h1_cef3_pedSubtracted_corr_3   = new TH1D("cef3_pedSubtracted_corr_3",   "", 400, 0., 400.*1.08781); 

  TH1D* h1_cef3_pedSubtracted_corr_sum   = new TH1D("cef3_pedSubtracted_sum",   "", 400, 0., 400.);
  TH1D* h1_cef3_pedSubtracted_corr_sum_dummy   = new TH1D("cef3_pedSubtracted_sum",   "", 400, 0., 400.);

  TH1D* h1_cef3_pedSubtracted_corr_rebin_0   = new TH1D("cef3_pedSubtracted_corr_rebin_0",   "", 200, 0., 400.*1.11228);
  TH1D* h1_cef3_pedSubtracted_corr_rebin_1   = new TH1D("cef3_pedSubtracted_corr_rebin_1",   "", 200, 0., 400.*0.855333);
  TH1D* h1_cef3_pedSubtracted_corr_rebin_2   = new TH1D("cef3_pedSubtracted_corr_rebin_2",   "", 200, 0., 400.*0.97973);
  TH1D* h1_cef3_pedSubtracted_corr_rebin_3   = new TH1D("cef3_pedSubtracted_corr_rebin_3",   "", 200, 0., 400.*1.08781);



  TH1D* h1_cef3_pedSubtracted_corr_muQ_0   = new TH1D("cef3_pedSubtracted_corr_muQ_0",   "", 400, 0., 400.*1.19514);
  TH1D* h1_cef3_pedSubtracted_corr_muQ_1   = new TH1D("cef3_pedSubtracted_corr_muQ_1",   "", 400, 0., 400.*0.860177);
  TH1D* h1_cef3_pedSubtracted_corr_muQ_2   = new TH1D("cef3_pedSubtracted_corr_muQ_2",   "", 400, 0., 400.*0.952363);
  TH1D* h1_cef3_pedSubtracted_corr_muQ_3   = new TH1D("cef3_pedSubtracted_corr_muQ_3",   "", 400, 0., 400.*0.977169);

  TH1D* h1_cef3_pedSubtracted_corr_muMean_0   = new TH1D("cef3_pedSubtracted_corr_muMean_0",   "", 400, 0., 400.*1.09716);
  TH1D* h1_cef3_pedSubtracted_corr_muMean_1   = new TH1D("cef3_pedSubtracted_corr_muMean_1",   "", 400, 0., 400.*0.843707);
  TH1D* h1_cef3_pedSubtracted_corr_muMean_2   = new TH1D("cef3_pedSubtracted_corr_muMean_2",   "", 400, 0., 400.*0.966413);
  TH1D* h1_cef3_pedSubtracted_corr_muMean_3   = new TH1D("cef3_pedSubtracted_corr_muMean_3",   "", 400, 0., 400.*1.07241);


  // there is only one cosmic run
  unsigned int runNumber_;
  runNumber_=91;  


  std::string pedestalFileName = "../PositionAnalysis/pedestalFile.root";
  std::vector<std::pair<float, float> > pedestals = getPedestals( "cef3", pedestalFileName, runNumber_ );
  std::cout << std::endl;
  std::cout << "-> Got pedestals of CeF3: " << std::endl;
  for( unsigned i=0; i<CEF3_CHANNELS; ++i )
    std::cout << " CeF3 Channel " << i << ": " << pedestals[i].first << " (+- " << pedestals[i].second << ")" << std::endl;
  std::cout << std::endl;


  int nSigma=4;  

  for( unsigned iEntry=0; iEntry<nentries; ++iEntry ) {
    
    tree->GetEntry(iEntry);
    
    if( iEntry % 5000 == 0 ) std::cout << "Entry: " << iEntry << " / " << nentries << std::endl;
    
    for( unsigned i=0; i<40; ++i ) {
      
      int board  = adcBoard[i];
      int channel= adcChannel[i];
      
      float cef3=0;
      
      
      if( board==CEF3_ADC_BOARD ) {
	if( channel==(CEF3_ADC_START_CHANNEL  ) ){
	  h1_cef3_0->Fill(adcData[i]);
	  cef3+=adcData[i];
	  if(adcData[i]>(pedestals[0].first + nSigma*pedestals[0].second)) h1_cef3_pedSubtracted_0->Fill(adcData[i]-pedestals[0].first);
	}
        else if( channel==(CEF3_ADC_START_CHANNEL+1) ){
	  h1_cef3_1->Fill(adcData[i]);
	  cef3+=adcData[i];
	  if(adcData[i]>(pedestals[1].first + nSigma*pedestals[1].second))h1_cef3_pedSubtracted_1->Fill(adcData[i]-pedestals[1].first);
	}
        else if( channel==(CEF3_ADC_START_CHANNEL+2) ) {
	  h1_cef3_2->Fill(adcData[i]);
	  cef3+=adcData[i];
	  if(adcData[i]>(pedestals[2].first + nSigma*pedestals[2].second))h1_cef3_pedSubtracted_2->Fill(adcData[i]-pedestals[2].first);
	}
        else if( channel==(CEF3_ADC_START_CHANNEL+3) ) {
	  h1_cef3_3->Fill(adcData[i]);
	  cef3+=adcData[i];
	  if(adcData[i]>(pedestals[3].first + nSigma*pedestals[3].second))h1_cef3_pedSubtracted_3->Fill(adcData[i]-pedestals[3].first);
	}
	h1_cef3_tot->Fill(cef3);
      }
      
    }
  }




  h1_cef3_0->SetLineWidth(2);
  h1_cef3_1->SetLineWidth(2);
  h1_cef3_2->SetLineWidth(2);
  h1_cef3_3->SetLineWidth(2);

  h1_cef3_0->SetLineColor(kBlack);
  h1_cef3_1->SetLineColor(kRed);
  h1_cef3_2->SetLineColor(kBlue);
  h1_cef3_3->SetLineColor(kMagenta);

  h1_cef3_corr_0->SetLineWidth(2);
  h1_cef3_corr_1->SetLineWidth(2);
  h1_cef3_corr_2->SetLineWidth(2);
  h1_cef3_corr_3->SetLineWidth(2);

  h1_cef3_corr_0->SetLineColor(kBlack);
  h1_cef3_corr_1->SetLineColor(kRed);
  h1_cef3_corr_2->SetLineColor(kBlue);
  h1_cef3_corr_3->SetLineColor(kMagenta);

  h1_cef3_pedSubtracted_0->SetLineWidth(2);
  h1_cef3_pedSubtracted_1->SetLineWidth(2);
  h1_cef3_pedSubtracted_2->SetLineWidth(2);
  h1_cef3_pedSubtracted_3->SetLineWidth(2);

  h1_cef3_pedSubtracted_0->SetLineColor(kBlack);
  h1_cef3_pedSubtracted_1->SetLineColor(kRed);
  h1_cef3_pedSubtracted_2->SetLineColor(kBlue);
  h1_cef3_pedSubtracted_3->SetLineColor(kMagenta);

  h1_cef3_pedSubtracted_corr_0->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_1->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_2->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_3->SetLineWidth(2);

  h1_cef3_pedSubtracted_corr_0->SetLineColor(kBlack);
  h1_cef3_pedSubtracted_corr_1->SetLineColor(kRed);
  h1_cef3_pedSubtracted_corr_2->SetLineColor(kBlue);
  h1_cef3_pedSubtracted_corr_3->SetLineColor(kMagenta);

  h1_cef3_pedSubtracted_corr_muQ_0->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_muQ_1->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_muQ_2->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_muQ_3->SetLineWidth(2);
			     
  h1_cef3_pedSubtracted_corr_muQ_0->SetLineColor(kBlack);
  h1_cef3_pedSubtracted_corr_muQ_1->SetLineColor(kRed);
  h1_cef3_pedSubtracted_corr_muQ_2->SetLineColor(kBlue);
  h1_cef3_pedSubtracted_corr_muQ_3->SetLineColor(kMagenta);

  h1_cef3_pedSubtracted_corr_muMean_0->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_muMean_1->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_muMean_2->SetLineWidth(2);
  h1_cef3_pedSubtracted_corr_muMean_3->SetLineWidth(2);
			     
  h1_cef3_pedSubtracted_corr_muMean_0->SetLineColor(kBlack);
  h1_cef3_pedSubtracted_corr_muMean_1->SetLineColor(kRed);
  h1_cef3_pedSubtracted_corr_muMean_2->SetLineColor(kBlue);
  h1_cef3_pedSubtracted_corr_muMean_3->SetLineColor(kMagenta);


  //plot uncorr energy (before intercalibration)
  TCanvas* cuncorr = new TCanvas( "cuncorr", "", 600, 600 );



  cuncorr->cd();
  cuncorr->SetLogy();

  TH1D* histo_axes = new TH1D("cef3_0",   "", 400, 0., 350.);


  histo_axes->GetXaxis()->SetRangeUser(80.,350.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_0->GetMaximum()+h1_cef3_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();

  TLegend* legend = new TLegend( 0.7, 0.7, 0.90, 0.9 );
  legend->SetLineColor(0);
  legend->SetFillColor(0);
  legend->SetFillStyle(0);
  legend->SetTextSize(0.038);
  legend->AddEntry( h1_cef3_0, "channel 0", "L" );
  legend->AddEntry( h1_cef3_1, "channel 1", "L" );
  legend->AddEntry( h1_cef3_2, "channel 2", "L" );
  legend->AddEntry( h1_cef3_3, "channel 3", "L" );
  legend->Draw("same");


  h1_cef3_0->Draw("same");
  h1_cef3_1->Draw("same");
  h1_cef3_2->Draw("same");
  h1_cef3_3->Draw("same");

  cuncorr->SaveAs("uncorrEnergyAllChannels.png");
  cuncorr->SaveAs("uncorrEnergyAllChannels.eps");

  TCanvas* cuncorr_2 = new TCanvas( "cuncorr_2", "", 600, 600 );

  cuncorr_2->cd();
  cuncorr_2->SetLogy();

  histo_axes->GetXaxis()->SetRangeUser(120.,200.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_0->GetMaximum()+h1_cef3_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();


  h1_cef3_0->Draw("same");
  h1_cef3_1->Draw("same");
  h1_cef3_2->Draw("same");
  h1_cef3_3->Draw("same");

  legend->Draw("same");

  cuncorr_2->SaveAs("uncorrEnergyAllChannels_zoom.png");
  cuncorr_2->SaveAs("uncorrEnergyAllChannels_zoom.eps");

  //plot uncorr energy (before intercalibration) for pedSubtracted
  TCanvas* cuncorr_pedSubtracted = new TCanvas( "cuncorr_pedSubtracted", "", 600, 600 );


  cuncorr_pedSubtracted->cd();
  cuncorr_pedSubtracted->SetLogy();


  histo_axes->GetXaxis()->SetRangeUser(0.,250.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();

  legend->Draw("same");


  h1_cef3_pedSubtracted_0->Draw("same");
  h1_cef3_pedSubtracted_1->Draw("same");
  h1_cef3_pedSubtracted_2->Draw("same");
  h1_cef3_pedSubtracted_3->Draw("same");

  cuncorr_pedSubtracted->SaveAs("uncorrEnergyAllChannelspedSubtracted.png");
  cuncorr_pedSubtracted->SaveAs("uncorrEnergyAllChannelspedSubtracted.eps");


  TCanvas* cuncorr_pedSubtracted_2 = new TCanvas( "cuncorr_pedSubtracted_2", "", 600, 600 );

  cuncorr_pedSubtracted_2->cd();
  cuncorr_pedSubtracted_2->SetLogy();

  histo_axes->GetXaxis()->SetRangeUser(20.,100.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();


  h1_cef3_pedSubtracted_0->Draw("same");
  h1_cef3_pedSubtracted_1->Draw("same");
  h1_cef3_pedSubtracted_2->Draw("same");
  h1_cef3_pedSubtracted_3->Draw("same");

  legend->Draw("same");

  cuncorr_pedSubtracted_2->SaveAs("uncorrEnergyAllChannelspedSubtracted_zoom.png");
  cuncorr_pedSubtracted_2->SaveAs("uncorrEnergyAllChannelspedSubtracted_zoom.eps");



  //intercalibration of single fibers with photoelectrons
  FitResults fr_0 = fitSingleHisto( h1_cef3_0, 110., 135., 138., 185. );
  FitResults fr_1 = fitSingleHisto( h1_cef3_1, 100., 125., 125., 190. );
  FitResults fr_2 = fitSingleHisto( h1_cef3_2, 100., 125., 128., 190. );
  FitResults fr_3 = fitSingleHisto( h1_cef3_3, 100., 125., 137., 198. );

  std::vector<float> lowerFitBoundary;
  lowerFitBoundary.push_back(137.);
  lowerFitBoundary.push_back(125.);
  lowerFitBoundary.push_back(127.);
  lowerFitBoundary.push_back(137.);

  

  FitResults fr_pedSubtracted_0 = fitSingleHisto( h1_cef3_pedSubtracted_0, 0., 0., lowerFitBoundary[0]-pedestals[0].first, 185.-pedestals[0].first );
  FitResults fr_pedSubtracted_1 = fitSingleHisto( h1_cef3_pedSubtracted_1, 0., 0., lowerFitBoundary[1]-pedestals[1].first, 190.-pedestals[1].first );
  FitResults fr_pedSubtracted_2 = fitSingleHisto( h1_cef3_pedSubtracted_2, 0., 0., lowerFitBoundary[2]-pedestals[2].first, 190.-pedestals[2].first );
  FitResults fr_pedSubtracted_3 = fitSingleHisto( h1_cef3_pedSubtracted_3, 0., 0., lowerFitBoundary[3]-pedestals[3].first, 198.-pedestals[3].first );


  std::vector<float> correctionFactors = intercalibrateFibers(fr_0,fr_1,fr_2,fr_3,true);
  std::vector<float> correctionFactors_pedSubtracted = intercalibrateFibers(fr_pedSubtracted_0,fr_pedSubtracted_1,fr_pedSubtracted_2,fr_pedSubtracted_3,true);
  std::vector<float> correctionFactors_pedSubtracted_muQ = intercalibrateFibers(fr_pedSubtracted_0,fr_pedSubtracted_1,fr_pedSubtracted_2,fr_pedSubtracted_3,false);

  std::vector<float> mu;
  mu.push_back(fr_0.mu);
  mu.push_back(fr_1.mu);
  mu.push_back(fr_2.mu);
  mu.push_back(fr_3.mu);
  float mumean=0.;


  for(int i=0;i<4;i++){
    mumean+=mu[i];
  }

  mumean=mumean/4.;

  std::vector<float> correctionFactors_pedSubtracted_muMean= intercalibrateFibers(fr_pedSubtracted_0,fr_pedSubtracted_1,fr_pedSubtracted_2,fr_pedSubtracted_3,false,mumean);

  for(int i=0;i<4;i++){
    std::cout<<"correctionFactors "<<correctionFactors[i]<<std::endl;
    std::cout<<"correctionFactors pedSub "<<correctionFactors_pedSubtracted[i]<<std::endl;
    std::cout<<"correctionFactors pedSub muQ "<<correctionFactors_pedSubtracted_muQ[i]<<std::endl;
    std::cout<<"correctionFactors pedSub muMean "<<correctionFactors_pedSubtracted_muMean[i]<<std::endl;
  }
  TRandom a;
  a.SetSeed(100);

  for( unsigned iEntry=0; iEntry<nentries; ++iEntry ) {
    
    tree->GetEntry(iEntry);
    
    if( iEntry % 5000 == 0 ) std::cout << "Entry: " << iEntry << " / " << nentries << std::endl;
    
    for( unsigned i=0; i<40; ++i ) {
      
      int board  = adcBoard[i];
      int channel= adcChannel[i];
      
      
      float cef3_corr=0;

      
      if( board==CEF3_ADC_BOARD ) {
	if( channel==(CEF3_ADC_START_CHANNEL  ) ){
	  h1_cef3_corr_0->Fill(adcData[i]*correctionFactors[0]);
	  if(adcData[i]>(pedestals[0].first + nSigma*pedestals[0].second)){
	    h1_cef3_pedSubtracted_corr_0->Fill((adcData[i]-pedestals[0].first)*correctionFactors_pedSubtracted[0]);
	    h1_cef3_pedSubtracted_corr_rebin_0->Fill((adcData[i]-pedestals[0].first)*correctionFactors_pedSubtracted[0]);
	    h1_cef3_pedSubtracted_corr_muQ_0->Fill((adcData[i]-pedestals[0].first)*correctionFactors_pedSubtracted_muQ[0]);
	    h1_cef3_pedSubtracted_corr_muMean_0->Fill((adcData[i]-pedestals[0].first)*correctionFactors_pedSubtracted_muMean[0]);
	    h1_cef3_pedSubtracted_corr_sum->Fill(a.Uniform(adcData[i]-pedestals[0].first-0.5,adcData[i]-pedestals[0].first+0.5)*correctionFactors_pedSubtracted[0]);
	  }
	  cef3_corr+=adcData[i]*correctionFactors[0];
	}
        else if( channel==(CEF3_ADC_START_CHANNEL+1) ){
	  h1_cef3_corr_1->Fill(adcData[i]*correctionFactors[1]);
	  if(adcData[i]>(pedestals[1].first + nSigma*pedestals[1].second)) {
	    h1_cef3_pedSubtracted_corr_1->Fill((adcData[i]-pedestals[1].first)*correctionFactors_pedSubtracted[1]);
	    h1_cef3_pedSubtracted_corr_rebin_1->Fill((adcData[i]-pedestals[1].first)*correctionFactors_pedSubtracted[1]);
	    h1_cef3_pedSubtracted_corr_muQ_1->Fill((adcData[i]-pedestals[1].first)*correctionFactors_pedSubtracted_muQ[1]);
	    h1_cef3_pedSubtracted_corr_muMean_1->Fill((adcData[i]-pedestals[1].first)*correctionFactors_pedSubtracted_muMean[1]);
	    h1_cef3_pedSubtracted_corr_sum->Fill(a.Uniform(adcData[i]-pedestals[1].first-0.5,adcData[i]-pedestals[1].first+0.5)*correctionFactors_pedSubtracted[1]);
	  }
	  cef3_corr+=adcData[i]*correctionFactors[1];
	}
        else if( channel==(CEF3_ADC_START_CHANNEL+2) ) {
	  h1_cef3_corr_2->Fill(adcData[i]*correctionFactors[2]);
	  if(adcData[i]>(pedestals[2].first + nSigma*pedestals[2].second)) {
	    h1_cef3_pedSubtracted_corr_2->Fill((adcData[i]-pedestals[2].first)*correctionFactors_pedSubtracted[2]);
	    h1_cef3_pedSubtracted_corr_rebin_2->Fill((adcData[i]-pedestals[2].first)*correctionFactors_pedSubtracted[2]);
	    h1_cef3_pedSubtracted_corr_muQ_2->Fill((adcData[i]-pedestals[2].first)*correctionFactors_pedSubtracted_muQ[2]);
	    h1_cef3_pedSubtracted_corr_muMean_2->Fill((adcData[i]-pedestals[2].first)*correctionFactors_pedSubtracted_muMean[2]);
	    h1_cef3_pedSubtracted_corr_sum->Fill(a.Uniform(adcData[i]-pedestals[2].first-0.5,adcData[i]-pedestals[2].first+0.5)*correctionFactors_pedSubtracted[2]);
	  }
	  cef3_corr+=adcData[i]*correctionFactors[2];
	}
        else if( channel==(CEF3_ADC_START_CHANNEL+3) ) {
	  h1_cef3_corr_3->Fill(adcData[i]*correctionFactors[3]);
	  if(adcData[i]>(pedestals[3].first + nSigma*pedestals[3].second)){
	    h1_cef3_pedSubtracted_corr_3->Fill((adcData[i]-pedestals[3].first)*correctionFactors_pedSubtracted[3]);
	    h1_cef3_pedSubtracted_corr_rebin_3->Fill((adcData[i]-pedestals[3].first)*correctionFactors_pedSubtracted[3]);
	    h1_cef3_pedSubtracted_corr_muQ_3->Fill((adcData[i]-pedestals[3].first)*correctionFactors_pedSubtracted_muQ[3]);
	    h1_cef3_pedSubtracted_corr_muMean_3->Fill((adcData[i]-pedestals[3].first)*correctionFactors_pedSubtracted_muMean[3]);
	    h1_cef3_pedSubtracted_corr_sum->Fill(a.Uniform(adcData[i]-pedestals[3].first-0.5,adcData[i]-pedestals[3].first+0.5)*correctionFactors_pedSubtracted[3]);
	  }
	  cef3_corr+=adcData[i]*correctionFactors[3];
	}
	h1_cef3_tot->Fill(cef3_corr);
      }
      
    }
  }




  //plot corr energy (after intercalibration)
  TCanvas* ccorr = new TCanvas( "ccorr", "", 600, 600 );

  ccorr->cd();
  ccorr->SetLogy();

  TH2D* h2_axes_corr = new TH2D("axes_corr", "", 10, 0., 350., 10, 10., 1.1*h1_cef3_corr_0->GetMaximum() );
  h2_axes_corr->GetXaxis()->SetRangeUser(80.,350);
  h2_axes_corr->SetXTitle( "ADC Counts" );
  h2_axes_corr->Draw();


  h1_cef3_corr_0->Draw("same");
  h1_cef3_corr_1->Draw("same");
  h1_cef3_corr_2->Draw("same");
  h1_cef3_corr_3->Draw("same");

  legend->Draw("same");

  ccorr->SaveAs("corrEnergyAllChannels.png");
  ccorr->SaveAs("corrEnergyAllChannels.eps");

  //pedsubtracted plot
  ccorr->Clear();

  histo_axes->GetXaxis()->SetRangeUser(0.,250.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();

  histo_axes->Draw();

  h1_cef3_pedSubtracted_corr_0->Draw("same");
  h1_cef3_pedSubtracted_corr_1->Draw("same");
  h1_cef3_pedSubtracted_corr_2->Draw("same");
  h1_cef3_pedSubtracted_corr_3->Draw("same");

  legend->Draw("same");

  ccorr->SaveAs("corrEnergyAllChannelspedSubtracted.png");
  ccorr->SaveAs("corrEnergyAllChannelspedSubtracted.eps");

  h1_cef3_pedSubtracted_corr_sum->Rebin(2);
  FitResults fr_corr_sum = fitSingleHisto_sum( h1_cef3_pedSubtracted_corr_sum, 0., 0.,13.,68.,true );

  //plot for the paper. all corr channels sum and fit
  ccorr->Clear();
  ccorr->SetLogy(0);
  ccorr->cd();

  h1_cef3_pedSubtracted_corr_sum->SetLineWidth(2);
  
  h1_cef3_pedSubtracted_corr_sum->GetXaxis()->SetRangeUser(0.,150.);
  h1_cef3_pedSubtracted_corr_sum->GetYaxis()->SetRangeUser(50.,h1_cef3_pedSubtracted_corr_sum->GetMaximum()+h1_cef3_pedSubtracted_corr_sum->GetMaximum()*0.10);
  h1_cef3_pedSubtracted_corr_sum->SetYTitle( "Events / 2" );
  h1_cef3_pedSubtracted_corr_sum->SetXTitle( "ADC Counts" );

 
  h1_cef3_pedSubtracted_corr_sum->Draw();
  //  ccorr->SetLogy(1);
  TPaveText* labelTop = DrawTools::getLabelTop("Cosmic Data");
  labelTop->Draw("same");
  gPad->RedrawAxis(); 
  ccorr->SaveAs("sum_fitted.png");
  ccorr->SaveAs("sum_fitted.eps");
  ccorr->SaveAs("sum_fitted.C");
  //ccorr->SaveAs("sum_fitted_log.png");

  ccorr->Clear();
  h1_cef3_pedSubtracted_corr_sum->Draw();
  labelTop->Draw("same");
  ccorr->SetLogy(1);
  ccorr->SaveAs("sum_fitted_log.png");
  ccorr->SaveAs("sum_fitted_log.eps");
  ccorr->SaveAs("sum_fitted_log.C");


  //unconstrained fit
  FitResults fr_corr_unconstrained_sum = fitSingleHisto_sum( h1_cef3_pedSubtracted_corr_sum, 0., 0.,14.,69.,false );
  
  h1_cef3_pedSubtracted_corr_sum->GetXaxis()->SetRangeUser(0.,150.);
  h1_cef3_pedSubtracted_corr_sum->GetYaxis()->SetRangeUser(50.,h1_cef3_pedSubtracted_corr_sum->GetMaximum()+h1_cef3_pedSubtracted_corr_sum->GetMaximum()*0.10);
  h1_cef3_pedSubtracted_corr_sum->SetXTitle( "ADC Counts" );

 
  h1_cef3_pedSubtracted_corr_sum->Draw();
  ccorr->SetLogy(1);
  ccorr->SaveAs("sum_fitted_log_unc.png");

  ccorr->Clear();
  ccorr->cd();
  h1_cef3_pedSubtracted_corr_sum_dummy->Add(h1_cef3_pedSubtracted_corr_0);
  h1_cef3_pedSubtracted_corr_sum_dummy->Add(h1_cef3_pedSubtracted_corr_1);
  h1_cef3_pedSubtracted_corr_sum_dummy->Add(h1_cef3_pedSubtracted_corr_2);
  h1_cef3_pedSubtracted_corr_sum_dummy->Add(h1_cef3_pedSubtracted_corr_3);

  h1_cef3_pedSubtracted_corr_sum_dummy->Rebin(2);  
  FitResults fr_corr_sum_dummy = fitSingleHisto_sum( h1_cef3_pedSubtracted_corr_sum_dummy, 0., 0.,13.,68.,true );

  h1_cef3_pedSubtracted_corr_sum_dummy->GetXaxis()->SetRangeUser(0.,150.);
  h1_cef3_pedSubtracted_corr_sum_dummy->GetYaxis()->SetRangeUser(50.,h1_cef3_pedSubtracted_corr_sum->GetMaximum()+h1_cef3_pedSubtracted_corr_sum->GetMaximum()*0.10);
  h1_cef3_pedSubtracted_corr_sum_dummy->SetXTitle( "ADC Counts" );
  ccorr->SetLogy(0);

  h1_cef3_pedSubtracted_corr_sum_dummy->Draw();
  ccorr->SaveAs("sum_fitted_log_dummy.png");

  std::cout<<"######################## mean random:"<<h1_cef3_pedSubtracted_corr_sum->GetMean()<<"+-"<<h1_cef3_pedSubtracted_corr_sum->GetMeanError()<<std::endl;
  std::cout<<"######################## mean not random:"<<h1_cef3_pedSubtracted_corr_sum_dummy->GetMean()<<"+-"<<h1_cef3_pedSubtracted_corr_sum_dummy->GetMeanError()<<std::endl;


  cuncorr_pedSubtracted_2->Clear();
  cuncorr_pedSubtracted_2->cd();
  cuncorr_pedSubtracted_2->SetLogy();

  histo_axes->GetXaxis()->SetRangeUser(20.,100.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();


  h1_cef3_pedSubtracted_corr_0->Draw("same");
  h1_cef3_pedSubtracted_corr_1->Draw("same");
  h1_cef3_pedSubtracted_corr_2->Draw("same");
  h1_cef3_pedSubtracted_corr_3->Draw("same");

  legend->Draw("same");

  cuncorr_pedSubtracted_2->SaveAs("corrEnergyAllChannelspedSubtracted_zoom.png");
  cuncorr_pedSubtracted_2->SaveAs("corrEnergyAllChannelspedSubtracted_zoom.eps");


  //pedsubtracted plot
  ccorr->Clear();

  histo_axes->GetXaxis()->SetRangeUser(0.,250.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();

  histo_axes->Draw();

  h1_cef3_pedSubtracted_corr_muQ_0->Draw("same");
  h1_cef3_pedSubtracted_corr_muQ_1->Draw("same");
  h1_cef3_pedSubtracted_corr_muQ_2->Draw("same");
  h1_cef3_pedSubtracted_corr_muQ_3->Draw("same");

  legend->Draw("same");

  ccorr->SaveAs("corr_muQEnergyAllChannelspedSubtracted.png");
  ccorr->SaveAs("corr_muQEnergyAllChannelspedSubtracted.eps");

  cuncorr_pedSubtracted_2->Clear();
  cuncorr_pedSubtracted_2->cd();
  cuncorr_pedSubtracted_2->SetLogy();

  histo_axes->GetXaxis()->SetRangeUser(20.,100.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();


  h1_cef3_pedSubtracted_corr_muQ_0->Draw("same");
  h1_cef3_pedSubtracted_corr_muQ_1->Draw("same");
  h1_cef3_pedSubtracted_corr_muQ_2->Draw("same");
  h1_cef3_pedSubtracted_corr_muQ_3->Draw("same");

  legend->Draw("same");

  cuncorr_pedSubtracted_2->SaveAs("corr_muQEnergyAllChannelspedSubtracted_zoom.png");
  cuncorr_pedSubtracted_2->SaveAs("corr_muQEnergyAllChannelspedSubtracted_zoom.eps");

  //pedsubtracted muMean plot
  ccorr->Clear();

  histo_axes->GetXaxis()->SetRangeUser(0.,250.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();

  histo_axes->Draw();

  h1_cef3_pedSubtracted_corr_muMean_0->Draw("same");
  h1_cef3_pedSubtracted_corr_muMean_1->Draw("same");
  h1_cef3_pedSubtracted_corr_muMean_2->Draw("same");
  h1_cef3_pedSubtracted_corr_muMean_3->Draw("same");

  legend->Draw("same");

  ccorr->SaveAs("corr_muMeanEnergyAllChannelspedSubtracted.png");
  ccorr->SaveAs("corr_muMeanEnergyAllChannelspedSubtracted.eps");

  cuncorr_pedSubtracted_2->Clear();
  cuncorr_pedSubtracted_2->cd();
  cuncorr_pedSubtracted_2->SetLogy();

  histo_axes->GetXaxis()->SetRangeUser(20.,100.);
  histo_axes->GetYaxis()->SetRangeUser(10.,h1_cef3_pedSubtracted_0->GetMaximum()+h1_cef3_pedSubtracted_0->GetMaximum()*0.10);
  histo_axes->SetXTitle( "ADC Counts" );
  histo_axes->Draw();


  h1_cef3_pedSubtracted_corr_muMean_0->Draw("same");
  h1_cef3_pedSubtracted_corr_muMean_1->Draw("same");
  h1_cef3_pedSubtracted_corr_muMean_2->Draw("same");
  h1_cef3_pedSubtracted_corr_muMean_3->Draw("same");

  legend->Draw("same");

  cuncorr_pedSubtracted_2->SaveAs("corr_muMeanEnergyAllChannelspedSubtracted_zoom.png");
  cuncorr_pedSubtracted_2->SaveAs("corr_muMeanEnergyAllChannelspedSubtracted_zoom.eps");




  TCanvas* ccorr_2 = new TCanvas( "ccorr_2", "", 600, 600 );

  ccorr_2->cd();
  ccorr_2->SetLogy();

  h2_axes_corr->GetXaxis()->SetRangeUser(120.,200.);

  h2_axes_corr->Draw();
  h1_cef3_corr_0->Draw("same");
  h1_cef3_corr_1->Draw("same");
  h1_cef3_corr_2->Draw("same");
  h1_cef3_corr_3->Draw("same");

  legend->Draw("same");

  ccorr_2->SaveAs("corrEnergyAllChannels_zoom.png");
  ccorr_2->SaveAs("corrEnergyAllChannels_zoom.eps");


  //fit corrected histos
  FitResults fr_corr_0 = fitSingleHisto( h1_cef3_corr_0, 0.966779*120., 0.966779*130., 0.966779*138., 0.966779*185. );
  FitResults fr_corr_1 = fitSingleHisto( h1_cef3_corr_1, 1.04148*100., 1.04148*125., 1.04148*125., 1.04148*189. );
  FitResults fr_corr_2 = fitSingleHisto( h1_cef3_corr_2, 1.01311*100., 1.01311*125., 1.01311*128., 1.01311*189. );
  FitResults fr_corr_3 = fitSingleHisto( h1_cef3_corr_3, 0.984112*100., 0.984112*125., 0.984112*137., 0.984112*200. );

  FitResults fr_pedSubtracted_corr_0 = fitSingleHisto( h1_cef3_pedSubtracted_corr_0, 0., 0., lowerFitBoundary[0]+2-pedestals[0].first, 188.-pedestals[0].first );
  FitResults fr_pedSubtracted_corr_1 = fitSingleHisto( h1_cef3_pedSubtracted_corr_1, 0., 0., lowerFitBoundary[1]-3-pedestals[1].first, 182.-pedestals[1].first );
  FitResults fr_pedSubtracted_corr_2 = fitSingleHisto( h1_cef3_pedSubtracted_corr_2, 0., 0., lowerFitBoundary[2]+1-pedestals[2].first, 188.-pedestals[2].first );
  FitResults fr_pedSubtracted_corr_3 = fitSingleHisto( h1_cef3_pedSubtracted_corr_3, 0., 0., lowerFitBoundary[3]+1-pedestals[3].first, 198.-pedestals[3].first );



  FitResults fr_pedSubtracted_corr_rebin_0 = fitSingleHisto( h1_cef3_pedSubtracted_corr_rebin_0, 0., 0., lowerFitBoundary[0]+2-pedestals[0].first, 189.-pedestals[0].first );
  FitResults fr_pedSubtracted_corr_rebin_1 = fitSingleHisto( h1_cef3_pedSubtracted_corr_rebin_1, 0., 0., lowerFitBoundary[1]-3-pedestals[1].first, 177.-pedestals[1].first );
  FitResults fr_pedSubtracted_corr_rebin_2 = fitSingleHisto( h1_cef3_pedSubtracted_corr_rebin_2, 0., 0., lowerFitBoundary[2]+1-pedestals[2].first, 181.-pedestals[2].first );
  FitResults fr_pedSubtracted_corr_rebin_3 = fitSingleHisto( h1_cef3_pedSubtracted_corr_rebin_3, 0., 0., lowerFitBoundary[3]+1-pedestals[3].first, 196.-pedestals[3].first );





  h1_cef3_0->Write(); 
  h1_cef3_1->Write(); 
  h1_cef3_2->Write(); 
  h1_cef3_3->Write(); 
  h1_cef3_tot->Write(); 
                 
  h1_cef3_corr_0->Write();    
  h1_cef3_corr_1->Write();    
  h1_cef3_corr_2->Write();    
  h1_cef3_corr_3->Write();    
  h1_cef3_corr_tot->Write();  

  outFile->Write(); 


  doSummaryPlots(fr_pedSubtracted_0,fr_pedSubtracted_1,fr_pedSubtracted_2,fr_pedSubtracted_3,fr_pedSubtracted_corr_0,fr_pedSubtracted_corr_1,fr_pedSubtracted_corr_2,fr_pedSubtracted_corr_3);



  return 0;

}
Пример #12
0
int plotUnfoldingMatrixRooUnfold(
		        int analysisIs2D,
			const TString conf,
			DYTools::TRunMode_t runMode=DYTools::NORMAL_RUN,
			DYTools::TSystematicsStudy_t systMode=DYTools::NO_SYST,
			TString rndStudyStr=""
			) {

  const double FSRmassDiff=1.; // largest energy of FSR photon to consider


  // check whether it is a calculation
  if (conf.Contains("_DebugRun_")) {
    std::cout << "plotUnfoldingMatrix: _DebugRun_ detected. Terminating the script\n";
    return retCodeOk;
  }

  // normal calculation
  gBenchmark->Start("makeUnfoldingMatrix");

   {
    DYTools::printExecMode(runMode,systMode);
    const int debug_print=1;
    if (!DYTools::checkSystMode(systMode,debug_print,12,
				DYTools::NO_SYST, DYTools::SYST_RND,
				DYTools::RESOLUTION_STUDY, DYTools::FSR_STUDY,
				DYTools::PU_STUDY,
				DYTools::FSR_5plus, DYTools::FSR_5minus,
				DYTools::PILEUP_5plus, DYTools::PILEUP_5minus,
				//DYTools::ESCALE_STUDY,
				DYTools::ESCALE_RESIDUAL,
				DYTools::FSR_RND_STUDY, DYTools::PU_RND_STUDY))
      return retCodeError;
  }

  if (!DYTools::setup(analysisIs2D)) {
    std::cout << "failed to initialize the analysis\n";
    return retCodeError;
  }

  int escaleResidual_global=1;

  //--------------------------------------------------------------------------------------------------------------
  // Settings
  //==============================================================================================================

  InputFileMgr_t inpMgr;
  InputFileMgr_t *yieldInpMgr=NULL; // needed for ESCALE_RESIDUAL
  if (!inpMgr.Load(conf)) return retCodeError;

  // plotDetResponse uses escale!
  if (systMode==DYTools::ESCALE_RESIDUAL) {
    yieldInpMgr= new InputFileMgr_t(inpMgr);
    // create a temporary object to set proper directories
    EventSelector_t tmpEventSelector(*yieldInpMgr,runMode,
		   DYTools::APPLY_ESCALE,"","",EventSelector::_selectDefault);
    if (escaleResidual_global) {
      inpMgr.rootFileBaseDir("root_files_reg_EScaleResidualGlobal");
      std::cout << "changed rootFileBaseDir to <" << inpMgr.rootFileBaseDir()
		<< ">\n";
    }
  }
  else if (systMode!=DYTools::RESOLUTION_STUDY) {
    // no energy correction for this evaluation
    inpMgr.clearEnergyScaleTag();
  }
  else {
    if (inpMgr.energyScaleTag() == "UNCORRECTED") {
      std::cout << "RESOLUTION_STUDY needs energy scale correction\n";
      return retCodeError;
    }
  }

  // Construct eventSelector, update mgr and plot directory
  TString extraTag=rndStudyStr;
  EventSelector_t evtSelector(inpMgr,runMode,systMode,
			      extraTag, "", EventSelector::_selectDefault);
  evtSelector.setTriggerActsOnData(false);

  // PU and FSR RND studies have to provide the seed externally
  int globalSeed=-1;
  for (int i=0; (globalSeed<=0) && (i<rndStudyStr.Length()); ++i) {
    globalSeed=atoi(rndStudyStr.Data() + i);
  }

  // Event weight handler
  EventWeight_t evWeight;
  int res=evWeight.init(inpMgr.puReweightFlag(),inpMgr.fewzFlag(),
			systMode,rndStudyStr);
  // May 01, 2014: PU weights have to be applied at all steps
  //EventWeight_t evWeightNoPU; // for FSR unfolding weights
  //if (res) res=evWeightNoPU.init(0,inpMgr.fewzFlag(),systMode,rndStudyStr);
  if (!res) {
    std::cout << "failed to prepare weights\n";
    return retCodeError;
  }

  // Prepare output directory
  inpMgr.constDir(systMode,1);


  int seedMin=inpMgr.userKeyValueAsInt("SEEDMIN");
  int seedMax=inpMgr.userKeyValueAsInt("SEEDMAX");
  int dSeed=1;
  int seedDiff=(systMode==DYTools::FSR_STUDY) ? 3 : (seedMax-seedMin+1);

  //std::cout << "seedMin..seedMax=" << seedMin << ".." << seedMax << "\n";

  //return retCodeOk;

  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code
  //==============================================================================================================


  std::cout << mainpart;

  TRandom random;
  std::vector<ElectronEnergyScale*> escaleV;
  std::vector<EventWeight_t*> specEWeightsV;
  std::vector<double> specReweightsV;
  std::vector<EventSelector_t*> evtSelectorV;
  std::vector<TH2D*> specTH2DWeightV; // used for ESCALE_RESIDUAL

  double specWeight=1.;
  int useSpecWeight=0;
  if (systMode==DYTools::FSR_5plus) { specWeight=1.05; useSpecWeight=1; }
  else if (systMode==DYTools::FSR_5minus) { specWeight=0.95; useSpecWeight=1; }
  else if (systMode==DYTools::FSR_RND_STUDY) useSpecWeight=1;

  // check random seed. Special weights use their own,
  // built-in dependencies on seed
  {
    int startSeed=-1;
    if (systMode==DYTools::SYST_RND) {
      std::cout << "setting startSeed=" << globalSeed << "\n";
      startSeed= globalSeed;
    }
    random.SetSeed(startSeed);
    gRandom->SetSeed(startSeed);
  }

  // The random seeds are needed only if we are running this script in systematics mode

  if (systMode==DYTools::FSR_STUDY) {
    specReweightsV.reserve(seedDiff);
    specEWeightsV.reserve(seedDiff);
    for (int i=0; i<seedDiff; ++i) {
      double specW= 1 + 0.05*(i-1);
      specReweightsV.push_back(specW);
      specEWeightsV.push_back(new EventWeight_t(evWeight));
    }
  }
  else if (systMode==DYTools::PU_STUDY) {
    if (inpMgr.puReweightFlag()==0) {
      std::cout << "systMode=PU_STUDY needs puReweightFlag=1 in the input file\n";
      return retCodeError;
    }
    specEWeightsV.reserve(2);
    for (int i=0; i<2; ++i) {
      DYTools::TSystematicsStudy_t study=(i==0) ? DYTools::PILEUP_5minus : DYTools::PILEUP_5plus;
      EventWeight_t *ew=new EventWeight_t();
      if (!ew->init(inpMgr.puReweightFlag(),inpMgr.fewzFlag(),study,rndStudyStr)) {
	std::cout << "in plotUnfoldingMatrix.C\n";
	return retCodeError;
      }
      specEWeightsV.push_back(ew);
    }
  }
  else if (systMode==DYTools::SYST_RND) {
    // nothing special about weights
  }
  else if (systMode==DYTools::RESOLUTION_STUDY) {
    if (seedMax==-111) {
      seedMin=-111;
      seedMax= 111;
      dSeed=seedMax-seedMin;
      seedDiff=2;
    }
    if (seedMax < seedMin) {
      printf("error: randomSeedMax=%d, seedMin=%d\n",seedMax,seedMin);
      return retCodeError;
    }
    specEWeightsV.reserve(seedDiff); // not used, but needed as a check
    escaleV.reserve(seedDiff);
    for (int i=seedMin; i<=seedMax; i+=dSeed) {
      TString escaleTag=inpMgr.energyScaleTag() +
	TString(Form("_MIRROR_RANDOMIZED%d",i));
      ElectronEnergyScale *ees= new ElectronEnergyScale(escaleTag);
      if (1) {
	std::cout << "randomSeed=" << i << ". EScale=";
	ees->print();
	std::cout<<"\n";
      }
      escaleV.push_back(ees);
      specEWeightsV.push_back(new EventWeight_t(evWeight));
      EventSelector_t *evtSel=new EventSelector_t(evtSelector,ees);
      // correction acts like on data!
      evtSel->setEScaleCorrectionType(DYTools::DATA,DYTools::ESCALE_STUDY_RND);
      //evtSel->editECName().Append(Form("_idx%d",i+seedMin));
      evtSelectorV.push_back(evtSel);
    }
  }

  // prepare tools for ESCALE_RESIDUAL
  TH2D* h2ShapeWeights=NULL;
  if (systMode==DYTools::ESCALE_RESIDUAL) {
    if (!yieldInpMgr) {
      std::cout << "yieldInpMgr had to be created\n";
      return retCodeError;
    }
    DYTools::TSystematicsStudy_t yieldSystMode=DYTools::APPLY_ESCALE;
    TString shapeFName=yieldInpMgr->signalYieldFullFileName(yieldSystMode,1);
    delete yieldInpMgr; // no longer needed
    if (rndStudyStr.Length()) {
      shapeFName.ReplaceAll(TString("__") + rndStudyStr,"");
    }
    TString subdir="ShapeReweight";
    TString field="zeeMCShapeReweight_";
    TString ddBkg=(inpMgr.userKeyValueAsInt("DDBKG")==1) ? "ddBkg" : "mcBkg";
    field.Append(ddBkg);
    std::cout << "Obtaining shape weights from <"
	      << shapeFName << ">"
	      << "(use" << ddBkg << ")\n";
    h2ShapeWeights=LoadHisto2D(field,shapeFName,subdir,1);
    if (!h2ShapeWeights) {
      std::cout << "failed to find histo \"ZeeMCShapeReweight\"\n";
      return retCodeError;
    }
    if ((DYTools::massBinningSet==DYTools::_MassBins_2012) &&
	(DYTools::study2D==1)) {
      HERE("set weights for the underflow bin to 1.");
      int ibin=1;
      for (int jbin=1; jbin<=24; jbin++) {
	h2ShapeWeights->SetBinContent(ibin,jbin, 1.);
	h2ShapeWeights->SetBinError  (ibin,jbin, 0.);
      }
    }
    std::cout << "shapeWeights:\n"; printHisto(h2ShapeWeights);

    int ensembleSize= inpMgr.userKeyValueAsInt("RESIDUAL_STUDY_SIZE");
    if (ensembleSize<=0) ensembleSize=100;
    ensembleSize++;
    std::cout << "EScale_residual ensemble size=" << ensembleSize
	      << " (one added for non-randomized entry)\n";

    std::vector<TString> tmpLabelV; // local variable for testing
    specTH2DWeightV.reserve(ensembleSize);
    tmpLabelV.reserve(ensembleSize);

    specTH2DWeightV.push_back(Clone(h2ShapeWeights,
				    "h2NonRndShapeW","h2NonRndShapeW"));
    tmpLabelV.push_back("NonRndShape");

    if (!escaleResidual_global) {
      TH2D *h2ResApply=Clone(h2ShapeWeights,"h2ResApply");
      // vary randomly and independently in each bin
      // prepare histo for randomization. Assume 10% error on the deviation
      for (int ibin=1; ibin<=h2ResApply->GetNbinsX(); ++ibin) {
	for (int jbin=1; jbin<=h2ResApply->GetNbinsY(); ++jbin) {
	double dev=h2ResApply->GetBinContent(ibin,jbin);
	//h2ResApply->SetBinError(ibin,jbin, 0.1*dev);
	h2ResApply->SetBinError(ibin,jbin, 1.);
	h2ResApply->SetBinError(ibin,jbin, dev);
	}
      }

      HistoPair2D_t hpRnd("hpRnd",h2ResApply);

      for (int i=1; i<ensembleSize; ++i) {
	TString name=Form("rndShapeWeight_%d",i);
	TH2D* h2Rnd=hpRnd.randomizedWithinErr(0,name);
	specTH2DWeightV.push_back(h2Rnd);
	tmpLabelV.push_back(name);
      }
    }
    else { // global variation
      for (int i=1; i<ensembleSize; ++i) {
	double rnd=gRandom->Gaus(0,1.);
	TString name=Form("rndShapeWeight_%d",i);
	TH2D *h2Rnd=Clone(h2ShapeWeights,name);
	for (int ibin=1; ibin<=h2Rnd->GetNbinsX(); ++ibin) {
	  for (int jbin=1; jbin<=h2Rnd->GetNbinsY(); ++jbin) {
	    double shW = h2ShapeWeights->GetBinContent(ibin,jbin);
	    double rndScale= 1 + rnd*(1-shW);
	    h2Rnd->SetBinContent(ibin,jbin, rndScale);
	  }
	}
	specTH2DWeightV.push_back(h2Rnd);
	tmpLabelV.push_back(name);
      }
    }

    if (0) {
      specTH2DWeightV.push_back(h2ShapeWeights);
      tmpLabelV.push_back("original");
      TCanvas *cx= plotProfiles("cx",specTH2DWeightV,tmpLabelV,NULL,1,
				"MC/data shape reweight");
      cx->Update();
      return retCodeStop;
    }
  }

  //
  // Set up histograms
  //
  std::vector<TH1D*> hMassv;
  std::vector<TH1D*> hMassBinsv;
  //TH1D *hSelEvents=NULL;

  // debug distributions: 1GeV bins
  //createAnyH1Vec(hMassv,"hMass_",inpMgr.sampleNames(),2500,0.,2500.,"M_{ee} [GeV]","counts/1GeV");
  createAnyH1Vec(hMassv,"hMass_",inpMgr.mcSampleNames(),1490,10.,1500.,"M_{ee} [GeV]","counts/1GeV");
  // debug distributions for current mass bin
  createBaseH1Vec(hMassBinsv,"hMassBins_",inpMgr.mcSampleNames());
  // debug: accumulate info about the selected events in the samples
  //hSelEvents=createAnyTH1D("hSelEvents","hSelEvents",inpMgr.mcSampleCount(),0,inpMgr.mcSampleCount(),"sampleId","event count");


  /*
  TH1F *hMassDiff   = new TH1F("hMassDiff","", 100, -30, 30);
  TH1F *hMassDiffBB = new TH1F("hMassDiffBB","", 100, -30, 30);
  TH1F *hMassDiffEB = new TH1F("hMassDiffEB","", 100, -30, 30);
  TH1F *hMassDiffEE = new TH1F("hMassDiffEE","", 100, -30, 30);

  // These histograms will contain (gen-reco) difference
  // for each (mass, Y) bin in a flattened format
  TH2F *hMassDiffV = new TH2F("hMassDiffV","",
			      nUnfoldingBins, -0.5, nUnfoldingBins-0.5,
			      100, -50.0, 50.0);
  TH2F *hYDiffV = new TH2F("hYDiffV","",
			   nUnfoldingBins, -0.5, nUnfoldingBins-0.5,
			   100, -5.0, 5.0);
  */

//   TH1F *hMassDiffV[nUnfoldingBins];
//   for(int i=0; i<nUnfoldingBins; i++){
//     sprintf(hname,"hMassDiffV_%d",i);
//     hMassDiffV[i] = new TH1F(hname,"",100,-50,50);
//   }

  UnfoldingMatrix_t detResponse(UnfoldingMatrix::_cDET_Response,"detResponse");
  UnfoldingMatrix_t detResponseExact(UnfoldingMatrix::_cDET_Response,"detResponseExact");
  UnfoldingMatrix_t detResponseReversed(UnfoldingMatrix::_cDET_Response,"detResponseReversed");

  UnfoldingMatrix_t fsrGood(UnfoldingMatrix::_cFSR, "fsrGood");
  UnfoldingMatrix_t fsrExact(UnfoldingMatrix::_cFSR, "fsrExact");
  UnfoldingMatrix_t fsrDET(UnfoldingMatrix::_cFSR_DET,"fsrDET"); // only relevant indices are checked for ini,fin
  UnfoldingMatrix_t fsrDETexact(UnfoldingMatrix::_cFSR_DET,"fsrDETexact"); // all indices are checked
  // a good working version: response matrix and invResponse are modified after the inversion
  UnfoldingMatrix_t fsrDET_good(UnfoldingMatrix::_cFSR_DET,"fsrDETgood");

  // Pretend to have a uniform binning
  RooUnfoldResponse rooUnfDetRes(DYTools::nUnfoldingBins,
				 -0.5,DYTools::nUnfoldingBins-0.5,
				 "rooUnfDetRes","rooUnfDetRes");
  rooUnfDetRes.UseOverflow(true);

  std::vector<UnfoldingMatrix_t*> detRespV;

  if (systMode==DYTools::NO_SYST) {}
  else if (systMode==DYTools::SYST_RND) {
    detRespV.reserve(2);
    for (int ir=0; ir<2; ++ir) {
      TString name=Form("detResponse_seed%d_replica%d",globalSeed,ir);
      detRespV.push_back(new UnfoldingMatrix_t(UnfoldingMatrix::_cDET_Response,name));
    }
  }
  else if (systMode==DYTools::RESOLUTION_STUDY) {
    detRespV.reserve(escaleV.size());
    for (int i=seedMin; i<=seedMax; i+=dSeed) {
      TString name=Form("detResponse_seed%d",i);
      detRespV.push_back(new UnfoldingMatrix_t(UnfoldingMatrix::_cDET_Response,name));
    }
  }
  else if (systMode==DYTools::FSR_STUDY) {
    detRespV.reserve(specReweightsV.size());
    for (unsigned int i=0; i<specReweightsV.size(); i++) {
      TString wStr=(i==0) ? Form("0%2.0f",specReweightsV[i]*100.) : Form("%3.0f",specReweightsV[i]*100.);
      TString name=TString("detResponse_") + wStr;
      detRespV.push_back(new UnfoldingMatrix_t(UnfoldingMatrix::_cDET_Response,name));
    }
  }
  else if (systMode==DYTools::PU_STUDY) {
    if (specEWeightsV.size()!=2) { std::cout << "expected specEWeights.size=2\n"; return retCodeError; }
    detRespV.reserve(specEWeightsV.size());
    for (unsigned int i=0; i<specEWeightsV.size(); i++) {
      TString wStr=(i==0) ? "PU5minus" : "PU5plus";
      TString name=TString("detResponse_") + wStr;
      detRespV.push_back(new UnfoldingMatrix_t(UnfoldingMatrix::_cDET_Response,name));
    }
  }
  else if (systMode==DYTools::ESCALE_RESIDUAL) {
    unsigned int count=specTH2DWeightV.size();
    detRespV.reserve(count);
    for (unsigned int i=0; i<count; ++i) {
      TString name=Form("detResponse_%s",niceNumber(i,count).Data());
      if (i==0) name="detResponse_0_nonRnd";
      detRespV.push_back(new UnfoldingMatrix_t(UnfoldingMatrix::_cDET_Response,name));
    }
  }
  /*
  else if (systMode==DYTools::ESCALE_STUDY) {
    detRespV.reserve(escaleV.size());
    for (unsigned int i=0; i<escaleV.size(); ++i) {
      TString name=TString("detResponse_") + escaleV[i]->calibrationSetShortName();
      detRespV.push_back(new UnfoldingMatrix_t(UnfoldingMatrix_t::_cDET_Response,name));
    }
  }
  */
  if (detRespV.size()) {
    std::cout << "names in detRespV:\n";
    for (unsigned int i=0; i<detRespV.size(); ++i) {
      std::cout << "  - " << detRespV[i]->getName() << "\n";
    }
  }

  // check
  if ((systMode==DYTools::RESOLUTION_STUDY) ||
      (systMode==DYTools::FSR_STUDY) ||
      (systMode==DYTools::PU_STUDY)
      //|| (systMode==DYTools::ESCALE_STUDY)
      ) {
    if (//(detRespV.size() != escaleV.size()) ||
	(detRespV.size() != specEWeightsV.size())) {
      std::cout << "error: detRespV.size=" << detRespV.size()
	//<< ", escaleV.size=" << escaleV.size()
	//<< ", specReweightsV.size=" << specReweightsV.size()
		<< ", specEWeightsV.size=" << specEWeightsV.size()
		<< "\n";
      assert(0);
    }
  }

  //
  // Access samples and fill histograms
  //
  AccessOrigNtuples_t accessInfo;

  //
  // loop over samples
  //
  if (DYTools::processData(runMode)) {

  double extraWeightFactor=1.0;
  EventCounterExt_t ecTotal("total");
  for (unsigned int isample=0; isample<inpMgr.mcSampleCount(); ++isample) {
    const CSample_t *mcSample=inpMgr.mcSampleInfo(isample);
    std::cout << "Processing " << mcSample->getLabel() << "..." << std::endl;
    std::cout << " of size " << mcSample->size() << "\n";
    if (mcSample->size()!=1) {
      std::cout << "mcSample->size is expected to be 1\n";
      return retCodeError;
    }

    for (unsigned int ifile=0; ifile<mcSample->size(); ++ifile) {
      // Read input file
      TFile *infile= new TFile(mcSample->getFName(ifile),"read");
      if (!infile || !infile->IsOpen()) {
	TString skimName=inpMgr.convertSkim2Ntuple(mcSample->getFName(ifile));
	std::cout <<  "  .. failed. Trying <" << skimName << ">" << std::endl;
	infile= new TFile(skimName,"read");
      }
      assert(infile->IsOpen());

      // Get the TTrees
      if (!accessInfo.setTree(*infile,"Events",true)) {
	return retCodeError;
      }

      // Find weight for events for this file
      // The first file in the list comes with weight 1*extraWeightFactor,
      // all subsequent ones are normalized to xsection and luminosity
      ULong_t maxEvents = accessInfo.getEntries();
      // to match old version package (DYee 7TeV paper),
      if (inpMgr.userKeyValueAsInt("USE7TEVMCWEIGHT") &&
	  (isample==0) && (ifile==0)) {
	extraWeightFactor=maxEvents / (inpMgr.totalLumi() * inpMgr.mcSampleInfo(0)->getXsec(ifile));
	//extraWeightFactor=maxEvents / inpMgr.mcSampleInfo(0)->getXsec(ifile);
      }
      //std::cout << "extraWeightFactor=" << extraWeightFactor << ", chk=" << (maxEvents0/inpMgr.mcSampleInfo(0)->getXsec(ifile)) << "\n";
      //const double extraWeightFactor=1.0;
      if (! evWeight.setWeight_and_adjustMaxEvents(maxEvents,
						   inpMgr.totalLumi(),
						   mcSample->getXsec(ifile),
						   extraWeightFactor, inpMgr.selectEventsFlag())) {
	std::cout << "adjustMaxEvents failed\n";
	return retCodeError;
      }
      std::cout << "mcSample xsec=" << mcSample->getXsec(ifile) << ", nEntries=" << maxEvents << "\n";

      std::cout << "       -> sample base weight is " << evWeight.baseWeight() << "\n";
      for (unsigned int iSt=0; iSt<specEWeightsV.size(); ++iSt) {
	specEWeightsV[iSt]->setBaseWeight(evWeight);
      }

      // loop through events
      EventCounterExt_t ec(Form("%s_file%d",mcSample->name.Data(),ifile));
      ec.setIgnoreScale(0); // 1 - count events, 0 - take weight in account
      // adjust the scale in the counter
      // if FEWZ weight should be considered, use evWeight.totalWeight() after
      // the FEWZ weight has been identified (see a line below)
      ec.setScale(evWeight.baseWeight());

      std::cout << "numEntries = " << accessInfo.getEntriesFast()
		<< ", " << maxEvents << " events will be used" << std::endl;

      for(ULong_t ientry=0; ientry<maxEvents; ientry++) {
	if (DYTools::isDebugMode(runMode) &&
	    (ientry>ULong_t(1000000)+DYTools::study2D*ULong_t(2000000))) break; // debug option
	//if (DYTools::isDebugMode(runMode) && (ientry>100)) break; // debug option
	printProgress(250000," ientry=",ientry,maxEvents);
	ec.numEvents_inc();

	// Load generator level info
	accessInfo.GetGen(ientry);
	// If the Z->ll leptons are not electrons, discard this event.
	// This is needed for signal MC samples such as Madgraph Z->ll
	// where all 3 lepton flavors are possible
	if (!accessInfo.genLeptonsAreElectrons()) continue;

	// Load event info
	accessInfo.GetInfoEntry(ientry);

	// Adjust event weight
	// .. here "false" = "not data"
	evWeight.set_PU_and_FEWZ_weights(accessInfo,false);
	//evWeightNoPU.set_PU_and_FEWZ_weights(accessInfo,false);
	if (useSpecWeight) {
	  evWeight.setSpecWeightValue(accessInfo,FSRmassDiff,specWeight);
	  //evWeightNoPU.setSpecWeightValue(accessInfo,FSRmassDiff,specWeight);
	}

	// FSR study correction for weight
	if (systMode==DYTools::FSR_STUDY) {
	  for (unsigned int iSt=0; iSt<specEWeightsV.size(); ++iSt) {
	    specEWeightsV[iSt]->setSpecWeightValue(accessInfo,FSRmassDiff,specReweightsV[iSt]);
	  }
	}

	// setup spec weights
	// .. here "false" = "not data"
	for (unsigned int iSt=0; iSt<specEWeightsV.size(); ++iSt) {
	  specEWeightsV[iSt]->set_PU_and_FEWZ_weights(accessInfo,false);
	}

	if (ientry<20) {
	  std::cout << "ientry=" << ientry << ", "; evWeight.Print(0);
	  //printf("reweight=%4.2lf, fewz_weight=%4.2lf,dE_fsr=%+6.4lf\n",reweight,fewz_weight,(gen->mass-gen->vmass));
	  if (systMode!=DYTools::RESOLUTION_STUDY) {
	    for (unsigned int iSt=0; iSt<specEWeightsV.size(); ++iSt) {
	      std::cout << " specEWeight[" << iSt << "] = "; specEWeightsV[iSt]->Print(0); //std::cout << "\n";
	    }
	  }
	  std::cout << "\n";
	}

	// adjust the scale in the counter to include FEWZ
	// (and possibly PU) weight
	//ec.setScale(evWeight.totalWeight());

	FlatIndex_t fiGenPreFsr, fiGenPostFsr;
	fiGenPreFsr.setGenPreFsrIdx(accessInfo);
	fiGenPostFsr.setGenPostFsrIdx(accessInfo);

	// begin FSR unfolding block
	fsrGood.fillIni(fiGenPreFsr , evWeight.totalWeight());
	fsrGood.fillFin(fiGenPostFsr, evWeight.totalWeight());
	if (fiGenPreFsr.isValid() && fiGenPostFsr.isValid()) {
	  fsrGood.fillMigration(fiGenPreFsr, fiGenPostFsr, evWeight.totalWeight());
	  fsrExact.fillIni(fiGenPreFsr , evWeight.totalWeight());
	  fsrExact.fillFin(fiGenPostFsr, evWeight.totalWeight());
	  fsrExact.fillMigration(fiGenPreFsr, fiGenPostFsr, evWeight.totalWeight());
	}

	int preFsrOk=0, postFsrOk=0;
	if (evtSelector.inAcceptancePreFsr(accessInfo) &&
	    fiGenPreFsr.isValid()) {
	  preFsrOk=1;
	  fsrDET     .fillIni(fiGenPreFsr, evWeight.totalWeight());
	  fsrDET_good.fillIni(fiGenPreFsr, evWeight.totalWeight());
	}

	if (evtSelector.inAcceptance(accessInfo) &&
	    fiGenPostFsr.isValid()) {
	  postFsrOk=1;
	  fsrDET     .fillFin(fiGenPostFsr, evWeight.totalWeight());
	  fsrDET_good.fillFin(fiGenPostFsr, evWeight.totalWeight());
	}

	if (preFsrOk && postFsrOk) {
	  fsrDET.fillMigration(fiGenPreFsr, fiGenPostFsr, evWeight.totalWeight());
	  fsrDET_good.fillMigration(fiGenPreFsr, fiGenPostFsr, evWeight.totalWeight());
	  fsrDETexact.fillIni(fiGenPreFsr , evWeight.totalWeight());
	  fsrDETexact.fillFin(fiGenPostFsr, evWeight.totalWeight());
	  fsrDETexact.fillMigration(fiGenPreFsr, fiGenPostFsr, evWeight.totalWeight());
	}
	// end of FSR unfolding block


	// check event trigger
	if (!evtSelector.eventTriggerOk(accessInfo)) {
	  continue; // no trigger accept? Skip to next event...	
	}
	ec.numEventsPassedEvtTrigger_inc();

	// load dielectron array
	accessInfo.GetDielectrons(ientry);

	// loop through dielectrons
	//int pass=0;
	int candCount=0;
	mithep::TDielectron uncorrDielectron;
	for(Int_t i=0; i<accessInfo.dielectronCount(); i++) {
	  mithep::TDielectron *dielectron = accessInfo.editDielectronPtr(i);
	  ec.numDielectrons_inc();

	  // keep unmodified dielectron
	  if (escaleV.size()) uncorrDielectron.restoreEScaleModifiedValues(*dielectron);

	  // escale may modify dielectron! But it should not here
	  if (!evtSelector.testDielectron(dielectron,accessInfo.evtInfoPtr(),&ec)) continue;
	  //pass=1;

          /******** We have a Z candidate! HURRAY! ********/

	  candCount++;
	  ec.numDielectronsPass_inc();
	  if (ec.numDielectronsOkSameSign_inc(dielectron->q_1,dielectron->q_2)) {
	    // same sign event
	  }

	  //
	  // Fill structures for response matrix

	  FlatIndex_t fiReco;
	  fiReco.setRecoIdx(dielectron);

	  // Fill the matrix of post-FSR generator level invariant mass and rapidity
	  double diWeight=evWeight.totalWeight();
	  detResponse.fillIni(fiGenPostFsr, diWeight);
	  detResponse.fillFin(fiReco      , diWeight);

	  int bothFIValid=fiGenPostFsr.isValid() && fiReco.isValid();
	  if (bothFIValid) {
	    ec.numDielectronsGoodMass_inc();
	    detResponse.fillMigration(fiGenPostFsr, fiReco, diWeight);

	    detResponseExact.fillIni(fiGenPostFsr, diWeight);
	    detResponseExact.fillFin(fiReco      , diWeight);
	    detResponseExact.fillMigration(fiGenPostFsr, fiReco, diWeight);
	  }

	  if (fiGenPostFsr.isValid()) {
	    if (fiReco.isValid()) {
	      rooUnfDetRes.Fill(fiReco.idx(),fiGenPostFsr.idx(), diWeight);
	    }
	    else {
	      rooUnfDetRes.Miss(fiGenPostFsr.idx(), diWeight);
	    }
	  }
	  else rooUnfDetRes.Fake(fiReco.idx(), diWeight);

	  detResponseReversed.fillIni(fiReco,       diWeight);
	  detResponseReversed.fillFin(fiGenPostFsr, diWeight);
	  if (bothFIValid) {
	    detResponseReversed.fillMigration(fiReco,fiGenPostFsr, diWeight);
	  }

	  if (systMode != DYTools::RESOLUTION_STUDY) {
	    switch(systMode) {
	    case DYTools::SYST_RND: {
	      double rnd=gRandom->Gaus(0,1.);
	      if (rnd==double(0.)) rnd=gRandom->Gaus(0,1.);
	      int idx=(rnd<double(0.)) ? 0:1;
	      detRespV[idx]->fillIni( fiGenPostFsr, diWeight );
	      detRespV[idx]->fillFin( fiReco      , diWeight );
	      if (bothFIValid) {
		detRespV[idx]->fillMigration( fiGenPostFsr, fiReco, diWeight);
	      }
	    }
	      break;

	    case DYTools::ESCALE_RESIDUAL:
	      for (unsigned int iSt=0; iSt<detRespV.size(); ++iSt) {
		const TH2D *h2Rnd= specTH2DWeightV[iSt];
		double w=1.;
		if (fiReco.isValid()) {
		  w=h2Rnd->GetBinContent(fiReco.iM()+1,fiReco.iY()+1);
		  if ((iSt==0) && (ientry<20)) {
		    std::cout << "dielectron(M,Y)=" << dielectron->mass
			      << "," << dielectron->y << ", fiReco="
			      << fiReco << ", specWeight=" << w << "\n";
		  }
		}
		double studyWeight= diWeight * w;
		detRespV[iSt]->fillIni( fiGenPostFsr, studyWeight );
		detRespV[iSt]->fillFin( fiReco      , studyWeight );
		if (bothFIValid) {
		  detRespV[iSt]->fillMigration( fiGenPostFsr, fiReco,
						studyWeight);
		}
	      }
	      break;

	    default:
	      for (unsigned int iSt=0; iSt<detRespV.size(); ++iSt) {
		double studyWeight=specEWeightsV[iSt]->totalWeight();
		detRespV[iSt]->fillIni( fiGenPostFsr, studyWeight );
		detRespV[iSt]->fillFin( fiReco      , studyWeight );
		if (bothFIValid) {
		  detRespV[iSt]->fillMigration( fiGenPostFsr, fiReco,
						studyWeight );
		}
	      }
	    }
	  }

	  if (escaleV.size() && (systMode==DYTools::RESOLUTION_STUDY)) {
	    for (unsigned int iESc=0; iESc<escaleV.size(); ++iESc) {
	      dielectron->restoreEScaleModifiedValues(uncorrDielectron);
	      if (evtSelectorV[iESc]->testDielectron(dielectron,
						accessInfo.evtInfoPtr())) {
		FlatIndex_t fiRecoMdf;
		fiRecoMdf.setRecoIdx(dielectron);
		detRespV[iESc]->fillIni(fiGenPostFsr, diWeight);
		detRespV[iESc]->fillFin(fiRecoMdf   , diWeight);
		if (fiGenPostFsr.isValid() && fiRecoMdf.isValid()) {
		  detRespV[iESc]->fillMigration(fiGenPostFsr,fiRecoMdf,
						diWeight);
		}
	      }
	    }
	  }

	  /*
	  Bool_t isB1 = DYTools::isBarrel(dielectron->scEta_1);
	  Bool_t isB2 = DYTools::isBarrel(dielectron->scEta_2);

	  hMassDiff->Fill(massResmeared - gen->mass);
	  if( isB1 && isB2 )
	    hMassDiffBB->Fill(massResmeared - gen->mass);
	  if( (isB1 && !isB2) || (!isB1 && isB2) )
	    hMassDiffEB->Fill(massResmeared - gen->mass);
	  if( !isB1 && !isB2 )
	    hMassDiffEE->Fill(massResmeared - gen->mass);

	  hMassDiffV->Fill(iIndexFlatGen, massResmeared - gen->mass);
	  hYDiffV   ->Fill(iIndexFlatGen, dielectron->y - gen->y);
	  // 	if(iIndexFlatGen != -1){
	  // 	  hMassDiffV[iIndexFlatGen]->Fill(massResmeared - gen->mass);
	  // 	}
	  */

	} // end loop over dielectrons
	if (candCount>1) ec.numMultiDielectronsOk_inc();

      } // end loop over events
      infile->Close();
      delete infile;
      std::cout << ec << "\n";
      ecTotal.add(ec);
    } // end loop over files
    std::cout << "total counts : " << ecTotal << "\n";

  } // loop over iSample
  } // runMode


  UnfoldingMatrix_t fsrDETcorrections(UnfoldingMatrix::_cFSR_DETcorrFactors,"fsrCorrFactors");

  if (DYTools::processData(runMode)) {
    // Compute the errors on the elements of migration matrix
    detResponse.finalizeDetMigrationErr();
    detResponseExact.finalizeDetMigrationErr();
    detResponseReversed.finalizeDetMigrationErr();
    fsrGood.finalizeDetMigrationErr();
    fsrExact.finalizeDetMigrationErr();
    fsrDET.finalizeDetMigrationErr();
    fsrDETexact.finalizeDetMigrationErr();
    fsrDET_good.finalizeDetMigrationErr();
    for (unsigned int i=0; i<detRespV.size(); ++i) detRespV[i]->finalizeDetMigrationErr();

  // Find response matrix, which is simply the normalized migration matrix
    std::cout << "find response matrix" << std::endl;
    detResponse.computeResponseMatrix();
    detResponseExact.computeResponseMatrix();
    detResponseReversed.computeResponseMatrix();
    fsrGood.computeResponseMatrix();
    fsrExact.computeResponseMatrix();
    fsrDET.computeResponseMatrix();
    fsrDETexact.computeResponseMatrix();
    fsrDET_good.computeResponseMatrix();
    for (unsigned int i=0; i<detRespV.size(); ++i) detRespV[i]->computeResponseMatrix();

    std::cout << "find inverted response matrix" << std::endl;
    detResponse.invertResponseMatrix();
    detResponseExact.invertResponseMatrix();
    detResponseReversed.invertResponseMatrix();
    fsrGood.invertResponseMatrix();
    fsrExact.invertResponseMatrix();
    fsrDET.invertResponseMatrix();
    fsrDETexact.invertResponseMatrix();
    fsrDET_good.invertResponseMatrix();
    for (unsigned int i=0; i<detRespV.size(); ++i) detRespV[i]->invertResponseMatrix();

    fsrDETcorrections.prepareFsrDETcorrFactors(fsrDET,fsrDETexact);
    //fsrDETcorrections.printYields();

    std::cout << "finalize fsrDET_good" << std::endl;
    fsrGood.modifyDETResponseMatrices(fsrExact);
    fsrDET_good.modifyDETResponseMatrices(fsrDETexact);

    std::cout << "prepare flat-index arrays" << std::endl;
    detResponse.prepareFIArrays();
    detResponseExact.prepareFIArrays();
    detResponseReversed.prepareFIArrays();
    fsrGood.prepareFIArrays();
    fsrExact.prepareFIArrays();
    fsrDET.prepareFIArrays();
    fsrDETexact.prepareFIArrays();
    fsrDET_good.prepareFIArrays();
    fsrDETcorrections.prepareFIArrays();
    for (unsigned int i=0; i<detRespV.size(); ++i) detRespV[i]->prepareFIArrays();
  }

  //
  // Store constants and reference arrays in files
  //
  if (DYTools::processData(runMode))  std::cout << "store constants in a file" << std::endl;

  //TString outFile=inpMgr.correctionFullFileName("unfolding",systMode,0);
  TString outputDir=inpMgr.constDir(systMode,0);

  //int saveIdxMin=-1;
  TString fnameTag=UnfoldingMatrix_t::generateFNameTag(systMode,globalSeed);
  /*
  {
    TString u="_";
    switch(systMode) {
    case DYTools::NO_SYST:
      fnameTag=DYTools::analysisTag;
      break;
    case DYTools::SYST_RND:
      fnameTag=TString("_replica_") + DYTools::analysisTag;
      //saveIdxMin=0;
     //fnameTag+=seed;
       break;
    case DYTools::RESOLUTION_STUDY:
      fnameTag=TString("_seed_") + DYTools::analysisTag;
      //fnameTag+=seed;
      break;
    case DYTools::FSR_STUDY:
      fnameTag=TString("_fsrStudy_") + DYTools::analysisTag;
      //fnameTag=TString("_reweight_") + DYTools::analysisTag;
      //fnameTag+= int(100*reweightFsr);
      break;
    case DYTools::PU_STUDY:
      fnameTag=TString("_puStudy_") + DYTools::analysisTag;
      break;
    case DYTools::ESCALE_STUDY:
      fnameTag=DYTools::analysisTag+TString("_escale") + u;
      break;
    case DYTools::ESCALE_RESIDUAL:
      fnameTag=DYTools::analysisTag+TString("_escaleResidual");
      break;
    default:
      std::cout<<"requested mode not recognized when determining fnameTag"<<std::endl;
      assert(0);
    }
  }
  */
  if (DYTools::isDebugMode(runMode)) fnameTag.Prepend("_DebugRun_");
  std::cout << "fnameTag=<" << fnameTag << ">\n";
  CPlot::sOutDir.Append(fnameTag);
  CPlot::sOutDir.ReplaceAll(DYTools::analysisTag,"");
  CPlot::sOutDir.Append(DYTools::analysisTag);

  TString callingMacro="plotUnfoldingMatrix.systMode=";
  callingMacro.Append(SystematicsStudyName(systMode));

  if (DYTools::processData(runMode)) {
    if (//(systMode!=DYTools::NORMAL_RND) &&
	(systMode!=DYTools::RESOLUTION_STUDY) &&
	//(systMode!=DYTools::FSR_STUDY) &&
	(systMode!=DYTools::ESCALE_STUDY)) {
      detResponse.autoSaveToFile(outputDir,fnameTag,callingMacro);  // detResponse, reference mc arrays
      detResponseExact.autoSaveToFile(outputDir,fnameTag,callingMacro);
      detResponseReversed.autoSaveToFile(outputDir,fnameTag,callingMacro);
      fsrGood.autoSaveToFile(outputDir,fnameTag,callingMacro);
      fsrExact.autoSaveToFile(outputDir,fnameTag,callingMacro);
      fsrDET.autoSaveToFile(outputDir,fnameTag,callingMacro);
      fsrDETexact.autoSaveToFile(outputDir,fnameTag,callingMacro);
      fsrDET_good.autoSaveToFile(outputDir,fnameTag,callingMacro);
      fsrDETcorrections.autoSaveToFile(outputDir,fnameTag,callingMacro);
    }

    TString fname=Form("rooUnfDetRes_%s.root",DYTools::analysisTag.Data());
    if (DYTools::isDebugMode(runMode))
      fname.ReplaceAll(".root","_DebugRun.root");
    TFile fout(fname,"recreate");
    if (!fout.IsOpen()) {
      std::cout << "failed to create the file <" << fout.GetName() << ">\n";
      return retCodeError;
    }
    rooUnfDetRes.Write();
    writeBinningArrays(fout,"plotUnfoldingMatrixRooUnfold");
    std::cout << "file <" << fout.GetName() << "> created\n";
    fout.Close();

    for (unsigned int i=0; i<detRespV.size(); i++)
      detRespV[i]->autoSaveToFile(outputDir,fnameTag,callingMacro);

    // additional saving for systematics
    if (systMode==DYTools::FSR_STUDY) {
      detRespV[0]->autoSaveToFile(inpMgr.constDir(DYTools::FSR_5minus,0),
	  UnfoldingMatrix_t::generateFNameTag(DYTools::FSR_5minus,globalSeed),
				  callingMacro);
      detRespV[2]->autoSaveToFile(inpMgr.constDir(DYTools::FSR_5plus,0),
	  UnfoldingMatrix_t::generateFNameTag(DYTools::FSR_5plus,globalSeed),
				  callingMacro);
    }
    else if (systMode==DYTools::PU_STUDY) {
      TString dir0=inpMgr.constDir(DYTools::PILEUP_5minus,0);
      TString tag0=UnfoldingMatrix_t::generateFNameTag(DYTools::PILEUP_5minus,
						       globalSeed);
      TString dir1=inpMgr.constDir(DYTools::PILEUP_5plus,0);
      TString tag1=UnfoldingMatrix_t::generateFNameTag(DYTools::PILEUP_5plus,
						       globalSeed);
      detRespV[0]->autoSaveToFile(dir0,tag0,callingMacro);
      detRespV[1]->autoSaveToFile(dir1,tag1,callingMacro);
    }
  }
  else {
    if (//(systMode!=DYTools::NORMAL_RND) &&
	(systMode!=DYTools::RESOLUTION_STUDY) &&
	//(systMode!=DYTools::FSR_STUDY) &&
	(systMode!=DYTools::ESCALE_STUDY)) {
      if (!detResponse.autoLoadFromFile(outputDir,fnameTag) ||
	  !detResponseExact.autoLoadFromFile(outputDir,fnameTag) ||
	  !detResponseReversed.autoLoadFromFile(outputDir,fnameTag) ||
	  !fsrGood.autoLoadFromFile(outputDir,fnameTag) ||
	  !fsrExact.autoLoadFromFile(outputDir,fnameTag) ||
	  !fsrDET.autoLoadFromFile(outputDir,fnameTag) ||
	  !fsrDETexact.autoLoadFromFile(outputDir,fnameTag) ||
	  !fsrDET_good.autoLoadFromFile(outputDir,fnameTag) ||
	  !fsrDETcorrections.autoLoadFromFile(outputDir,fnameTag)) {
	std::cout << "loading failed\n";
	return retCodeError;
      }
    }
    for (unsigned int i=0; i<detRespV.size(); i++) detRespV[i]->autoLoadFromFile(outputDir,fnameTag);
  }


  UnfoldingMatrix_t detRespAvg(detResponse.kind, "detResponseAvg");
  if (1 && detRespV.size()) { //computeAverage
    const double weight=1/double(detRespV.size());
    for (unsigned int i=0; i<detRespV.size(); ++i) {
      TString name=Form("tmp_%d",i);
      UnfoldingMatrix_t tmp(*detRespV[i],name);
      tmp.squareDetMigrationErr();
      detRespAvg.addMigration(tmp,weight);
    }
    detRespAvg.finalizeDetMigrationErr();
    detRespAvg.computeResponseMatrix();
    detRespAvg.invertResponseMatrix();
    detRespAvg.prepareFIArrays();
    detRespAvg.autoSaveToFile(outputDir,fnameTag,callingMacro); // detResponse, reference mc arrays
  }


  //--------------------------------------------------------------------------------------------------------------
  // Make plots
  //==============================================================================================================

  /*
  std::cout << "making plots" << std::endl;

  TString unfoldingConstFileName, yieldsFileName;
  detResponse.getFileNames(outputDir,fnameTag, unfoldingConstFileName, yieldsFileName);
  TString unfoldingConstantsPlotFName=unfoldingConstFileName;
  unfoldingConstantsPlotFName.Replace(unfoldingConstantsPlotFName.Index(".root"),
				      sizeof(".root"),
				      "_plots.root");
  TFile *fPlots=new TFile(unfoldingConstantsPlotFName,"recreate");
  if (!fPlots) {
    std::cout << "failed to create a file <" << unfoldingConstantsPlotFName << ">\n";
  }

#ifdef CrossSection_HH
  if (1) {  // study Ini and Fin vecs
    std::vector<VXSectD_t*> dataV;
    TString canvName="canvChk";
    TString fewzTag=(useFewzWeights) ? "_withFEWZ" : "_noFEWZ";
    if (useFewzWeights && regularizeFEWZ) fewzTag="_withMdfFEWZ";
    canvName.Append(fewzTag);
    const int twoPads=0;
    TCanvas *c=new TCanvas(canvName,canvName,600*(1+twoPads),600);
    if (twoPads) {
      c->Divide(2,1);
      c->GetPad(1)->SetLogx(1);
      c->GetPad(2)->SetLogx(1);
      c->GetPad(1)->SetLogy(1);
      c->GetPad(2)->SetLogy(1);
    }
    else { c->SetLogx(1); c->SetLogy(1); }
    int ok=1;

    TH1F *hGenAvg=new TH1F("hGenAvg","hGenAvg",DYTools::nMassBins,DYTools::massBinLimits);
    TH1F *hRecAvg=new TH1F("hRecAvg","hRecAvg",DYTools::nMassBins,DYTools::massBinLimits);
    hGenAvg->SetDirectory(0);
    hRecAvg->SetDirectory(0);
    hGenAvg->Sumw2();
    hRecAvg->Sumw2();

    TH1F *hGenAvg_chk=NULL; //new TH1F("hGenAvg_chk","hGenAvg_chk",DYTools::nMassBins,DYTools::massBinLimits);
    TH1F *hRecAvg_chk=NULL; //new TH1F("hRecAvg_chk","hRecAvg_chk",DYTools::nMassBins,DYTools::massBinLimits);
    if (ok && hGenAvg_chk && hRecAvg_chk) {
      hGenAvg_chk->SetDirectory(0);
      hRecAvg_chk->SetDirectory(0);
      VXSectD_t d("yields_repAvg",DYTools::nUnfoldingBinsMax);
      TString matrixFName,yieldsFName;
      detRespAvg.getFileNames(outputDir,fnameTag, matrixFName,yieldsFName);
      ok=d.Load(matrixFName,"yieldsMcPostFsrGenFIArray","yieldsMcPostFsrRecFIArray","");
      if (ok) ok= (d.FillHisto(hGenAvg_chk,1) && d.FillHistoWithError(hRecAvg_chk));
    }

    for (unsigned int i=0; ok && (i<detRespV.size()); ++i) {
      TString name=Form("yields_rep%d",i);
      VXSectD_t *d=new VXSectD_t(name,DYTools::nUnfoldingBinsMax);
      dataV.push_back(d);
      TString matrixFName,yieldsFName;
      detRespV[i]->getFileNames(outputDir,fnameTag, matrixFName,yieldsFName);
      ok=d->Load(matrixFName,"yieldsMcPostFsrGenFIArray","yieldsMcPostFsrRecFIArray","");
      if (!ok) continue;
      TString hGenName=Form("hGen_rep%d",i);
      TString hRecName=Form("hRec_rep%d",i);
      TH1F *hGen=new TH1F(hGenName,hGenName,DYTools::nMassBins,DYTools::massBinLimits);
      TH1F *hRec=new TH1F(hRecName,hRecName,DYTools::nMassBins,DYTools::massBinLimits);
      hGen->SetDirectory(0);
      hRec->SetDirectory(0);
      if (i==0) {
	hGen->SetTitle(hGen->GetTitle() + fewzTag);
	hRec->SetTitle(hRec->GetTitle() + fewzTag);
      }
      ok= (d->FillHisto(hGen,1) && d->FillHistoWithError(hRec));
      if (!ok) continue;
      hGenAvg->Add(hGen,1/double(detRespV.size()));
      hRecAvg->Add(hRec,1/double(detRespV.size()));
      TString opt="L";
      if (i>0) opt.Append("same");
      int color = i%(50-20) + 20;
      hGen->SetLineColor(color);
      hRec->SetLineColor(color);
      hGen->GetYaxis()->SetRangeUser(5.,3.e6);
      hRec->GetYaxis()->SetRangeUser(5.,3.e6);
      if (twoPads) c->cd(1);
      hGen->Draw(opt);
      if (twoPads) c->cd(2);
      else { if (i==0) opt.Append("same"); }
      hRec->Draw(opt);
    }
    hGenAvg->SetLineColor(kAzure+1);
    hRecAvg->SetLineColor(kRed+1);
    if (twoPads) c->cd(1);
    hGenAvg->Draw("L same");
    if (hGenAvg_chk) hGenAvg_chk->Draw("L same");
    if (twoPads) c->cd(2);
    hRecAvg->Draw("L same");
    if (hRecAvg_chk) hRecAvg_chk->Draw("L same");
    c->Update();
    return;
  }
#endif


  TCanvas *c = MakeCanvas("canvZmass1","canvZmass1",800,600);

  // string buffers
  char ylabel[50];   // y-axis label

  //
  // Draw DY candidate mass at the reconstruction level. Extra
  // smearing is applied. This figure allows one to judge the
  // correctness of the weights aplied to different samples from the
  // smoothness of the combined result.
  //
  sprintf(ylabel,"a.u. / %.1f GeV/c^{2}",hZMassv[0]->GetBinWidth(1));
  CPlot plotZMass1("zmass1","","m(ee) [GeV/c^{2}]",ylabel);
  for(UInt_t i=0; i<fnamev.size(); i++) {
    plotZMass1.AddHist1D(hZMassv[i],labelv[i],"hist",colorv[i],linev[i]);
  }
  plotZMass1.SetLogy();
  plotZMass1.Draw(c);
  SaveCanvas(c,"zmass1");
//   plotZMass1.Draw(c,doSave,format);
//   if (fPlots) { fPlots->cd(); c->Write(); }

  //
  // Draw a plot that illustrates the detector resolution effects.
  // We plot (gen-rec)/gen as a function of mass and rapidity.
  //
  TMatrixD resolutionEffect(DYTools::nMassBins,DYTools::nYBinsMax);
  resolutionEffect = 0;
  for(int i=0; i < resolutionEffect.GetNrows(); i++){
    for(int j=0; j < resolutionEffect.GetNcols(); j++){
      double ngen = (*detResponse.yieldsIni)(i,j);
      double nrec = (*detResponse.yieldsFin)(i,j);
      if( ngen != 0 )
	resolutionEffect(i,j) = (ngen-nrec)/ngen;
    }
  }
  resolutionEffect.Print();
  PlotMatrixVariousBinning(resolutionEffect, "resolution_effect", "LEGO2", NULL);

  //
  // Draw a plot that illustrates the losses due to reconstruction
  // We plot (preFsrExact-preFsr)/preFsrExact as a
  // function of mass and rapidity.
  //
  TMatrixD *unfRecoEffect=detResponseExact.getReconstructionEffect(detResponse);
  unfRecoEffect->Print();
  PlotMatrixVariousBinning(*unfRecoEffect, "reconstruction_effect", "LEGO2", NULL);
  delete unfRecoEffect;

  TMatrixD *unfFsrDETRecoEffect=fsrDETexact.getReconstructionEffect(fsrDET);

  PlotMatrixVariousBinning(*unfFsrDETRecoEffect, "reconstruction_effect_fsrDET", "LEGO2", NULL);
  delete unfFsrDETRecoEffect;

  */

  // Plot response and inverted response matrices
  //std::vector<TH2F*> hResponseV, hInvResponseV;
  //std::vector<TCanvas*> canvV;
  //std::vector<CPlot*> cpResponseV;

  //TH2F *hR, *hIR;
  //TCanvas *e2;
  //CPlot *cpR, *cpIR;
  detResponse.prepareHResponse();
  fsrGood.prepareHResponse();
  fsrExact.prepareHResponse();
  fsrDET.prepareHResponse();
  fsrDETexact.prepareHResponse();
  fsrDET_good.prepareHResponse();

  for (unsigned int iESc=0; iESc<detRespV.size(); ++iESc) {
    detRespV[iESc]->prepareHResponse();
  }

  /*
  // Create a plot of detector resolution without mass binning
  TCanvas *g = MakeCanvas("canvMassDiff","canvMassDiff",600,600);
  CPlot plotMassDiff("massDiff","","reco mass - gen post-FSR mass [GeV/c^{2}]","a.u.");
  hMassDiffBB->Scale(1.0/hMassDiffBB->GetSumOfWeights());
  hMassDiffEB->Scale(1.0/hMassDiffEB->GetSumOfWeights());
  hMassDiffEE->Scale(1.0/hMassDiffEE->GetSumOfWeights());
  plotMassDiff.AddHist1D(hMassDiffBB,"EB-EB","hist",kBlack);
  plotMassDiff.AddHist1D(hMassDiffEB,"EE-EB","hist",kBlue);
  plotMassDiff.AddHist1D(hMassDiffEE,"EE-EE","hist",kRed);
  plotMassDiff.Draw(g);
  SaveCanvas(g,"massDiff");
//   if (fPlots) g->Write();

  // Create a plot of reco - gen post-FSR mass and rapidity difference
  TCanvas *h1 = MakeCanvas("canvMassDiffV","canvMassDiffV",600,600);
  CPlot plotMassDiffV("massDiffV","",
		      "flat index",
		      "reco mass - gen post-FSR mass [GeV/c^{2}]");
  plotMassDiffV.AddHist2D(hMassDiffV,"LEGO");
  plotMassDiffV.Draw(h1);
  SaveCanvas(h1,"hMassDiffV");

  // Create a plot of reco - gen post-FSR mass and rapidity difference
  TCanvas *h2 = MakeCanvas("canvYDiffV","canvYDiffV",600,600);
  CPlot plotYDiffV("massDiffV","",
		      "flat index",
		      "reco Y - gen post-FSR Y");
  plotYDiffV.AddHist2D(hYDiffV,"LEGO");
  plotYDiffV.Draw(h2);
  SaveCanvas(h2,"hYDiffV");

  if (fPlots) {
    fPlots->Close();
    delete fPlots;
    std::cout << "plots saved to a file <" << unfoldingConstantsPlotFName << ">\n";
  }

  //draw errors of Unfolding matrix
  TCanvas *cErrorsResp = MakeCanvas("cErrorsResp","detResponse.DetInvertedResponseErr", 600,600);
  detResponse.DetInvertedResponseErr->Draw("LEGO2");
  cErrorsResp->Update();
  SaveCanvas(cErrorsResp,"cErrorsResp");

  TCanvas *cFsrErrorsResp = MakeCanvas("cErrorsFsr","fsr__.DetInvertedResponseErr", 1200, 600);
  cFsrErrorsResp->Divide(2,1);
  cFsrErrorsResp->cd(1);
  fsrExact.DetInvertedResponseErr->Draw("LEGO2");
  cFsrErrorsResp->cd(2);
  fsrDET.DetInvertedResponseErr->Draw("LEGO2");
  SaveCanvas(cFsrErrorsResp,"cErrorsFsr");



  //--------------------------------------------------------------------------------------------------------------
  // Summary print out
  //==============================================================================================================
  cout << endl;
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl;

  detResponse.printConditionNumber();
  fsrExact.printConditionNumber();
  fsrDET.printConditionNumber();
  fsrDETexact.printConditionNumber();

  if (0) {
    //detResponse.printMatrices();
    //fsr.printMatrices();
    //fsrDET.printMatrices();
    fsrDET_Mdf.printMatrices();
    fsrDET_good.printMatrices();
  }

  //Print errors of the Unfolding matrix when they exceed 0.1
  /
  for (int iM=0; iM<DYTools::nMassBins; iM++)
    for (int iY=0; iY<DYTools::nYBins[iM]; iY++)
      for (int jM=0; jM<DYTools::nMassBins; jM++)
        for (int jY=0; jY<DYTools::nYBins[jM]; jY++)
          {
	    int i=DYTools::findIndexFlat(iM,iY);
	    int j=DYTools::findIndexFlat(jM,jY);
             if (DetInvertedResponseErr(i,j)>0.1)
                {
                   std::cout<<"DetInvertedResponseErr("<<i<<","<<j<<")="<<DetInvertedResponseErr(i,j);
                   std::cout<<", DetInvertedResponse("<<i<<","<<j<<")="<<DetInvertedResponse(i,j)<<std::endl;
                   std::cout<<"(iM="<<iM<<", iY="<<iY<<", jM="<<jM<<", jY="<<jY<<")"<<std::endl<<std::endl;
                }
             if (DetInvertedResponseErr2(i,j)>0.1)
                {
                   std::cout<<"DetInvertedResponseErr2("<<i<<","<<j<<")="<<DetInvertedResponseErr2(i,j);
                   std::cout<<", DetInvertedResponse("<<i<<","<<j<<")="<<DetInvertedResponse(i,j)<<std::endl;
                   std::cout<<"(iM="<<iM<<", iY="<<iY<<", jM="<<jM<<", jY="<<jY<<")"<<std::endl<<std::endl;
                }
          }
  /

  /
  if (0) {
    // Printout of all constants, uncomment if needed
    //printf("DetCorrFactor:\n"); DetCorrFactor.Print();
    printf("DetMigration:\n"); DetMigration.Print();
    printf("DetResponse:\n"); DetResponse.Print();

    printf("DetInvertedResponse:\n"); DetInvertedResponse.Print();
    //printf("DetInvertedResponseErr:\n"); DetInvertedResponseErr.Print();
    //printf("DetResponseArr:\n"); DetResponseArr.Print();
    //printf("DetInvertedResponseArr:\n"); DetInvertedResponseArr.Print();
    //printf("DetInvertedResonseErrArr:\n"); DetInvertedResponseErrArr.Print();

    //   printf("Detector corr factor numerator:\n");
    //   DetCorrFactorNumerator.Print();

    printf("yieldsMcPostFsrGen:\n");
    yieldsMcPostFsrGen.Print();

    printf("yieldsMcPostFsrRec:\n");
    yieldsMcPostFsrRec.Print();


    //   printf("Detector corr factor denominator:\n");
    //   DetCorrFactorDenominator.Print();
    //   printf("yieldsMcPostFsrRecArr:\n");
    //   yieldsMcPostFsrRecArr.Print();

    //printf("yieldsMcGen:\n");
    //yieldsMcGen.Print();
  }
  /

  if (0) {
    detResponse.printYields();
    fsrExact.printYields();
    fsrDET.printYields();
  }
*/
  //gBenchmark->Show("makeUnfoldingMatrix");
  ShowBenchmarkTime("makeUnfoldingMatrix");
  return retCodeOk;
}
Пример #13
0
bool PSEC4Sim::Execute(){
  
  PSECElement *tmp=new PSECElement(6);
  
  tmp->starttime=0;
  tmp->timestep=acq_rate_usecs;
  tmp->numpoints=256;
  tmp->numreadouts=num_readouts;

  m_data->vars.Get("crateid",tmp->crateid);
  m_data->vars.Get("cardid",tmp->cardid);
  tmp->cardid++;
  if(tmp->cardid>7){
    tmp->crateid++;
    tmp->cardid=0;
    m_data->vars.Set("crateid",tmp->crateid);
  }
  m_data->vars.Set("cardid",tmp->cardid);
  std::cout<<"cardid "<<tmp->cardid<<" crateid "<<tmp->crateid<<std::endl;
  int tmppmtid;
  m_data->vars.Get("pmtid",tmppmtid);
  tmppmtid+=1;
  m_data->vars.Set("pmtid",tmppmtid+5);

  double pi=3.14159265351;
  double angle =(2*pi)/(6*8);
  double r=5.5;
  double dist=22.0/72.0;
  

  for (int i=0;i<6;i++){
    tmp->pmtids[i]=i+tmppmtid;
    std::vector<float> tmploc;
    tmploc.push_back(cos((((tmp->cardid)*6)+(i+1))*angle)*r);
     std::cout<<"i= "<<i<<" angle multiplier "<<((tmp->cardid)*6)+(i+1)<<std::endl;

    tmploc.push_back(sin((((tmp->cardid)*6)+(i+1))*angle)*r);
    tmploc.push_back((dist/2.0)+(tmp->crateid*dist));
    tmploc.push_back((((tmp->cardid)*6)+(i+1))*angle);
    tmp->pmtlocations.push_back(tmploc);
  }
  
  
  TRandom *eventGenerator = new TRandom();
  
time_t seconds;

// seconds = time (NULL);
 uint seed= ((dist/2.0)+(tmp->crateid*dist)+((tmp->cardid)*6))*100;
  //std::cout<<"seed = "<<((uint) seconds)<<std::endl;
  eventGenerator->SetSeed(seed);
  std::vector<std::vector<std::vector<float> > >tmpf3;
  std::vector< std::vector<std::vector<int> > >tmpi3;


  for(int k=0;k<num_readouts;k++){

  std::vector<std::vector<float> >tmpf2;
  std::vector<std::vector<int> >tmpi2;
  
  for(int j=0;j<6;j++){
    std::vector<float> tmpf;
    std::vector<int> tmpi;
    
    for (int i=0;i<256;i++){
      tmpf.push_back(eventGenerator->Gaus(0.00,0.002));
      tmpi.push_back(floor(eventGenerator->Gaus(2100.0,50.0)));
    }
    tmpf2.push_back(tmpf);
    tmpi2.push_back(tmpi);
  }

  tmpf3.push_back(tmpf2);
  tmpi3.push_back(tmpi2);
  }
  
  tmp->caldata=tmpf3;
  tmp->rawdata=tmpi3;
  
  m_data->elements.push_back(tmp);

  return true;

}
Пример #14
0
void plotDYUnfoldingMatrix(const TString input, int systematicsMode = DYTools::NORMAL, int randomSeed = 1, double reweightFsr = 1.0, double massLimit = -1.0)
//systematicsMode 0 (NORMAL) - no systematic calc
//1 (RESOLUTION_STUDY) - systematic due to smearing, 2 (FSR_STUDY) - systematics due to FSR, reweighting
//check mass spectra with reweightFsr = 0.95; 1.00; 1.05  
//mass value until which do reweighting
{

  // check whether it is a calculation
  if (input.Contains("_DebugRun_")) {
    std::cout << "plotDYUnfoldingMatrix: _DebugRun_ detected. Terminating the script\n";
    return;
  }

  // normal calculation

  gBenchmark->Start("plotDYUnfoldingMatrix");

  if (systematicsMode==DYTools::NORMAL)
    std::cout<<"Running script in the NORMAL mode"<<std::endl;
  else if (systematicsMode==DYTools::RESOLUTION_STUDY)
    std::cout<<"Running script in the RESOLUTION_STUDY mode"<<std::endl;
  else if (systematicsMode==DYTools::FSR_STUDY)
    std::cout<<"Running script in the FSR_STUDY mode"<<std::endl;
  else if (systematicsMode==DYTools::ESCALE_RESIDUAL) 
    std::cout << "Running script in the ESCALE_RESIDUAL mode\n";
  else { 
    std::cout<<"requested mode not recognized"<<std::endl;
    assert(0);
  }

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================
  
  Bool_t doSave  = false;    // save plots?
  TString format = "png";   // output file format
  int saveMadePlots = 1;  // whether save produced canvases
  
  vector<TString> fnamev;   // file names   
  vector<TString> labelv;   // legend label
  vector<Int_t>   colorv;   // color in plots
  vector<Int_t>   linev;    // line style
  vector<Double_t> xsecv;
  vector<Double_t> lumiv;
  TString          dirTag;

  ifstream ifs;
  ifs.open(input.Data());
  if (!ifs.is_open()) std::cout << "failed to open a file <" << input.Data() << ">\n";
  assert(ifs.is_open());
  string line;
  Int_t state=0;
  const int inputFileMayContainEScaleDefinition = 1;
  int expectEscaleLine=1;
  ElectronEnergyScale escale((inputFileMayContainEScaleDefinition) ? 
	  ElectronEnergyScale::UNDEFINED : // read electron energy scale from the file
	  ElectronEnergyScale::Date20120101_default);
  while(getline(ifs,line)) {
    if(line[0]=='#') continue;
    if(state == 0){
      dirTag = TString(line);
      state++;
      continue;
    }else{
      if (inputFileMayContainEScaleDefinition && expectEscaleLine) {
	expectEscaleLine=0;
	// try to determine whether the input file was updated
	if (ElectronEnergyScale::DetermineCalibrationSet(line.c_str()) !=
	    ElectronEnergyScale::UNDEFINED) {
	  //std::cout << "got it ok: <" << line << ">" << std::endl;
	  escale.init(TString(line.c_str()));
	  if (!escale.isInitialized()) {
	    std::cout << "code error\n";
	    return;
	  }
	  // continue reading the file
	  getline(ifs,line);
	}
	else {
	  std::cout << "\n";
	  std::cout << "\n\tInput file does not contain electron energy scale. The expected file format:\n";
	  std::cout << "\tLine1: directory\n";
	  std::cout << "\tLine2: electron energy scale correction name (NEW from 2012 Jan 21)\n";
	  std::cout << "\tLine3: file_name.root xsect color linesty label\n";
	  std::cout << "using the default set\n\n";
	  escale.init("Date20120101_default");
	  if (!escale.isInitialized()) {
	    std::cout << "failed to correct the behavior\n";
	    return;
	  }
	}
	std::cout << "energy scale corrections: " << escale.calibrationSetName() << "\n";
      }
      string fname;
      Int_t color, linesty;
      stringstream ss(line);
      Double_t xsec;
      ss >> fname >> xsec >> color >> linesty;
      string label = line.substr(line.find('@')+1);
      fnamev.push_back(fname);
      labelv.push_back(label);
      colorv.push_back(color);
      linev.push_back(linesty);
      xsecv.push_back(xsec);
      lumiv.push_back(0);
    }
  }
  ifs.close();
  
  const Double_t kGAP_LOW  = 1.4442;
  const Double_t kGAP_HIGH = 1.566;


  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================


  TRandom random;
  // The random seeds are needed only if we are running this script in systematics mode
  int seed = randomSeed;
  random.SetSeed(seed);
  gRandom->SetSeed(seed);
  // In the case of systematic studies, generate an array of random offsets
  TVectorD shift(escale._nEtaBins); // this vector is outdated by the new features in the escale obj.class
  shift = 0;
  if(systematicsMode==DYTools::RESOLUTION_STUDY) {
    escale.randomizeSmearingWidth(seed);
    for(int i=0; i<escale._nEtaBins; i++)
      shift[i] = gRandom->Gaus(0,1);
  }

  // prepare tools for ESCALE_RESIDUAL
  TH1F *shapeWeights=NULL;
  if (systematicsMode==DYTools::ESCALE_RESIDUAL) {
    TString shapeFName=TString("../root_files/yields/") + dirTag + TString("/shape_weights.root");
    std::cout << "Obtaining shape_weights.root from <" << shapeFName << ">\n";
    TFile fshape(shapeFName);
    if (!fshape.IsOpen()) {
      std::cout << "failed to open a file <" << shapeFName << ">\n";
      throw 2;
    }
    shapeWeights = (TH1F*)fshape.Get("weights");
    shapeWeights->SetDirectory(0);
    dirTag += TString("_escale_residual");
    std::cout << "changing dirTag to <" << dirTag << ">\n";
  }

  //  
  // Set up histograms
  //
  vector<TH1F*> hZMassv;//, hZMass2v, hZPtv, hZPt2v, hZyv, hZPhiv;  
  
  char hname[100];
  for(UInt_t ifile = 0; ifile<fnamev.size(); ifile++) {
    sprintf(hname,"hZMass_%i",ifile); hZMassv.push_back(new TH1F(hname,"",500,0,1500)); hZMassv[ifile]->Sumw2();
  }

  TH1F *hMassDiff   = new TH1F("hMassDiff","", 100, -30, 30);
  TH1F *hMassDiffBB = new TH1F("hMassDiffBB","", 100, -30, 30);
  TH1F *hMassDiffEB = new TH1F("hMassDiffEB","", 100, -30, 30);
  TH1F *hMassDiffEE = new TH1F("hMassDiffEE","", 100, -30, 30);

  TH1F *hMassDiffV[DYTools::nMassBins];
  for(int i=0; i<DYTools::nMassBins; i++){
    sprintf(hname,"hMassDiffV_%d",i);
    hMassDiffV[i] = new TH1F(hname,"",100,-50,50);
  }

  // MC spectra for storage in ROOT file
  // The FSR of RECO means that this is the spectrum of generator-level
  // post-FSR mass for events that were actually reconstructed (i.e. includes
  // efficiency and acceptances losses)
  TVectorD yieldsMcFsrOfRec    (DYTools::nMassBins);
  TVectorD yieldsMcFsrOfRecErr (DYTools::nMassBins);
  TVectorD yieldsMcRec         (DYTools::nMassBins);
  TVectorD yieldsMcRecErr      (DYTools::nMassBins);
  yieldsMcFsrOfRec     = 0;
  yieldsMcFsrOfRecErr  = 0;
  yieldsMcRec          = 0;
  yieldsMcRecErr       = 0;
  // The yields at generator level with mass bins defined by post-FSR di-leptons
  TVectorD yieldsMcFsr    (DYTools::nMassBins);
  yieldsMcFsr          = 0;

  // Vectors for bin to bin corrections
  TVectorD DetCorrFactorNumerator  (DYTools::nMassBins);
  TVectorD DetCorrFactorDenominator(DYTools::nMassBins);
  TVectorD DetCorrFactor           (DYTools::nMassBins);
  TVectorD DetCorrFactorErrPos     (DYTools::nMassBins);
  TVectorD DetCorrFactorErrNeg     (DYTools::nMassBins);
  DetCorrFactorNumerator   = 0;
  DetCorrFactorDenominator = 0;
  DetCorrFactor            = 0;
  DetCorrFactorErrPos      = 0;
  DetCorrFactorErrNeg      = 0;
  
  // Matrices for unfolding
  TMatrixD DetMigration(DYTools::nMassBins, DYTools::nMassBins);
  TMatrixD DetResponse(DYTools::nMassBins, DYTools::nMassBins);
  TMatrixD DetResponseErrPos(DYTools::nMassBins, DYTools::nMassBins);
  TMatrixD DetResponseErrNeg(DYTools::nMassBins, DYTools::nMassBins);
  for(int i=0; i<DYTools::nMassBins; i++){
    for(int j=0; j<DYTools::nMassBins; j++){
      DetMigration(i,j) = 0;
      DetResponse(i,j) = 0;
      DetResponseErrPos(i,j) = 0;
      DetResponseErrNeg(i,j) = 0;
    }
  }

  //
  // Access samples and fill histograms
  //  
  TFile *infile=0;
  TTree *eventTree=0;  
    
  // Data structures to store info from TTrees
  mithep::TEventInfo    *info = new mithep::TEventInfo();
  mithep::TGenInfo *gen  = new mithep::TGenInfo();
  TClonesArray *dielectronArr = new TClonesArray("mithep::TDielectron");
  
  // loop over samples  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
  
    // Read input file
    cout << "Processing " << fnamev[ifile] << "..." << endl;
    infile = new TFile(fnamev[ifile]); 
    assert(infile);

    // Get the TTrees
    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);

    // Find weight for events for this file
    // The first file in the list comes with weight 1,
    // all subsequent ones are normalized to xsection and luminosity
    double xsec=xsecv[ifile];
    AdjustXSectionForSkim(infile,xsec,eventTree->GetEntries(),1);
    lumiv[ifile] = eventTree->GetEntries()/xsec;
    double scale = lumiv[0]/lumiv[ifile];
    cout << "       -> sample weight is " << scale << endl;

    // Set branch address to structures that will store the info  
    eventTree->SetBranchAddress("Info",&info);                TBranch *infoBr       = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("Gen",&gen);                  TBranch *genBr = eventTree->GetBranch("Gen");
    eventTree->SetBranchAddress("Dielectron",&dielectronArr); TBranch *dielectronBr = eventTree->GetBranch("Dielectron");
  
    // loop over events    
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
      //if (ientry>100000) break;

      genBr->GetEntry(ientry);
      infoBr->GetEntry(ientry);

      double reweight;
      if (systematicsMode!=DYTools::FSR_STUDY) reweight=1.0;
      else if (((gen->mass)-(gen->vmass))>massLimit) reweight=1.0;
      else reweight=reweightFsr;

      if (ientry<20) std::cout<<"reweight="<<reweight<<std::endl;


      // Use post-FSR generator level mass in unfolding
      int ibinFsr = DYTools::findMassBin(gen->mass);
      if(ibinFsr != -1 && ibinFsr < yieldsMcFsr.GetNoElements()){
         yieldsMcFsr[ibinFsr] += reweight * scale * gen->weight;
      }


      /*
      // For EPS2011 for both data and MC (starting from Summer11 production)
      // we use an OR of the twi triggers below. Both are unpresecaled.
      ULong_t eventTriggerBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL 
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL;
      ULong_t leadingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele1Obj
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele1Obj;
      ULong_t trailingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele2Obj
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele2Obj;
      */

      const bool isData=kFALSE;
      TriggerConstantSet constantsSet = Full2011DatasetTriggers; // Enum from TriggerSelection.hh
      TriggerSelection requiredTriggers(constantsSet, isData, info->runNum);
      ULong_t eventTriggerBit = requiredTriggers.getEventTriggerBit(info->runNum);
      ULong_t leadingTriggerObjectBit = requiredTriggers.getLeadingTriggerObjectBit(info->runNum);
      ULong_t trailingTriggerObjectBit = requiredTriggers.getTrailingTriggerObjectBit(info->runNum);

      
      if(!(info->triggerBits & eventTriggerBit)) continue;  // no trigger accept? Skip to next event...                                   

      // loop through dielectrons
      dielectronArr->Clear();
      dielectronBr->GetEntry(ientry);    
      for(Int_t i=0; i<dielectronArr->GetEntriesFast(); i++) {

        const mithep::TDielectron *dielectron = (mithep::TDielectron*)((*dielectronArr)[i]);
	
	// Apply selection
	// Eta cuts
        if((fabs(dielectron->scEta_1)>kGAP_LOW) && (fabs(dielectron->scEta_1)<kGAP_HIGH)) continue;
        if((fabs(dielectron->scEta_2)>kGAP_LOW) && (fabs(dielectron->scEta_2)<kGAP_HIGH)) continue;
	if((fabs(dielectron->scEta_1) > 2.5)       || (fabs(dielectron->scEta_2) > 2.5))       continue;  // outside eta range? Skip to next event...
	
	// Asymmetric SC Et cuts
	if( ! ( ( dielectron->scEt_1 > DYTools::etMinLead  && dielectron->scEt_2 > DYTools::etMinTrail)
		|| ( dielectron->scEt_1 > DYTools::etMinTrail  && dielectron->scEt_2 > DYTools::etMinLead) )) continue;
    	
	// Both electrons must match trigger objects. At least one ordering
	// must match
	if( ! ( 
	       (dielectron->hltMatchBits_1 & leadingTriggerObjectBit && 
		dielectron->hltMatchBits_2 & trailingTriggerObjectBit )
	       ||
	       (dielectron->hltMatchBits_1 & trailingTriggerObjectBit && 
		dielectron->hltMatchBits_2 & leadingTriggerObjectBit ) ) ) continue;
	
	// The Smurf electron ID package is the same as used in HWW analysis
	// and contains cuts like VBTF WP80 for pt>20, VBTF WP70 for pt<10
	// with some customization, plus impact parameter cuts dz and dxy
	if(!passSmurf(dielectron)) continue;  

        // We have a Z candidate! HURRAY! 

	// Apply extra smearing to MC reconstructed dielectron mass
	// to better resemble the data
	/*
	  outdated lines. kept for reference
	double smear1 = escale.extraSmearingSigma(dielectron->scEta_1);
        double smear2 = escale::extraSmearingSigma(dielectron->scEta_2);
	// In systematics mode, overwrite the smear values with
	// shifted ones.
	if(systematicsMode==DYTools::RESOLUTION_STUDY){
	  smear1 = escale::extraSmearingSigmaShifted(dielectron->scEta_1,shift);
	  smear2 = escale::extraSmearingSigmaShifted(dielectron->scEta_2,shift);
	}
        double smearTotal = sqrt(smear1*smear1 + smear2*smear2);
        double massResmeared = dielectron->mass + random.Gaus(0.0,smearTotal);
	*/
	/* lines based on new features -- begin */
	double massSmear = (systematicsMode == DYTools::RESOLUTION_STUDY) ?
	  escale.generateMCSmearRandomized(dielectron->scEta_1,dielectron->scEta_2) :
	  escale.generateMCSmear(dielectron->scEta_1,dielectron->scEta_2);
        double massResmeared = dielectron->mass + massSmear;
	/* lines based on new features -- end */

	hZMassv[ifile]->Fill(massResmeared,scale * gen->weight);

	// Fill structures for response matrix and bin by bin corrections

	if(ibinFsr != -1 && ibinFsr < yieldsMcFsrOfRec.GetNoElements()){
	    yieldsMcFsrOfRec[ibinFsr] += reweight * scale * gen->weight;
	    DetCorrFactorDenominator(ibinFsr) += reweight * scale * gen->weight;
          }

	else if(ibinFsr >= yieldsMcFsrOfRec.GetNoElements())
	  cout << "ERROR: binning problem" << endl;

	int ibinRec = DYTools::findMassBin(massResmeared);
	double shape_weight = (shapeWeights && (ibinRec!=-1)) ? 
	  shapeWeights->GetBinContent(ibinRec+1) : 1.0;
	if(ibinRec != -1 && ibinRec < yieldsMcRec.GetNoElements()){
	    yieldsMcRec[ibinRec] += reweight * scale * gen->weight;
	    DetCorrFactorNumerator(ibinRec) += reweight * scale * gen->weight * shape_weight;
          }

	else if(ibinRec >= yieldsMcRec.GetNoElements())
	  cout << "ERROR: binning problem" << endl;
	
	if( ibinRec != -1 && ibinRec < yieldsMcRec.GetNoElements() 
	    && ibinFsr != -1 && ibinFsr < yieldsMcRec.GetNoElements() ){
          DetMigration(ibinFsr,ibinRec) += reweight * scale * gen->weight * shape_weight;
	}
	
        Bool_t isB1 = (fabs(dielectron->scEta_1)<kGAP_LOW);
        Bool_t isB2 = (fabs(dielectron->scEta_2)<kGAP_LOW);         
	hMassDiff->Fill(massResmeared - gen->mass);
	if( isB1 && isB2 )
	  hMassDiffBB->Fill(massResmeared - gen->mass);
	if( (isB1 && !isB2) || (!isB1 && isB2) )
	  hMassDiffEB->Fill(massResmeared - gen->mass);
	if( !isB1 && !isB2 )
	  hMassDiffEE->Fill(massResmeared - gen->mass);
	
	if(ibinFsr != -1){
	  hMassDiffV[ibinFsr]->Fill(massResmeared - gen->mass);
	}
// 	if(ibinRec == -1)
// 	  printf("Missed bin:  M_fsr=%f   M_reco=%f\n", gen->mass, massResmeared);
	
      } // end loop over dielectrons

    } // end loop over events 
    delete infile;
    infile=0, eventTree=0;
  } // end loop over files
  delete gen;


  //finish reweighting of mass spectra

  
  // Find bin by bin corrections and the errors
  double tCentral, tErrNeg, tErrPos;
  for(int i=0; i<DYTools::nMassBins; i++){
    if ( DetCorrFactorDenominator(i) != 0 ){
      // This method does not take into account correlation between numerator
      // and denominator in calculation of errors. This is a flaw to be corrected
      // in the future.
      SimpleDivide( DetCorrFactorNumerator(i), DetCorrFactorDenominator(i), tCentral, tErrNeg, tErrPos);
      DetCorrFactor(i) = tCentral;
      DetCorrFactorErrPos(i) = tErrPos;
      DetCorrFactorErrNeg(i) = tErrNeg;
    } else {
      DetCorrFactor(i) = 0;
      DetCorrFactorErrPos(i) = 0;
      DetCorrFactorErrNeg(i) = 0;
    }
  }
  
  // Find response matrix, which is simply the normalized migration matrix
  for(int ifsr = 0; ifsr < DetMigration.GetNrows(); ifsr++){
    double nEventsInFsrMassBin = 0;
    for(int ireco = 0; ireco < DetMigration.GetNcols(); ireco++)
      nEventsInFsrMassBin += DetMigration(ifsr,ireco);
    // Now normalize each element and find errors
    for(int ireco = 0; ireco < DetMigration.GetNcols(); ireco++){
      tCentral = 0;
      tErrPos  = 0;
      tErrNeg  = 0;
      // Note: the event counts supposedly are dominated with events with weight "1"
      // coming from the primary MC sample, so the error is assumed Poissonian in
      // the call for efficiency-calculating function below.
      if( nEventsInFsrMassBin != 0 ){
	EfficiencyDivide(DetMigration(ifsr,ireco), nEventsInFsrMassBin, tCentral, tErrNeg, tErrPos);
      // BayesEfficiency does not seem to be working in newer ROOT versions, 
      // so it is replaced by simler method
//         BayesEfficiency( DetMigration(ifsr,ireco), nEventsInFsrMassBin, tCentral, tErrNeg, tErrPos);
      }
      DetResponse      (ifsr,ireco) = tCentral;
      DetResponseErrPos(ifsr,ireco) = tErrPos;
      DetResponseErrNeg(ifsr,ireco) = tErrNeg;
    }
  }

  // Find inverted response matrix
  TMatrixD DetInvertedResponse = DetResponse;
  Double_t det;
  DetInvertedResponse.Invert(&det);
  TMatrixD DetInvertedResponseErr(DetInvertedResponse.GetNrows(), DetInvertedResponse.GetNcols());
  calculateInvertedMatrixErrors(DetResponse, DetResponseErrPos, DetResponseErrNeg, DetInvertedResponseErr);

  // Package bin limits into TVectorD for storing in a file
  TVectorD BinLimitsArray(DYTools::nMassBins+1);
  for(int i=0; i<DYTools::nMassBins+1; i++)
    BinLimitsArray(i) = DYTools::massBinLimits[i];

  // Store constants in the file
  TString outputDir(TString("../root_files/constants/")+dirTag);
  if((systematicsMode==DYTools::RESOLUTION_STUDY) || (systematicsMode==DYTools::FSR_STUDY))
    outputDir = TString("../root_files/systematics/")+dirTag;
  gSystem->mkdir(outputDir,kTRUE);
  TString unfoldingConstFileName(outputDir+TString("/unfolding_constants.root"));
  if(systematicsMode==DYTools::RESOLUTION_STUDY){
    unfoldingConstFileName = outputDir+TString("/unfolding_constants_seed_");
    unfoldingConstFileName += seed;
    unfoldingConstFileName += ".root";
  }
  if(systematicsMode==DYTools::FSR_STUDY){
    unfoldingConstFileName = outputDir+TString("/unfolding_constants_reweight_");
    unfoldingConstFileName += int(100*reweightFsr);
    unfoldingConstFileName += ".root";
  }

  TFile fConst(unfoldingConstFileName, "recreate" );
  DetResponse             .Write("DetResponse");
  DetInvertedResponse     .Write("DetInvertedResponse");
  DetInvertedResponseErr  .Write("DetInvertedResponseErr");
  BinLimitsArray          .Write("BinLimitsArray");
  DetCorrFactor           .Write("DetCorrFactor");
  DetCorrFactorErrPos     .Write("DetCorrFactorErrPos");
  DetCorrFactorErrNeg     .Write("DetCorrFactorErrNeg");
  fConst.Close();
  
  // Store reference MC arrays in a file
  TString refFileName(outputDir+TString("/yields_MC_unfolding_reference.root"));
  TFile fRef(refFileName, "recreate" );
  BinLimitsArray    .Write("BinLimitsArray");
  yieldsMcFsr       .Write("yieldsMcFsr");
  yieldsMcFsrOfRec  .Write("yieldsMcFsrOfRec");
  yieldsMcRec       .Write("yieldsMcRec");
  fRef.Close();


  //--------------------------------------------------------------------------------------------------------------
  // Make plots 
  //==============================================================================================================  

  std::vector<TCanvas*> canvasV; // holder for a quick saver
  canvasV.reserve(10);

  TCanvas *c = MakeCanvas("zMass1","zMass1",800,600);
  canvasV.push_back(c);

  // string buffers
  char ylabel[50];   // y-axis label

  // Z mass
  sprintf(ylabel,"a.u. / %.1f GeV/c^{2}",hZMassv[0]->GetBinWidth(1));
  CPlot plotZMass1("zmass1","","m(ee) [GeV/c^{2}]",ylabel);
  if (fnamev.size()) hZMassv[0]->GetXaxis()->SetLimits(10.,2000.);
  for(UInt_t i=0; i<fnamev.size(); i++) { 
    plotZMass1.AddHist1D(hZMassv[i],labelv[i],"hist",colorv[i],linev[i]); 
  }
  plotZMass1.SetLogy();
  plotZMass1.SetLogx(); 
  plotZMass1.TransLegend(0.02, 0.0);
  plotZMass1.Draw(c,doSave,format);

  // Create plots of how reco mass looks and how unfolded mass should look like
  TVectorD massBinCentral     (DYTools::nMassBins);
  TVectorD massBinHalfWidth   (DYTools::nMassBins);
  TVectorD yieldMcFsrOfRecErr (DYTools::nMassBins);
  TVectorD yieldMcRecErr      (DYTools::nMassBins);
  for(int i=0; i < DYTools::nMassBins; i++){
    massBinCentral  (i) = (DYTools::massBinLimits[i+1] + DYTools::massBinLimits[i])/2.0;
    massBinHalfWidth(i) = (DYTools::massBinLimits[i+1] - DYTools::massBinLimits[i])/2.0;
    yieldsMcFsrOfRecErr(i) = sqrt(yieldsMcFsrOfRec[i]);
    yieldsMcRecErr     (i) = sqrt(yieldsMcRec[i]);
  }
  TGraphErrors *grFsrOfRec = new TGraphErrors(massBinCentral, yieldsMcFsrOfRec, 
					      massBinHalfWidth, yieldsMcFsrOfRecErr);
  TGraphErrors *grRec      = new TGraphErrors(massBinCentral, yieldsMcRec, 
					      massBinHalfWidth, yieldsMcRecErr);
  TCanvas *d = MakeCanvas("zMass2","zMass2",800,600);
  canvasV.push_back(d);
  CPlot plotZMass2("zmass2","","m(ee) [GeV/c^{2}]","events");
  plotZMass2.SetLogx(1);
  plotZMass2.AddGraph(grFsrOfRec,"no detector effects","PE",kBlack);
  plotZMass2.AddGraph(grRec,"reconstructed","PE",kBlue);
  plotZMass2.Draw(d);

//   double xsize = 600;
//   double ysize = 600;
  int xsize = 600;
  int ysize = 400;

  // Create the plot of the response matrix
  TH2F *hResponse = new TH2F("hResponse","",DYTools::nMassBins, DYTools::massBinLimits,
			     DYTools::nMassBins, DYTools::massBinLimits);
  for(int i=1; i<=DYTools::nMassBins; i++)
    for(int j=1; j<=DYTools::nMassBins; j++)
      hResponse->SetBinContent(i,j,DetResponse(i-1,j-1));
  TCanvas *e = MakeCanvas("response","response",xsize,ysize);
  canvasV.push_back(e);
  CPlot plotResponse("response","",
		     "generator post-FSR m(ee) [GeV/c^{2}]",
		     "reconstructed  m(ee) [GeV/c^{2}]");
  plotResponse.AddHist2D(hResponse,"COLZ");
  e->cd();
  plotResponse.SetLogx();
  plotResponse.SetLogy();
  gPad->SetRightMargin(0.15);
  gStyle->SetPalette(1);
  hResponse->GetXaxis()->SetMoreLogLabels();
  hResponse->GetXaxis()->SetNoExponent();
  hResponse->GetYaxis()->SetNoExponent();
  plotResponse.Draw(e);

  // Create the plot of the inverted response matrix
  TH2F *hInvResponse = new TH2F("hInvResponse","",DYTools::nMassBins, DYTools::massBinLimits,
			     DYTools::nMassBins, DYTools::massBinLimits);
  for(int i=1; i<=DYTools::nMassBins; i++)
    for(int j=1; j<=DYTools::nMassBins; j++)
      hInvResponse->SetBinContent(i,j,DetInvertedResponse(i-1,j-1));
  TCanvas *f = MakeCanvas("invResponse","invResponse",xsize,ysize);
  canvasV.push_back(f);
  CPlot plotInvResponse("inverted response","",
			"reconstructed  m(ee) [GeV/c^{2}]",
			"generator post-FSR m(ee) [GeV/c^{2}]");
  plotInvResponse.AddHist2D(hInvResponse,"COLZ");
  f->cd();
  plotInvResponse.SetLogx();
  plotInvResponse.SetLogy();
  gPad->SetRightMargin(0.15);
  gStyle->SetPalette(1);
  hInvResponse->GetXaxis()->SetMoreLogLabels();
  hInvResponse->GetXaxis()->SetNoExponent();
  hInvResponse->GetYaxis()->SetNoExponent();
  plotInvResponse.Draw(f);

  // Create a plot of detector resolution without mass binning
  TCanvas *g = MakeCanvas("massDiff","massDiff",600,600);
  canvasV.push_back(g);
  CPlot plotMassDiff("massDiff","","reco mass - gen post-FSR mass [GeV/c^{2}]","a.u.");
  hMassDiffBB->Scale(1.0/hMassDiffBB->GetSumOfWeights());
  hMassDiffEB->Scale(1.0/hMassDiffEB->GetSumOfWeights());
  hMassDiffEE->Scale(1.0/hMassDiffEE->GetSumOfWeights());
  plotMassDiff.AddHist1D(hMassDiffBB,"EB-EB","hist",kBlack);
  plotMassDiff.AddHist1D(hMassDiffEB,"EE-EB","hist",kBlue);
  plotMassDiff.AddHist1D(hMassDiffEE,"EE-EE","hist",kRed);
  plotMassDiff.TransLegend(0.1, 0.0);
  plotMassDiff.Draw(g);



  // Create a plot of reco - gen post-FSR mass difference for several mass bins
  TCanvas *h = MakeCanvas("massDiffV","massDiffV",600,600);
  canvasV.push_back(h);
  CPlot plotMassDiffV("massDiffV","","reco mass - gen post-FSR mass [GeV/c^{2}]","a.u.");
  hMassDiffV[7]->Scale(1.0/hMassDiffV[7]->GetSumOfWeights());
  hMassDiffV[6]->Scale(1.0/hMassDiffV[6]->GetSumOfWeights());
  hMassDiffV[5]->Scale(1.0/hMassDiffV[5]->GetSumOfWeights());
  hMassDiffV[4]->Scale(1.0/hMassDiffV[4]->GetSumOfWeights());
  plotMassDiffV.AddHist1D(hMassDiffV[4],"50-60 GeV/c^{2}","hist",kBlack);
  plotMassDiffV.AddHist1D(hMassDiffV[5],"60-76 GeV/c^{2}","hist",kBlue);
  plotMassDiffV.AddHist1D(hMassDiffV[6],"76-86 GeV/c^{2}","hist",kRed);
  plotMassDiffV.AddHist1D(hMassDiffV[7],"86-96 GeV/c^{2}","hist",kMagenta);
  plotMassDiffV.SetXRange(-20,50);
  plotMassDiffV.Draw(h);

  // Create graph of bin-to-bin corrections
  TGraphAsymmErrors *grCorrFactor 
    = new TGraphAsymmErrors(massBinCentral, DetCorrFactor,
			    massBinHalfWidth, massBinHalfWidth,
			    DetCorrFactorErrNeg, DetCorrFactorErrPos);
  TCanvas *c11 = MakeCanvas("corrFactor","corrFactor",800,600);
  canvasV.push_back(c11);
  CPlot plotCorrFactor("corrFactor","","m(ee) [GeV/c^{2}]","correction factor");
  plotCorrFactor.AddGraph(grCorrFactor,"PE",kBlue);
  plotCorrFactor.SetLogx();
  plotCorrFactor.SetYRange(0,2.0);
  plotCorrFactor.Draw(c11);

  if (saveMadePlots) {
    TString plotPath=TString("../root_files/plots/") + dirTag; 
    TString name=plotPath + TString("/unfolding_plots.root");
    gSystem->mkdir(plotPath,true);
    TFile* fplots = TFile::Open(name,"RECREATE");
    for (unsigned int i=0; i<canvasV.size(); ++i) {
      canvasV[i]->Write();
    }
    fplots->Close();
  }

  //--------------------------------------------------------------------------------------------------------------
  // Summary print out
  //==============================================================================================================
  cout << endl;
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl; 
  
  // Printout of all constants, uncomment if needed

  //printf("DetMigration:\n"); DetMigration.Print();
  //printf("DetResponse:\n"); DetResponse.Print();
  //printf("DetInvertedResponse:\n"); DetInvertedResponse.Print();

//   DetCorrFactor.Print();
//   DetResponse.Print();
  
//   printf("Detector corr factor numerator:\n");
//   DetCorrFactorNumerator.Print();
//   printf("yieldsMcRec:\n");
//   yieldsMcRec.Print();

//   printf("Detector corr factor denominator:\n");
//   DetCorrFactorDenominator.Print();
//   printf("yieldsMcFsrOfRec:\n");
//   yieldsMcFsrOfRec.Print();

  gBenchmark->Show("plotDYUnfoldingMatrix");
}
Пример #15
0
int main(int argc, char *argv[])
{
    TRandom rng;
    rng.SetSeed(2014);
    hxx_tree data;

    std::string opt, infile, outroot, outdir;
    koptions options(argc, argv);

    //check for the --help option:
    if ( options.find("--help") ) {
        usage();
    }
    //options.set("--seed=", seed);
    //if (seed > 0) rng.SetSeed(seed);
    double met_smear = 30.0;
    options.set("--met_smear=", met_smear);
    int    num_smear = 1;
    options.set("--num_smear=", num_smear);
    double fake_rate = 0.0;
    options.set("--fake_rate=", fake_rate);
    int mode_8tev = options.find("--8tev");
    int pub_plots = options.find("--pub_plots");



    double lumi = 300;
    double met_cut = 250.0;

    if (mode_8tev) {
        lumi = 20.0;
        met_cut = 250;
        cout << "INFO:  settings for sqrt(s) = 8 TeV\n";
    } else {
        cout << "INFO:  settings for sqrt(s) = 14 TeV\n";
    }
    cout << "INFO:  lumi:     " << lumi << "\n";
    cout << "INFO:  MET cut:  " << met_cut << "\n";

    //check for unrecognized options (beginning with -- or -)
    while(options.unrecognized_option(opt)) {
        cout << "WARNING: unrecognized option:" << opt << "\n";
        usage();
    }

    if (options.size() != 3) {
        usage();
    }

    options.shift_argument(infile);
    options.shift_argument(outroot);
    options.shift_argument(outdir);

    cout << "INFO: reading analysis tree file:    " << infile  << "\n";
    cout << "INFO: writing histogram root file:   " << outroot << "\n";
    cout << "INFO: writing results to directory:  " << outdir  << "\n";
    cout << "INFO: MET smearing amount is " << met_smear << "\n";
    cout << "INFO: MET smearing number is " << num_smear << "\n";
    cout << "INFO: W+jets fake rate is " << fake_rate << "\n";

    auto_write aw;

    cutflow_tool cutflow;
    histogram_manager h0mll(new TH1F("h0mll","",60,60.0,120.0));

    if (pub_plots) {
        h0mll.add_sample(1,  "_z");
        h0mll.add_sample(2,  "_h");
        h0mll.add_sample(3,  "_w");
        h0mll.add_sample(4,  "_top");

        cutflow.add_sample_name(1, "Z,ZZ,ZW");
        cutflow.add_sample_name(2, "Higgs");
        cutflow.add_sample_name(3, "W,WW");
        cutflow.add_sample_name(4, "tt");
    } else {
        h0mll.add_sample(1,  "_zjj");
        h0mll.add_sample(2,  "_zz_zw");
        h0mll.add_sample(3,  "_ww");
        h0mll.add_sample(4,  "_tt");
        h0mll.add_sample(5,  "_hzz");
        h0mll.add_sample(6,  "_zh");
        h0mll.add_sample(7,  "_wh");
        h0mll.add_sample(8,  "_wjjj");

        cutflow.add_sample_name(1, "Zjj");
        cutflow.add_sample_name(2, "ZZ,ZW");
        cutflow.add_sample_name(3, "WW");
        cutflow.add_sample_name(4, "tt");
        cutflow.add_sample_name(5, "HZZ");
        cutflow.add_sample_name(6, "ZH");
        cutflow.add_sample_name(7, "WH");
        cutflow.add_sample_name(8, "W+jets");
    }




    h0mll.add_sample(20,  "_hxx1");
    h0mll.add_sample(21,  "_hxx10");
    h0mll.add_sample(22,  "_hxx100");
    h0mll.add_sample(23,  "_hxx500");
    h0mll.add_sample(24,  "_hxx1000");

    cutflow.add_sample_name(20, "HXX1");
    cutflow.add_sample_name(21, "HXX10");
    cutflow.add_sample_name(22, "HXX100");
    cutflow.add_sample_name(23, "HXX500");
    cutflow.add_sample_name(24, "HXX1000");


    h0mll.add_sample(30,  "_hzp_100_1");
    h0mll.add_sample(31,  "_hzp_100_10");
    h0mll.add_sample(32,  "_hzp_100_100");
    h0mll.add_sample(33,  "_hzp_100_500");
    h0mll.add_sample(34,  "_hzp_100_1000");
    h0mll.add_sample(35,  "_hzp_1000_1");
    h0mll.add_sample(36,  "_hzp_1000_10");
    h0mll.add_sample(37,  "_hzp_1000_100");
    h0mll.add_sample(38,  "_hzp_1000_500");
    h0mll.add_sample(39,  "_hzp_1000_1000");

    cutflow.add_sample_name(30, "HZP_100_1");
    cutflow.add_sample_name(31, "HZP_100_10");
    cutflow.add_sample_name(32, "HZP_100_100");
    cutflow.add_sample_name(33, "HZP_100_500");
    cutflow.add_sample_name(34, "HZP_100_1000");
    cutflow.add_sample_name(35, "HZP_1000_1");
    cutflow.add_sample_name(36, "HZP_1000_10");
    cutflow.add_sample_name(37, "HZP_1000_100");
    cutflow.add_sample_name(38, "HZP_1000_500");
    cutflow.add_sample_name(39, "HZP_1000_1000");


    h0mll.add_sample(40,  "_hzpzp_100_1");
    h0mll.add_sample(41,  "_hzpzp_100_10");
    h0mll.add_sample(42,  "_hzpzp_100_100");
    h0mll.add_sample(43,  "_hzpzp_100_500");
    h0mll.add_sample(44,  "_hzpzp_100_1000");
    h0mll.add_sample(45,  "_hzpzp_1000_1");
    h0mll.add_sample(46,  "_hzpzp_1000_10");
    h0mll.add_sample(47,  "_hzpzp_1000_100");
    h0mll.add_sample(48,  "_hzpzp_1000_500");
    h0mll.add_sample(49,  "_hzpzp_1000_1000");

    cutflow.add_sample_name(40, "HZPZP_100_1");
    cutflow.add_sample_name(41, "HZPZP_100_10");
    cutflow.add_sample_name(42, "HZPZP_100_100");
    cutflow.add_sample_name(43, "HZPZP_100_500");
    cutflow.add_sample_name(44, "HZPZP_100_1000");
    cutflow.add_sample_name(45, "HZPZP_1000_1");
    cutflow.add_sample_name(46, "HZPZP_1000_10");
    cutflow.add_sample_name(47, "HZPZP_1000_100");
    cutflow.add_sample_name(48, "HZPZP_1000_500");
    cutflow.add_sample_name(49, "HZPZP_1000_1000");


    h0mll.add_auto_write(aw);


    TH1F hfit_bkg("sample_1","",  100,0.0,300.0);
    TH1F hfit_sig20("signal20","",  100,0.0,300.0);
    TH1F hfit_sig21("signal21","",  100,0.0,300.0);
    TH1F hfit_sig22("signal22","",  100,0.0,300.0);
    TH1F hfit_sig23("signal23","",  100,0.0,300.0);
    TH1F hfit_sig24("signal24","",  100,0.0,300.0);

    int    nsig = 0;
    double wsig = 0.0;
    hfit_bkg.Sumw2();
    hfit_sig20.Sumw2();
    hfit_sig21.Sumw2();
    hfit_sig22.Sumw2();
    hfit_sig23.Sumw2();
    hfit_sig24.Sumw2();

    //control plots (no pre-selection)
    histogram_manager hcnjet  (new TH1F("hcnjet",  "", 10,  0.0, 10.0),     h0mll, aw);
    histogram_manager hcmjjon (new TH1F("hcmjjon", "", 75,  0.0, 150.0),    h0mll, aw);
    histogram_manager hcmjjoff(new TH1F("hcmjjoff","", 100, 0.0, 500.0),    h0mll, aw);

    //test new variables
    histogram_manager htestx  (new TH1F("htestx",  "", 25,  0.0, 3.2),      h0mll, aw);
    histogram_manager htesty  (new TH1F("htesty",  "", 25,  0.0, 200.0),    h0mll, aw);

    //histograms at stage 0
    histogram_manager h0mjj   (new TH1F("h0mjj",   "", 100, 0.0,  500.0),   h0mll, aw);
    histogram_manager h0mlj   (new TH1F("h0mlj",   "", 100, 0.0,  500.0),   h0mll, aw);
    histogram_manager h0mlljj (new TH1F("h0mlljj", "", 100, 0.0,  500.0),  h0mll, aw);
    histogram_manager h0mllj  (new TH1F("h0mllj",  "", 100, 0.0,  500.0),   h0mll, aw);
    histogram_manager h0met   (new TH1F("h0met",   "", 100, 0.0,  300.0),   h0mll, aw);
    histogram_manager h0njet  (new TH1F("h0njet",  "", 10,  0.0,  10.0),    h0mll, aw);
    histogram_manager h0nbjet (new TH1F("h0nbjet", "", 8,   0.0,  8.0),     h0mll, aw);
    histogram_manager h0jdphi (new TH1F("h0jdphi", "", 100, 0.0,  3.2),     h0mll, aw);
    histogram_manager h0ptja  (new TH1F("h0ptja","", 32, 0.0,  300.0),   h0mll, aw);
    histogram_manager h0drlla (new TH1F("h0drlla","", 81,  0.0,  8.1),     h0mll, aw);
    histogram_manager h0drllb (new TH1F("h0drllb","", 81,  0.0,  8.1),     h0mll, aw);
    histogram_manager h0dphizz     (new TH1F("h0dphizz",     "", 32, 0.0, 3.2), h0mll, aw);
    histogram_manager h0dphizllmet (new TH1F("h0dphizllmet", "", 32, 0.0, 3.2), h0mll, aw);


    histogram_manager h0ht   (new TH1F("h0ht",    "", 100, 0.0, 500.0), h0mll, aw);
    histogram_manager h0l1pt (new TH1F("h0l1pt",  "", 100, 0.0, 300.0), h0mll, aw);
    histogram_manager h0l2pt (new TH1F("h0l2pt",  "", 100, 0.0, 300.0), h0mll, aw);
    histogram_manager h0j1pt (new TH1F("h0j1pt",  "", 100, 0.0, 300.0), h0mll, aw);
    histogram_manager h0j2pt (new TH1F("h0j2pt",  "", 100, 0.0, 300.0), h0mll, aw);

    histogram_manager h0l1eta(new TH1F("h0l1eta","", 60, -3.0, 3.0), h0mll, aw);
    histogram_manager h0l2eta(new TH1F("h0l2eta","", 60, -3.0, 3.0), h0mll, aw);
    histogram_manager h0j1eta(new TH1F("h0j1eta","", 60, -3.0, 3.0), h0mll, aw);
    histogram_manager h0j2eta(new TH1F("h0j2eta","", 60, -3.0, 3.0), h0mll, aw);

    //histograms at stage 1
    histogram_manager h1mll   (new TH1F("h1mll",   "", 60, 60.0,  120.0),   h0mll, aw);
    histogram_manager h1mjj   (new TH1F("h1mjj",   "", 100, 0.0,  500.0),   h0mll, aw);
    histogram_manager h1mlj   (new TH1F("h1mlj",   "", 100, 0.0,  500.0),   h0mll, aw);
    histogram_manager h1mlljj (new TH1F("h1mlljj", "", 100, 0.0,  500.0),  h0mll, aw);
    histogram_manager h1mllj  (new TH1F("h1mllj",  "", 100, 0.0,  500.0),   h0mll, aw);
    histogram_manager h1met   (new TH1F("h1met",   "", 100, 0.0,  300.0),   h0mll, aw);
    histogram_manager h1njet  (new TH1F("h1njet",  "", 10,  0.0,  10.0),    h0mll, aw);
    histogram_manager h1nbjet (new TH1F("h1nbjet", "", 8,   0.0,  8.0),     h0mll, aw);
    histogram_manager h1jdphi (new TH1F("h1jdphi", "", 100, 0.0,  3.2),     h0mll, aw);
    histogram_manager h1ptja  (new TH1F("h1ptja","", 100, 0.0,  300.0),   h0mll, aw);
    histogram_manager h1drlla (new TH1F("h1drlla","", 81,  0.0,  8.1),     h0mll, aw);
    histogram_manager h1drllb (new TH1F("h1drllb","", 81,  0.0,  8.1),     h0mll, aw);
    histogram_manager h1dphizz     (new TH1F("h1dphizz",     "", 100, 0.0, 3.2), h0mll, aw);
    histogram_manager h1dphizllmet (new TH1F("h1dphizllmet", "", 100, 0.0, 3.2), h0mll, aw);

    cout << "INFO: opening file: " << infile << "\n";

    TFile * file = new TFile(infile.c_str());
    TTree * tree = (TTree*) file->Get("hxxtree");

    if (! tree) {
        cout << "ERROR:  could not open tree.\n";
        exit(0);
    }

    data.ReadTree(tree);
    long int numberOfEntries = tree->GetEntries();

    //tree->Print();

    int count = 0;
    int nupdate = numberOfEntries / 20;
    if (nupdate < 1) nupdate=1;
    cout << "PROGRESS:  ";

    int prescale  = 0;
    int iprescale = 0;
    // Loop over all events
    for(Int_t entry = 0; entry < numberOfEntries; ++entry)
    {
        count++;
        if (count % nupdate == 0) {
            cout << ".";
            cout.flush();
        }

        if (iprescale < prescale) {
            iprescale++;
            continue;
        } else {
            iprescale = 0;
        }

        tree->GetEntry(entry);


        int num_smear_event = num_smear;
        if (data.sample == 1) {
            num_smear_event = num_smear * 10;
        }
        //if (data.sample == 4) {
        //num_smear_event = num_smear * 10;
        //}
        //if (data.sample == 3) {
        //num_smear_event = num_smear * 10;
        //}


        // First, apply W+jets fake rate if applicable:
        if (fake_rate > 0.0 && data.sample == 8) {
            apply_fake_rate(rng, data, fake_rate);
        }

        // remap sample id for publication plots:
        if (pub_plots) {
            switch (data.sample) {
            case 1:
                data.sample = 1;
                break;
            case 2:
                data.sample = 1;
                break;
            case 3:
                data.sample = 3;
                break;
            case 4:
                data.sample = 4;
                break;
            case 5:
                data.sample = 2;
                break;
            case 6:
                data.sample = 2;
                break;
            case 7:
                data.sample = 2;
                break;
            case 8:
                data.sample = 3;
                break;
            }
        }


        double mjjon;
        control_vars(data, mjjon);
        if (mjjon > 0.0) hcmjjon.Fill(data.sample, mjjon, data.weight);
        hcnjet.Fill(data.sample, data.jet_pt->size(), data.weight);


        //if (data.l1_pt < 12.0) continue;
        //if (data.l2_pt < 12.0) continue;

        if (data.l1_pt < 20.0) continue;
        if (data.l2_pt < 15.0) continue;

        // prune jet list according to analysis selection:
        for (int i=0; i<data.jet_pt->size(); i++) {
            int veto = 0;
            if (data.jet_pt->at(i) < 15.0) veto = 1;
            if (fabs(data.jet_eta->at(i)) > 2.5) veto = 1;
            if (veto) {
                data.erase_jet(i);
                i--;
            }
        }
        if (data.jet_pt->size() != data.jet_btag->size()) {
            cout << "ERROR:  Jet vectors out of sync.  Something is wrong.\n";
            exit(0);
        }

        int nbtag = 0;
        for (int i=0; i<data.jet_btag->size(); i++) {
            if (data.jet_btag->at(i)) nbtag++;
        }

        //preselection cuts:
        if (data.jet_pt->size() < 2) continue;
        if (data.nmuon + data.nelec > 2) continue;


        // checking 2-jet bin:
        //if (data.jet_pt->size() > 2) continue;

        cutflow.increment(0, data.sample, data.weight);


        double mlj, pt_ja, dr_lla, dr_llb, mjj, mjj_off, mllj, mlljj, dphi_zz, zll_phi, x, y;
        best_mlj(data, mlj);
        kinematic_vars(data, pt_ja, dr_lla, dr_llb, mjj, mjj_off, mllj, mlljj, dphi_zz, zll_phi, x, y);

        if (mjj_off > 0.0) {
            hcmjjoff.Fill(data.sample, mjj_off, data.weight);
        }

        // Here we smear the MET to account for pile-up effects:
        vector<double> met;
        vector<double> met_phi;
        vector<double> jet_dphi;
        vector<double> zllmet_dphi;

        // use reduced weight when looping over entire MET vector:
        double met_weight = (data.weight / (double) num_smear_event);
        double nopu_metx = data.nopu_met * cos(data.nopu_met_phi);
        double nopu_mety = data.nopu_met * sin(data.nopu_met_phi);

        for (int i=0; i<num_smear_event; i++) {
            double metx            = nopu_metx + rng.Gaus() * met_smear;
            double mety            = nopu_mety + rng.Gaus() * met_smear;
            double new_met         = sqrt(metx*metx + mety*mety);
            double new_met_phi     = atan2(mety, metx);
            int min_i;
            double new_jet_dphi    = min_delta_phi(new_met_phi, *data.jet_phi, min_i,-1,1);
            double new_zllmet_dphi = delta_phi(new_met_phi, zll_phi);
            met.push_back(new_met);
            met_phi.push_back(new_met_phi);
            jet_dphi.push_back(new_jet_dphi);
            zllmet_dphi.push_back(new_zllmet_dphi);
        }

        // high MET test:
        //if (data.nopu_met < 100.0) continue;

        h0mll.Fill(data.sample, data.mll, data.weight);




        if (data.jet_pt->size() > 0) {
            h0j1pt  .Fill(data.sample, data.jet_pt ->at(0), data.weight);
            h0j1eta .Fill(data.sample, data.jet_eta->at(0), data.weight);
        }
        if (data.jet_pt->size() > 1) {
            h0j2pt  .Fill(data.sample, data.jet_pt ->at(1), data.weight);
            h0j2eta .Fill(data.sample, data.jet_eta->at(1), data.weight);
        }
        h0l1pt  .Fill(data.sample, data.l1_pt,  data.weight);
        h0l1eta .Fill(data.sample, data.l1_eta, data.weight);
        h0l2pt  .Fill(data.sample, data.l2_pt,  data.weight);
        h0l2eta .Fill(data.sample, data.l2_eta, data.weight);

        h0njet.Fill(data.sample, data.jet_pt->size(), data.weight);
        h0nbjet.Fill(data.sample, nbtag, data.weight);

        h0mjj.Fill(data.sample, mjj, data.weight);
        h0mlj.Fill(data.sample, mlj, data.weight);
        h0mlljj.Fill(data.sample, mlljj, data.weight);
        h0mllj.Fill(data.sample, mllj, data.weight);
        h0ht.Fill(data.sample, data.ht, data.weight);
        h0dphizz .Fill(data.sample, dphi_zz, data.weight);

        h0ptja   .Fill(data.sample, pt_ja,  data.weight);
        h0drlla  .Fill(data.sample, dr_lla, data.weight);
        h0drllb  .Fill(data.sample, dr_llb, data.weight);




        htestx .Fill(data.sample, x);
        htesty .Fill(data.sample, y);

        for (int i=0; i<met.size(); i++) {
            h0met        .Fill(data.sample, met[i],          met_weight);
            h0jdphi      .Fill(data.sample, jet_dphi[i],     met_weight);
            h0dphizllmet .Fill(data.sample, zllmet_dphi[i] , met_weight);
        }



        // Z-peak:
        if (data.mll < 82)  continue;
        if (data.mll > 98) continue;
        cutflow.increment(1, data.sample, data.weight);
        if (mllj > 124.0)  continue;
        cutflow.increment(2, data.sample, data.weight);
        if (dphi_zz > 2.25)  continue;
        cutflow.increment(3, data.sample, data.weight);
        //if (mlj > 60.0)  continue;
        // These two cuts are applied in MET loop... 0 = no cut
        double jet_dphi_cut = 0.0;
        double zllmet_dphi_cut = 0.0;
        //if (mlj > 120.0)  continue;
        //






        h1njet.  Fill(data.sample, data.jet_pt->size(), data.weight);
        h1mll.   Fill(data.sample, data.mll,            data.weight);
        h1mjj.   Fill(data.sample, mjj,                 data.weight);
        h1mlj.   Fill(data.sample, mlj,                 data.weight);
        h1mlljj. Fill(data.sample, mlljj,               data.weight);
        h1mllj.  Fill(data.sample, mllj,                data.weight);
        h1ptja.  Fill(data.sample, pt_ja,  data.weight);
        h1drlla. Fill(data.sample, dr_lla, data.weight);
        h1drllb. Fill(data.sample, dr_llb, data.weight);


        for (int i=0; i<met.size(); i++) {
            double tmet =met[i];
            if (tmet > 299.0) tmet = 299.;

            h1jdphi .Fill(data.sample, jet_dphi[i], met_weight);
            h1dphizllmet .Fill(data.sample, zllmet_dphi[i] , met_weight);
            if (jet_dphi[i]   < jet_dphi_cut) continue; // APPEARS IN TWO PLACES
            if (zllmet_dphi[i] < zllmet_dphi_cut) continue; // APPEARS IN TWO PLACES
            h1met.Fill(data.sample, tmet, met_weight);
        }

        // fill limit setting histograms:
        for (int i=0; i<met.size(); i++) {
            if (met_weight > 100) {
                cout << "WARNING:  large weight at MET stage:  " << met_weight << "\n";
            }
            double tmet =met[i];
            if (tmet > 299.0) tmet = 299.;

            if (jet_dphi[i]   < jet_dphi_cut) continue; // APPEARS IN TWO PLACES
            if (zllmet_dphi[i] < zllmet_dphi_cut) continue; // APPEARS IN TWO PLACES
            if (data.sample < 20)  hfit_bkg.Fill(tmet, met_weight);
            if (data.sample == 20) hfit_sig20.Fill(tmet, met_weight);
            if (data.sample == 21) hfit_sig21.Fill(tmet, met_weight);
            if (data.sample == 22) hfit_sig22.Fill(tmet, met_weight);
            if (data.sample == 23) hfit_sig23.Fill(tmet, met_weight);
            if (data.sample == 24) hfit_sig24.Fill(tmet, met_weight);

            if (met[i] > met_cut)
                cutflow.increment(4, data.sample, met_weight);
        }
    }
    cout << "\n";

    cout << "SUMMARY:  read " << count << " of " << tree->GetEntries() << " events from analysis tree.\n";

    TFile * foutroot = new TFile(outroot.c_str(), "RECREATE");
    foutroot->cd();
    aw.WriteAll();
    foutroot->Close();

    //cout << "SUMMARY:  done writing files.\n";

    cout << "Cutflow:  Stage 0 (lljj preselection)\n";
    cutflow.print(0);

    cout << "Cutflow:  Stage 1 (mll cut)\n";
    cutflow.print(1);

    cout << "Cutflow:  Stage 2 (after mjj cut) \n";
    cutflow.print(2);

    cout << "Cutflow:  Stage 3 (after mjjll cut) \n";
    cutflow.print(3);

    cout << "Cutflow:  Stage 4 (after MET cut) \n";
    cutflow.print(4);

    cout << "Fit Histogram Summary:  \n";
    double SIGTOT = lumi * 149.8;
    hfit_sig20.Scale(1.0/SIGTOT);
    hfit_sig21.Scale(1.0/SIGTOT);
    hfit_sig22.Scale(1.0/SIGTOT);
    hfit_sig23.Scale(1.0/SIGTOT);
    hfit_sig24.Scale(1.0/SIGTOT);
    cout << " -> using total signal events of :    " << SIGTOT << "\n";
    cout << " -> background integral (evts):       " << hfit_bkg.GetSumOfWeights() << "\n";
    cout << " -> signal 1    integral (eff):       " << hfit_sig20.GetSumOfWeights() << "\n";
    cout << " -> signal 10   integral (eff):       " << hfit_sig21.GetSumOfWeights() << "\n";
    cout << " -> signal 100  integral (eff):       " << hfit_sig22.GetSumOfWeights() << "\n";
    cout << " -> signal 500  integral (eff):       " << hfit_sig23.GetSumOfWeights() << "\n";
    cout << " -> signal 1000 integral (eff):       " << hfit_sig24.GetSumOfWeights() << "\n";
    cout << " -> local count of signal events:     " << nsig << "\n";
    cout << " -> local integral of signal weight:  " << wsig << "\n";

    cout << " --> signal 1    sensitivity:  " << sensitivity(&hfit_sig20, &hfit_bkg, SIGTOT) << "\n";
    cout << " --> signal 10   sensitivity:  " << sensitivity(&hfit_sig21, &hfit_bkg, SIGTOT) << "\n";
    cout << " --> signal 100  sensitivity:  " << sensitivity(&hfit_sig22, &hfit_bkg, SIGTOT) << "\n";
    cout << " --> signal 500  sensitivity:  " << sensitivity(&hfit_sig23, &hfit_bkg, SIGTOT) << "\n";
    cout << " --> signal 1000 sensitivity:  " << sensitivity(&hfit_sig24, &hfit_bkg, SIGTOT) << "\n";

    char name[100];
    TFile * f = NULL;
    TH1F * h = NULL;

    sprintf(name, "%s/mchi1.root", outdir.c_str());
    f = new TFile(name, "RECREATE");
    f->cd();
    h = (TH1F *) hfit_sig20.Clone("signal");
    h->Write();
    hfit_bkg.Write();
    f->Close();

    sprintf(name, "%s/mchi10.root", outdir.c_str());
    f = new TFile(name, "RECREATE");
    f->cd();
    h = (TH1F *) hfit_sig21.Clone("signal");
    h->Write();
    hfit_bkg.Write();
    f->Close();

    sprintf(name, "%s/mchi100.root", outdir.c_str());
    f = new TFile(name, "RECREATE");
    f->cd();
    h = (TH1F *) hfit_sig22.Clone("signal");
    h->Write();
    hfit_bkg.Write();
    f->Close();

    sprintf(name, "%s/mchi500.root", outdir.c_str());
    f = new TFile(name, "RECREATE");
    f->cd();
    h = (TH1F *) hfit_sig23.Clone("signal");
    h->Write();
    hfit_bkg.Write();
    f->Close();

    sprintf(name, "%s/mchi1000.root", outdir.c_str());
    f = new TFile(name, "RECREATE");
    f->cd();
    h = (TH1F *) hfit_sig24.Clone("signal");
    h->Write();
    hfit_bkg.Write();
    f->Close();



}