ROOT logo
#include "TTree.h"
#include "TF1.h"
#include "TH2D.h"
#include "TList.h"
#include "TString.h"
#include "TFile.h"
#include "TMath.h"
#include "TDatime.h"

#include <iostream>
#include "ProgressBar.h"

#define pidTypeAvailable

Int_t splitPbPbTreeMultiplicity(TString pathTree, Bool_t isMC, Int_t stepSize = 2000, Int_t maxMult = 14000,
                                TString fileNameTree = "bhess_PIDetaTree.root", TString treeName = "fTree") 
{ 
	// Extract the data tree		       
	TFile* fTree = TFile::Open(Form("%s/%s", pathTree.Data(), fileNameTree.Data()));
  if (!fTree)  {
    std::cout << "Failed to open file \"" << Form("%s/%s", pathTree.Data(), fileNameTree.Data()) << "\"!" << std::endl;
    return -1;
  }
  
  TTree* tree = dynamic_cast<TTree*>(fTree->Get(treeName.Data()));
  if (!tree) {
    std::cout << "Failed to load data tree!" << std::endl;
    return -1;
  }
  
  Long64_t nTreeEntries = tree->GetEntriesFast();
  Long64_t nTreeEntriesRejected = 0;
  Long64_t nTreeEntriesSkipped = 0;
  
  Double_t pTPC = 0.; 
  Double_t dEdx = 0.; 
  Double_t dEdxExpected = 0.;
  Double_t tanTheta = 0.; 
  Int_t fMultiplicity = 0.; 
  UShort_t tpcSignalN = 0.;
#ifdef pidTypeAvailable
  UChar_t pidType = 0;
#endif
  
  tree->SetBranchStatus("*", 0); // Disable all branches
  tree->SetBranchStatus("pTPC", 1);
  tree->SetBranchStatus("dEdx", 1);
  tree->SetBranchStatus("dEdxExpected", 1);
  tree->SetBranchStatus("tanTheta", 1);
  tree->SetBranchStatus("fMultiplicity", 1);
  tree->SetBranchStatus("tpcSignalN", 1);
#ifdef pidTypeAvailable
  tree->SetBranchStatus("pidType", 1);
#endif
  
  tree->SetBranchAddress("pTPC", &pTPC);
  tree->SetBranchAddress("dEdx", &dEdx);
  tree->SetBranchAddress("dEdxExpected", &dEdxExpected);
  tree->SetBranchAddress("tanTheta", &tanTheta);
  tree->SetBranchAddress("tpcSignalN", &tpcSignalN);
  tree->SetBranchAddress("fMultiplicity", &fMultiplicity);
#ifdef pidTypeAvailable
  tree->SetBranchAddress("pidType", &pidType);
#endif
 
  /* OLD - For nContributorsToPrimaryVertex
  const Int_t stepSize = 600;
  
  const Int_t numMultBins = TMath::Ceil((4000. - 0.) / stepSize);
  */
  
  const Int_t numMultBins = TMath::Ceil((maxMult - 0.) / stepSize);
  
  TFile* fSave[numMultBins];
  TTree* treeMult[numMultBins];
  
  for (Int_t i = 0; i < numMultBins; i++)   {
    // Output files
    TString savefileName = Form("%s_mult%d_%d.root", fileNameTree.ReplaceAll(".root", "").Data(), i * stepSize, (i + 1) * stepSize - 1);
    
    fSave[i] = TFile::Open(Form("%s/%s", pathTree.Data(), savefileName.Data()), "recreate");
    if (!fSave[i]) {
      std::cout << "Failed to open save file \"" << Form("%s/%s", pathTree.Data(), savefileName.Data()) << "\"!" << std::endl;
      return -1;
    }
    
    fSave[i]->cd();
    treeMult[i] = new TTree("fTree", Form("Tree with multiplicity %d - %d", i * stepSize, (i + 1) * stepSize - 1));
    treeMult[i]->Write(0, TObject::kOverwrite);
    treeMult[i]->Branch("pTPC", &pTPC);
    treeMult[i]->Branch("dEdx", &dEdx);
    treeMult[i]->Branch("dEdxExpected", &dEdxExpected);
    treeMult[i]->Branch("tanTheta", &tanTheta);
    treeMult[i]->Branch("tpcSignalN", &tpcSignalN);
    treeMult[i]->Branch("fMultiplicity", &fMultiplicity);
#ifdef pidTypeAvailable
    treeMult[i]->Branch("pidType", &pidType);
#endif
  }
  
  TF1 cutFunc("cutFunc","50./TMath::Power(x,1.3)", 0.05, 6);
  
  Bool_t isProtonTree = kFALSE;
  if (treeName.CompareTo("fTree") == 0) {
    isProtonTree = kTRUE;
    printf("Applying cut for protons (if no MC)...\n");
  }
  else {
    printf("Species seems to be different from protons - no cut...\n");
  }
  
  progressbar(0.);
  
  for (Long64_t i = 0; i < nTreeEntries; i++) {
    tree->GetEntry(i);

    // Filter tracks according to shape recognition
    if (dEdx < 10 || dEdxExpected < 10 || (!isMC && isProtonTree && pTPC < 0.6 && dEdx < cutFunc.Eval(pTPC))) {
      nTreeEntriesRejected++;
      continue;
    }
    
    Int_t multBin = (Int_t)(fMultiplicity / stepSize);
    if (multBin >= numMultBins || multBin < 0) {
      nTreeEntriesSkipped++;
      //std::cout << std::endl << "Warning: Skipping entry with fMultiplicity " << fMultiplicity << std::endl;
      //printedSomething = kTRUE;
      continue;
    }
    
    treeMult[multBin]->Fill();
    
    if (i % 100000 == 0)
      progressbar(100. * (((Double_t)i) / nTreeEntries));
  }
  
  Long64_t nSplitTreeEntries = 0;
  for (Int_t i = 0; i < numMultBins; i++)   {
    fSave[i]->cd();
    treeMult[i]->Write(0, TObject::kOverwrite);
    nSplitTreeEntries += treeMult[i]->GetEntriesFast();
    fSave[i]->Close();
  }
  
  progressbar(100.);
  
  std::cout << std::endl << "Entries original tree: " << nTreeEntries << std::endl << "Entries split trees: " << nSplitTreeEntries << std::endl;
  std::cout << "Rejected entries (cuts): " << nTreeEntriesRejected << std::endl;
  std::cout << "Skipped entries (out of range): " << nTreeEntriesSkipped << std::endl;
  std::cout << "=> Difference (after subtracting rejected and skipped entries) is "
            << nTreeEntries - nTreeEntriesRejected - nTreeEntriesSkipped - nSplitTreeEntries << std::endl;
  
  return 0;
}
 splitPbPbTreeMultiplicity.C:1
 splitPbPbTreeMultiplicity.C:2
 splitPbPbTreeMultiplicity.C:3
 splitPbPbTreeMultiplicity.C:4
 splitPbPbTreeMultiplicity.C:5
 splitPbPbTreeMultiplicity.C:6
 splitPbPbTreeMultiplicity.C:7
 splitPbPbTreeMultiplicity.C:8
 splitPbPbTreeMultiplicity.C:9
 splitPbPbTreeMultiplicity.C:10
 splitPbPbTreeMultiplicity.C:11
 splitPbPbTreeMultiplicity.C:12
 splitPbPbTreeMultiplicity.C:13
 splitPbPbTreeMultiplicity.C:14
 splitPbPbTreeMultiplicity.C:15
 splitPbPbTreeMultiplicity.C:16
 splitPbPbTreeMultiplicity.C:17
 splitPbPbTreeMultiplicity.C:18
 splitPbPbTreeMultiplicity.C:19
 splitPbPbTreeMultiplicity.C:20
 splitPbPbTreeMultiplicity.C:21
 splitPbPbTreeMultiplicity.C:22
 splitPbPbTreeMultiplicity.C:23
 splitPbPbTreeMultiplicity.C:24
 splitPbPbTreeMultiplicity.C:25
 splitPbPbTreeMultiplicity.C:26
 splitPbPbTreeMultiplicity.C:27
 splitPbPbTreeMultiplicity.C:28
 splitPbPbTreeMultiplicity.C:29
 splitPbPbTreeMultiplicity.C:30
 splitPbPbTreeMultiplicity.C:31
 splitPbPbTreeMultiplicity.C:32
 splitPbPbTreeMultiplicity.C:33
 splitPbPbTreeMultiplicity.C:34
 splitPbPbTreeMultiplicity.C:35
 splitPbPbTreeMultiplicity.C:36
 splitPbPbTreeMultiplicity.C:37
 splitPbPbTreeMultiplicity.C:38
 splitPbPbTreeMultiplicity.C:39
 splitPbPbTreeMultiplicity.C:40
 splitPbPbTreeMultiplicity.C:41
 splitPbPbTreeMultiplicity.C:42
 splitPbPbTreeMultiplicity.C:43
 splitPbPbTreeMultiplicity.C:44
 splitPbPbTreeMultiplicity.C:45
 splitPbPbTreeMultiplicity.C:46
 splitPbPbTreeMultiplicity.C:47
 splitPbPbTreeMultiplicity.C:48
 splitPbPbTreeMultiplicity.C:49
 splitPbPbTreeMultiplicity.C:50
 splitPbPbTreeMultiplicity.C:51
 splitPbPbTreeMultiplicity.C:52
 splitPbPbTreeMultiplicity.C:53
 splitPbPbTreeMultiplicity.C:54
 splitPbPbTreeMultiplicity.C:55
 splitPbPbTreeMultiplicity.C:56
 splitPbPbTreeMultiplicity.C:57
 splitPbPbTreeMultiplicity.C:58
 splitPbPbTreeMultiplicity.C:59
 splitPbPbTreeMultiplicity.C:60
 splitPbPbTreeMultiplicity.C:61
 splitPbPbTreeMultiplicity.C:62
 splitPbPbTreeMultiplicity.C:63
 splitPbPbTreeMultiplicity.C:64
 splitPbPbTreeMultiplicity.C:65
 splitPbPbTreeMultiplicity.C:66
 splitPbPbTreeMultiplicity.C:67
 splitPbPbTreeMultiplicity.C:68
 splitPbPbTreeMultiplicity.C:69
 splitPbPbTreeMultiplicity.C:70
 splitPbPbTreeMultiplicity.C:71
 splitPbPbTreeMultiplicity.C:72
 splitPbPbTreeMultiplicity.C:73
 splitPbPbTreeMultiplicity.C:74
 splitPbPbTreeMultiplicity.C:75
 splitPbPbTreeMultiplicity.C:76
 splitPbPbTreeMultiplicity.C:77
 splitPbPbTreeMultiplicity.C:78
 splitPbPbTreeMultiplicity.C:79
 splitPbPbTreeMultiplicity.C:80
 splitPbPbTreeMultiplicity.C:81
 splitPbPbTreeMultiplicity.C:82
 splitPbPbTreeMultiplicity.C:83
 splitPbPbTreeMultiplicity.C:84
 splitPbPbTreeMultiplicity.C:85
 splitPbPbTreeMultiplicity.C:86
 splitPbPbTreeMultiplicity.C:87
 splitPbPbTreeMultiplicity.C:88
 splitPbPbTreeMultiplicity.C:89
 splitPbPbTreeMultiplicity.C:90
 splitPbPbTreeMultiplicity.C:91
 splitPbPbTreeMultiplicity.C:92
 splitPbPbTreeMultiplicity.C:93
 splitPbPbTreeMultiplicity.C:94
 splitPbPbTreeMultiplicity.C:95
 splitPbPbTreeMultiplicity.C:96
 splitPbPbTreeMultiplicity.C:97
 splitPbPbTreeMultiplicity.C:98
 splitPbPbTreeMultiplicity.C:99
 splitPbPbTreeMultiplicity.C:100
 splitPbPbTreeMultiplicity.C:101
 splitPbPbTreeMultiplicity.C:102
 splitPbPbTreeMultiplicity.C:103
 splitPbPbTreeMultiplicity.C:104
 splitPbPbTreeMultiplicity.C:105
 splitPbPbTreeMultiplicity.C:106
 splitPbPbTreeMultiplicity.C:107
 splitPbPbTreeMultiplicity.C:108
 splitPbPbTreeMultiplicity.C:109
 splitPbPbTreeMultiplicity.C:110
 splitPbPbTreeMultiplicity.C:111
 splitPbPbTreeMultiplicity.C:112
 splitPbPbTreeMultiplicity.C:113
 splitPbPbTreeMultiplicity.C:114
 splitPbPbTreeMultiplicity.C:115
 splitPbPbTreeMultiplicity.C:116
 splitPbPbTreeMultiplicity.C:117
 splitPbPbTreeMultiplicity.C:118
 splitPbPbTreeMultiplicity.C:119
 splitPbPbTreeMultiplicity.C:120
 splitPbPbTreeMultiplicity.C:121
 splitPbPbTreeMultiplicity.C:122
 splitPbPbTreeMultiplicity.C:123
 splitPbPbTreeMultiplicity.C:124
 splitPbPbTreeMultiplicity.C:125
 splitPbPbTreeMultiplicity.C:126
 splitPbPbTreeMultiplicity.C:127
 splitPbPbTreeMultiplicity.C:128
 splitPbPbTreeMultiplicity.C:129
 splitPbPbTreeMultiplicity.C:130
 splitPbPbTreeMultiplicity.C:131
 splitPbPbTreeMultiplicity.C:132
 splitPbPbTreeMultiplicity.C:133
 splitPbPbTreeMultiplicity.C:134
 splitPbPbTreeMultiplicity.C:135
 splitPbPbTreeMultiplicity.C:136
 splitPbPbTreeMultiplicity.C:137
 splitPbPbTreeMultiplicity.C:138
 splitPbPbTreeMultiplicity.C:139
 splitPbPbTreeMultiplicity.C:140
 splitPbPbTreeMultiplicity.C:141
 splitPbPbTreeMultiplicity.C:142
 splitPbPbTreeMultiplicity.C:143
 splitPbPbTreeMultiplicity.C:144
 splitPbPbTreeMultiplicity.C:145
 splitPbPbTreeMultiplicity.C:146
 splitPbPbTreeMultiplicity.C:147
 splitPbPbTreeMultiplicity.C:148
 splitPbPbTreeMultiplicity.C:149
 splitPbPbTreeMultiplicity.C:150
 splitPbPbTreeMultiplicity.C:151
 splitPbPbTreeMultiplicity.C:152
 splitPbPbTreeMultiplicity.C:153
 splitPbPbTreeMultiplicity.C:154
 splitPbPbTreeMultiplicity.C:155