Warning, /eic-smear/src/erhic/Forester.cxx.betterbutdifferent is written in an unsupported language. File is not indexed.
0001 /**
0002 \file
0003 Implementation of class erhic::Forester.
0004
0005 \author Thomas Burton
0006 \date 2011-06-23
0007 \copyright 2011 Brookhaven National Lab
0008 */
0009
0010 #include "eicsmear/erhic/Forester.h"
0011
0012 #include <iomanip>
0013 #include <memory>
0014 #include <stdexcept>
0015 #include <string>
0016
0017 #include <TRefArray.h>
0018
0019 #include "eicsmear/erhic/EventFactory.h"
0020 #include "eicsmear/erhic/File.h"
0021 #include "eicsmear/erhic/ParticleIdentifier.h"
0022
0023 namespace erhic {
0024
0025 Forester::Forester()
0026 : mQuit(false)
0027 , mVerbose(false)
0028 , mTree(NULL)
0029 , mEvent(NULL)
0030 , mFile(NULL)
0031 , mRootFile(NULL)
0032 , mMaxNEvents(0)
0033 , mInterval(1)
0034 , mTextFile(NULL)
0035 , mInputName("default.txt")
0036 , mOutputName("default.root")
0037 , mTreeName("EICTree")
0038 , mBranchName("event")
0039 , mFactory(NULL) {
0040 }
0041
0042 Forester::~Forester() {
0043 if (mFile) {
0044 delete mFile;
0045 mFile = NULL;
0046 } // if
0047 if (mEvent) {
0048 delete mEvent;
0049 mEvent = NULL;
0050 } // if
0051 if (mFactory) {
0052 delete mFactory;
0053 mFactory = NULL;
0054 } // if
0055 if (mRootFile) {
0056 delete mRootFile;
0057 mRootFile = NULL;
0058 } // if
0059 if (mTextFile) {
0060 delete mTextFile;
0061 mTextFile = NULL;
0062 } // if
0063 // We don't delete the mTree pointer because mRootFile
0064 // has ownership of it.
0065 }
0066
0067 Long64_t Forester::Plant() {
0068 try {
0069 // Initialisation of the input and output files.
0070 OpenInput();
0071 SetupOutput();
0072 if (BeVerbose()) {
0073 std::cout << "\nProcessing " << GetInputFileName() << std::endl;
0074 } // if
0075 /**
0076 \todo Get rid of the static counter. Replace with a member
0077 that is reset every time Plant() is called.
0078 */
0079 static int i(0);
0080 while (!MustQuit()) {
0081 ++i;
0082 if (BeVerbose() && i % mInterval == 0) {
0083 // Make the field just wide enough for the maximum
0084 // number of events.
0085 int width = static_cast<int>(::log10(GetMaxNEvents()) + 1);
0086 std::cout << "Processing event "<< std::setw(width) << i;
0087 if (GetMaxNEvents() > 0) {
0088 std::cout << "/" << std::setw(width) << GetMaxNEvents();
0089 } // if
0090 std::cout << std::endl;
0091 } // if
0092 // Build the next event
0093 if (mEvent) {
0094 delete mEvent;
0095 mEvent = NULL;
0096 } // if
0097 // Catch exceptions from event builder here so we don't break
0098 // out of the whole tree building loop for a single bad event.
0099 try {
0100 mEvent = mFactory->Create();
0101 // Fill the tree
0102 if (mEvent) {
0103 mTree->Fill();
0104 if (GetMaxNEvents() > 0 && i >= GetMaxNEvents()) {
0105 SetMustQuit(true); // Hit max number of events, so quit
0106 } // if
0107 mStatus.ModifyEventCount(1);
0108 mStatus.ModifyParticleCount(mEvent->GetNTracks());
0109 // We must ResetBranchAddress before deleting the event.
0110 } else {
0111 break;
0112 } // if
0113 } // try
0114 catch(std::exception& e) {
0115 std::cerr << "Caught exception in Forester::Plant(): "
0116 << e.what() << std::endl;
0117 std::cerr << "Event will be skipped..." << std::endl;
0118 } // catch
0119 } // while
0120 Finish();
0121 return 0;
0122 } // try
0123 catch(std::exception& e) {
0124 std::cerr << "Caught exception in Forester::Plant(): "
0125 << e.what() << std::endl;
0126 return -1;
0127 } // catch
0128 }
0129
0130 bool Forester::OpenInput() {
0131 try {
0132 // Open the input file for reading.
0133 if (!mTextFile) {
0134 mTextFile = new std::ifstream;
0135 } // if
0136 mTextFile->open(GetInputFileName().c_str());
0137 // Throw a runtime_error if the file could not be opened.
0138 if (!mTextFile->good()) {
0139 std::string message("Unable to open file ");
0140 throw std::runtime_error(message.append(GetInputFileName()));
0141 } // if
0142 // Determine which Monte Carlo generator produced the file.
0143 mFile =
0144 erhic::FileFactory::GetInstance().GetFile(*mTextFile);
0145 if (!mFile) {
0146 throw std::runtime_error(GetInputFileName() +
0147 " is not from a supported generator");
0148 } // for
0149 mFactory = mFile->CreateEventFactory(*mTextFile);
0150 return true;
0151 } // try...
0152 // Pass the exception on to be dealt with higher up the food chain.
0153 catch(std::exception&) {
0154 throw;
0155 } // catch
0156 }
0157
0158 bool Forester::SetupOutput() {
0159 try {
0160 // Open the ROOT file and check it opened OK
0161 mRootFile = new TFile(GetOutputFileName().c_str(), "RECREATE");
0162 if (!mRootFile->IsOpen()) {
0163 std::string message("Unable to open file ");
0164 throw std::runtime_error(message.append(GetOutputFileName()));
0165 } // if
0166 // Create the tree and check for errors
0167 mTree = new TTree(GetTreeName().c_str(), "my EIC tree");
0168 if (!mTree) {
0169 std::string message("Error allocating TTree ");
0170 throw std::runtime_error(message.append(GetTreeName()));
0171 } // if
0172 // Allocate memory for the branch buffer and
0173 // add the branch to the tree
0174 AllocateEvent();
0175 mTree->Branch(GetBranchName().c_str(), mEvent->ClassName(),
0176 &mEvent, 32000, 99);
0177 // Auto-save every 500 MB
0178 mTree->SetAutoSave(500LL * 1024LL * 1024LL);
0179 // Align the input file at the start of the first event.
0180 FindFirstEvent();
0181 // Start timing after opening and creating files,
0182 // before looping over events
0183 mStatus.StartTimer();
0184 return true;
0185 } // try...
0186 catch(std::exception&) {
0187 throw;
0188 } // catch
0189 }
0190
0191 void Forester::Finish() {
0192 if (BeVerbose()) {
0193 std::cout << "\nProcessed " << GetInputFileName() << std::endl;
0194 } // if
0195 // Write the TTree to the file.
0196 mRootFile = mTree->GetCurrentFile();
0197 mRootFile->cd();
0198 mTree->Write();
0199 mRootFile->ls();
0200 // Write the Forester itself to make it easier to reproduce the file
0201 // with the same settings.
0202 Write("forester");
0203 // Reset quit flag in case of further runs.
0204 SetMustQuit(false);
0205 // Stop timing the run.
0206 mStatus.StopTimer();
0207 if (BeVerbose()) {
0208 GetGetStatus().Print(std::cout); // Messages for the user
0209 } // if
0210 mRootFile->Close();
0211 }
0212
0213 bool Forester::AllocateEvent() {
0214 try {
0215 if (mEvent) {
0216 delete mEvent;
0217 mEvent = NULL;
0218 } // if
0219 mEvent = mFile->AllocateEvent();
0220 return mEvent;
0221 } // try...
0222 // Catch exceptions and pass up the food chain
0223 catch(std::exception&) {
0224 throw;
0225 } // catch
0226 }
0227
0228 bool Forester::FindFirstEvent() {
0229 // Naughty kludge alert!
0230 // The first line was already read to determine the generator.
0231 // The header in the text files is six lines, so
0232 // read the remaining five lines of header.
0233 std::getline(*mTextFile, mLine);
0234 std::getline(*mTextFile, mLine);
0235 std::getline(*mTextFile, mLine);
0236 std::getline(*mTextFile, mLine);
0237 std::getline(*mTextFile, mLine);
0238 return true;
0239 }
0240
0241 void Forester::Print(std::ostream& os) const {
0242 os << "Input file: " << mInputName << std::endl;
0243 os << "Output file: " << mOutputName << std::endl;
0244 os << "Output tree: " << mTreeName << std::endl;
0245 os << "Output branch: " << mBranchName << std::endl;
0246 os << "Maximum number of events: " << mMaxNEvents << std::endl;
0247 if (mEvent) {
0248 os << "Event type: " << mEvent->ClassName() << std::endl;
0249 } // if
0250 }
0251
0252 void Forester::Print(Option_t* /* not used */) const {
0253 Print(std::cout);
0254 }
0255 } // namespace erhic