CMS 3D CMS Logo

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