eic-smear  1.0.3
A collection of ROOT classes for Monte Carlo events and a fast-smearing code simulating detector effects for the Electron-Ion Collider task force
Forester.cxx
Go to the documentation of this file.
1 
11 
12 #include <iomanip>
13 #include <memory>
14 #include <stdexcept>
15 #include <string>
16 
17 #include <TRefArray.h>
18 
20 #include "eicsmear/erhic/File.h"
22 
23 namespace erhic {
24 
26 : mQuit(false)
27 , mVerbose(false)
28 , mTree(NULL)
29 , mEvent(NULL)
30 , mFile(NULL)
31 , mRootFile(NULL)
32 , mMaxNEvents(0)
33 , mInterval(1)
34 , mTextFile(NULL)
35 , mInputName("default.txt")
36 , mOutputName("default.root")
37 , mTreeName("EICTree")
38 , mBranchName("event")
39 , mFactory(NULL) {
40 }
41 
43  if (mFile) {
44  delete mFile;
45  mFile = NULL;
46  } // if
47  if (mEvent) {
48  delete mEvent;
49  mEvent = NULL;
50  } // if
51  if (mFactory) {
52  delete mFactory;
53  mFactory = NULL;
54  } // if
55  if (mRootFile) {
56  delete mRootFile;
57  mRootFile = NULL;
58  } // if
59  if (mTextFile) {
60  delete mTextFile;
61  mTextFile = NULL;
62  } // if
63  // We don't delete the mTree pointer because mRootFile
64  // has ownership of it.
65 }
66 
67 Long64_t Forester::Plant() {
68  try {
69  // Initialisation of the input and output files.
70  OpenInput();
71  SetupOutput();
72  if (BeVerbose()) {
73  std::cout << "\nProcessing " << GetInputFileName() << std::endl;
74  } // if
79  static int i(0);
80  while (!MustQuit()) {
81  ++i;
82  if (BeVerbose() && i % mInterval == 0) {
83  // Make the field just wide enough for the maximum
84  // number of events.
85  int width = static_cast<int>(::log10(GetMaxNEvents()) + 1);
86  std::cout << "Processing event "<< std::setw(width) << i;
87  if (GetMaxNEvents() > 0) {
88  std::cout << "/" << std::setw(width) << GetMaxNEvents();
89  } // if
90  std::cout << std::endl;
91  } // if
92  // Build the next event
93  if (mEvent) {
94  delete mEvent;
95  mEvent = NULL;
96  } // if
97  // Catch exceptions from event builder here so we don't break
98  // out of the whole tree building loop for a single bad event.
99  try {
100  mEvent = mFactory->Create();
101  // Fill the tree
102  if (mEvent) {
103  mTree->Fill();
104  if (GetMaxNEvents() > 0 && i >= GetMaxNEvents()) {
105  SetMustQuit(true); // Hit max number of events, so quit
106  } // if
107  mStatus.ModifyEventCount(1);
108  mStatus.ModifyParticleCount(mEvent->GetNTracks());
109  // We must ResetBranchAddress before deleting the event.
110  } else {
111  break;
112  } // if
113  } // try
114  catch(std::exception& e) {
115  std::cerr << "Caught exception in Forester::Plant(): "
116  << e.what() << std::endl;
117  std::cerr << "Event will be skipped..." << std::endl;
118  } // catch
119  } // while
120  Finish();
121  return 0;
122  } // try
123  catch(std::exception& e) {
124  std::cerr << "Caught exception in Forester::Plant(): "
125  << e.what() << std::endl;
126  return -1;
127  } // catch
128 }
129 
131  try {
132  // Open the input file for reading.
133  if (!mTextFile) {
134  mTextFile = new std::ifstream;
135  } // if
136  mTextFile->open(GetInputFileName().c_str());
137  // Throw a runtime_error if the file could not be opened.
138  if (!mTextFile->good()) {
139  std::string message("Unable to open file ");
140  throw std::runtime_error(message.append(GetInputFileName()));
141  } // if
142  // Determine which Monte Carlo generator produced the file.
143  mFile =
145  if (!mFile) {
146  throw std::runtime_error(GetInputFileName() +
147  " is not from a supported generator");
148  } // for
150  return true;
151  } // try...
152  // Pass the exception on to be dealt with higher up the food chain.
153  catch(std::exception&) {
154  throw;
155  } // catch
156 }
157 
159  try {
160  // Open the ROOT file and check it opened OK
161  mRootFile = new TFile(GetOutputFileName().c_str(), "RECREATE");
162  if (!mRootFile->IsOpen()) {
163  std::string message("Unable to open file ");
164  throw std::runtime_error(message.append(GetOutputFileName()));
165  } // if
166  // Create the tree and check for errors
167  mTree = new TTree(GetTreeName().c_str(), "my EIC tree");
168  if (!mTree) {
169  std::string message("Error allocating TTree ");
170  throw std::runtime_error(message.append(GetTreeName()));
171  } // if
172  // Allocate memory for the branch buffer and
173  // add the branch to the tree
174  AllocateEvent();
175  mTree->Branch(GetBranchName().c_str(), mEvent->ClassName(),
176  &mEvent, 32000, 99);
177  // Auto-save every 500 MB
178  mTree->SetAutoSave(500LL * 1024LL * 1024LL);
179  // Align the input file at the start of the first event.
180  FindFirstEvent();
181  // Start timing after opening and creating files,
182  // before looping over events
183  mStatus.StartTimer();
184  return true;
185  } // try...
186  catch(std::exception&) {
187  throw;
188  } // catch
189 }
190 
192  if (BeVerbose()) {
193  std::cout << "\nProcessed " << GetInputFileName() << std::endl;
194  } // if
195  // Write the TTree to the file.
196  mRootFile = mTree->GetCurrentFile();
197  mRootFile->cd();
198  mTree->Write();
199  mRootFile->ls();
200  // Write the Forester itself to make it easier to reproduce the file
201  // with the same settings.
202  Write("forester");
203  // Reset quit flag in case of further runs.
204  SetMustQuit(false);
205  // Stop timing the run.
206  mStatus.StopTimer();
207  if (BeVerbose()) {
208  GetGetStatus().Print(std::cout); // Messages for the user
209  } // if
210  mRootFile->Close();
211 }
212 
214  try {
215  if (mEvent) {
216  delete mEvent;
217  mEvent = NULL;
218  } // if
220  return mEvent;
221  } // try...
222  // Catch exceptions and pass up the food chain
223  catch(std::exception&) {
224  throw;
225  } // catch
226 }
227 
229  // Naughty kludge alert!
230  // The first line was already read to determine the generator.
231  // The header in the text files is six lines, so
232  // read the remaining five lines of header.
233  std::getline(*mTextFile, mLine);
234  std::getline(*mTextFile, mLine);
235  std::getline(*mTextFile, mLine);
236  std::getline(*mTextFile, mLine);
237  std::getline(*mTextFile, mLine);
238  return true;
239 }
240 
241 void Forester::Print(std::ostream& os) const {
242  os << "Input file: " << mInputName << std::endl;
243  os << "Output file: " << mOutputName << std::endl;
244  os << "Output tree: " << mTreeName << std::endl;
245  os << "Output branch: " << mBranchName << std::endl;
246  os << "Maximum number of events: " << mMaxNEvents << std::endl;
247  if (mEvent) {
248  os << "Event type: " << mEvent->ClassName() << std::endl;
249  } // if
250 }
251 
252 void Forester::Print(Option_t* /* not used */) const {
253  Print(std::cout);
254 }
255 } // namespace erhic
Status mStatus
Forester status information.
Definition: Forester.h:286
const Status & GetGetStatus() const
Definition: Forester.h:217
std::string mLine
Stores the latest text line read from the input file.
Definition: Forester.h:285
virtual VirtualEvent * Create()=0
std::ifstream * mTextFile
Input text file.
Definition: Forester.h:280
virtual EventBase * AllocateEvent() const =0
std::string mOutputName
Name of the output ROOT file.
Definition: Forester.h:282
std::string mBranchName
Name of the event TBranch.
Definition: Forester.h:284
TFile * mRootFile
Pointer to output ROOT file.
Definition: Forester.h:277
std::string GetInputFileName() const
Definition: Forester.h:308
Long64_t Plant()
Definition: Forester.cxx:67
void Print(std::ostream &stream) const
Definition: Forester.cxx:241
const erhic::FileType * mFile
File type information.
Definition: Forester.h:276
static FileFactory & GetInstance()
Definition: File.cxx:518
std::string GetOutputFileName() const
Definition: Forester.h:312
std::string mInputName
Name of the input text file.
Definition: Forester.h:281
VirtualEvent * mEvent
Stores event branch address.
Definition: Forester.h:275
std::string GetTreeName() const
Definition: Forester.h:316
virtual UInt_t GetNTracks() const =0
bool FindFirstEvent()
Definition: Forester.cxx:228
Long64_t mInterval
Event interval between printing status messages.
Definition: Forester.h:279
Long64_t GetMaxNEvents() const
Definition: Forester.h:328
std::string GetBranchName() const
Definition: Forester.h:320
virtual ~Forester()
Definition: Forester.cxx:42
const FileType * GetFile(const std::string &generatorName) const
Definition: File.cxx:523
VirtualEventFactory * mFactory
Pointer to the event-builder object.
Definition: Forester.h:287
bool BeVerbose() const
Definition: Forester.h:348
Long64_t mMaxNEvents
Maximum number of events to process.
Definition: Forester.h:278
std::string mTreeName
Name of the output TTree.
Definition: Forester.h:283
bool SetupOutput()
Definition: Forester.cxx:158
TTree * mTree
Output TTree, owned by mRootFile.
Definition: Forester.h:274
bool AllocateEvent()
Definition: Forester.cxx:213
void SetMustQuit(bool quit)
Definition: Forester.h:340
bool MustQuit() const
Definition: Forester.h:336
virtual VirtualEventFactory * CreateEventFactory(std::istream &) const =0
bool OpenInput()
Definition: Forester.cxx:130