00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <iostream>
00015
00016
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
00043 #include "DataFormats/Provenance/interface/EventAux.h"
00044
00045
00046
00047
00048 namespace {
00049 struct NoDelete {
00050 void operator()(void*){}
00051 };
00052 }
00053
00054 namespace fwlite {
00055
00056
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
00073
00074 Event::Event(TFile* iFile):
00075 file_(iFile),
00076
00077 eventHistoryTree_(0),
00078
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
00097 fileVersion_ = branchMap_.getFileVersion(iFile);
00098
00099
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
00130
00131
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
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
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
00178 return branchMap_.updateEvent(iEntry);
00179 }
00180
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
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
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
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
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
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 }