CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/FWLite/src/Event.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     FWLite
00004 // Class  :     Event
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Tue May  8 15:07:03 EDT 2007
00011 //
00012 
00013 // system include files
00014 #include <iostream>
00015 
00016 // user include files
00017 #include "DataFormats/FWLite/interface/Event.h"
00018 #include "TFile.h"
00019 #include "TTree.h"
00020 #include "FWCore/Utilities/interface/Exception.h"
00021 #include "DataFormats/Provenance/interface/BranchType.h"
00022 #include "DataFormats/Common/interface/EDProductGetter.h"
00023 
00024 #include "DataFormats/Provenance/interface/FileFormatVersion.h"
00025 #include "DataFormats/Provenance/interface/History.h"
00026 #include "DataFormats/Provenance/interface/ProcessHistoryID.h"
00027 
00028 #include "FWCore/FWLite/interface/setRefStreamer.h"
00029 
00030 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
00031 #include "DataFormats/Provenance/interface/ParameterSetID.h"
00032 #include "FWCore/Utilities/interface/ThreadSafeRegistry.h"
00033 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00034 #include "FWCore/ParameterSet/interface/Registry.h"
00035 #include "FWCore/ParameterSet/interface/ParameterSetConverter.h"
00036 #include "DataFormats/FWLite/interface/Handle.h"
00037 #include "DataFormats/Common/interface/TriggerResults.h"
00038 #include "FWCore/Common/interface/TriggerResultsByName.h"
00039 #include "DataFormats/FWLite/interface/EventHistoryGetter.h"
00040 #include "DataFormats/FWLite/interface/RunFactory.h"
00041 
00042 //used for backwards compatability
00043 #include "DataFormats/Provenance/interface/EventAux.h"
00044 
00045 //
00046 // constants, enums and typedefs
00047 //
00048 namespace {
00049   struct NoDelete {
00050     void operator()(void*){}
00051   };
00052 }
00053 
00054 namespace fwlite {
00055 //
00056 // static data member definitions
00057 //
00058     namespace internal {
00059         class ProductGetter : public edm::EDProductGetter {
00060             public:
00061                 ProductGetter(Event* iEvent) : event_(iEvent) {}
00062 
00063                 edm::EDProduct const*
00064                 getIt(edm::ProductID const& iID) const {
00065                     return event_->getByProductID(iID);
00066                 }
00067             private:
00068                 Event* event_;
00069         };
00070     }
00071 //
00072 // constructors and destructor
00073 //
00074   Event::Event(TFile* iFile):
00075   file_(iFile),
00076 //  eventTree_(0),
00077   eventHistoryTree_(0),
00078 //  eventIndex_(-1),
00079   branchMap_(iFile),
00080   pAux_(&aux_),
00081   pOldAux_(0),
00082   fileVersion_(-1),
00083   parameterSetRegistryFilled_(false),
00084   dataHelper_(branchMap_.getEventTree(),
00085               boost::shared_ptr<HistoryGetterBase>(new EventHistoryGetter(this)),
00086               boost::shared_ptr<BranchMapReader>(&branchMap_,NoDelete()),
00087               boost::shared_ptr<edm::EDProductGetter>(new internal::ProductGetter(this)),
00088               true) {
00089     if(0 == iFile) {
00090       throw cms::Exception("NoFile") << "The TFile pointer passed to the constructor was null";
00091     }
00092 
00093     if(0 == branchMap_.getEventTree()) {
00094       throw cms::Exception("NoEventTree") << "The TFile contains no TTree named " << edm::poolNames::eventTreeName();
00095     }
00096     //need to know file version in order to determine how to read the basic event info
00097     fileVersion_ = branchMap_.getFileVersion(iFile);
00098 
00099     //got this logic from IOPool/Input/src/RootFile.cc
00100 
00101     TTree* eventTree = branchMap_.getEventTree();
00102     if(fileVersion_ >= 3 ) {
00103       auxBranch_ = eventTree->GetBranch(edm::BranchTypeToAuxiliaryBranchName(edm::InEvent).c_str());
00104       if(0 == auxBranch_) {
00105         throw cms::Exception("NoEventAuxilliary") << "The TTree "
00106         << edm::poolNames::eventTreeName()
00107         << " does not contain a branch named 'EventAuxiliary'";
00108       }
00109       auxBranch_->SetAddress(&pAux_);
00110     } else {
00111       pOldAux_ = new edm::EventAux();
00112       auxBranch_ = eventTree->GetBranch(edm::BranchTypeToAuxBranchName(edm::InEvent).c_str());
00113       if(0 == auxBranch_) {
00114         throw cms::Exception("NoEventAux") << "The TTree "
00115           << edm::poolNames::eventTreeName()
00116           << " does not contain a branch named 'EventAux'";
00117       }
00118       auxBranch_->SetAddress(&pOldAux_);
00119     }
00120     branchMap_.updateEvent(0);
00121 
00122     if(fileVersion_ >= 7 && fileVersion_ < 17) {
00123       eventHistoryTree_ = dynamic_cast<TTree*>(iFile->Get(edm::poolNames::eventHistoryTreeName().c_str()));
00124     }
00125     runFactory_ =  boost::shared_ptr<RunFactory>(new RunFactory());
00126 
00127 }
00128 
00129 // Event::Event(const Event& rhs)
00130 // {
00131 //    // do actual copying here;
00132 // }
00133 
00134 Event::~Event() {
00135   for(std::vector<const char*>::iterator it = labels_.begin(), itEnd = labels_.end();
00136       it != itEnd;
00137       ++it) {
00138     delete [] *it;
00139   }
00140   delete pOldAux_;
00141 }
00142 
00143 //
00144 // assignment operators
00145 //
00146 // const Event& Event::operator=(const Event& rhs) {
00147 //   //An exception safe implementation is
00148 //   Event temp(rhs);
00149 //   swap(rhs);
00150 //
00151 //   return *this;
00152 // }
00153 
00154 //
00155 // member functions
00156 //
00157 
00158 const Event&
00159 Event::operator++() {
00160    Long_t eventIndex = branchMap_.getEventEntry();
00161    if(eventIndex < size()) {
00162       branchMap_.updateEvent(++eventIndex);
00163    }
00164    return *this;
00165 }
00166 
00167 Long64_t
00168 Event::indexFromEventId(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event) {
00169    entryFinder_.fillIndex(branchMap_);
00170    EntryFinder::EntryNumber_t entry = entryFinder_.findEvent(run, lumi, event);
00171    return (entry == EntryFinder::invalidEntry) ? -1 : entry;
00172 }
00173 
00174 bool
00175 Event::to(Long64_t iEntry) {
00176    if (iEntry < size()) {
00177       // this is a valid entry
00178       return branchMap_.updateEvent(iEntry);
00179    }
00180    // if we're here, then iEntry was not valid
00181    return false;
00182 }
00183 
00184 bool
00185 Event::to(edm::RunNumber_t run, edm::EventNumber_t event) {
00186    return to(run, 0U, event);
00187 }
00188 
00189 bool
00190 Event::to(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event) {
00191    entryFinder_.fillIndex(branchMap_);
00192    EntryFinder::EntryNumber_t entry = entryFinder_.findEvent(run, lumi, event);
00193    if (entry == EntryFinder::invalidEntry) {
00194       return false;
00195    }
00196    return branchMap_.updateEvent(entry);
00197 }
00198 
00199 bool
00200 Event::to(const edm::EventID &id) {
00201    return to(id.run(), id.luminosityBlock(), id.event());
00202 }
00203 
00204 const Event&
00205 Event::toBegin() {
00206    branchMap_.updateEvent(0);
00207    return *this;
00208 }
00209 
00210 //
00211 // const member functions
00212 //
00213 void       Event::draw(Option_t* opt) {
00214    GetterOperate op(dataHelper_.getter());
00215    branchMap_.getEventTree()->Draw(opt);
00216 }
00217 Long64_t   Event::draw(const char* varexp, const TCut& selection, Option_t* option, Long64_t nentries, Long64_t firstentry) {
00218    GetterOperate op(dataHelper_.getter());
00219    return branchMap_.getEventTree()->Draw(varexp,selection,option,nentries,firstentry);
00220 }
00221 Long64_t   Event::draw(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry) {
00222    GetterOperate op(dataHelper_.getter());
00223    return branchMap_.getEventTree()->Draw(varexp,selection,option,nentries,firstentry);
00224 }
00225 Long64_t   Event::scan(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry) {
00226    GetterOperate op(dataHelper_.getter());
00227    return branchMap_.getEventTree()->Scan(varexp,selection,option,nentries,firstentry);
00228 }
00229 
00230 
00231 Long64_t
00232 Event::size() const {
00233   return branchMap_.getEventTree()->GetEntries();
00234 }
00235 
00236 bool
00237 Event::isValid() const {
00238   Long_t eventIndex = branchMap_.getEventEntry();
00239   return eventIndex != -1 and eventIndex < size();
00240 }
00241 
00242 
00243 Event::operator bool() const {
00244   return isValid();
00245 }
00246 
00247 bool
00248 Event::atEnd() const {
00249   Long_t eventIndex = branchMap_.getEventEntry();
00250   return eventIndex == -1 or eventIndex == size();
00251 }
00252 
00253 
00254 const std::vector<std::string>&
00255 Event::getProcessHistory() const {
00256   if (procHistoryNames_.empty()) {
00257     const edm::ProcessHistory& h = history();
00258     for (edm::ProcessHistory::const_iterator iproc = h.begin(), eproc = h.end();
00259          iproc != eproc; ++iproc) {
00260       procHistoryNames_.push_back(iproc->processName());
00261     }
00262   }
00263   return procHistoryNames_;
00264 }
00265 
00266 
00267 const std::string
00268 Event::getBranchNameFor(const std::type_info& iInfo,
00269                   const char* iModuleLabel,
00270                   const char* iProductInstanceLabel,
00271                   const char* iProcessLabel) const {
00272     return dataHelper_.getBranchNameFor(iInfo, iModuleLabel, iProductInstanceLabel, iProcessLabel);
00273 }
00274 
00275 
00276 bool
00277 Event::getByLabel(const std::type_info& iInfo,
00278                   const char* iModuleLabel,
00279                   const char* iProductInstanceLabel,
00280                   const char* iProcessLabel,
00281                   void* oData) const {
00282     if(atEnd()) {
00283         throw cms::Exception("OffEnd") << "You have requested data past the last event";
00284     }
00285     Long_t eventIndex = branchMap_.getEventEntry();
00286     return dataHelper_.getByLabel(iInfo, iModuleLabel, iProductInstanceLabel, iProcessLabel, oData, eventIndex);
00287 }
00288 
00289 
00290 edm::EventAuxiliary const&
00291 Event::eventAuxiliary() const {
00292    Long_t eventIndex = branchMap_.getEventEntry();
00293    updateAux(eventIndex);
00294    return aux_;
00295 }
00296 
00297 void
00298 Event::updateAux(Long_t eventIndex) const {
00299   if(auxBranch_->GetEntryNumber() != eventIndex) {
00300     auxBranch_->GetEntry(eventIndex);
00301     //handling dealing with old version
00302     if(0 != pOldAux_) {
00303       conversion(*pOldAux_,aux_);
00304     }
00305   }
00306 }
00307 
00308 const edm::ProcessHistory&
00309 Event::history() const {
00310   edm::ProcessHistoryID processHistoryID;
00311 
00312   bool newFormat = (fileVersion_ >= 5);
00313 
00314   Long_t eventIndex = branchMap_.getEventEntry();
00315   updateAux(eventIndex);
00316   if (!newFormat) {
00317     processHistoryID = aux_.processHistoryID();
00318   }
00319   if(historyMap_.empty() || newFormat) {
00320     procHistoryNames_.clear();
00321     TTree *meta = dynamic_cast<TTree*>(branchMap_.getFile()->Get(edm::poolNames::metaDataTreeName().c_str()));
00322     if(0 == meta) {
00323       throw cms::Exception("NoMetaTree") << "The TFile does not appear to contain a TTree named "
00324       << edm::poolNames::metaDataTreeName();
00325     }
00326     if (historyMap_.empty()) {
00327       if (fileVersion_ < 11) {
00328         edm::ProcessHistoryMap* pPhm = &historyMap_;
00329         TBranch* b = meta->GetBranch(edm::poolNames::processHistoryMapBranchName().c_str());
00330         b->SetAddress(&pPhm);
00331         b->GetEntry(0);
00332       } else {
00333         edm::ProcessHistoryVector historyVector;
00334         edm::ProcessHistoryVector* pPhv = &historyVector;
00335         TBranch* b = meta->GetBranch(edm::poolNames::processHistoryBranchName().c_str());
00336         b->SetAddress(&pPhv);
00337         b->GetEntry(0);
00338         for (edm::ProcessHistoryVector::const_iterator i = historyVector.begin(), e = historyVector.end();
00339             i != e; ++i) {
00340           historyMap_.insert(std::make_pair(i->id(), *i));
00341         }
00342       }
00343     }
00344     if (newFormat) {
00345       if (fileVersion_ >= 17) {
00346         processHistoryID = aux_.processHistoryID();
00347       } else if (fileVersion_ >= 7) {
00348         edm::History history;
00349         edm::History* pHistory = &history;
00350         TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(edm::poolNames::eventHistoryBranchName().c_str());
00351         if (!eventHistoryBranch)
00352           throw edm::Exception(edm::errors::FatalRootError)
00353             << "Failed to find history branch in event history tree";
00354         eventHistoryBranch->SetAddress(&pHistory);
00355         eventHistoryTree_->GetEntry(eventIndex);
00356         processHistoryID = history.processHistoryID();
00357       } else {
00358         std::vector<edm::EventProcessHistoryID> *pEventProcessHistoryIDs = &eventProcessHistoryIDs_;
00359         TBranch* b = meta->GetBranch(edm::poolNames::eventHistoryBranchName().c_str());
00360         b->SetAddress(&pEventProcessHistoryIDs);
00361         b->GetEntry(0);
00362         edm::EventProcessHistoryID target(aux_.id(), edm::ProcessHistoryID());
00363         processHistoryID = std::lower_bound(eventProcessHistoryIDs_.begin(), eventProcessHistoryIDs_.end(), target)->processHistoryID();
00364       }
00365     }
00366 
00367   }
00368 
00369   return historyMap_[processHistoryID];
00370 }
00371 
00372 
00373 edm::EDProduct const*
00374 Event::getByProductID(edm::ProductID const& iID) const {
00375   Long_t eventIndex = branchMap_.getEventEntry();
00376   return dataHelper_.getByProductID(iID, eventIndex);
00377 }
00378 
00379 
00380 edm::TriggerNames const&
00381 Event::triggerNames(edm::TriggerResults const& triggerResults) const {
00382   edm::TriggerNames const* names = triggerNames_(triggerResults);
00383   if (names != 0) return *names;
00384 
00385   if (!parameterSetRegistryFilled_) {
00386     fillParameterSetRegistry();
00387     names = triggerNames_(triggerResults);
00388   }
00389   if (names != 0) return *names;
00390 
00391   throw cms::Exception("TriggerNamesNotFound")
00392     << "TriggerNames not found in ParameterSet registry";
00393   return *names;
00394 }
00395 
00396 void
00397 Event::fillParameterSetRegistry() const {
00398   if (parameterSetRegistryFilled_) return;
00399   parameterSetRegistryFilled_ = true;
00400 
00401   TTree* meta = dynamic_cast<TTree*>(branchMap_.getFile()->Get(edm::poolNames::metaDataTreeName().c_str()));
00402   if (0 == meta) {
00403     throw cms::Exception("NoMetaTree") << "The TFile does not contain a TTree named "
00404       << edm::poolNames::metaDataTreeName();
00405   }
00406 
00407   edm::FileFormatVersion fileFormatVersion;
00408   edm::FileFormatVersion *fftPtr = &fileFormatVersion;
00409   if(meta->FindBranch(edm::poolNames::fileFormatVersionBranchName().c_str()) != 0) {
00410     TBranch *fft = meta->GetBranch(edm::poolNames::fileFormatVersionBranchName().c_str());
00411     fft->SetAddress(&fftPtr);
00412     fft->GetEntry(0);
00413   }
00414 
00415   typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> PsetMap;
00416   PsetMap psetMap;
00417   TTree* psetTree(0);
00418   if (meta->FindBranch(edm::poolNames::parameterSetMapBranchName().c_str()) != 0) {
00419     PsetMap *psetMapPtr = &psetMap;
00420     TBranch* b = meta->GetBranch(edm::poolNames::parameterSetMapBranchName().c_str());
00421     b->SetAddress(&psetMapPtr);
00422     b->GetEntry(0);
00423   } else if( 0 == (psetTree = dynamic_cast<TTree *>(branchMap_.getFile()->Get(edm::poolNames::parameterSetsTreeName().c_str())))) {
00424     throw cms::Exception("NoParameterSetMapTree")
00425     << "The TTree "
00426     << edm::poolNames::parameterSetsTreeName() << " could not be found in the file.";
00427   } else {
00428     typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs;
00429     IdToBlobs idToBlob;
00430     IdToBlobs* pIdToBlob = &idToBlob;
00431     psetTree->SetBranchAddress(edm::poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
00432     for(long long i = 0; i != psetTree->GetEntries(); ++i) {
00433       psetTree->GetEntry(i);
00434       psetMap.insert(idToBlob);
00435     }
00436   }
00437   edm::ParameterSetConverter::ParameterSetIdConverter psetIdConverter;
00438   if(!fileFormatVersion.triggerPathsTracked()) {
00439     edm::ParameterSetConverter converter(psetMap, psetIdConverter, fileFormatVersion.parameterSetsByReference());
00440   } else {
00441     // Merge into the parameter set registry.
00442     edm::pset::Registry& psetRegistry = *edm::pset::Registry::instance();
00443     for(PsetMap::const_iterator i = psetMap.begin(), iEnd = psetMap.end();
00444         i != iEnd; ++i) {
00445       edm::ParameterSet pset(i->second.pset());
00446       pset.setID(i->first);
00447       psetRegistry.insertMapped(pset);
00448     }
00449   }
00450 }
00451 
00452 edm::TriggerResultsByName
00453 Event::triggerResultsByName(std::string const& process) const {
00454 
00455   fwlite::Handle<edm::TriggerResults> hTriggerResults;
00456   hTriggerResults.getByLabel(*this,"TriggerResults","",process.c_str());
00457   if ( !hTriggerResults.isValid()) {
00458     return edm::TriggerResultsByName(0,0);
00459   }
00460 
00461   edm::TriggerNames const* names = triggerNames_(*hTriggerResults);
00462   if (names == 0 && !parameterSetRegistryFilled_) {
00463     fillParameterSetRegistry();
00464     names = triggerNames_(*hTriggerResults);
00465   }
00466   return edm::TriggerResultsByName(hTriggerResults.product(), names);
00467 }
00468 
00469 //
00470 // static member functions
00471 //
00472 void
00473 Event::throwProductNotFoundException(const std::type_info& iType, const char* iModule, const char* iProduct, const char* iProcess) {
00474     edm::TypeID type(iType);
00475   throw edm::Exception(edm::errors::ProductNotFound) << "A branch was found for \n  type ='" << type.className() << "'\n  module='" << iModule
00476     << "'\n  productInstance='" << ((0!=iProduct)?iProduct:"") << "'\n  process='" << ((0 != iProcess) ? iProcess : "") << "'\n"
00477     "but no data is available for this Event";
00478 }
00479 
00480 
00481 fwlite::LuminosityBlock const& Event::getLuminosityBlock() const {
00482   if (not lumi_) {
00483     // Branch map pointer not really being shared, owned by event, have to trick Lumi
00484     lumi_ = boost::shared_ptr<fwlite::LuminosityBlock> (
00485              new fwlite::LuminosityBlock(boost::shared_ptr<BranchMapReader>(&branchMap_,NoDelete()),
00486              runFactory_)
00487             );
00488   }
00489   edm::RunNumber_t             run  = eventAuxiliary().run();
00490   edm::LuminosityBlockNumber_t lumi = eventAuxiliary().luminosityBlock();
00491   lumi_->to(run, lumi);
00492   return *lumi_;
00493 }
00494 
00495 fwlite::Run const& Event::getRun() const {
00496   run_ = runFactory_->makeRun(boost::shared_ptr<BranchMapReader>(&branchMap_,NoDelete()));
00497   edm::RunNumber_t run = eventAuxiliary().run();
00498   run_->to(run);
00499   return *run_;
00500 }
00501 
00502 }