Crombie Tools
FlatSkimmer.cc
Go to the documentation of this file.
1 /**
2  @file FlatSkimmer.cc
3  Describes FlatSkimmer class.
4  @author Daniel Abercrombie <dabercro@mit.edu>
5 */
6 
7 #include <fstream>
8 #include <iostream>
9 
10 #include "TFile.h"
11 #include "TTree.h"
12 #include "TObject.h"
13 #include "TTreeFormula.h"
14 
15 #include "FlatSkimmer.h"
16 
18 
19 //--------------------------------------------------------------------
21 { }
22 
23 //--------------------------------------------------------------------
25 { }
26 
27 //--------------------------------------------------------------------
28 
29 /**
30  Adds an event filter list to be removed during skimming.
31  And event filter list must be a text file consisting of events to
32  remove in the format <RunNumber>:<LumiNumber>:<EventNumber>.
33  Multiple event filters can be added.
34 */
35 
36 void FlatSkimmer::AddEventFilter(TString filterName){
37  std::ifstream filterFile;
38  filterFile.open(filterName.Data());
39  TString eventString;
40  while (!filterFile.eof()) {
41  filterFile >> eventString;
42  if (eventString != "")
43  fEventFilter.insert(eventString);
44  }
45 }
46 
47 //--------------------------------------------------------------------
48 
49 /**
50  Skims a file from the input directory and places it in the output.
51  Skimming is done using a cut, GoodLumiFilter, event filters, and
52  possibly removing duplicate events. The duplicate events flag is false
53  by default because it's a very expensive check.
54  The function reports the number of events removed from the file from
55  each mechanism.
56 */
57 
58 void FlatSkimmer::Skim(TString fileName)
59 {
60  SetReportFile(fileName);
61  TFile *inFile = TFile::Open(AddInDir(fileName));
62  TTree *inTree = (TTree*) inFile->Get(fTreeName);
63 
64  if (fDisableFile != "") {
65  std::ifstream disableFile(fDisableFile.Data());
66  TString branchToDisable;
67  while (!disableFile.eof()) {
68  disableFile >> branchToDisable;
69  if (branchToDisable != "")
70  inTree->SetBranchStatus(branchToDisable, 0);
71  }
72  disableFile.close();
73  }
74 
75  if (fKeepFile != "") {
76  inTree->SetBranchStatus("*", 0);
77  std::ifstream keepFile(fKeepFile.Data());
78  TString branchToKeep;
79  while (!keepFile.eof()) {
80  keepFile >> branchToKeep;
81  if (branchToKeep != "")
82  inTree->SetBranchStatus(branchToKeep, 1);
83  }
84  keepFile.close();
85  }
86 
87  for (auto* branch : *(inTree->GetListOfBranches())) {
88  auto name = branch->GetName();
89  if (fCut.Contains(name))
90  inTree->SetBranchStatus(name, 1);
91  }
92 
93  TTreeFormula *cutter = new TTreeFormula("cutter",fCut,inTree);
94 
95  UInt_t runNum = 0;
96  UInt_t lumiNum = 0;
97  ULong64_t eventNum = 0;
98  inTree->SetBranchAddress(fRunExpr,&runNum);
99  inTree->SetBranchAddress(fLumiExpr,&lumiNum);
100  inTree->SetBranchAddress(fEventExpr,&eventNum);
101 
102  TFile *outFile = new TFile(AddOutDir(fileName),"RECREATE");
103  TTree *outTree = inTree->CloneTree(0);
104 
105  std::set<TString> eventsRecorded;
106  TString testString = "";
107 
108  Int_t badlumis = 0;
109  Int_t cutevents = 0;
110  Int_t filtered = 0;
111  Int_t duplicates = 0;
112 
113  Long64_t nentries = SetNumberOfEntries(inTree);
114 
115  for (Long64_t iEntry = 0; iEntry != nentries; ++iEntry) {
116  ReportProgress(iEntry);
117  inTree->GetEntry(iEntry);
118  if (fGoodLumiFilter.IsGood(runNum,lumiNum)) {
119  if (cutter->EvalInstance()) {
120  testString = TString::Format("%i:%i:%llu",runNum,lumiNum,eventNum);
121  if (fEventFilter.find(testString) != fEventFilter.end()) {
122  filtered++;
123  continue;
124  }
125  if (fCheckDuplicates) {
126  if (eventsRecorded.find(testString) == eventsRecorded.end())
127  eventsRecorded.insert(testString);
128  else {
129  std::cerr << "Duplicate: " << testString << std::endl;
130  duplicates++;
131  continue;
132  }
133  }
134  outTree->Fill();
135  }
136  else
137  cutevents++;
138  }
139  else
140  badlumis++;
141  }
142 
143  outFile->WriteTObject(outTree,fTreeName,"Overwrite");
144  for (UInt_t iObj = 0; iObj != fCopyObjects.size(); ++iObj) {
145  if (inFile->Get(fCopyObjects[iObj])) {
146  auto* tree = dynamic_cast<TTree*>(inFile->Get(fCopyObjects[iObj]));
147  if (tree) {
148  TTree* outtree = tree->CloneTree();
149  outFile->Write();
150  }
151  else
152  outFile->WriteTObject(inFile->Get(fCopyObjects[iObj])->Clone());
153  }
154  else
155  std::cout << "Could not find " << fCopyObjects[iObj] << " in " << fileName << std::endl;
156  }
157 
158  outFile->Close();
159  inFile->Close();
160 
161  std::cout << fileName << " events removed for" << std::endl;
162  std::cout << " Bad Runs: " << badlumis << std::endl;
163  std::cout << " Event Cut: " << cutevents << std::endl;
164  std::cout << " Filter: " << filtered << std::endl;
165  std::cout << " Duplicates: ";
166  if (fCheckDuplicates)
167  std::cout << duplicates << std::endl;
168  else
169  std::cout << "Not Checking" << std::endl;
170 
171 }
172 
173 //--------------------------------------------------------------------
176 {
177  FlatSkimmer *newSkimmer = new FlatSkimmer();
178  *newSkimmer = *this;
179  return newSkimmer;
180 }