CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/DataFormats/FWLite/src/ChainEvent.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     FWLite
00004 // Class  :     ChainEvent
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Sat Jun 16 06:48:39 EDT 2007
00011 //
00012 
00013 // system include files
00014 
00015 // user include files
00016 #include "DataFormats/FWLite/interface/ChainEvent.h"
00017 #include "DataFormats/Provenance/interface/BranchType.h"
00018 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00019 #include "TFile.h"
00020 #include "TTree.h"
00021 #include "TROOT.h"
00022 
00023 namespace fwlite {
00024 //
00025 // constants, enums and typedefs
00026 //
00027 
00028 //
00029 // static data member definitions
00030 //
00031 
00032 //
00033 // constructors and destructor
00034 //
00035 ChainEvent::ChainEvent(std::vector<std::string> const& iFileNames):
00036   fileNames_(),
00037   file_(),
00038   event_(),
00039   eventIndex_(0),
00040   accumulatedSize_()
00041 {
00042   Long64_t summedSize=0;
00043   accumulatedSize_.reserve(iFileNames.size()+1);
00044   fileNames_.reserve(iFileNames.size());
00045     
00046   for (std::vector<std::string>::const_iterator it= iFileNames.begin(), itEnd = iFileNames.end();
00047       it!=itEnd;
00048       ++it) {
00049     TFile *tfilePtr = TFile::Open(it->c_str());
00050     file_ = boost::shared_ptr<TFile>(tfilePtr);
00051     gROOT->GetListOfFiles()->Remove(tfilePtr);
00052     TTree* tree = dynamic_cast<TTree*>(file_->Get(edm::poolNames::eventTreeName().c_str()));
00053     if (0 == tree) {
00054       throw cms::Exception("NotEdmFile")<<"The file "<<*it<<" has no 'Events' TTree and therefore is not an EDM ROOT file";
00055     }
00056     Long64_t nEvents = tree->GetEntries();
00057     if (nEvents > 0) { // skip empty files
00058       fileNames_.push_back(*it);
00059       // accumulatedSize_ is the entry # at the beginning of this file
00060       accumulatedSize_.push_back(summedSize);
00061       summedSize += nEvents;
00062     }
00063   }
00064   // total accumulated size (last enry + 1) at the end of last file
00065   accumulatedSize_.push_back(summedSize);
00066 
00067   if (fileNames_.size() > 0)
00068     switchToFile(0);
00069 }
00070 
00071 // ChainEvent::ChainEvent(ChainEvent const& rhs)
00072 // {
00073 //    // do actual copying here;
00074 // }
00075 
00076 ChainEvent::~ChainEvent()
00077 {
00078 }
00079 
00080 //
00081 // assignment operators
00082 //
00083 // ChainEvent const& ChainEvent::operator=(ChainEvent const& rhs)
00084 // {
00085 //   //An exception safe implementation is
00086 //   ChainEvent temp(rhs);
00087 //   swap(rhs);
00088 //
00089 //   return *this;
00090 // }
00091 
00092 //
00093 // member functions
00094 //
00095 
00096 ChainEvent const&
00097 ChainEvent::operator++()
00098 {
00099    if(eventIndex_ != static_cast<Long64_t>(fileNames_.size())-1)
00100    {
00101       ++(*event_);
00102       if(event_->atEnd()) {
00103          switchToFile(++eventIndex_);
00104       }
00105    } else {
00106       if(*event_) {
00107          ++(*event_);
00108       }
00109    }
00110    return *this;
00111 }
00112 
00114 bool
00115 ChainEvent::to(Long64_t iIndex)
00116 {
00117    if (iIndex >= accumulatedSize_.back())
00118    {
00119       // if we're here, then iIndex was not valid
00120       return false;
00121    }
00122 
00123    Long64_t offsetIndex = eventIndex_;
00124 
00125    // we're going backwards, so start from the beginning
00126    if (iIndex < accumulatedSize_[offsetIndex]) {
00127       offsetIndex = 0;
00128    }
00129 
00130    // is it past the end of this file?
00131    while (iIndex >= accumulatedSize_[offsetIndex+1]) {
00132       ++offsetIndex;
00133    }
00134 
00135    if(offsetIndex != eventIndex_) {
00136       switchToFile(eventIndex_ = offsetIndex);
00137    }
00138 
00139    // adjust to entry # in this file
00140    return event_->to(iIndex-accumulatedSize_[offsetIndex]);
00141 }
00142 
00143 
00145 bool
00146 ChainEvent::to(const edm::EventID &id)
00147 {
00148   return to(id.run(), id.luminosityBlock(), id.event());
00149 }
00150 
00153 bool
00154 ChainEvent::to(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event)
00155 {
00156 
00157    // First try this file
00158    if (event_->to(run, lumi, event))
00159    {
00160       // found it, return
00161       return true;
00162    }
00163    else
00164    {
00165       // Did not find it, try the other files sequentially.
00166       // Someday I can make this smarter. For now... we get something working.
00167       Long64_t thisFile = eventIndex_;
00168       std::vector<std::string>::const_iterator filesBegin = fileNames_.begin(),
00169          filesEnd = fileNames_.end(), ifile = filesBegin;
00170       for (; ifile != filesEnd; ++ifile)
00171       {
00172          // skip the "first" file that we tried
00173          if (ifile - filesBegin != thisFile)
00174          {
00175             // switch to the next file
00176             switchToFile(ifile - filesBegin);
00177             // check that tree for the desired event
00178             if (event_->to(run, lumi, event))
00179             {
00180                // found it, return
00181                return true;
00182             }
00183          }// end ignore "first" file that we tried
00184       }// end loop over files
00185 
00186       // did not find the event with id "id".
00187       return false;
00188    }// end if we did not find event id in "first" file
00189 }
00190 
00191 bool
00192 ChainEvent::to(edm::RunNumber_t run, edm::EventNumber_t event)
00193 {
00194   return to(run, 0U, event);
00195 }
00196 
00199 ChainEvent const&
00200 ChainEvent::toBegin()
00201 {
00202    if (eventIndex_ != 0)
00203    {
00204       switchToFile(0);
00205    }
00206    event_->toBegin();
00207    return *this;
00208 }
00209 
00210 void
00211 ChainEvent::switchToFile(Long64_t iIndex)
00212 {
00213   eventIndex_= iIndex;
00214   TFile *tfilePtr = TFile::Open(fileNames_[iIndex].c_str());
00215   file_ = boost::shared_ptr<TFile>(tfilePtr);
00216   gROOT->GetListOfFiles()->Remove(tfilePtr);
00217   event_ = boost::shared_ptr<Event>(new Event(file_.get()));
00218 }
00219 
00220 //
00221 // const member functions
00222 //
00223 std::string const
00224 ChainEvent::getBranchNameFor(std::type_info const& iType,
00225                              char const* iModule,
00226                              char const* iInstance,
00227                              char const* iProcess) const
00228 {
00229   return event_->getBranchNameFor(iType,iModule,iInstance,iProcess);
00230 }
00231 
00232 std::vector<edm::BranchDescription> const&
00233 ChainEvent::getBranchDescriptions() const
00234 {
00235   return event_->getBranchDescriptions();
00236 }
00237 
00238 std::vector<std::string> const&
00239 ChainEvent::getProcessHistory() const
00240 {
00241   return event_->getProcessHistory();
00242 }
00243 
00244 edm::ProcessHistory const&
00245 ChainEvent::processHistory() const
00246 {
00247   return event_->processHistory();
00248 }
00249 
00250 edm::EventAuxiliary const&
00251 ChainEvent::eventAuxiliary() const
00252 {
00253    return event_->eventAuxiliary();
00254 }
00255 
00256 fwlite::LuminosityBlock const& ChainEvent::getLuminosityBlock()
00257 {
00258    return event_->getLuminosityBlock();
00259 }
00260 
00261 fwlite::Run const& ChainEvent::getRun()
00262 {
00263    return event_->getRun();
00264 }
00265 
00266 bool
00267 ChainEvent::getByLabel(std::type_info const& iType,
00268                        char const* iModule,
00269                        char const* iInstance,
00270                        char const* iProcess,
00271                        void* iValue) const
00272 {
00273   return event_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
00274 }
00275 
00276 bool
00277 ChainEvent::getByLabel(std::type_info const& iType,
00278                        char const* iModule,
00279                        char const* iInstance,
00280                        char const* iProcess,
00281                        edm::WrapperHolder& holder) const
00282 {
00283   return event_->getByLabel(iType, iModule, iInstance, iProcess, holder);
00284 }
00285 
00286 edm::WrapperHolder ChainEvent::getByProductID(edm::ProductID const& iID) const
00287 {
00288   return event_->getByProductID(iID);
00289 }
00290 
00291 bool
00292 ChainEvent::isValid() const
00293 {
00294   return event_->isValid();
00295 }
00296 ChainEvent::operator bool() const
00297 {
00298   return *event_;
00299 }
00300 
00301 bool
00302 ChainEvent::atEnd() const
00303 {
00304   if (eventIndex_ == static_cast<Long64_t>(fileNames_.size())-1) {
00305     return event_->atEnd();
00306   }
00307   return false;
00308 }
00309 
00310 Long64_t
00311 ChainEvent::size() const
00312 {
00313   return accumulatedSize_.back();
00314 }
00315 
00316 edm::TriggerNames const&
00317 ChainEvent::triggerNames(edm::TriggerResults const& triggerResults) const
00318 {
00319   return event_->triggerNames(triggerResults);
00320 }
00321 
00322 void
00323 ChainEvent::fillParameterSetRegistry() const
00324 {
00325   event_->fillParameterSetRegistry();
00326 }
00327 
00328 edm::TriggerResultsByName
00329 ChainEvent::triggerResultsByName(std::string const& process) const {
00330   return event_->triggerResultsByName(process);
00331 }
00332 
00333 //
00334 // static member functions
00335 //
00336 void
00337 ChainEvent::throwProductNotFoundException(std::type_info const& iType,
00338                                           char const* iModule,
00339                                           char const* iInstance,
00340                                           char const* iProcess) {
00341   Event::throwProductNotFoundException(iType,iModule,iInstance,iProcess);
00342 }
00343 }