Example #1
0
int main(int argc, char **argv) {
	setUpOnce();
	TStopwatch watch;

	watch.Start();
	ConfigFile config(argc, argv);
	setConfiguration(config);
	watch.Stop();

	cout << "Time to read configuration: " << watch.CpuTime() << "s" << endl;
	watch.Reset();

	watch.Start();

	boost::scoped_ptr<Analysis> myAnalysis(new Analysis(config.datasetInfoFile()));
	myAnalysis->setMaximalNumberOfEvents(Globals::maxEvents);

	vector<string> inputFiles = config.inputFiles();

	for (unsigned int index = 0; index < inputFiles.size(); ++index) {
		myAnalysis->addInputFile(inputFiles.at(index).c_str());
	}

	watch.Stop();
	cout << "Time to prepare analysis: " << watch.CpuTime() << "s" << endl;
	watch.Reset();

	cout << "starting analysis" << endl;
	watch.Start();
	//	ProfilerStart("BATProfile");
	myAnalysis->analyse();
	//	ProfilerStop();
	watch.Stop();
	double eventsPerMinute = myAnalysis->getNumberOfProccessedEvents() / (watch.CpuTime() / 60);
	cout << "Number of events processed per minute: " << eventsPerMinute << endl;
	watch.Print();
	watch.Reset();
	cout << "Finishing up analysis and writing histograms do disk (wait for \"Analysis finished\")" << endl;
	watch.Start();
	myAnalysis->finishAnalysis();
	watch.Stop();
	watch.Print();
	cout << "==========================================================" << endl;
	cout << "\t \t Analysis finished" << endl;
	cout << "==========================================================" << endl;
	return 0;
}
Example #2
0
int NeroMonteCarlo::analyze(const edm::Event& iEvent){

    if ( iEvent.isRealData() ) return 0;
    isRealData = iEvent.isRealData() ? 1 : 0 ; // private, not the one in the tree

    TStopwatch sw;
    if(VERBOSE)sw.Start();
    // maybe handle should be taken before
    iEvent.getByToken(info_token, info_handle);
    iEvent.getByToken(packed_token, packed_handle);
    iEvent.getByToken(pruned_token, pruned_handle);
    iEvent.getByToken(pu_token, pu_handle);
    iEvent.getByToken(jet_token, jet_handle);

    if ( not info_handle.isValid() ) cout<<"[NeroMonteCarlo]::[analyze]::[ERROR] info_handle is not valid"<<endl;
    if ( not packed_handle.isValid() ) cout<<"[NeroMonteCarlo]::[analyze]::[ERROR] packed_handle is not valid"<<endl;
    if ( not pruned_handle.isValid() ) cout<<"[NeroMonteCarlo]::[analyze]::[ERROR] pruned_handle is not valid"<<endl;
    if ( not pu_handle.isValid() ) cout<<"[NeroMonteCarlo]::[analyze]::[ERROR] pu_handle is not valid"<<endl;
    if ( not jet_handle.isValid() ) cout<<"[NeroMonteCarlo]::[analyze]::[ERROR] jet_handle is not valid"<<endl;

    if(VERBOSE){ sw.Stop() ; cout<<"[NeroMonteCarlo]::[analyze] getToken took "<<sw.CpuTime()<<" Cpu and "<<sw.RealTime()<<" RealTime"<<endl; sw.Reset(); sw.Start();}
    // INFO
    if(VERBOSE>1) cout<<"[NeroMonteCarlo]::[analyze]::[DEBUG] mcWeight="<<endl;
    mcWeight = info_handle -> weight();
    if(VERBOSE>1) cout<<"                                     mcWeight="<<mcWeight<<endl;
    //weights() 
    //---  scale
    if ( info_handle -> weights()  .size() >= 9){
        r1f2 = info_handle -> weights() [1] ;   
        r1f5 = info_handle -> weights() [2] ;   
        r2f1 = info_handle -> weights() [3] ;   
        r2f2 = info_handle -> weights() [4] ;   
        r5f1 = info_handle -> weights() [6] ;    
        r5f5 = info_handle -> weights() [8] ;     
    }

    if (info_handle -> weights().size() > 109)
        for( int pdfw = 9 ; pdfw<109 ;++pdfw)
        {
        pdfRwgt -> push_back( info_handle -> weights() [pdfw] );    
        }
    // --- fill pdf Weights
    //
    if(VERBOSE>1) cout<<"[NeroMonteCarlo]::[analyze]::[DEBUG] PDF="<<endl;
    if ( mParticleGun ) {
        qScale   = -999 ;
        alphaQED = -999 ;
        alphaQCD = -999 ;
        x1       = -999 ;
        x2       = -999 ;
        pdf1Id   = -999 ;
        pdf2Id   = -999 ;
        scalePdf = -999 ;
    }
    else {
        qScale   = info_handle -> qScale();
        alphaQED = info_handle -> alphaQED();
        alphaQCD = info_handle -> alphaQCD();
        x1       = info_handle -> pdf() -> x.first;
        x2       = info_handle -> pdf() -> x.second;
        pdf1Id   = info_handle -> pdf() -> id.first;
        pdf2Id   = info_handle -> pdf() -> id.second;
        scalePdf = info_handle -> pdf() -> scalePDF;
    }
    if(VERBOSE>1) cout<<"                                     PDF="<<qScale<<" "<< alphaQED<<endl;

    //PU
    if(VERBOSE>1){ cout<<endl<<"[NeroMonteCarlo]::[analyze] PU LOOP"<<endl;}
    puTrueInt = 0;
    for(const auto & pu : *pu_handle)
    {
        //Intime
        if (pu.getBunchCrossing() == 0)
            puTrueInt += pu.getTrueNumInteractions();
        //puInt += getPU_NumInteractions(); //old
        //Out-of-time
    }

    if(VERBOSE){ sw.Stop() ; cout<<"[NeroMonteCarlo]::[analyze] pu&info took "<<sw.CpuTime()<<" Cpu and "<<sw.RealTime()<<" RealTime"<<endl; sw.Reset(); sw.Start();}
    // GEN PARTICLES
    //TLorentzVector genmet(0,0,0,0);
    //for ( auto & gen : *packed_handle)
    for ( unsigned int i=0;i < packed_handle->size() ;++i)
    {
        const auto gen  = & (*packed_handle)[i];
        if (gen->pt()  < 5 ) continue;
        if (gen->pt() < mMinGenParticlePt ) continue;
        int pdg = gen->pdgId();
        int apdg = abs(pdg);

        //neutrinos
        // --- if ( (apdg != 12 and apdg !=14 and apdg != 16
        // ---       and apdg > 1000000  neutrinos and neutralinos
        // ---      )//SUSY
        // ---         and fabs(gen->eta() ) <4.7 
        // ---    )
        // --- { 
        // ---     TLorentzVector tmp( gen->px(),gen->py(),gen->pz(),gen->energy() ); 
        // ---     genmet += tmp;
        // --- }
        // --- genmet = -genmet;


        //FILL
        //    e mu photons
        if ( apdg == 11 or apdg == 13 or apdg == 22  // e - mu - gamma
                or (apdg >=12 and apdg<=16) // neutrinos
                or apdg > 1000000  // susy neutrinos and neutralinos
            )
        {
            new ( (*p4)[p4->GetEntriesFast()]) TLorentzVector(gen->px(), gen->py(), gen->pz(), gen->energy());
            pdgId -> push_back( pdg );
            flags -> push_back( ComputeFlags( *gen ) );
            // compute ISOLATION
            float iso=0;
            float isoFx=0;

            if (apdg == 22 or apdg ==11 or apdg ==13)
            {

                    TLorentzVector g1(gen->px(),gen->py(),gen->pz(),gen->energy());
                    vector< pair<float,float> > inIsoFx ; //isoFx, dR, pT
                    for ( unsigned int j=0;j < packed_handle->size() ;++j)
                    {
                        if (i==j) continue;
                        const auto gen2  = & (*packed_handle)[j];
                        if ( gen2->pt() ==0 ) continue;
                        if (gen2->pz() > 10e8 ) continue; // inf
                        TLorentzVector g2(gen2->px(),gen2->py(),gen2->pz(),gen2->energy());
                        if (g2.DeltaR(g1) <0.4){
                            iso += g2.Pt();
                            // isoFx containes the epsilon 
                            inIsoFx.push_back( pair<float,float>(g2.DeltaR(g1) ,g2.Pt() ) );
                         }
                    }

                    if (apdg==22){ // ONLY for photon Frixione isolation
                        sort(inIsoFx.begin(), inIsoFx.end() );  // sort in DR, first entry

                        float sumEtFx=0;
                        for( const auto & p : inIsoFx )
                        {
                               const float& pt= p.second ;
                               const float& delta = p.first;
                               sumEtFx += pt / gen->pt(); // relative iso
                               if (delta == 0 ) continue; // guard
                               float isoCandidate = sumEtFx * TMath::Power(  (1. - TMath::Cos(0.4) ) / (1. - TMath::Cos(delta ) ), 2) ;// n=2
                               if (isoFx < isoCandidate) isoFx = isoCandidate;
                        }
                    }
            
            }
            genIso -> push_back(iso);
            genIsoFrixione -> push_back(isoFx);
            // computed dressed objects
            //

            if (apdg == 11 or apdg == 13) { // only for final state muons and electrons
                    TLorentzVector dressedLepton(gen->px(),gen->py(),gen->pz(),gen->energy());
                    TLorentzVector lepton(dressedLepton); //original lepton for dR
                    for ( unsigned int j=0;j < packed_handle->size() ;++j)
                    {
                        const auto gen2  = & (*packed_handle)[j];
                        TLorentzVector photon(gen2->px(),gen2->py(),gen2->pz(),gen2->energy());
                        if (i != j and abs( gen->pdgId() ) ==22  and lepton.DeltaR( photon ) <0.1 ) dressedLepton += photon;
                    }
                    new ( (*p4)[p4->GetEntriesFast()]) TLorentzVector( dressedLepton );
                    pdgId -> push_back( pdg );
                    flags -> push_back( Dressed );
                    genIso -> push_back (0.) ;
                    genIsoFrixione -> push_back (0.) ;
                    // --- end of dressing
            }
             
        }

    } //end packed


    if(VERBOSE){ sw.Stop() ; cout<<"[NeroMonteCarlo]::[analyze] packed took "<<sw.CpuTime()<<" Cpu and "<<sw.RealTime()<<" RealTime"<<endl; sw.Reset(); sw.Start();}
    // LOOP over PRUNED PARTICLES
    //for (auto & gen : *pruned_handle)
    for (unsigned int i=0;i<pruned_handle->size() ;++i)
    {
        const auto gen = &(*pruned_handle)[i];
        if (gen->pt()  < 5 ) continue;
        if (gen->pt()  < mMinGenParticlePt ) continue;
        int pdg = gen->pdgId();
        int apdg = abs(pdg);
        if (gen->status() == 1) continue; //packed

        unsigned flag = ComputeFlags(*gen);

    
        if ( apdg == 15 or  // tau (15)
                (apdg >= 23 and apdg <26 ) or   // Z(23) W(24) H(25)
                apdg == 37 or // chHiggs: H+(37)
                apdg <= 6 or // quarks up (2) down (1)  charm (4) strange (3) top (6) bottom (5)
                apdg == 21 or // gluons (21)
                apdg > 1000000 // susy neutrinos,neutralinos, charginos ...  lightest neutralinos (1000022)
                or ( apdg == 11 and  ( flag &  HardProcessBeforeFSR) )
                or ( apdg == 11 and  ( flag &  HardProcess) )
                or ( apdg == 13 and  ( flag &  HardProcessBeforeFSR) )
                or ( apdg == 13 and  ( flag &  HardProcess) )
                )
        {
            new ( (*p4)[p4->GetEntriesFast()]) TLorentzVector(gen->px(), gen->py(), gen->pz(), gen->energy());
            pdgId -> push_back( pdg );
            flags -> push_back( flag );
            genIso -> push_back (0.) ;
            genIsoFrixione -> push_back (0.) ;
        }
    }

    if(VERBOSE){ sw.Stop() ; cout<<"[NeroMonteCarlo]::[analyze] pruned took "<<sw.CpuTime()<<" Cpu and "<<sw.RealTime()<<" RealTime"<<endl; sw.Reset(); sw.Start();}
    // GEN JETS
    for (const auto & j : *jet_handle)
    {
        if (j.pt() < 20 ) continue;
        if (j.pt() < mMinGenJetPt ) continue;
        // --- FILL
        new ( (*jetP4)[jetP4->GetEntriesFast()]) TLorentzVector(j.px(), j.py(), j.pz(), j.energy());
    }
    if(VERBOSE){ sw.Stop() ; cout<<"[NeroMonteCarlo]::[analyze] jets took "<<sw.CpuTime()<<" Cpu and "<<sw.RealTime()<<" RealTime"<<endl; sw.Reset();}
    return 0;
}
Example #3
0
File: Analyze.C Project: XuQiao/HI
void
Analyze(const TString mode="CLOSED",
        UShort_t       maxH=6,
        Bool_t         /*doLoops*/=false,
        Int_t ifile=0   )
{
#ifdef __CINT__
  gROOT->LoadMacro("correlations/Types.hh++");
  gROOT->LoadMacro("correlations/Result.hh++");
  gROOT->LoadMacro("correlations/QVector.hh++");
  gROOT->LoadMacro("correlations/recursive/FromQVector.hh++");
  gROOT->LoadMacro("correlations/recurrence/FromQVector.hh++");
  gROOT->LoadMacro("correlations/closed/FromQVector.hh++");
  gROOT->LoadMacro("correlations/test/ReadData.hh++");
#endif
  // --- Setup of harmonics, etc -------------------------------------
  gRandom->SetSeed(54321);
  UShort_t emode = 0;
  if      (mode.EqualTo("closed",     TString::kIgnoreCase)) emode = 0;
  else if (mode.EqualTo("recurrence", TString::kIgnoreCase)) emode = 1;
  else if (mode.EqualTo("recursive",  TString::kIgnoreCase)) emode = 2;
  else
    Warning("Analyze", "Mode %s unknown, assuming CLOSED", mode.Data());

  correlations::QVector        q[nbin];
  correlations::FromQVector*   c[nbin];
  correlations::HarmonicVector h(maxH);
  for (UShort_t i = 0; i < maxH; i++) {
    // Generate random harmonicx
   // h[i] = -6 + gRandom->Integer(12);
   h[0] = 2;
   h[1] = -2;
   h[2] = 2;
   h[3] = -2;
   h[4] = 2;
   h[5] = -2;
   h[6] = -2;
   h[7] = 2;
   // Printf("h_%d:\t%d", i, h[i]);
  }

  // Resize the Q-vector to fit the harmonics
    for(int ibin=0;ibin<nbin;ibin++){
    q[ibin] = correlations::QVector(0,0,false);
    q[ibin].resize(h);
  switch (emode) {
  case 0: c[ibin] = new correlations::closed::FromQVector(q[ibin]); break;
  case 1: c[ibin] = new correlations::recurrence::FromQVector(q[ibin]); break;
  case 2: c[ibin] = new correlations::recursive::FromQVector(q[ibin]); break;
    }
  }
  //Printf("Correlator: %s", c->name());


  // --- Some histograms ---------------------------------------------
  TH1* sumreals[nbin];
  TH1* sumimags[nbin];
  TH1* weights[nbin];
  TVectorD tottrk;
  TVectorD Nevent;
  tottrk.ResizeTo(nbin);
  tottrk.Zero();
  Nevent.ResizeTo(nbin);
  Nevent.Zero();

  //TH1*      reals  = new TH1D("reals", "Re(C{n})", maxH-2+1, 2+.5, maxH+1+.5);
  //TH1*      imags  = static_cast<TH1*>(reals->Clone("imags"));
    for(int ibin=0;ibin<nbin;ibin++){
  sumreals[ibin]  = new TH1D(Form("sumreals_%d",ibin), "Re(C{n})", maxH-2+1, 2+.5, maxH+1+.5);
  sumimags[ibin]  = static_cast<TH1*>(sumreals[ibin]->Clone(Form("sumimags_%d",ibin)));
  weights[ibin]  = static_cast<TH1*>(sumreals[ibin]->Clone(Form("weights_%d",ibin)));
    }
  TProfile* timing = new TProfile("timing", "Timing", maxH-2+1, 2+.5,maxH+1+.5);
  TH1*      hs     = new TH1I("harmonics", "Harmonics", maxH, 1.5, maxH+1.5);
  /*reals->SetFillColor(kGreen+1);
  reals->SetFillStyle(3001);
  reals->SetStats(0);
  imags->SetTitle("Im(C{n})");
  imags->SetFillColor(kBlue+1);
  imags->SetFillStyle(3001);
  imags->SetStats(0);
  timing->SetFillColor(kRed+1);
  timing->SetFillStyle(3001);
  timing->SetStats(0);
  hs->SetFillColor(kMagenta+1);
  hs->SetFillStyle(3001);
  hs->SetStats(0);*/
  for (UShort_t i = 0; i < maxH-1; i++) {
    TString label = TString::Format("C{%d}", i+2);
//    reals->GetXaxis()->SetBinLabel(i+1, label);
//    imags->GetXaxis()->SetBinLabel(i+1, label);
    timing->GetXaxis()->SetBinLabel(i+1, label);
    hs->GetXaxis()->SetBinLabel(i+1,Form("h_{%d}", i+1));
    hs->SetBinContent(i+1, h[i]);
  }
  hs->GetXaxis()->SetBinLabel(maxH,Form("h_{%d}", maxH));
  hs->SetBinContent(maxH, h[maxH-1]);

  TStopwatch timer;
 
  // --- Setup input ------------------------------------------------
  TFile*   file = TFile::Open(Form("%s/vndata_50k_%d.root",dir.Data(),ifile), "READ");
  TTree*   tree = static_cast<TTree*>(file->Get("tree"));
//  TArrayD  phis(0);
  Int_t M;
  Float_t phi[10000],pt[10000],eta[10000];
//  TArrayD  weights(0);
//  Double_t phiR = 0;
//  TArrayD* pPhis = &phis;
//  TArrayD* pWeights = &weights;
  tree->SetBranchAddress("phig", phi);
  tree->SetBranchAddress("ptg",pt);
  tree->SetBranchAddress("etag",eta);
  tree->SetBranchAddress("n", &M);
//  tree->SetBranchAddress("weight", &pWeights);
//  tree->SetBranchAddress("event", &phiR);


  // --- The results -------------------------------------------------
  const UShort_t             nQ = maxH - 1;
  correlations::ResultVector qs[nbin];
    for(int ibin=0;ibin<nbin;ibin++)
        qs[ibin] = correlations::ResultVector(nQ);

  // --- Event loop --------------------------------------------------
  Int_t nEvents = tree->GetEntries();
  for (Int_t event = 0; event < nEvents; event++) {
    tree->GetEntry(event);
    int ntrk = M; int xbin=-1;
    for(int j=0;j<nbin;j++)
        if(ntrk<trkbin[j]&&ntrk>=trkbin[j+1])
            xbin=j;
        if(xbin<0 || xbin==nbin) continue;
    tottrk[xbin]+=ntrk;
    q[xbin].reset();
 //   printf("Event # %4u  %4d particles ", event++, phis.GetSize());
    for (UShort_t pa = 0; pa < M; pa++){
	if(fabs(eta[pa])>etamax) continue;
        if(pt[pa]<ptmin||pt[pa]>ptmax) continue; //event selection
  //  phis.Set(n,pPhis);
      q[xbin].fill(phi[pa], 1.);
    }
    for (UShort_t i = 0; i < nQ; i++) {
      UShort_t n = i + 2;
   //   printf("%s%d", i == 0 ? "" : "..", n);
      timer.Reset();
      timer.Start();
      qs[xbin][i] += c[xbin]->calculate(n, h);
      timer.Stop();
      timing->Fill(n+.5, timer.RealTime());
    }

  //  printf(" done\n");
  Nevent[xbin]++;
  }
  file->Close();

    for(int ibin=0;ibin<nbin;ibin++){
  for (UShort_t i = 0; i < nQ; i++) {
 //   UShort_t iq = i+2;
 //   Double_t              t  = timing->GetBinContent(i+1);
 //   correlations::Complex rc = qs[i].eval();
   // Printf("QC{%2d}: %12g + %12gi  <t>: %10gs",
//	   iq, rc.real(), rc.imag(), t);
   // if(i==0)Printf("v2{%2d}: %3g\n",2,sqrt(qs[0].eval().real()));
   // if(i==2)Printf("v2{%2d}: %3g\n",4,TMath::Power(fabs(qs[2].eval().real()),1./4));
   // if(i==4)Printf("v2{%2d}: %3g\n",6,TMath::Power(fabs(qs[4].eval().real()),1./6));
    sumreals[ibin]->SetBinContent(i+1,qs[ibin][i]._sum.real());
    sumimags[ibin]->SetBinContent(i+1,qs[ibin][i]._sum.imag());
    weights[ibin]->SetBinContent(i+1,qs[ibin][i]._weights);
    //reals->SetBinContent(i+1, rc.real());
    //imags->SetBinContent(i+1, rc.imag());
  }
    }

/*
  TCanvas* can = new TCanvas("C", "C");
  can->SetTopMargin(0.15);
  can->SetBottomMargin(0.15);
  can->SetRightMargin(0.03);
  can->Divide(1,3, 0, 0);

  DrawInPad(can, 3, timing, true);
  DrawInPad(can, 1, reals);
  DrawInPad(can, 2, imags);

  can->cd(0);
  TLatex* ltx = new TLatex(0.5,0.995,c->name());
  ltx->SetNDC(true);
  ltx->SetTextAlign(23);
  ltx->SetTextSize(0.04);
  ltx->Draw();

  can->Modified();
  can->Update();
  can->cd();
*/
  TString out(mode);
  out.ToLower();
  file = TFile::Open(Form("%s/%s_%d.root",outdir.Data(),out.Data(),ifile), "RECREATE");
    for(int ibin=0;ibin<nbin;ibin++){
  sumimags[ibin]->Write();
  sumreals[ibin]->Write();
  weights[ibin]->Write();
    }
  Nevent.Write("Nevent");
  tottrk.Write("tottrk");
  timing->Write();
  hs->Write();
  file->Write();
  file->Close();
    for(int ibin=0;ibin<nbin;ibin++){
  delete sumimags[ibin];
  delete sumreals[ibin];
  delete weights[ibin];
    }
  delete timing;
  delete hs;
}
int main(int argc, char *argv[]) {

  /* Some CTRL-C interrupt handling stuff... */
  gotsignal = 0;
  signal(SIGINT, breakhandler);
  
  /* When not enough arguments, print the help information */
  if ( (argc<3) ) {
    PrintHelpInformation();
    exit(1);
  }
  
  /* Initialize analysis control flags to default values,
     then read in the command line arguments. */
  controlVariables *ctrl = new controlVariables();
  ctrl->Initialize();
  Int_t good2Go = ctrl->InterpretCommandLine(argc, argv);
  if (good2Go != 1) { exit(-1); }

  cout << endl;
  cout << "********************************************************" << endl;
  cout << endl;
  
  cout << endl;
  
  good2Go = ctrl->ReportRunFlags();
  if (good2Go != 1) { exit(-2); }
  
  cout << endl;

  TStopwatch timer;

  /* Declare and then initialize GRETINA variables, i.e. geometry
     stuff, and calibration parameters, etc. */
  counterVariables *cnt = new counterVariables();

  /* Initialize the GRETINA data structures. */

  /* And data arrays... */
  /* GRETINA */
  unsigned char gBuf[32*32*1024];

  FILE *inf = NULL;

  FILE *generalOut = NULL;
  
  /* Loop over each run given at the command line. */
  if (ctrl->fileType == "f") { ctrl->startRun = 0; argc = 1; } /* For specific file name, 
								  once through loop only. */

  for (Int_t mm = ctrl->startRun; mm<argc; mm++) {
    
    timer.Reset();
    timer.Start();
    
    cnt->ResetRunCounters();

    TString runNumber = argv[mm];
    cnt->runNum = atoi(argv[mm]);
    
    /* Figure out the filename, etc. */
    if (ctrl->fileType == "g") {
      ctrl->fileName = ctrl->directory + "/Run" + runNumber + "/Global.dat";
      ctrl->outfileName = "./ROOTFiles/Run" + runNumber + "wGH.root";
    } else if (ctrl->fileType == "f") {
      ctrl->outfileName = "./ROOTFiles/test-wGH.root";
    } else {
      cerr << "WHAT???" << endl;
      return 0;
    }

    cout << "********************************************************" << endl;
    cout << endl;

    /* Open the input data file... */
    if (ctrl->compressedFile) {
      ctrl->fileName = "zcat " + ctrl->fileName;
      if (ctrl->fileName.EndsWith(".gz")) { }
      else { ctrl->fileName = ctrl->fileName + ".gz"; }
      inf = popen(ctrl->fileName.Data(), "r");
    } else if (ctrl->compressedFileB) {
      ctrl->fileName = "bzcat " + ctrl->fileName;
      if (ctrl->fileName.EndsWith(".bz2")) { }
      else { ctrl->fileName = ctrl->fileName + ".bz2"; }
      inf = popen(ctrl->fileName.Data(), "r");
    } else {
      inf = fopen(ctrl->fileName.Data(), "r");
    }

    ctrl->outputON = 1;
    
    if (ctrl->outputON) {
      if (ctrl->outputName) {
	generalOut = fopen(ctrl->outputFileName.Data(), "wb");
      } else if (!ctrl->outputName) {
	ctrl->outputFileName = ctrl->fileName;
	if (ctrl->fileName.EndsWith(".bz2")) { 
	  ctrl->outputFileName.ReplaceAll(".dat.bz2","GH.dat");
	} else if (ctrl->fileName.EndsWith(".gz")) {
	  ctrl->outputFileName.ReplaceAll(".dat.gz","GH.dat");
	} else {
	  ctrl->outputFileName.ReplaceAll(".dat","GH.dat");
	}
	ctrl->outputFileName.ReplaceAll("zcat ", "");
	generalOut = fopen(ctrl->outputFileName.Data(), "wb");
      }
      if (!generalOut) {
	cout << "Could not open output file " << ctrl->outputFileName.Data() << endl;
	exit(2); 
      } else {
	cout << "Opened output file " << ctrl->outputFileName.Data() << endl;
      } 
    } else {
      generalOut = NULL;
    }
    
    /* Reset variables needed for unpacking, histogramming, etc. */
    cnt->ResetRunCounters();
    
    Int_t TSerrors = 0;
    long long int currTS = 0;  long long int lastTS = 0;
    
    Int_t remaining = 0;
    
    /********************************************************/
    /*  THE MAIN EVENT -- SORTING LOOP                      */
    /********************************************************/

    /* Loop over file, reading data, and building events... */
    while (!gotsignal) {

      if (ctrl->pgh == 2) {
	
	gHeader.type = DECOMP;
	remaining = GetGRETINA(inf, generalOut, gBuf, sizeof(gBuf), gHeader.type, 0, ctrl, cnt);
	gHeader.timestamp = gMode2.timestamp;

      } else if (ctrl->pgh == 3) {

	gHeader.type = RAW;
	remaining = GetGRETINA(inf, generalOut, gBuf, sizeof(gBuf), gHeader.type, 0, ctrl, cnt);
	gHeader.timestamp = gMode3.led_timestamp;

      }

      /* Check against timestamps in file being out of order... */
      if (gHeader.timestamp < lastTS) {
	if (!ctrl->suppressTS)
	  cout << "TS out of order : lastTS " << lastTS << " current " 
	       << gHeader.timestamp << endl;
	TSerrors++;
      }
      lastTS = gHeader.timestamp;
	
      if ( (gHeader.timestamp != 0) && (currTS == 0) ) {
	currTS = gHeader.timestamp;
      }
      
      if (cnt->bytes_read_since_last_time > 2*1024*1024) {    
	cerr << "Processing " << cnt->bytes_read/(1024*1024) << " MB" <<"\r";
	cnt->MBread+=2;
	cnt->bytes_read_since_last_time = 0;
      }
      
      /**********************************************************/
      /* More GRETINA information before another global header. */
      /**********************************************************/
      while (remaining && !gotsignal) { 

	remaining = GetGRETINA(inf, generalOut, gBuf, sizeof(gBuf), gHeader.type, 
			       remaining, ctrl, cnt);
	if (ctrl->pgh == 2) { gHeader.timestamp = gMode2.timestamp; }
	else if (ctrl->pgh == 3) { gHeader.timestamp = gMode3.led_timestamp; }

	if (cnt->bytes_read_since_last_time > 2*1024*1024) {    
	  cerr << "Processing " << cnt->bytes_read/(1024*1024) << " MB" << "\r";
	  cnt->MBread+=2;
	  cnt->bytes_read_since_last_time = 0;
	}
      } /* end of ' while (remaining) ' */

    } /* End of "while we still have data and no interrupt signal" */
    
    timer.Stop();
    
    cout << "\n CPU time: " << timer.CpuTime() << "\tReal time: " << timer.RealTime() << endl;
    cout << " Average processing speed: " << (cnt->bytes_read/(1024*1024))/timer.RealTime() 
	 << "MB/s -- File size was " << cnt->bytes_read/(1024*1024) << " MB \n" << endl;
    
    cnt->PrintRunStatistics(ctrl->pgh, ctrl->withWAVE, ctrl->superPulse, ctrl->analyze2AND3);
    cnt->ResetRunCounters();

  } /* End of iterating over different run # */

  if (ctrl->outputON) {
    cout << endl;
    cout << "Closing output file...";
    fclose(generalOut);
    cout << "Done. " << endl;    
  }
  
  /* Declare victory!!! */
  
  cout << endl;
  timer.Delete();
  cout << "We finished without crashing!! Yay us! :)" << endl;
  cout << endl;

  return 1;
}
Int_t dieleAna(TString inputlist, TString outfile, Int_t nev=-1, Int_t whichweight = 0)
{

    TH1::SetDefaultSumw2();
    TH3F *p3DEffEle[6][NWEIGHTS+1]; // mult bins, MLP weights + HC
    TH3F *p3DEffPos[6][NWEIGHTS+1];
    TH3F *p3DAccEle[6][NWEIGHTS+1];
    TH3F *p3DAccPos[6][NWEIGHTS+1];
    readAccEffMatrices(p3DAccEle, p3DAccPos, p3DEffEle, p3DEffPos);
    TH2F *smear_ele, *smear_pos;
    TFile *file_smear = new TFile("smearing_matrix.root","read");
    smear_ele = (TH2F*)file_smear->Get("smear_ele");
    smear_pos = (TH2F*)file_smear->Get("smear_pos");

    TRandom random;

/*
    TFile *pEffFile;

    pEffFile = new TFile("Input/EffMatrixMVA2RefAccNewCP_100Mio.root");
    if (pEffFile)
    {
	pEffFile->cd();
	for(Int_t i = 0 ; i < 5 ; i++){
            p3DEffEle[i][6] = (TH3F*) pEffFile->Get(Form("hHistEff3DMult%iNeg",i));
            p3DEffPos[i][6] = (TH3F*) pEffFile->Get(Form("hHistEff3DMult%iPos",i));
     //       p3DEffEle[i] = (TH3F*) pEffFile->Get("hHistEff3DNeg");
      //      p3DEffPos[i] = (TH3F*) pEffFile->Get("hHistEff3DPos");
        }
    }
    else
    {
	Error("DrawFromNtuple constructor","pointer to eff matrix file is NULL");
	for(Int_t i = 0 ; i < 5 ; i++){
	    p3DEffEle[i][6] = NULL;
	    p3DEffPos[i][6] = NULL;
        }
    }
*/

    TH1F *pEventClass;
    TH1F *pEventClass_recur;
    TFile *pEventClassFile;
//    pEventClassFile = new TFile("eventClass_mult_nonempty_4secmult_200fpj_wait.root");
//    pEventClassFile = new TFile("eventClass_target_mult_rplane_nonempty_4secmult.root");
    pEventClassFile = new TFile("eventClass_target_mult_rplane_minmom_nmix_w6.root");
    if (pEventClassFile) {
        pEventClass = (TH1F*)pEventClassFile->Get("eventClass");
        pEventClass_recur = (TH1F*)pEventClassFile->Get("eventClass_recur");
        if (pEventClass == NULL || pEventClass_recur == NULL) {
            Error("DrawFromNtuple constructor","Histogram not found in the event class file");
            exit (-1);
        }
    }    
    else {
        Error("DrawFromNtuple constructor","Event class file not found");
        exit (-1);
    }
    HLoop* loop = new HLoop(kTRUE);  // kTRUE : create Hades  (needed to work with standard eventstructure)
    TString readCategories = "";
    if (inputlist.EndsWith(".list")) {
        loop->addFilesList(inputlist);
    }
    else {
        loop->addMultFiles(inputlist);
    }
    if(!loop->setInput(readCategories)) { exit(1); }
    loop->printCategories();
    loop->readSectorFileList("FileListLepton.list");
    int sectors[6];

    HGeantKine *kine1;
    HGeantKine *kine2;

    HCategory* kineCat = (HCategory*)HCategoryManager::getCategory(catGeantKine);

    HHistMap hM(outfile.Data());
    hM.setSilentFail(kTRUE);

    //------------------------------------------------------------------
    //--------------- begin histo booking -----------------------------------------------------
    //------------------------------------------------------------------------------------------

    const Int_t nbins = 26;
    Double_t xAxis1[nbins+1] = {0, 0.010, 0.020, 0.030, 0.040, 0.050, 0.060, 0.070, 0.080, 0.090, 0.110, 0.130, 0.150, 0.170, 0.200, 0.250, 0.300, 0.350, 0.400, 0.450, 0.500, 0.550, 0.600, 0.700, 0.800, 0.900, 1.};

    hM.addHist(new TH1F(TString("hmassNP"),TString("hmassNP"),nbins,xAxis1));
    hM.addHist(new TH1F(TString("hmassPP"),TString("hmassPP"),nbins,xAxis1));
    hM.addHist(new TH1F(TString("hmassNN"),TString("hmassNN"),nbins,xAxis1));
    hM.addHist(new TH1F(TString("hoAngleNP"),TString("hoAngleNP"),2000,0,200));
    hM.addHist(new TH1F(TString("hoAnglePP"),TString("hoAnglePP"),2000,0,200));
    hM.addHist(new TH1F(TString("hoAngleNN"),TString("hoAngleNN"),2000,0,200));
    hM.addHist(new TH1F(TString("hyNP"),TString("hyNP"),100,0,2));
    hM.addHist(new TH1F(TString("hyPP"),TString("hyPP"),100,0,2));
    hM.addHist(new TH1F(TString("hyNN"),TString("hyNN"),100,0,2));
    hM.addHist(new TH1F(TString("hptNP"),TString("hptNP"),100,0,1000));
    hM.addHist(new TH1F(TString("hptPP"),TString("hptPP"),100,0,1000));
    hM.addHist(new TH1F(TString("hptNN"),TString("hptNN"),100,0,1000));
    hM.addHist(new TH2F(TString("hoAnglemassNP"),TString("hoAnglemassNP"),90,0,180,nbins,xAxis1));
    hM.addHist(new TH2F(TString("hoAnglemassPP"),TString("hoAnglemassPP"),90,0,180,nbins,xAxis1));
    hM.addHist(new TH2F(TString("hoAnglemassNN"),TString("hoAnglemassNN"),90,0,180,nbins,xAxis1));
    hM.addHist(new TH2F(TString("hoAngleptNP"),TString("hoAngleptNP"),90,0,180,120,0,1200));
    hM.addHist(new TH2F(TString("hoAngleptPP"),TString("hoAngleptPP"),90,0,180,120,0,1200));
    hM.addHist(new TH2F(TString("hoAngleptNN"),TString("hoAngleptNN"),90,0,180,120,0,1200));
    hM.addHist(new TH2F(TString("hmassptNP"),TString("hmassptNP"),nbins,xAxis1,120,0,1200));
    hM.addHist(new TH2F(TString("hmassptPP"),TString("hmassptPP"),nbins,xAxis1,120,0,1200));
    hM.addHist(new TH2F(TString("hmassptNN"),TString("hmassptNN"),nbins,xAxis1,120,0,1200));
    hM.addHist(new TH2F(TString("hoAngleyNP"),TString("hoAngleyNP"),90,0,180,100,0,2));
    hM.addHist(new TH2F(TString("hoAngleyPP"),TString("hoAngleyPP"),90,0,180,100,0,2));
    hM.addHist(new TH2F(TString("hoAngleyNN"),TString("hoAngleyNN"),90,0,180,100,0,2));
    hM.addHist(new TH2F(TString("hmassyNP"),TString("hmassyNP"),nbins,xAxis1,100,0,2));
    hM.addHist(new TH2F(TString("hmassyPP"),TString("hmassyPP"),nbins,xAxis1,100,0,2));
    hM.addHist(new TH2F(TString("hmassyNN"),TString("hmassyNN"),nbins,xAxis1,100,0,2));
    hM.addHist(new TH2F(TString("hptyNP"),TString("hptyNP"),120,0,1200,100,0,2));
    hM.addHist(new TH2F(TString("hptyPP"),TString("hptyPP"),120,0,1200,100,0,2));
    hM.addHist(new TH2F(TString("hptyNN"),TString("hptyNN"),120,0,1200,100,0,2));
    hM.addHist(new TH2F(TString("hth1th2NP"),TString("hth1th2NP"),90,0,90,90,0,90));
    hM.addHist(new TH2F(TString("hth1th2PP"),TString("hth1th2PP"),90,0,90,90,0,90));
    hM.addHist(new TH2F(TString("hth1th2NN"),TString("hth1th2NN"),90,0,90,90,0,90));
    hM.addHist(new TH2F(TString("hp1p2NP"),TString("hp1p2NP"),100,0,1100,100,0,1100));
    hM.addHist(new TH2F(TString("hp1p2PP"),TString("hp1p2PP"),100,0,1100,100,0,1100));
    hM.addHist(new TH2F(TString("hp1p2NN"),TString("hp1p2NN"),100,0,1100,100,0,1100));

    for (int i = 0; i < 5; ++i) {
        hM.addHist(new TH1F(TString("hmassNP_eff_multbin")+TString::Itoa(i,10),TString("hmassNP_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1));
        hM.addHist(new TH1F(TString("hmassPP_eff_multbin")+TString::Itoa(i,10),TString("hmassPP_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1));
        hM.addHist(new TH1F(TString("hmassNN_eff_multbin")+TString::Itoa(i,10),TString("hmassNN_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1));
        hM.addHist(new TH1F(TString("hoAngleNP_eff_multbin")+TString::Itoa(i,10),TString("hoAngleNP_eff_multbin")+TString::Itoa(i,10),2000,0,200));
        hM.addHist(new TH1F(TString("hoAnglePP_eff_multbin")+TString::Itoa(i,10),TString("hoAnglePP_eff_multbin")+TString::Itoa(i,10),2000,0,200));
        hM.addHist(new TH1F(TString("hoAngleNN_eff_multbin")+TString::Itoa(i,10),TString("hoAngleNN_eff_multbin")+TString::Itoa(i,10),2000,0,200));
        hM.addHist(new TH1F(TString("hyNP_eff_multbin")+TString::Itoa(i,10),TString("hyNP_eff_multbin")+TString::Itoa(i,10),100,0,2));
        hM.addHist(new TH1F(TString("hyPP_eff_multbin")+TString::Itoa(i,10),TString("hyPP_eff_multbin")+TString::Itoa(i,10),100,0,2));
        hM.addHist(new TH1F(TString("hyNN_eff_multbin")+TString::Itoa(i,10),TString("hyNN_eff_multbin")+TString::Itoa(i,10),100,0,2));
        hM.addHist(new TH1F(TString("hptNP_eff_multbin")+TString::Itoa(i,10),TString("hptNP_eff_multbin")+TString::Itoa(i,10),100,0,1000));
        hM.addHist(new TH1F(TString("hptPP_eff_multbin")+TString::Itoa(i,10),TString("hptPP_eff_multbin")+TString::Itoa(i,10),100,0,1000));
        hM.addHist(new TH1F(TString("hptNN_eff_multbin")+TString::Itoa(i,10),TString("hptNN_eff_multbin")+TString::Itoa(i,10),100,0,1000));
        hM.addHist(new TH2F(TString("hoAnglemassNP_eff_multbin")+TString::Itoa(i,10),TString("hoAnglemassNP_eff_multbin")+TString::Itoa(i,10),90,0,180,nbins,xAxis1));
        hM.addHist(new TH2F(TString("hoAnglemassPP_eff_multbin")+TString::Itoa(i,10),TString("hoAnglemassPP_eff_multbin")+TString::Itoa(i,10),90,0,180,nbins,xAxis1));
        hM.addHist(new TH2F(TString("hoAnglemassNN_eff_multbin")+TString::Itoa(i,10),TString("hoAnglemassNN_eff_multbin")+TString::Itoa(i,10),90,0,180,nbins,xAxis1));
        hM.addHist(new TH2F(TString("hoAngleptNP_eff_multbin")+TString::Itoa(i,10),TString("hoAngleptNP_eff_multbin")+TString::Itoa(i,10),90,0,180,120,0,1200));
        hM.addHist(new TH2F(TString("hoAngleptPP_eff_multbin")+TString::Itoa(i,10),TString("hoAngleptPP_eff_multbin")+TString::Itoa(i,10),90,0,180,120,0,1200));
        hM.addHist(new TH2F(TString("hoAngleptNN_eff_multbin")+TString::Itoa(i,10),TString("hoAngleptNN_eff_multbin")+TString::Itoa(i,10),90,0,180,120,0,1200));
        hM.addHist(new TH2F(TString("hmassptNP_eff_multbin")+TString::Itoa(i,10),TString("hmassptNP_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1,120,0,1200));
        hM.addHist(new TH2F(TString("hmassptPP_eff_multbin")+TString::Itoa(i,10),TString("hmassptPP_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1,120,0,1200));
        hM.addHist(new TH2F(TString("hmassptNN_eff_multbin")+TString::Itoa(i,10),TString("hmassptNN_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1,120,0,1200));
        hM.addHist(new TH2F(TString("hoAngleyNP_eff_multbin")+TString::Itoa(i,10),TString("hoAngleyNP_eff_multbin")+TString::Itoa(i,10),90,0,180,100,0,2));
        hM.addHist(new TH2F(TString("hoAngleyPP_eff_multbin")+TString::Itoa(i,10),TString("hoAngleyPP_eff_multbin")+TString::Itoa(i,10),90,0,180,100,0,2));
        hM.addHist(new TH2F(TString("hoAngleyNN_eff_multbin")+TString::Itoa(i,10),TString("hoAngleyNN_eff_multbin")+TString::Itoa(i,10),90,0,180,100,0,2));
        hM.addHist(new TH2F(TString("hmassyNP_eff_multbin")+TString::Itoa(i,10),TString("hmassyNP_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1,100,0,2));
        hM.addHist(new TH2F(TString("hmassyPP_eff_multbin")+TString::Itoa(i,10),TString("hmassyPP_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1,100,0,2));
        hM.addHist(new TH2F(TString("hmassyNN_eff_multbin")+TString::Itoa(i,10),TString("hmassyNN_eff_multbin")+TString::Itoa(i,10),nbins,xAxis1,100,0,2));
        hM.addHist(new TH2F(TString("hptyNP_eff_multbin")+TString::Itoa(i,10),TString("hptyNP_eff_multbin")+TString::Itoa(i,10),120,0,1200,100,0,2));
        hM.addHist(new TH2F(TString("hptyPP_eff_multbin")+TString::Itoa(i,10),TString("hptyPP_eff_multbin")+TString::Itoa(i,10),120,0,1200,100,0,2));
        hM.addHist(new TH2F(TString("hptyNN_eff_multbin")+TString::Itoa(i,10),TString("hptyNN_eff_multbin")+TString::Itoa(i,10),120,0,1200,100,0,2));
        hM.addHist(new TH2F(TString("hth1th2NP_eff_multbin")+TString::Itoa(i,10),TString("hth1th2NP_eff_multbin")+TString::Itoa(i,10),90,0,90,90,0,90));
        hM.addHist(new TH2F(TString("hth1th2PP_eff_multbin")+TString::Itoa(i,10),TString("hth1th2PP_eff_multbin")+TString::Itoa(i,10),90,0,90,90,0,90));
        hM.addHist(new TH2F(TString("hth1th2NN_eff_multbin")+TString::Itoa(i,10),TString("hth1th2NN_eff_multbin")+TString::Itoa(i,10),90,0,90,90,0,90));
        hM.addHist(new TH2F(TString("hp1p2NP_eff_multbin")+TString::Itoa(i,10),TString("hp1p2NP_eff_multbin")+TString::Itoa(i,10),100,0,1100,100,0,1100));
        hM.addHist(new TH2F(TString("hp1p2PP_eff_multbin")+TString::Itoa(i,10),TString("hp1p2PP_eff_multbin")+TString::Itoa(i,10),100,0,1100,100,0,1100));
        hM.addHist(new TH2F(TString("hp1p2NN_eff_multbin")+TString::Itoa(i,10),TString("hp1p2NN_eff_multbin")+TString::Itoa(i,10),100,0,1100,100,0,1100));
    }

    //--------------- end histo booking -----------------------------------------------------

    HGenericEventMixer<HGeantKine> eventmixer;
    eventmixer.setPIDs(2,3,1);
    eventmixer.setBuffSize(80);
    //eventmixer.setBuffSize(2);
    HGenericEventMixer<HGeantKine> eventmixer_eff[5];
    for (int mb = 0; mb < 5; ++mb) {
        eventmixer_eff[mb].setPIDs(2,3,1);
        eventmixer_eff[mb].setBuffSize(80);
        //eventmixer_eff[mb].setBuffSize(2);
    }

    TStopwatch timer;
    timer.Reset();
    timer.Start();

    Float_t impB = -1.;
    Float_t impB_bins[]  = {9.3, 8.1, 6.6, 4.7, 0.};

    Int_t evtsInFile = loop->getEntries();
    if(nev < 0 || nev > evtsInFile ) nev = evtsInFile;

    for(Int_t i = 1; i < nev; i++)
    {
        //----------break if last event is reached-------------
        //if(!gHades->eventLoop(1)) break;
        if(loop->nextEvent(i) <= 0) { cout<<" end recieved "<<endl; break; } // last event reached
        HTool::printProgress(i,nev,1,"Analyze :");
        loop->getSectors(sectors);

	HPartialEvent *fSimul        = ((HRecEvent*)gHades->getCurrentEvent())->getPartialEvent(catSimul);
	HGeantHeader *fSubHeader = (HGeantHeader*)(fSimul->getSubHeader());
	impB = fSubHeader->getImpactParameter();

	Int_t multbin = 0;
        if (impB >= impB_bins[4] && impB <= impB_bins[3]) {multbin=1;} // most central
	if (impB >  impB_bins[3] && impB <= impB_bins[2]) {multbin=2;}
	if (impB >  impB_bins[2] && impB <= impB_bins[1]) {multbin=3;}
	if (impB >  impB_bins[1] && impB <= impB_bins[0]) {multbin=4;} // most peripheral
	if (impB >  impB_bins[0]) {multbin=5;}
/*
	HParticleEvtInfo* evtinfo;
	evtinfo = HCategoryManager::getObject(evtinfo,catParticleEvtInfo,0);

	Int_t multbin = 0;
	Int_t mult_meta = evtinfo->getSumTofMultCut() + evtinfo->getSumRpcMultHitCut();
        if (mult_meta >  60 && mult_meta <=  88) multbin = 4; // most peripheral
        if (mult_meta >  88 && mult_meta <= 121) multbin = 3;
        if (mult_meta > 121 && mult_meta <= 160) multbin = 2;
        if (mult_meta > 160 && mult_meta <= 250) multbin = 1; // most central
        if (mult_meta > 250) multbin = 5;
*/

        if (multbin == 0 || multbin == 5) continue;

        Int_t size = kineCat->getEntries();

        // Additional loop to fill vector
        vector<HGeantKine *> vep;
        vector<HGeantKine *> vem;
        vector<HGeantKine *> vep_eff;
        vector<HGeantKine *> vem_eff;
        vector<HGeantKine *> vep_eff_multbin;
        vector<HGeantKine *> vem_eff_multbin;
	for(Int_t j = 0; j < size; j ++){
	    kine1 = HCategoryManager::getObject(kine1,kineCat,j);
            Float_t vx,vy,vz;
            kine1->getVertex(vx,vy,vz);
	    Float_t vr = TMath::Sqrt(vx*vx+vy*vy);
            if (vz < -60 || vz > 0) continue;
            if (vr > 2) continue;
            Int_t mamaNum = kine1->getParentTrack();

            if (kine1->isInAcceptance()) {
                if (kine1->getTotalMomentum() > 100 && kine1->getTotalMomentum() < 1000) {
                    Float_t px,py,pz;
                    kine1->getMomentum(px,py,pz);
                    TH2F *smear_matr;
                    if (kine1->getID() == 2) {
                        smear_matr = smear_pos;
                    } else {
                        smear_matr = smear_ele;
                    }
                    Float_t mom_ideal = kine1->getTotalMomentum();
                    Float_t mom_reco = smear(mom_ideal,smear_matr,random);
                    Float_t reco_over_ideal = mom_reco / mom_ideal;
                    kine1->setMomentum(px*reco_over_ideal,py*reco_over_ideal,pz*reco_over_ideal);
                    TLorentzVector vec;
                    HParticleTool::getTLorentzVector(kine1,vec,kine1->getID());

                    Float_t mom = vec.Vect().Mag();
                    Float_t the = vec.Theta()*TMath::RadToDeg();
                    Float_t phi = (vec.Phi()+TMath::Pi())*TMath::RadToDeg();
                    Float_t chg = (kine1->getID() == 2) ? 1 : -1;

                    if (kine1->getID() == 3) {
                        vem.push_back(new HGeantKine(*kine1));
                    }
                    if (kine1->getID() == 2) {
                        vep.push_back(new HGeantKine(*kine1));
                    }
                    Float_t eff = 1./getEfficiencyFactor(p3DEffEle[0][6],p3DEffPos[0][6],mom_ideal,the,phi,chg,false,false); // don't debug, don't check min value
                    if (isinf(eff) || isnan(eff)) eff = 0.;
                    if (random.Uniform(1) > eff) {
                        if (kine1->getID() == 3) {
                            vem_eff.push_back(new HGeantKine(*kine1));
                        }
                        if (kine1->getID() == 2) {
                            vep_eff.push_back(new HGeantKine(*kine1));
                        }
                    }
                    Float_t eff_multbin = 1./getEfficiencyFactor(p3DEffEle[multbin][6],p3DEffPos[multbin][6],mom,the,phi,chg,false,false);
                    if (isinf(eff_multbin) || isnan(eff_multbin)) eff_multbin = 0.;
                    if (random.Uniform(1) > eff_multbin) {
                        if (kine1->getID() == 3) {
                            vem_eff_multbin.push_back(new HGeantKine(*kine1));
                        }
                        if (kine1->getID() == 2) {
                            vep_eff_multbin.push_back(new HGeantKine(*kine1));
                        }
                    }
                }
            }
        }

        eventmixer.nextEvent();
        eventmixer.addVector(vep,2);
        eventmixer.addVector(vem,3);
        vector<pair<HGeantKine *, HGeantKine* > >& pairsVec_acc = eventmixer.getMixedVector();

        eventmixer_eff[0].nextEvent();
        eventmixer_eff[0].addVector(vep_eff,2);
        eventmixer_eff[0].addVector(vem_eff,3);
        vector<pair<HGeantKine *, HGeantKine* > >& pairsVec_eff = eventmixer_eff[0].getMixedVector();

        eventmixer_eff[multbin].nextEvent();
        eventmixer_eff[multbin].addVector(vep_eff,2);
        eventmixer_eff[multbin].addVector(vem_eff,3);
        vector<pair<HGeantKine *, HGeantKine* > >& pairsVec_eff_multbin = eventmixer_eff[multbin].getMixedVector();

        for (int imix = 0; imix < 3; ++imix) {
            vector<pair<HGeantKine *, HGeantKine* > > pairsVec;
            TString suffix;
            switch (imix) {
                case 0: 
                    pairsVec = pairsVec_acc;
                    suffix = TString(""); 
                    break;
                case 1: 
                    pairsVec = pairsVec_eff;
                    suffix = TString("_eff_multbin0");
                    break;
                case 2: 
                    pairsVec = pairsVec_eff_multbin;
                    suffix = TString("_eff_multbin")+TString::Itoa(multbin,10);
                    break;
            }
            size = pairsVec.size();

            for (Int_t j = 0; j < size; j ++) {
                pair<HGeantKine*,HGeantKine*>& pair = pairsVec[j];

                kine1 = pair.first;
                kine2 = pair.second;
                TLorentzVector vec1, vec2;
                HParticleTool::getTLorentzVector(kine1,vec1,kine1->getID());
                HParticleTool::getTLorentzVector(kine2,vec2,kine2->getID());

                Float_t mom1 = vec1.Vect().Mag();
                Float_t the1 = vec1.Theta()*TMath::RadToDeg();
                Float_t mom2 = vec2.Vect().Mag();
                Float_t the2 = vec2.Theta()*TMath::RadToDeg();

                TLorentzVector dilep = vec1 + vec2;
                Float_t oAngle = vec1.Angle(vec2.Vect())*TMath::RadToDeg();
                Float_t mass   = dilep.M()/1000;
                Float_t pt     = dilep.Perp();
                Float_t y      = dilep.Rapidity();
                Float_t mbinw  = hM.get("hmassNP")->GetBinWidth(hM.get("hmassNP")->FindBin(mass));

                if (oAngle < 9) continue;

                TString chg = "NP";
                if (kine1->getID() == kine2->getID()) {
                    if (kine1->getID() == 2) chg = "PP";
                    if (kine1->getID() == 3) chg = "NN";
                }

                hM.get( TString("hmass")      +chg+suffix)->Fill(mass,       1./mbinw);
                hM.get( TString("hoAngle")    +chg+suffix)->Fill(oAngle      );
                hM.get( TString("hy")         +chg+suffix)->Fill(y           );
                hM.get( TString("hpt")        +chg+suffix)->Fill(pt          );
                hM.get2(TString("hoAnglemass")+chg+suffix)->Fill(oAngle,mass,1./mbinw);
                hM.get2(TString("hoAnglept")  +chg+suffix)->Fill(oAngle,pt   );
                hM.get2(TString("hmasspt")    +chg+suffix)->Fill(mass,pt,    1./mbinw);
                hM.get2(TString("hoAngley")   +chg+suffix)->Fill(oAngle,y    );
                hM.get2(TString("hmassy")     +chg+suffix)->Fill(mass,y,     1./mbinw);
                hM.get2(TString("hpty")       +chg+suffix)->Fill(pt,y        );
                hM.get2(TString("hth1th2")    +chg+suffix)->Fill(the1,the2   );
                hM.get2(TString("hp1p2")      +chg+suffix)->Fill(mom1,mom2   );
            }
        }
//#define DELETE_MIX
#ifdef DELETE_MIX
        vector <HGeantKine *>* toDel = eventmixer.getObjectsToDelete();
        for (unsigned int ii = 0; ii < toDel->size(); ++ii) {
            delete toDel->at(ii);
        }
        toDel->clear();
        delete toDel;
        vector <HGeantKine *>* toDel_eff = eventmixer_eff[0].getObjectsToDelete();
        for (unsigned int ii = 0; ii < toDel_eff->size(); ++ii) {
            delete toDel_eff->at(ii);
        }
        toDel_eff->clear();
        delete toDel_eff;
        vector <HGeantKine *>* toDel_eff_multbin = eventmixer_eff[multbin].getObjectsToDelete();
        for (unsigned int ii = 0; ii < toDel_eff_multbin->size(); ++ii) {
            delete toDel_eff_multbin->at(ii);
        }
        toDel_eff_multbin->clear();
        delete toDel_eff_multbin;
#endif

    } // end event loop

    timer.Stop();

    hM.getFile()->cd();
    TMacro m1(__DIELEANA_FILE__);
    m1.Write();
    hM.writeHists("nomap");

    cout<<"####################################################"<<endl;
    return 0;
}