HighLAND
SimpleLoopBase.cxx
1 #include "SimpleLoopBase.hxx"
2 #include "Parameters.hxx"
3 #include "Header.hxx"
4 #include <sys/time.h>
5 
6 // save all trees every 5000 entries
7 const int NENTRIES_TREESAVE_SIMPLE=5000;
8 
9 //********************************************************************
10 SimpleLoopBase::SimpleLoopBase(int argc, char *argv[]){
11 //********************************************************************
12  std::string programName = argv[0];
13  std::string paramFile = "";
14  _entry_nmax = 0;
15  _entry_imin = 0;
16  _outputFileName = "";
17  _inputFileName = "";
18  _cosmicMode = false;
19  _versionCheck = true;
20  bool logMemory = false;
21 
22  for (;;) {
23  int c = getopt(argc, argv, "cvmn:o:p:s:");
24  if (c < 0)
25  break;
26  switch (c) {
27  case 'c': {
28  _cosmicMode = true;
29  break;
30  }
31  case 'v': {
32  _versionCheck = false;
33  break;
34  }
35  case 'm': {
36  logMemory = true;
37  break;
38  }
39  case 'n': {
40  std::istringstream tmp(optarg);
41  tmp >> _entry_nmax;
42  break;
43  }
44  case 'o': {
45  _outputFileName = optarg;
46  break;
47  }
48  case 'p': {
49  paramFile = optarg;
50  break;
51  }
52  case 's': {
53  std::istringstream tmp(optarg);
54  tmp >> _entry_imin;
55  break;
56  }
57  default: {
58  PrintUsage(programName);
59  }
60  }
61  }
62 
63  // Check that an output file was specified
64  if (_outputFileName == "") {
65  std::cerr << "ERROR: No output file" << std::endl << std::endl;
66  PrintUsage(programName);
67  }
68 
69  // Check that there is an input file.
70  if (argc <= optind) {
71  std::cerr << "ERROR: No input file" << std::endl << std::endl;
72  PrintUsage(programName);
73  } else if (argc != optind + 1) {
74  std::cerr << "ERROR: Only one input file may be specified. To process multiple ROOT files, " << std::endl
75  << " list them in a text file, and specify that text file as the input." << std::endl << std::endl;
76  PrintUsage(programName);
77  }
78 
79  _inputFileName = argv[optind++];
80 
81  // Set up the parameter override file if it was specified
82  if (paramFile != "") {
83  ND::params().ReadParamOverrideFile(paramFile);
84  }
85 
86  // Make sure no parameters have been accessed yet
88 
89  _memory.Enable(logMemory);
90 
91  /*
92  // Add package versions to be saved in config tree
93  ND::versioning().AddPackage("psycheCore", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHECOREROOT")));
94  ND::versioning().AddPackage("psycheUtils", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHEUTILSROOT")));
95  ND::versioning().AddPackage("highlandTools", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDTOOLSROOT")));
96  ND::versioning().AddPackage("highlandCorrections", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDCORRECTIONSROOT")));
97  ND::versioning().AddPackage("highlandIO", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDIOROOT")));
98  */
99  SetDocStringManager(&_docStrings);
100 }
101 
102 //********************************************************************
104 //********************************************************************
105 
106  // Initialize the InputManager by specifying the input type and the input file
107  if (!input().Initialize(_inputFileName,_inputFileType,_cosmicMode)) return false;
108 
109  // Read corrections from the input file
110 
111  // When running over a FlatTree corrections may already exist in it.
112  // It that case corrections are read from the input file (config tree) and added to the CorrectionManager.
113  // In this case each correction is stored as
114  // "appliedInInput" and "disabled", such that it is not applied twice.
115  if (!_input.InputIsOriginalTree()){
117  }
118 
119  // Initialize the tree manager
120  if (!OutputManager::Initialize()) return false;
121 
122  // Open the output file
123  if (!OpenOutputFile(_outputFileName)) return false;
124 
125  // Initialize the top level algorithm
126  if (!Initialize()) return false;
127 
128  // Print on the screen the corrections
130 
131  // if (input().GetChain() == 0) return;
132 
133  // Define the output tree
135 
136  // Create and fill the "config" tree with a single entry
137  FillConfigTree();
138 
139  return true;
140 }
141 
142 //********************************************************************
144 //********************************************************************
145 
146  // Initialize the tree manager
147  OutputManager::InitializeEntry();
148 
149  // To compute the entry increment
150  Int_t entry0 = _entry;
151 
152  // Fill the spill structure for the current spill from the input tree
153  // The previous succesfully read spill is deleted internally if the current spill is OK
154  bool spillOK = input().LoadSpill(_entry);
155 
156  // To compute the entry increment
157  Int_t entry1 = _entry;
158 
159  // Increment the number of entries run so far
160  _entry_count += entry1-entry0;
161 
162  // Dump info about number of entries run
163  if (_entry_count%1000==0 || _entry_count == _entry_nmax)
164  std::cout << "entry: " << _entry_count << " of " << _entry_nmax << " (" << (100*_entry_count/_entry_nmax) << "%) --> " << _entry << std::endl;
165 
166  // return if the read spill is not OK
167  if (!spillOK) return false;
168 
169  // Apply corrections
170  _corrections.ApplyCorrections(input().GetCorrectedSpill());
171 
172  // Create a clone of the Corrected Spill
173  input().MakeFinalSpill();
174 
175  // Record the POT for this spill
176  input().IncrementPOTBySpill();
177 
178  // initialize the MyAnalysis spill
179  if (!InitializeSpill()) return false;
180 
181  return true;
182 }
183 
184 //********************************************************************
186 //********************************************************************
187 
188  // Finalize the derived class
189  FinalizeSpill();
190 
191  // Save all trees every NENTRIES_TREESAVE_SIMPLE entries
192  if (_entry%NENTRIES_TREESAVE_SIMPLE == 0){
193  std::vector< TTree* >::iterator it;
194  for (it=GetTrees().begin();it!=GetTrees().end();it++){
195  (*it)->AutoSave("SaveSelf");
196  }
197  }
198 
199  // Log memory usage
200  _memory.LogMemory();
201 
202  // Finalize the input manager (delete Spill and RawSpill)
203  // input().FinalizeSpill();
204 }
205 
206 //********************************************************************
208 //********************************************************************
209 
210  // Finalize the derived class
211  Finalize();
212 
213  // Create and fill the header tree with a single entry
214  AddTreeWithName(OutputManager::header,"header");
215  Header* headerp = &_input.header();
216  GetTree(OutputManager::header)->Branch("POTInfo","Header",&headerp,32000,0);
217  GetTree(OutputManager::header)->Fill();
218 
219  // Save all trees after looping over all events
220  std::vector< TTree* >::iterator it;
221  for (it=GetTrees().begin();it!=GetTrees().end();it++){
222  (*it)->AutoSave("SaveSelf");
223  }
224 
225  // Finalize the base class
226  OutputManager::Finalize();
227 
228  // Clean up
229  input().RemoveConverters();
230 
231  // Write out the memory used.
232  _memory.Write();
233 
234  // Close the output file
235  CloseOutputFile();
236 }
237 
238 //********************************************************************
240 //********************************************************************
241 
243 }
244 
245 //********************************************************************
246 void SimpleLoopBase::Loop(int nmax,int imin){
247 //********************************************************************
248 
249  if (!SimpleLoopBase::Initialize()) return;
250 
251  // Get the number of entries in the tree
252  Long64_t nentries = _input.GetEntries();
253 
254  if (imin>nentries){
255  std::cout << "SimpleLoopBase::Loop(). input tree has " << nentries << " entries. You cannot start from entry " << imin << std::endl;
256  return;
257  }
258 
259  // Compute the number of entries to be run
260  if (nmax==0 || imin+nmax>nentries) _entry_nmax = nentries-imin;
261  else _entry_nmax = nmax;
262 
263  // Compute the number of the last entry to be run
264  _entry_imax = _entry_imin+_entry_nmax;
265 
266  if (input().InputIsFlatTree())
267  std::cout << "SimpleLoopBase::Loop(). input tree has " << nentries << " entries for " << input().header().GetPOT() << " good POT" << std::endl;
268  else
269  std::cout << "SimpleLoopBase::Loop(). input tree has " << nentries << " entries (POT counted on the fly)" << std::endl;
270  std::cout << "SimpleLoopBase::Loop(). loop over " << _entry_nmax << " entries from entry number "<< _entry_imin << std::endl;
271 
272  // Initialize clock
273  timeval tim;
274  gettimeofday(&tim, NULL);
275  double t0=tim.tv_sec+(tim.tv_usec/1000000.0);
276 
277  //--------- Loop over entries in the tree ----------------------------------
278  _entry=_entry_imin;
279 
280  while (_entry<_entry_imax) {
281  if (!SimpleLoopBase::InitializeSpill()) continue;
282  Process();
284  }
286 
287  gettimeofday(&tim, NULL);
288  double t1=tim.tv_sec+(tim.tv_usec/1000000.0);
289 
290  std::cout << "--------- time profile --------------" << std::endl;
291  std::cout << _entry_nmax << " entries processed in " << t1-t0 << " seconds" << std::endl;
292 
293 }
294 
295 //********************************************************************
297 //********************************************************************
298 
299  // Add a tree
300  AddTreeWithName(OutputManager::config, "config");
301 
302 
303  SetFillSingleTree(OutputManager::config);
304 
305  // The $CMTPATH
306  AddVar(OutputManager::config, SimpleLoopBase::CMTPATH, "CMTPATH", "C", "the CMTPATH used to produce the output file");
307  FillVar(SimpleLoopBase::CMTPATH, (std::string)getenv("CMTPATH") );
308 
309  // The Machine name
310  AddVar(OutputManager::config, SimpleLoopBase::HOSTNAME, "HOSTNAME", "C", "the machine used to produce the output file");
311  if (getenv("HOSTNAME"))
312  FillVar(SimpleLoopBase::HOSTNAME, (std::string)getenv("HOSTNAME") );
313  else
314  FillVar(SimpleLoopBase::HOSTNAME, "unknown" );
315 
316  // The input file name
317  AddVar(OutputManager::config, SimpleLoopBase::INPUTFILE, "InputFile", "C", "the input file used to produce the output file");
318  FillVar(SimpleLoopBase::INPUTFILE, _inputFileName );
319 
320  // The original file (i.e. the recon output file)
321  AddVar(OutputManager::config, SimpleLoopBase::OriginalFile, "OriginalFile", "C", "the original file used to produce the output file");
322 
323  if (!_input.InputIsOriginalTree()){
324  TChain* chain = new TChain("config");
325  chain->AddFile(_inputFileName.c_str());
326  char OriginalFile[200]="unknown";
327  if (chain->FindLeaf("OriginalFile")){
328  chain->SetBranchAddress("OriginalFile", OriginalFile);
329  Long64_t centry = chain->LoadTree(0);
330  Int_t nb = chain->GetEntry(0);
331  (void) centry;
332  (void) nb;
333  }
334  FillVar(SimpleLoopBase::OriginalFile, OriginalFile );
335  }
336  else
337  FillVar(SimpleLoopBase::OriginalFile, _inputFileName );
338 
339 
340  SetFillAllTrees();
341 
342 
343  // The software version
344  ND::versioning().WriteClonesArray(*GetTree(OutputManager::config));
345 
346  // docstrings
347  _docStrings.WriteClonesArray(*GetTree(OutputManager::config));
348 
349  // DocStringManager* doc= &(_docStrings);
350  // OutputManager::GetTree(OutputManager::config)->Branch("DocMan","DocStringManager",&doc,64000,0);
351 
352 
353  // Corrections
354  _corrections.WriteClonesArray(*GetTree(OutputManager::config));
355 
356  // CorrectionManager* corr= &(_corrections);
357  // OutputManager::GetTree(OutputManager::config)->Branch("CorrMan","CorrectionManager",&corr,64000,0);
358 
359 
360  // Fill the tree
361  GetTree(OutputManager::config)->Fill();
362  GetTree(OutputManager::config)->AutoSave("SaveSelf");
363 }
364 
365 //********************************************************************
366 void SimpleLoopBase::PrintUsage(const std::string& programName){
367 //********************************************************************
368  std::cout << "usage: " << programName << " [options] [input-file]" << std::endl;
369  std::cout << std::endl;
370  std::cout << "Options:" << std::endl;
371  std::cout << " -c Run in cosmics mode, putting all tracks in one 'bunch'" << std::endl;
372  std::cout << " -n <cnt> Only read <cnt> events" << std::endl;
373  std::cout << " -o <file> Set the name of an output file (mandatory)" << std::endl;
374  std::cout << " -s <cnt> Skip <cnt> events" << std::endl;
375  std::cout << " -p <file> Set the name of a parameter override file" << std::endl;
376  std::cout << " -v Don't Check version compatibility between nd280AnalysisTools and oaAnalysis file" << std::endl;
377  std::cout << " -m Log memory usage (written to histograms in output file)" << std::endl;
378  std::exit(1);
379 }
380 
381 //********************************************************************
383 //********************************************************************
384  Loop(_entry_nmax,_entry_imin);
385 }
void AddVar(Int_t index, const std::string &name, const std::string &type, const std::string &doc, double ini=-9999)
Add a single variable to all trees.
void Loop(int nmax=0, int imin=0)
void LogMemory()
Definition: MemoryUsage.cxx:18
void AddTreeWithName(Int_t tree_index, const std::string &tree_name, TTree *tree=NULL)
Add a tree provided its index and name.
virtual void DefineOutputTree()
Define the tree that should be written to the output file.
CorrectionManager _corrections
Correction manager.
This class handles POT info, SoftwareVersion and IsMC.
Definition: Header.hxx:10
void RemoveConverters()
Delete all the converters that have been added.
void IncrementPOTBySpill()
MemoryUsage _memory
Memory logging.
std::string _inputFileName
Input file name, as specified by the user.
Double_t GetPOT()
This is the method used externaly. It corresponds to POT that passed beam and ND280 quality cuts...
Definition: Header.hxx:36
virtual bool InitializeSpill()
void ApplyCorrections(AnaSpillC &spill)
Apply all corrections.
virtual bool Process()=0
Long64_t _entry
The current entry in the file.
void PrintUsage(const std::string &programName)
Print the program&#39;s usage statement.
virtual void FinalizeSpill()
Finalize each spill, including cleaning up data read from the input file.
void ReadParamOverrideFile(TString filename)
Definition: Parameters.cxx:192
virtual bool Initialize()
virtual void Finalize()
Long64_t GetEntries()
Return the number of entries in the input file tree(s).
void FillVar(Int_t index, Float_t var)
Fill a single variable.
void DumpCorrections()
Dump all corrections.
std::vector< TTree *> & GetTrees()
Returns the map of trees.
Definition: TreeManager.hxx:25
void CloseOutputFile()
close the output file
DocStringManager _docStrings
DocStrings manager.
void MakeFinalSpill()
Creates a clone of the corrected Spill. This must be done after applying corrections.
bool OpenOutputFile(const std::string &file)
open the output file
bool _versionCheck
Check version compatibility between nd280AnalysisTools compilation and oaAnalysis file...
void Enable(bool enable=true)
Definition: MemoryUsage.cxx:14
TTree * GetTree()
Returns the a tree set as current.
Definition: TreeManager.hxx:34
void FillConfigTree()
Fill the "config" tree, which includes details of the analysis cuts etc.
void Write()
Write histograms of the memory usage to the output file.
Definition: MemoryUsage.cxx:27
std::string _inputFileType
bool LoadSpill(Long64_t &entry)
std::string _outputFileName
The output file name, as specified by the user.
void SetReadParamOverrideFilePointPassed()
Set whether the point in which the overwride parameters file is read is passed or not...
Definition: Parameters.hxx:110
void ReadCorrections(const std::string &file, bool input=false)
Readthe corrections from a file.
bool InputIsOriginalTree()
Whether an OriginalTree converter has been selected.