Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:35:52

0001 // -*- C++ -*-
0002 //
0003 // Package:     FWLite
0004 // Class  :     ChainEvent
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Sat Jun 16 06:48:39 EDT 2007
0011 //
0012 
0013 // system include files
0014 
0015 // user include files
0016 #include "DataFormats/FWLite/interface/ChainEvent.h"
0017 #include "DataFormats/Provenance/interface/BranchType.h"
0018 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0019 #include "TFile.h"
0020 #include "TTree.h"
0021 #include "TROOT.h"
0022 
0023 namespace fwlite {
0024   //
0025   // constants, enums and typedefs
0026   //
0027 
0028   //
0029   // static data member definitions
0030   //
0031 
0032   //
0033   // constructors and destructor
0034   //
0035   ChainEvent::ChainEvent(std::vector<std::string> const& iFileNames)
0036       : fileNames_(), file_(), event_(), eventIndex_(0), accumulatedSize_() {
0037     Long64_t summedSize = 0;
0038     accumulatedSize_.reserve(iFileNames.size() + 1);
0039     fileNames_.reserve(iFileNames.size());
0040 
0041     for (auto const& fileName : iFileNames) {
0042       TFile* tfilePtr = TFile::Open(fileName.c_str());
0043       if (nullptr == tfilePtr) {
0044         throw cms::Exception("FileOpenFailed") << "TFile::Open of " << fileName << " failed";
0045       }
0046       file_ = std::shared_ptr<TFile>(tfilePtr);
0047       gROOT->GetListOfFiles()->Remove(tfilePtr);
0048       TTree* tree = dynamic_cast<TTree*>(file_->Get(edm::poolNames::eventTreeName().c_str()));
0049       if (nullptr == tree) {
0050         throw cms::Exception("NotEdmFile")
0051             << "The file " << fileName << " has no 'Events' TTree and therefore is not an EDM ROOT file";
0052       }
0053       Long64_t nEvents = tree->GetEntries();
0054       if (nEvents > 0) {  // skip empty files
0055         fileNames_.push_back(fileName);
0056         // accumulatedSize_ is the entry # at the beginning of this file
0057         accumulatedSize_.push_back(summedSize);
0058         summedSize += nEvents;
0059       }
0060     }
0061     // total accumulated size (last enry + 1) at the end of last file
0062     accumulatedSize_.push_back(summedSize);
0063 
0064     if (!fileNames_.empty())
0065       switchToFile(0);
0066   }
0067 
0068   // ChainEvent::ChainEvent(ChainEvent const& rhs)
0069   // {
0070   //    // do actual copying here;
0071   // }
0072 
0073   ChainEvent::~ChainEvent() {}
0074 
0075   //
0076   // assignment operators
0077   //
0078   // ChainEvent const& ChainEvent::operator=(ChainEvent const& rhs)
0079   // {
0080   //   //An exception safe implementation is
0081   //   ChainEvent temp(rhs);
0082   //   swap(rhs);
0083   //
0084   //   return *this;
0085   // }
0086 
0087   //
0088   // member functions
0089   //
0090 
0091   ChainEvent const& ChainEvent::operator++() {
0092     if (eventIndex_ != static_cast<Long64_t>(fileNames_.size()) - 1) {
0093       ++(*event_);
0094       if (event_->atEnd()) {
0095         switchToFile(++eventIndex_);
0096       }
0097     } else {
0098       if (*event_) {
0099         ++(*event_);
0100       }
0101     }
0102     return *this;
0103   }
0104 
0105   ///Go to the event at index iIndex
0106   bool ChainEvent::to(Long64_t iIndex) {
0107     if (iIndex >= accumulatedSize_.back()) {
0108       // if we're here, then iIndex was not valid
0109       return false;
0110     }
0111 
0112     Long64_t offsetIndex = eventIndex_;
0113 
0114     // we're going backwards, so start from the beginning
0115     if (iIndex < accumulatedSize_[offsetIndex]) {
0116       offsetIndex = 0;
0117     }
0118 
0119     // is it past the end of this file?
0120     while (iIndex >= accumulatedSize_[offsetIndex + 1]) {
0121       ++offsetIndex;
0122     }
0123 
0124     if (offsetIndex != eventIndex_) {
0125       switchToFile(eventIndex_ = offsetIndex);
0126     }
0127 
0128     // adjust to entry # in this file
0129     return event_->to(iIndex - accumulatedSize_[offsetIndex]);
0130   }
0131 
0132   ///Go to event with event id "id"
0133   bool ChainEvent::to(const edm::EventID& id) { return to(id.run(), id.luminosityBlock(), id.event()); }
0134 
0135   ///If lumi is non-zero, go to event with given run, lumi, and event number
0136   ///If lumi is zero, go to event with given run and event number
0137   bool ChainEvent::to(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event) {
0138     // First try this file
0139     if (event_->to(run, lumi, event)) {
0140       // found it, return
0141       return true;
0142     } else {
0143       // Did not find it, try the other files sequentially.
0144       // Someday I can make this smarter. For now... we get something working.
0145       Long64_t thisFile = eventIndex_;
0146       std::vector<std::string>::const_iterator filesBegin = fileNames_.begin(), filesEnd = fileNames_.end(),
0147                                                ifile = filesBegin;
0148       for (; ifile != filesEnd; ++ifile) {
0149         // skip the "first" file that we tried
0150         if (ifile - filesBegin != thisFile) {
0151           // switch to the next file
0152           switchToFile(ifile - filesBegin);
0153           // check that tree for the desired event
0154           if (event_->to(run, lumi, event)) {
0155             // found it, return
0156             return true;
0157           }
0158         }  // end ignore "first" file that we tried
0159       }  // end loop over files
0160 
0161       // did not find the event with id "id".
0162       return false;
0163     }  // end if we did not find event id in "first" file
0164   }
0165 
0166   bool ChainEvent::to(edm::RunNumber_t run, edm::EventNumber_t event) { return to(run, 0U, event); }
0167 
0168   /** Go to the very first Event*/
0169 
0170   ChainEvent const& ChainEvent::toBegin() {
0171     if (!size())
0172       return *this;
0173     if (eventIndex_ != 0) {
0174       switchToFile(0);
0175     }
0176     event_->toBegin();
0177     return *this;
0178   }
0179 
0180   void ChainEvent::switchToFile(Long64_t iIndex) {
0181     eventIndex_ = iIndex;
0182     TFile* tfilePtr = TFile::Open(fileNames_[iIndex].c_str());
0183     file_ = std::shared_ptr<TFile>(tfilePtr);
0184     gROOT->GetListOfFiles()->Remove(tfilePtr);
0185     event_ = std::make_shared<Event>(file_.get());
0186   }
0187 
0188   //
0189   // const member functions
0190   //
0191   std::string const ChainEvent::getBranchNameFor(std::type_info const& iType,
0192                                                  char const* iModule,
0193                                                  char const* iInstance,
0194                                                  char const* iProcess) const {
0195     return event_->getBranchNameFor(iType, iModule, iInstance, iProcess);
0196   }
0197 
0198   std::vector<edm::BranchDescription> const& ChainEvent::getBranchDescriptions() const {
0199     return event_->getBranchDescriptions();
0200   }
0201 
0202   std::vector<std::string> const& ChainEvent::getProcessHistory() const { return event_->getProcessHistory(); }
0203 
0204   edm::ProcessHistory const& ChainEvent::processHistory() const { return event_->processHistory(); }
0205 
0206   edm::EventAuxiliary const& ChainEvent::eventAuxiliary() const { return event_->eventAuxiliary(); }
0207 
0208   fwlite::LuminosityBlock const& ChainEvent::getLuminosityBlock() { return event_->getLuminosityBlock(); }
0209 
0210   fwlite::Run const& ChainEvent::getRun() { return event_->getRun(); }
0211 
0212   bool ChainEvent::getByLabel(std::type_info const& iType,
0213                               char const* iModule,
0214                               char const* iInstance,
0215                               char const* iProcess,
0216                               void* iValue) const {
0217     return event_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
0218   }
0219 
0220   bool ChainEvent::getByTokenImp(edm::EDGetToken iToken, edm::WrapperBase const*& iValue) const {
0221     return event_->getByTokenImp(iToken, iValue);
0222   }
0223 
0224   edm::WrapperBase const* ChainEvent::getByProductID(edm::ProductID const& iID) const {
0225     return event_->getByProductID(iID);
0226   }
0227 
0228   std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> ChainEvent::getThinnedProduct(
0229       edm::ProductID const& pid, unsigned int key) const {
0230     return event_->getThinnedProduct(pid, key);
0231   }
0232 
0233   void ChainEvent::getThinnedProducts(edm::ProductID const& pid,
0234                                       std::vector<edm::WrapperBase const*>& foundContainers,
0235                                       std::vector<unsigned int>& keys) const {
0236     event_->getThinnedProducts(pid, foundContainers, keys);
0237   }
0238 
0239   edm::OptionalThinnedKey ChainEvent::getThinnedKeyFrom(edm::ProductID const& parent,
0240                                                         unsigned int key,
0241                                                         edm::ProductID const& thinned) const {
0242     return event_->getThinnedKeyFrom(parent, key, thinned);
0243   }
0244 
0245   bool ChainEvent::isValid() const { return event_->isValid(); }
0246   ChainEvent::operator bool() const { return *event_; }
0247 
0248   bool ChainEvent::atEnd() const {
0249     if (!size())
0250       return true;
0251     if (eventIndex_ == static_cast<Long64_t>(fileNames_.size()) - 1) {
0252       return event_->atEnd();
0253     }
0254     return false;
0255   }
0256 
0257   Long64_t ChainEvent::size() const { return accumulatedSize_.empty() ? 0 : accumulatedSize_.back(); }
0258 
0259   edm::TriggerNames const& ChainEvent::triggerNames(edm::TriggerResults const& triggerResults) const {
0260     return event_->triggerNames(triggerResults);
0261   }
0262 
0263   edm::ParameterSet const* ChainEvent::parameterSet(edm::ParameterSetID const& psID) const {
0264     return event_->parameterSet(psID);
0265   }
0266 
0267   void ChainEvent::fillParameterSetRegistry() const { event_->fillParameterSetRegistry(); }
0268 
0269   edm::TriggerResultsByName ChainEvent::triggerResultsByName(edm::TriggerResults const& triggerResults) const {
0270     return event_->triggerResultsByName(triggerResults);
0271   }
0272 
0273   //
0274   // static member functions
0275   //
0276   void ChainEvent::throwProductNotFoundException(std::type_info const& iType,
0277                                                  char const* iModule,
0278                                                  char const* iInstance,
0279                                                  char const* iProcess) {
0280     Event::throwProductNotFoundException(iType, iModule, iInstance, iProcess);
0281   }
0282 }  // namespace fwlite