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
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
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 
257  : mNEvents(0)
258  , mNParticles(0) {
259  // Initialise the start and end time to the creation time and reset
260  // the timer to ensure it is at zero.
261  std::time(&mStartTime);
263  mTimer.Reset();
264  }
265 
266  Forester::Status::~Status() { /* noop */ }
267 
268  std::ostream& Forester::Status::Print(std::ostream& os) const {
269  // Put start and end times in different os <<... otherwise I get
270  // the same time for each...
271  os << "Began on " << std::ctime(&mStartTime);
272  os << "Ended on " << std::ctime(&mEndTime);
273  os << "Processed " << mNEvents << " events containing "
274  << mNParticles << " particles in "
275  << mTimer.RealTime() << " seconds "
276  << '(' << mTimer.RealTime()/mNEvents <<" sec/event)" << std::endl;
277  return os;
278  }
279 
281  std::time(&mStartTime);
282  mTimer.Start();
283  }
284 
286  std::time(&mEndTime);
287  mTimer.Stop();
288  }
289 
290  void Forester::Status::ModifyEventCount(Long64_t count) {
291  mNEvents += count;
292  }
293 
295  mNParticles += count;
296  }
297 
298  // ClassImp( ForesterStatus ); // throws error for some reason
299 
300 
301 
302 } // namespace erhic
erhic::Forester::mFile
const erhic::FileType * mFile
< Stores event branch address
Definition: Forester.h:244
erhic::Forester::Forester
Forester()
Default constructor.
Definition: Forester.cxx:25
erhic::Forester::Status::mEndTime
time_t mEndTime
Definition: Forester.h:167
erhic::Forester::Finish
void Finish()
Writes output and takes end-of-file actions.
Definition: Forester.cxx:191
erhic::Forester::BeVerbose
bool BeVerbose() const
Returns the verbosity i.e.
Definition: Forester.h:317
erhic::FileFactory::GetFile
const FileType * GetFile(const std::string &generatorName) const
Returns a FileType object for the named generator.
Definition: File.cxx:525
erhic
Definition: EventDis.cxx:14
erhic::Forester::mEvent
VirtualEvent * mEvent
< Output TTree, owned by mRootFile
Definition: Forester.h:243
erhic::Forester::mMaxNEvents
Long64_t mMaxNEvents
< Pointer to output ROOT file
Definition: Forester.h:246
erhic::Forester::Status::~Status
virtual ~Status()
Definition: Forester.cxx:266
File.h
erhic::Forester::Status::StartTimer
virtual void StartTimer()
Definition: Forester.cxx:280
erhic::Forester::Status::ModifyParticleCount
virtual void ModifyParticleCount(Long64_t count)
Definition: Forester.cxx:294
erhic::Forester::GetInputFileName
std::string GetInputFileName() const
Returns the name of the input text file containing Monte Carlo data.
Definition: Forester.h:277
erhic::Forester::MustQuit
bool MustQuit() const
Prints the quit flag status.
Definition: Forester.h:305
erhic::Forester::Status::StopTimer
virtual void StopTimer()
Definition: Forester.cxx:285
erhic::Forester::mTextFile
std::ifstream * mTextFile
Definition: Forester.h:249
erhic::Forester::GetOutputFileName
std::string GetOutputFileName() const
Returns the name of the ROOT tree file to create.
Definition: Forester.h:281
erhic::Forester::FindFirstEvent
bool FindFirstEvent()
Aligns the input text file on the first line of the first event.
Definition: Forester.cxx:228
erhic::Forester::mStatus
Status mStatus
Forester status information.
Definition: Forester.h:255
erhic::Forester::Status::Status
Status()
Definition: Forester.cxx:256
erhic::Forester::mBranchName
std::string mBranchName
Name of the event TBranch.
Definition: Forester.h:253
erhic::FileType::CreateEventFactory
virtual VirtualEventFactory * CreateEventFactory(std::istream &) const =0
Returns a new event object for the generator making this type of file.
erhic::Forester::SetMustQuit
void SetMustQuit(bool quit)
Set the quit flag.
Definition: Forester.h:309
erhic::Forester::GetGetStatus
const Status & GetGetStatus() const
Prints a summary of the last call to Plant() to the requested output stream.
Definition: Forester.h:184
erhic::Forester::Print
void Print(std::ostream &stream) const
Prints the current configuration to the requested output stream.
Definition: Forester.cxx:241
erhic::VirtualEvent::GetNTracks
virtual UInt_t GetNTracks() const =0
Returns the number of tracks in the event.
erhic::Forester::SetupOutput
bool SetupOutput()
Opens the output ROOT file and creates the TTree ready for filling.
Definition: Forester.cxx:158
erhic::Forester::Status::Print
virtual std::ostream & Print(std::ostream &os=std::cout) const
Definition: Forester.cxx:268
Forester.h
erhic::Forester::AllocateEvent
bool AllocateEvent()
Allocate an event buffer for the TTree based on the generator type.
Definition: Forester.cxx:213
erhic::Forester::GetMaxNEvents
Long64_t GetMaxNEvents() const
Returns the maximum number of events to process.
Definition: Forester.h:297
erhic::Forester::mTree
TTree * mTree
Definition: Forester.h:242
erhic::Forester::mTreeName
std::string mTreeName
Name of the output TTree.
Definition: Forester.h:252
erhic::Forester::GetBranchName
std::string GetBranchName() const
Returns the name of the TBranch containing event objects.
Definition: Forester.h:289
erhic::Forester::mOutputName
std::string mOutputName
Name of the output ROOT file.
Definition: Forester.h:251
erhic::VirtualEventFactory::Create
virtual VirtualEvent * Create()=0
Returns a new event instance.
erhic::FileType::AllocateEvent
virtual EventBase * AllocateEvent() const =0
Returns a new event object for the generator making this type of file.
erhic::Forester::Plant
Long64_t Plant()
Processes a text file into a ROOT file.
Definition: Forester.cxx:67
erhic::Forester::Status::mStartTime
time_t mStartTime
Definition: Forester.h:166
erhic::Forester::mFactory
VirtualEventFactory * mFactory
Definition: Forester.h:256
erhic::Forester::mInterval
Long64_t mInterval
Event interval between printing status messages.
Definition: Forester.h:247
erhic::Forester::~Forester
virtual ~Forester()
Destructor.
Definition: Forester.cxx:42
erhic::FileFactory::GetInstance
static FileFactory & GetInstance()
Returns the single instance of FileFactory.
Definition: File.cxx:520
erhic::Forester::OpenInput
bool OpenInput()
Opens the input file and checks that it was produced by a supported Monte Carlo generator.
Definition: Forester.cxx:130
erhic::Forester::Status::mTimer
TStopwatch mTimer
Definition: Forester.h:172
erhic::Forester::mRootFile
TFile * mRootFile
< File type information
Definition: Forester.h:245
erhic::Forester::GetTreeName
std::string GetTreeName() const
Returns the name of the TTree to write to the file named by SetOutputFileName().
Definition: Forester.h:285
erhic::Forester::mInputName
std::string mInputName
< Input text file
Definition: Forester.h:250
EventFactory.h
erhic::Forester::mLine
std::string mLine
Stores the latest text line read from the input file.
Definition: Forester.h:254
ParticleIdentifier.h
erhic::Forester::Status::ModifyEventCount
virtual void ModifyEventCount(Long64_t count)
Definition: Forester.cxx:290