Back to home page

EIC code displayed by LXR

 
 

    


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