CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/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(const std::vector<std::string>& 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(const ChainEvent& rhs)
00072 // {
00073 //    // do actual copying here;
00074 // }
00075 
00076 ChainEvent::~ChainEvent()
00077 {
00078 }
00079 
00080 //
00081 // assignment operators
00082 //
00083 // const ChainEvent& ChainEvent::operator=(const ChainEvent& 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 const ChainEvent&
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 const ChainEvent&
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 const std::string
00224 ChainEvent::getBranchNameFor(const std::type_info& iType,
00225                              const char* iModule,
00226                              const char* iInstance,
00227                              const char* iProcess) const
00228 {
00229   return event_->getBranchNameFor(iType,iModule,iInstance,iProcess);
00230 }
00231 
00232 const std::vector<edm::BranchDescription>&
00233 ChainEvent::getBranchDescriptions() const
00234 {
00235   return event_->getBranchDescriptions();
00236 }
00237 
00238 const std::vector<std::string>&
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 
00267 bool
00268 ChainEvent::getByLabel(const std::type_info& iType,
00269                        const char* iModule,
00270                        const char* iInstance,
00271                        const char* iProcess,
00272                        void* iValue) const
00273 {
00274   return event_->getByLabel(iType,iModule,iInstance,iProcess,iValue);
00275 }
00276 
00277 edm::EDProduct const* ChainEvent::getByProductID(edm::ProductID const& iID) const
00278 {
00279   return event_->getByProductID( iID );
00280 }
00281 
00282 bool
00283 ChainEvent::isValid() const
00284 {
00285   return event_->isValid();
00286 }
00287 ChainEvent::operator bool() const
00288 {
00289   return *event_;
00290 }
00291 
00292 bool
00293 ChainEvent::atEnd() const
00294 {
00295   if (eventIndex_ == static_cast<Long64_t>(fileNames_.size())-1) {
00296     return event_->atEnd();
00297   }
00298   return false;
00299 }
00300 
00301 Long64_t
00302 ChainEvent::size() const
00303 {
00304   return accumulatedSize_.back();
00305 }
00306 
00307 edm::TriggerNames const&
00308 ChainEvent::triggerNames(edm::TriggerResults const& triggerResults) const
00309 {
00310   return event_->triggerNames(triggerResults);
00311 }
00312 
00313 void
00314 ChainEvent::fillParameterSetRegistry() const
00315 {
00316   event_->fillParameterSetRegistry();
00317 }
00318 
00319 edm::TriggerResultsByName
00320 ChainEvent::triggerResultsByName(std::string const& process) const {
00321   return event_->triggerResultsByName(process);
00322 }
00323 
00324 //
00325 // static member functions
00326 //
00327 void
00328 ChainEvent::throwProductNotFoundException(const std::type_info& iType,
00329                                           const char* iModule,
00330                                           const char* iInstance,
00331                                           const char* iProcess) {
00332   Event::throwProductNotFoundException(iType,iModule,iInstance,iProcess);
00333 }
00334 }