void treeToHistogramConverter(const std::string& fileName, const std::string& newFileName, const std::string& cut)
{
  TFile* file = TFile::Open(fileName.c_str());
  if(file->IsZombie())
  {
    std::cout << "File with name " << fileName << " not found!  Exiting." << std::endl;
    return;
  }
  TTree* tree = (TTree*)file->Get("tree");

  tree->SetBranchAddress("jetData", &jetInfo_.flavour);
  tree->SetBranchAddress("leptonData", &leptonInfo_.pt);
  tree->SetBranchAddress("svData", &svInfo_.svNSelectedTrks);
  tree->SetBranchAddress("2dIPTagInfo", &ip2dInfo_.ip2dTrk1);
  tree->SetBranchAddress("3dIPTagInfo", &ip3dInfo_.ip3dTrk1);
  tree->SetBranchAddress("tagData", &discInfo_.tcheDisc);

  tree->Draw(">>theList", cut.c_str(), "entrylist");
  TEntryList* theList = (TEntryList*)gDirectory->Get("theList");


  TFile* newFile = new TFile(newFileName.c_str(), "RECREATE");
  TH1F* flavour = new TH1F("flavour", "MC Flavour of the Jets with Leptons", 22, -0.5, 21.5);
  flavour->GetXaxis()->SetTitle("Jet Flavour");
  TH1F* jetPt = new TH1F("jetPt", "p_{T} of the Jets with Leptons", 100, 0.0, 350.0);
  jetPt->GetXaxis()->SetTitle("Jet p_{T} (GeV)");
  TH1F* jetEta = new TH1F("jetEta", "#eta of the Jets with Leptons", 100, -2.5, 2.5);
  jetEta->GetXaxis()->SetTitle("Jet #eta");
  TH1F* jetPhi = new TH1F("jetPhi", "#phi of the Jets with Leptons", 100, -3.2, 3.2);
  jetPhi->GetXaxis()->SetTitle("Jet #phi");
  TH1F* jetEMFraction = new TH1F("jetEMFraction", "EM Fraction of the Jets with Leptons", 100, -0.1, 1.1);
  jetEMFraction->GetXaxis()->SetTitle("Jet EM Fraction");

  TH1F* lepPt = new TH1F("lepPt", "p_{T} of Lepton Associated to a Jet", 100, 0.0, 50.0);
  lepPt->GetXaxis()->SetTitle("lepton p_{T} (GeV)");
  TH1F* lepEta = new TH1F("lepEta", "#eta of Lepton Associated to a Jet", 100, -2.5, 2.5);
  lepEta->GetXaxis()->SetTitle("lepton #eta");
  TH1F* lepPhi = new TH1F("lepPhi", "#phi of Lepton Associated to a Jet", 100, -3.2, 3.2);
  lepPhi->GetXaxis()->SetTitle("lepton #phi");
  TH1F* lepNHits = new TH1F("lepNHits", "Number of Track Hits of Lepton Associated to a Jet", 25, -0.5, 24.5);
  lepNHits->GetXaxis()->SetTitle("Number of Track Hits");
  TH1F* lepNChi2 = new TH1F("lepNChi2", "Track Normalized #chi^{2} of Lepton Associated to a Jet", 100, 0.0, 10.0);
  lepNChi2->GetXaxis()->SetTitle("lepton track Normalized #chi^{2}");
  TH1F* ptRel = new TH1F("ptRel", "p_{T,Rel} of Lepton Associated to a Jet", 100, 0.0, 8.0);
  ptRel->GetXaxis()->SetTitle("p_{T,Rel} (GeV)");
  TH1F* sip2d = new TH1F("sip2d", "sip2d of Lepton Associated to a Jet", 100, -10.0, 30.0);
  sip2d->GetXaxis()->SetTitle("Transverse Signed Impact Parameter Significance");
  TH1F* sip3d = new TH1F("sip3d", "sip3d of Lepton Associated to a Jet", 100, -10.0, 30.0);
  sip3d->GetXaxis()->SetTitle("3D Signed Impact Parameter Significance");
  TH1F* p0par = new TH1F("p0par", "p_{0,par} of Lepton Associated to a Jet", 100, -10.0, 10.0);
  p0par->GetXaxis()->SetTitle("p_{0,par} (GeV)");
  TH1F* deltaR = new TH1F("deltaR", "#Delta R of Lepton Associated to a Jet", 100, 0.0, 0.4);
  deltaR->GetXaxis()->SetTitle("#Delta R");
  TH1F* etaRel = new TH1F("etaRel", "Relative #eta of Lepton Associated to a Jet", 100, 0.0, 10.0);
  etaRel->GetXaxis()->SetTitle("Relative #eta");
  TH1F* ratio = new TH1F("ratio", "Ratio of Lepton Momentum to Associated Jet Energy", 100, 0.0, 2.0);
  ratio->GetXaxis()->SetTitle("p_{lep} / E_{Jet}");
  TH1F* ratioRel = new TH1F("ratioRel", "Ratio of Lepton p0par to Associated Jet Energy", 100, 0.0, 2.0);
  ratioRel->GetXaxis()->SetTitle("p_{0, par} / E_{Jet}");

  TH1F* svNSelectedTrks = new TH1F("svNSelectedTrks", "Number of Selected Tracks for SV Reconstruction", 26, -0.5, 25.5);
  svNSelectedTrks->GetXaxis()->SetTitle("Number of Selected Tracks");
  TH1F* svNVtx = new TH1F("svNVtx", "Number of SVs Associated to a Jet", 6, -0.5, 5.5);
  svNVtx->GetXaxis()->SetTitle("Number of Vertices");
  TH1F* svNVtxTrks = new TH1F("svNVtxTrks", "Number of Tracks Associated to SV with Longest Decay Length", 21, -0.5, 20.5);
  svNVtxTrks->GetXaxis()->SetTitle("Number of Vertex Tracks");
  TH1F* svNChi2 = new TH1F("svNChi2", "Normalized #chi^{2} of SV with Longest Decay Length", 100, 0.0, 20.0);
  svNChi2->GetXaxis()->SetTitle("Normalized #chi^{2}");
  TH1F* svDist2d = new TH1F("svDist2d", "Transverse Decay Length of SV with Longest Decay Length", 100, 0.0, 3.0);
  svDist2d->GetXaxis()->SetTitle("Transverse Decay Length (cm)");
  TH1F* svDist2dErr = new TH1F("svDist2dErr", "Transverse Decay Length Error of SV with Longest Decay Length", 100, 0.0, 0.12);
  svDist2dErr->GetXaxis()->SetTitle("Transverse Decay Length Error (cm)");
  TH1F* svDist3d = new TH1F("svDist3d", "3D Decay Length of SV with Longest Decay Length", 100, 0.0, 5.0);
  svDist3d->GetXaxis()->SetTitle("3D Decay Length (cm)");
  TH1F* svDist3dErr = new TH1F("svDist3dErr", "3D Decay Length Error of SV with Longest Decay Length", 100, 0.0, 0.2);
  svDist3dErr->GetXaxis()->SetTitle("3D Decay Length Error (cm)");

  TH1F* ip2dTrk1 = new TH1F("ip2dTrk1", "Transverse IP of 1st Track Associated to Jet", 100, 0.0, 0.3);
  ip2dTrk1->GetXaxis()->SetTitle("1st Track Transverse IP (cm)");
  TH1F* ip2dErrTrk1 = new TH1F("ip2dErrTrk1", "Transverse IP Error of 1st Track Associated to Jet", 100, 0.0, 0.04);
  ip2dErrTrk1->GetXaxis()->SetTitle("1st Track Transverse IP Error (cm)");
  TH1F* ip2dProbTrk1 = new TH1F("ip2dProbTrk1", "Transverse IP Probability of 1st Track Associated to Jet", 100, 0.0, 1.0);
  ip2dProbTrk1->GetXaxis()->SetTitle("1st Track Transverse IP Probability");
  TH1F* ip2dTrk2 = new TH1F("ip2dTrk2", "Transverse IP of 2nd Track Associated to Jet", 100, 0.0, 0.3);
  ip2dTrk2->GetXaxis()->SetTitle("2nd Track Transverse IP (cm)");
  TH1F* ip2dErrTrk2 = new TH1F("ip2dErrTrk2", "Transverse IP Error of 2nd Track Associated to Jet", 100, 0.0, 0.04);
  ip2dErrTrk2->GetXaxis()->SetTitle("2nd Track Transverse IP Error (cm)");
  TH1F* ip2dProbTrk2 = new TH1F("ip2dProbTrk2", "Transverse IP Probability of 2nd Track Associated to Jet", 100, 0.0, 1.0);
  ip2dProbTrk2->GetXaxis()->SetTitle("2nd Track Transverse IP Probability");
  TH1F* ip2dTrk3 = new TH1F("ip2dTrk3", "Transverse IP of 3rd Track Associated to Jet", 100, 0.0, 0.3);
  ip2dTrk3->GetXaxis()->SetTitle("3rd Track Transverse IP (cm)");
  TH1F* ip2dErrTrk3 = new TH1F("ip2dErrTrk3", "Transverse IP Error of 3rd Track Associated to Jet", 100, 0.0, 0.04);
  ip2dErrTrk3->GetXaxis()->SetTitle("3rd Track Transverse IP Error (cm)");
  TH1F* ip2dProbTrk3 = new TH1F("ip2dProbTrk3", "Transverse IP Probability of 3rd Track Associated to Jet", 100, 0.0, 1.0);
  ip2dProbTrk3->GetXaxis()->SetTitle("3rd Track Transverse IP Probability");

  TH1F* ip3dTrk1 = new TH1F("ip3dTrk1", "3D IP of 1st Track Associated to Jet", 100, 0.0, 0.5);
  ip3dTrk1->GetXaxis()->SetTitle("1st Track 3D IP (cm)");
  TH1F* ip3dErrTrk1 = new TH1F("ip3dErrTrk1", "3D IP Error of 1st Track Associated to Jet", 100, 0.0, 0.04);
  ip3dErrTrk1->GetXaxis()->SetTitle("1st Track 3D IP Error (cm)");
  TH1F* ip3dProbTrk1 = new TH1F("ip3dProbTrk1", "3D IP Probability of 1st Track Associated to Jet", 100, 0.0, 1.0);
  ip3dProbTrk1->GetXaxis()->SetTitle("1st Track 3D IP Probability");
  TH1F* ip3dTrk2 = new TH1F("ip3dTrk2", "3D IP of 2nd Track Associated to Jet", 100, 0.0, 0.5);
  ip3dTrk2->GetXaxis()->SetTitle("2nd Track 3D IP (cm)");
  TH1F* ip3dErrTrk2 = new TH1F("ip3dErrTrk2", "3D IP Error of 2nd Track Associated to Jet", 100, 0.0, 0.04);
  ip3dErrTrk2->GetXaxis()->SetTitle("2nd Track 3D IP Error (cm)");
  TH1F* ip3dProbTrk2 = new TH1F("ip3dProbTrk2", "3D IP Probability of 2nd Track Associated to Jet", 100, 0.0, 1.0);
  ip3dProbTrk2->GetXaxis()->SetTitle("2nd Track 3D IP Probability");
  TH1F* ip3dTrk3 = new TH1F("ip3dTrk3", "3D IP of 3rd Track Associated to Jet", 100, 0.0, 0.5);
  ip3dTrk3->GetXaxis()->SetTitle("3rd Track 3D IP (cm)");
  TH1F* ip3dErrTrk3 = new TH1F("ip3dErrTrk3", "3D IP Error of 3rd Track Associated to Jet", 100, 0.0, 0.04);
  ip3dErrTrk3->GetXaxis()->SetTitle("3rd Track 3D IP Error (cm)");
  TH1F* ip3dProbTrk3 = new TH1F("ip3dProbTrk3", "3D IP Probability of 3rd Track Associated to Jet", 100, 0.0, 1.0);
  ip3dProbTrk3->GetXaxis()->SetTitle("3rd Track 3D IP Probability");

  TH1F* tcheDisc = new TH1F("tcheDisc", "TCHE Discriminator for Jets with Leptons", 100, -10.0, 30.0);
  tcheDisc->GetXaxis()->SetTitle("Track Counting High Efficiency Discriminator");
  TH1F* tchpDisc = new TH1F("tchpDisc", "TCHP Discriminator for Jets with Leptons", 100, -10.0, 30.0);
  tchpDisc->GetXaxis()->SetTitle("Track Counting High Purity Discriminator");
  TH1F* jpDisc = new TH1F("jpDisc", "JP Discriminator for Jets with Leptons", 100, 0.0, 2.5);
  jpDisc->GetXaxis()->SetTitle("Jet Probability Discriminator");
  TH1F* jbpDisc = new TH1F("jbpDisc", "JBP Discriminator for Jets with Leptons", 100, 0.0, 8.0);
  jbpDisc->GetXaxis()->SetTitle("Jet B Probability Discriminator");
  TH1F* ssvDisc = new TH1F("ssvDisc", "SSV Discriminator for Jets with Leptons", 100, 0.0, 8.0);
  ssvDisc->GetXaxis()->SetTitle("Simple Secondary Vertex Discriminator");
  TH1F* csvDisc = new TH1F("csvDisc", "CSV Discriminator for Jets with Leptons", 100, 0.0, 1.0);
  csvDisc->GetXaxis()->SetTitle("Combined Secondary Vertex Discriminator");
  TH1F* csvMVADisc = new TH1F("csvMVADisc", "CSV MVA Discriminator for Jets with Leptons", 100, 0.0, 1.0);
  csvMVADisc->GetXaxis()->SetTitle("Combined Secondary Vertex MVA Discriminator");
  TH1F* smDisc = new TH1F("smDisc", "SMT Discriminator for Jets with Leptons", 100, 0.0, 1.0);
  smDisc->GetXaxis()->SetTitle("Soft Muon Discriminator");
  TH1F* smIPDisc = new TH1F("smIPDisc", "SM IP Discriminator for Jets with Leptons", 100, -10.0, 30.0);
  smIPDisc->GetXaxis()->SetTitle("Soft Muon SIP-3D Discriminator");
  TH1F* smPtDisc = new TH1F("smPtDisc", "SM PtRel Discriminator for Jets with Leptons", 100, 0.0, 8.0);
  smPtDisc->GetXaxis()->SetTitle("Soft Muon p_{T, Rel} Discriminator");
  TH1F* seIPDisc = new TH1F("seIPDisc", "SE IP Discriminator for Jets with Leptons", 100, -10.0, 30.0);
  seIPDisc->GetXaxis()->SetTitle("Soft Electron SIP-3D Discriminator");
  TH1F* sePtDisc = new TH1F("sePtDisc", "SE PtRel Discriminator for Jets with Leptons", 100, 0.0, 8.0);
  sePtDisc->GetXaxis()->SetTitle("Soft Electron p_{T, Rel} Discriminator");

  int nEntries = theList->GetN();
  for(int i = 0; i != nEntries; ++i)
  {
    tree->GetEntry(theList->Next());
    flavour->Fill(jetInfo_.flavour);
    jetPt->Fill(jetInfo_.pt);
    jetEta->Fill(jetInfo_.eta);
    jetPhi->Fill(jetInfo_.phi);
    jetEMFraction->Fill(jetInfo_.emFraction);

    lepPt->Fill(leptonInfo_.pt);
    lepEta->Fill(leptonInfo_.eta);
    lepPhi->Fill(leptonInfo_.phi);
    lepNHits->Fill(leptonInfo_.nhits);
    lepNChi2->Fill(leptonInfo_.nchi2);
    ptRel->Fill(leptonInfo_.ptRel);
    sip2d->Fill(leptonInfo_.sip2d);
    sip3d->Fill(leptonInfo_.sip3d);
    p0par->Fill(leptonInfo_.p0par);
    deltaR->Fill(leptonInfo_.deltaR);
    etaRel->Fill(leptonInfo_.etaRel);
    ratio->Fill(leptonInfo_.ratio);
    ratioRel->Fill(leptonInfo_.ratioRel);

    svNSelectedTrks->Fill(svInfo_.svNSelectedTrks);
    svNVtx->Fill(svInfo_.svNVtx);
    svNVtxTrks->Fill(svInfo_.svNVtxTrks);
    svNChi2->Fill(svInfo_.svNChi2);
    svDist2d->Fill(svInfo_.svDist2d);
    svDist2dErr->Fill(svInfo_.svDist2dErr);
    svDist3d->Fill(svInfo_.svDist3d);
    svDist3dErr->Fill(svInfo_.svDist3dErr);

    ip2dTrk1->Fill(ip2dInfo_.ip2dTrk1);
    ip2dErrTrk1->Fill(ip2dInfo_.ip2dErrTrk1);
    ip2dProbTrk1->Fill(ip2dInfo_.ip2dProbTrk1);
    ip2dTrk2->Fill(ip2dInfo_.ip2dTrk2);
    ip2dErrTrk2->Fill(ip2dInfo_.ip2dErrTrk2);
    ip2dProbTrk2->Fill(ip2dInfo_.ip2dProbTrk2);
    ip2dTrk3->Fill(ip2dInfo_.ip2dTrk3);
    ip2dErrTrk3->Fill(ip2dInfo_.ip2dErrTrk3);
    ip2dProbTrk3->Fill(ip2dInfo_.ip2dProbTrk3);

    ip3dTrk1->Fill(ip3dInfo_.ip3dTrk1);
    ip3dErrTrk1->Fill(ip3dInfo_.ip3dErrTrk1);
    ip3dProbTrk1->Fill(ip3dInfo_.ip3dProbTrk1);
    ip3dTrk2->Fill(ip3dInfo_.ip3dTrk2);
    ip3dErrTrk2->Fill(ip3dInfo_.ip3dErrTrk2);
    ip3dProbTrk2->Fill(ip3dInfo_.ip3dProbTrk2);
    ip3dTrk3->Fill(ip3dInfo_.ip3dTrk3);
    ip3dErrTrk3->Fill(ip3dInfo_.ip3dErrTrk3);
    ip3dProbTrk3->Fill(ip3dInfo_.ip3dProbTrk3);

    tcheDisc->Fill(discInfo_.tcheDisc);
    tchpDisc->Fill(discInfo_.tchpDisc);
    jpDisc->Fill(discInfo_.jpDisc);
    jbpDisc->Fill(discInfo_.jbpDisc);
    ssvDisc->Fill(discInfo_.ssvDisc);
    csvDisc->Fill(discInfo_.csvDisc);
    csvMVADisc->Fill(discInfo_.csvMVADisc);
    smDisc->Fill(discInfo_.smDisc);
    smIPDisc->Fill(discInfo_.smIPDisc);
    smPtDisc->Fill(discInfo_.smPtDisc);
    seIPDisc->Fill(discInfo_.seIPDisc);
    sePtDisc->Fill(discInfo_.sePtDisc);
  }

  newFile->Write();
  newFile->Close();
  file->Close();
}
int main(int argc, char** argv)
{ 
 TDRStyle();
 
 gStyle->SetPadTopMargin(0.2);
 gStyle->SetPadBottomMargin(0.2);
 gStyle->SetPadLeftMargin(0.07);
 gStyle->SetPadRightMargin(0.23);
 gStyle->cd(); 
 
 
 std::cout << " " << std::endl;
 std::cout << " " << std::endl;
 std::cout << " " << std::endl; 
 std::cout << "     ___|          | _)  |         ___|                            |                   " << std::endl;
 std::cout << "   \\___ \\   __ \\   |  |  __|     \\___ \\    _` |  __ `__ \\   __ \\   |   _ \\     " << std::endl; 
 std::cout << "         |  |   |  |  |  |             |  (   |  |   |   |  |   |  |   __/             " << std::endl;
 std::cout << "   _____/   .__/  _| _| \\__|     _____/  \\__,_| _|  _|  _|  .__/  _| \\___|          " << std::endl;
 std::cout << "           _|                                              _|                          " << std::endl;
 std::cout << " " << std::endl;
 std::cout << " " << std::endl;
 std::cout << "    _ \\                      _ \\                                   " << std::endl;
 std::cout << "   |   |  |   |  __ \\       |   |   _` |  __ \\    _` |   _ \\      " << std::endl;
 std::cout << "   __ <   |   |  |   |      __ <   (   |  |   |  (   |   __/         " << std::endl;
 std::cout << "  _| \\_\\ \\__,_| _|  _|     _| \\_\\ \\__,_| _|  _| \\__, | \\___| " << std::endl;
 std::cout << "                                                |___/                " << std::endl;
 std::cout << " " << std::endl;
 std::cout << " " << std::endl;
 
 
 //Check if all nedeed arguments to parse are there                                                                                                                               
 if(argc != 2)
 {
  std::cerr << ">>>>> analysis.cpp::usage: " << argv[0] << " configFileName" << std::endl ;
  return 1;
 }


 // Parse the config file                                                                                                                                                          
 parseConfigFile (argv[1]) ;
 
 std::string treeName  = gConfigParser -> readStringOption("Input::treeName");
 std::string inputFileName = gConfigParser -> readStringOption("Input::inputFileName");

 std::vector<int> runRangesMin = gConfigParser -> readIntListOption("Options::runRangesMin");
 std::vector<int> runRangesMax = gConfigParser -> readIntListOption("Options::runRangesMax");
 
 TTree *treeJetLepVect; 
 
 std::string CutFile = gConfigParser -> readStringOption("Selections::CutFile"); 
 std::vector<std::string> vCut; ///====> only the first cut is used!
 std::cout << " nCuts   = " << ReadFileCut(CutFile, vCut) << std::endl;
 
 ///==== output file ====
 std::string outputDirectory = gConfigParser -> readStringOption("Output::outputDirectory");
 std::string OutFileName    = gConfigParser -> readStringOption("Output::outFileName");
 
 ///==== debug flag (begin) ==== 
 bool  debug = false; 
 try {
  debug = gConfigParser -> readBoolOption("Input::debug");
 }
 catch (char const* exceptionString){
  std::cerr << " exception = " << exceptionString << std::endl;
 }
 std::cout << ">>>>> input::debug  " << debug  << std::endl;  
 ///==== debug flag (end) ==== 
 
 
 
 
 ///==== program ====
 
 TFile* f = new TFile(inputFileName.c_str(), "READ");    
 treeJetLepVect = (TTree*) f->Get(treeName.c_str());
  
 int totNumEvents = treeJetLepVect->GetEntries(vCut.at(0).c_str());
 int numOutputFiles = runRangesMax.size();
 std::cout << " totNumEvents   = " << totNumEvents   << std::endl;
 std::cout << " numOutputFiles = " << numOutputFiles << std::endl;
 
 treeJetLepVect->SetEntryList(0); 
 treeJetLepVect->Draw(">> myList",vCut.at(0).c_str(),"entrylist");
 TEntryList *myList = (TEntryList*)gDirectory->Get("myList");
 treeJetLepVect->SetEntryList(myList); 
 
 std::cout << " tot = " << myList->GetN() << " = " << totNumEvents << " =? " << treeJetLepVect -> GetEntries () << std::endl;
 
 TH1F* MyHistoCounterMC = (TH1F*) f->Get("AllEvents/totalEvents");
 
 for (int iOutFile = 0; iOutFile < numOutputFiles; iOutFile++) {
  std::cout << " iOutFile = " << iOutFile << " : " << numOutputFiles << std::endl;
  TString outputRootFileName = Form("%s/%s_%d.root",outputDirectory.c_str(),OutFileName.c_str(), iOutFile); 
  TFile outputRootFile ( outputRootFileName.Data(), "RECREATE") ;
  outputRootFile.cd () ;
  outputRootFile.mkdir ("ntupleEcalAlignment") ;
  outputRootFile.cd ("ntupleEcalAlignment") ;  
  
  TTree* cloneTree = treeJetLepVect -> CloneTree (0) ;
  
  int countiEntry = 0;
    
  ///==== create list for this run range ====
  TString Cut = Form ("((%s) && (runId >= %d && runId < %d))", vCut.at(0).c_str(), runRangesMin.at(iOutFile), runRangesMax.at(iOutFile));
  treeJetLepVect->SetEntryList(0); 
  treeJetLepVect->Draw(">> myList",Cut.Data(),"entrylist");
  TEntryList *myList = (TEntryList*)gDirectory->Get("myList");
  treeJetLepVect->SetEntryList(myList); 
  for ( int iEntry = 0; iEntry < myList -> GetN () ; iEntry++) { 
   countiEntry++;
   treeJetLepVect -> GetEntry (myList->Next());
   cloneTree -> Fill () ;
  }
  cloneTree -> AutoSave () ;
  outputRootFile.cd () ;
  outputRootFile.mkdir ("AllEvents") ;
  outputRootFile.cd ("AllEvents") ;  
  MyHistoCounterMC -> Write();
  outputRootFile.Close () ;
 }
 
}