Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-26 05:06:47

0001 // -*- C++ -*-
0002 //
0003 // Package:     FWLite
0004 // Class  :     BranchMapReader
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Dan Riley
0010 //         Created:  Tue May 20 10:31:32 EDT 2008
0011 //
0012 
0013 // system include files
0014 
0015 // user include files
0016 #include "FWCore/FWLite/interface/BranchMapReader.h"
0017 
0018 #include "DataFormats/Provenance/interface/BranchIDList.h"
0019 #include "DataFormats/Provenance/interface/BranchListIndex.h"
0020 #include "DataFormats/Provenance/interface/BranchType.h"
0021 #include "DataFormats/Provenance/interface/EventEntryInfo.h"
0022 #include "DataFormats/Provenance/interface/EventSelectionID.h"
0023 #include "DataFormats/Provenance/interface/FileFormatVersion.h"
0024 #include "DataFormats/Provenance/interface/History.h"
0025 #include "DataFormats/Provenance/interface/ProductIDToBranchID.h"
0026 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0027 #include "DataFormats/Provenance/interface/ThinnedAssociationsHelper.h"
0028 #include "FWCore/Utilities/interface/EDMException.h"
0029 #include "FWCore/Utilities/interface/propagate_const.h"
0030 
0031 #include "TBranch.h"
0032 #include "TFile.h"
0033 #include "TTree.h"
0034 
0035 #include <cassert>
0036 
0037 namespace fwlite {
0038   namespace internal {
0039 
0040     static const edm::BranchDescription kDefaultBranchDescription;
0041 
0042     BMRStrategy::BMRStrategy(TFile* file, int fileVersion)
0043         : currentFile_(file),
0044           eventTree_(nullptr),
0045           luminosityBlockTree_(nullptr),
0046           runTree_(nullptr),
0047           eventEntry_(-1),
0048           luminosityBlockEntry_(-1),
0049           runEntry_(-1),
0050           fileVersion_(fileVersion) {
0051       // do in derived obects
0052       // updateFile(file);
0053     }
0054 
0055     BMRStrategy::~BMRStrategy() {}
0056 
0057     class Strategy : public BMRStrategy {
0058     public:
0059       typedef std::map<edm::BranchID, edm::BranchDescription> bidToDesc;
0060 
0061       Strategy(TFile* file, int fileVersion);
0062       ~Strategy() override;
0063       bool updateFile(TFile* file) override;
0064       bool updateEvent(Long_t eventEntry) override {
0065         eventEntry_ = eventEntry;
0066         return true;
0067       }
0068       bool updateLuminosityBlock(Long_t luminosityBlockEntry) override {
0069         luminosityBlockEntry_ = luminosityBlockEntry;
0070         return true;
0071       }
0072       bool updateRun(Long_t runEntry) override {
0073         runEntry_ = runEntry;
0074         return true;
0075       }
0076       bool updateMap() override { return true; }
0077       edm::BranchID productToBranchID(edm::ProductID const& pid) override;
0078       edm::BranchDescription const& productToBranch(edm::ProductID const& pid) override;
0079       edm::BranchDescription const& branchIDToBranch(edm::BranchID const& bid) const override;
0080       std::vector<edm::BranchDescription> const& getBranchDescriptions() override;
0081       edm::ThinnedAssociationsHelper const& thinnedAssociationsHelper() const override {
0082         return *thinnedAssociationsHelper_;
0083       }
0084 
0085       TBranch* getBranchRegistry(edm::ProductRegistry** pReg);
0086 
0087       bidToDesc branchDescriptionMap_;
0088       std::vector<edm::BranchDescription> bDesc_;
0089       bool mapperFilled_;
0090       edm::propagate_const<std::unique_ptr<edm::ThinnedAssociationsHelper>> thinnedAssociationsHelper_;
0091     };
0092 
0093     Strategy::Strategy(TFile* file, int fileVersion)
0094         : BMRStrategy(file, fileVersion),
0095           mapperFilled_(false),
0096           thinnedAssociationsHelper_(new edm::ThinnedAssociationsHelper) {
0097       // do in derived obects
0098       // updateFile(file);
0099     }
0100 
0101     Strategy::~Strategy() {
0102       // probably need to clean up something here...
0103     }
0104 
0105     bool Strategy::updateFile(TFile* file) {
0106       currentFile_ = file;
0107       eventTree_ = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::eventTreeName().c_str()));
0108       luminosityBlockTree_ = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::luminosityBlockTreeName().c_str()));
0109       runTree_ = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::runTreeName().c_str()));
0110       fileUUID_ = currentFile_->GetUUID();
0111       branchDescriptionMap_.clear();
0112       bDesc_.clear();
0113       return nullptr != eventTree_;
0114     }
0115 
0116     TBranch* Strategy::getBranchRegistry(edm::ProductRegistry** ppReg) {
0117       TBranch* bReg(nullptr);
0118 
0119       TTree* metaDataTree = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::metaDataTreeName().c_str()));
0120       if (nullptr != metaDataTree) {
0121         bReg = metaDataTree->GetBranch(edm::poolNames::productDescriptionBranchName().c_str());
0122         bReg->SetAddress(ppReg);
0123         bReg->GetEntry(0);
0124       }
0125       return bReg;
0126     }
0127 
0128     std::vector<edm::BranchDescription> const& Strategy::getBranchDescriptions() {
0129       if (bDesc_.empty()) {
0130         for (auto const& item : branchDescriptionMap_) {
0131           bDesc_.push_back(item.second);
0132         }
0133       }
0134       return bDesc_;
0135     }
0136 
0137     edm::BranchID Strategy::productToBranchID(edm::ProductID const&) {
0138       throw edm::Exception(edm::errors::UnimplementedFeature) << "Unsupported EDM file version";
0139     }
0140 
0141     edm::BranchDescription const& Strategy::productToBranch(edm::ProductID const& pid) {
0142       edm::BranchID bid = productToBranchID(pid);
0143       bidToDesc::const_iterator bdi = branchDescriptionMap_.find(bid);
0144       if (branchDescriptionMap_.end() == bdi) {
0145         return kDefaultBranchDescription;
0146       }
0147       return bdi->second;
0148     }
0149 
0150     edm::BranchDescription const& Strategy::branchIDToBranch(edm::BranchID const& bid) const {
0151       bidToDesc::const_iterator bdi = branchDescriptionMap_.find(bid);
0152       if (branchDescriptionMap_.end() == bdi) {
0153         return kDefaultBranchDescription;
0154       }
0155       return bdi->second;
0156     }
0157 
0158     class BranchMapReaderStrategyV1 : public Strategy {
0159     public:
0160       BranchMapReaderStrategyV1(TFile* file, int fileVersion);
0161       bool updateFile(TFile* file) override;
0162       bool updateMap() override;
0163       edm::BranchListIndexes const& branchListIndexes() const override { return dummyBranchListIndexes_; }
0164 
0165     private:
0166       edm::BranchListIndexes dummyBranchListIndexes_;
0167     };
0168 
0169     BranchMapReaderStrategyV1::BranchMapReaderStrategyV1(TFile* file, int fileVersion) : Strategy(file, fileVersion) {
0170       updateFile(file);
0171     }
0172 
0173     bool BranchMapReaderStrategyV1::updateFile(TFile* file) {
0174       if (Strategy::updateFile(file)) {
0175         mapperFilled_ = false;
0176         return true;
0177       }
0178       return false;
0179     }
0180 
0181     bool BranchMapReaderStrategyV1::updateMap() {
0182       if (mapperFilled_) {
0183         return true;
0184       }
0185 
0186       branchDescriptionMap_.clear();
0187       bDesc_.clear();
0188 
0189       edm::ProductRegistry reg;
0190       edm::ProductRegistry* pReg = &reg;
0191       TBranch* br = getBranchRegistry(&pReg);
0192 
0193       if (nullptr != br) {
0194         edm::ProductRegistry::ProductList& prodList = reg.productListUpdator();
0195 
0196         for (auto& item : prodList) {
0197           edm::BranchDescription& prod = item.second;
0198           if (edm::InEvent == prod.branchType()) {
0199             // call to regenerate branchName
0200             prod.init();
0201             branchDescriptionMap_.insert(bidToDesc::value_type(prod.branchID(), prod));
0202           }
0203         }
0204         mapperFilled_ = true;
0205       }
0206       reg.setFrozen(false);
0207       return nullptr != br;
0208     }
0209 
0210     // v7 has differences in product status that are not implemented in BranchMapReader yet
0211     class BranchMapReaderStrategyV7 : public BranchMapReaderStrategyV1 {
0212     public:
0213       BranchMapReaderStrategyV7(TFile* file, int fileVersion);
0214       edm::BranchListIndexes const& branchListIndexes() const override { return dummyBranchListIndexes_; }
0215 
0216     private:
0217       edm::BranchListIndexes dummyBranchListIndexes_;
0218     };
0219 
0220     BranchMapReaderStrategyV7::BranchMapReaderStrategyV7(TFile* file, int fileVersion)
0221         : BranchMapReaderStrategyV1(file, fileVersion) {
0222       updateFile(file);
0223     }
0224 
0225     class BranchMapReaderStrategyV8 : public Strategy {
0226     public:
0227       BranchMapReaderStrategyV8(TFile* file, int fileVersion);
0228       bool updateFile(TFile* file) override;
0229       bool updateEvent(Long_t eventEntry) override;
0230       bool updateLuminosityBlock(Long_t luminosityBlockEntry) override;
0231       bool updateRun(Long_t runEntry) override;
0232       bool updateMap() override;
0233       edm::BranchListIndexes const& branchListIndexes() const override { return dummyBranchListIndexes_; }
0234 
0235     private:
0236       edm::propagate_const<TBranch*> entryInfoBranch_;
0237       edm::EventEntryInfoVector eventEntryInfoVector_;
0238       edm::EventEntryInfoVector const* pEventEntryInfoVector_;
0239       edm::BranchListIndexes dummyBranchListIndexes_;
0240     };
0241 
0242     BranchMapReaderStrategyV8::BranchMapReaderStrategyV8(TFile* file, int fileVersion)
0243         : Strategy(file, fileVersion), eventEntryInfoVector_(), pEventEntryInfoVector_(&eventEntryInfoVector_) {
0244       updateFile(file);
0245     }
0246 
0247     bool BranchMapReaderStrategyV8::updateEvent(Long_t newevent) {
0248       // std::cout << "v8 updateevent " << newevent << std::endl;
0249       if (newevent != eventEntry_) {
0250         eventEntry_ = newevent;
0251         mapperFilled_ = false;
0252       }
0253       return true;
0254     }
0255 
0256     bool BranchMapReaderStrategyV8::updateLuminosityBlock(Long_t newLumi) {
0257       if (newLumi != luminosityBlockEntry_) {
0258         luminosityBlockEntry_ = newLumi;
0259         mapperFilled_ = false;
0260       }
0261       return true;
0262     }
0263 
0264     bool BranchMapReaderStrategyV8::updateRun(Long_t newRun) {
0265       if (newRun != runEntry_) {
0266         runEntry_ = newRun;
0267         mapperFilled_ = false;
0268       }
0269       return true;
0270     }
0271 
0272     bool BranchMapReaderStrategyV8::updateFile(TFile* file) {
0273       Strategy::updateFile(file);
0274       mapperFilled_ = false;
0275       entryInfoBranch_ = nullptr;
0276       TTree* metaDataTree = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::eventMetaDataTreeName().c_str()));
0277       if (nullptr != metaDataTree) {
0278         entryInfoBranch_ = metaDataTree->GetBranch(BranchTypeToBranchEntryInfoBranchName(edm::InEvent).c_str());
0279         //         std::cout << "entryInfoBranch for " << BranchTypeToBranchEntryInfoBranchName(edm::InEvent) << " " << entryInfoBranch_ << std::endl;
0280       } else {
0281         return false;
0282       }
0283       pEventEntryInfoVector_ = &eventEntryInfoVector_;
0284       entryInfoBranch_->SetAddress(&pEventEntryInfoVector_);
0285 
0286       branchDescriptionMap_.clear();
0287       bDesc_.clear();
0288 
0289       edm::ProductRegistry reg;
0290       edm::ProductRegistry* pReg = &reg;
0291       TBranch* br = getBranchRegistry(&pReg);
0292 
0293       if (nullptr != br) {
0294         edm::ProductRegistry::ProductList& prodList = reg.productListUpdator();
0295 
0296         for (auto& item : prodList) {
0297           edm::BranchDescription& prod = item.second;
0298           if (edm::InEvent == prod.branchType()) {
0299             // call to regenerate branchName
0300             prod.init();
0301             branchDescriptionMap_.insert(bidToDesc::value_type(prod.branchID(), prod));
0302           }
0303         }
0304       }
0305       reg.setFrozen(false);
0306       return nullptr != br;
0307     }
0308 
0309     bool BranchMapReaderStrategyV8::updateMap() {
0310       if (mapperFilled_) {
0311         return true;
0312       }
0313 
0314       assert(entryInfoBranch_);
0315 
0316       entryInfoBranch_->GetEntry(eventEntry_);
0317 
0318       //      for(auto const& item : *pEventEntryInfoVector_) {
0319       //         eventInfoMap_.insert(item);
0320       //      }
0321       mapperFilled_ = true;
0322       return true;
0323     }
0324 
0325     class BranchMapReaderStrategyV11 : public Strategy {
0326     public:
0327       BranchMapReaderStrategyV11(TFile* file, int fileVersion);
0328       bool updateFile(TFile* file) override;
0329       bool updateEvent(Long_t eventEntry) override;
0330       bool updateLuminosityBlock(Long_t luminosityBlockEntry) override;
0331       bool updateRun(Long_t runEntry) override;
0332       bool updateMap() override;
0333       edm::BranchID productToBranchID(edm::ProductID const& pid) override;
0334       edm::BranchListIndexes const& branchListIndexes() const override { return history_.branchListIndexes(); }
0335 
0336     private:
0337       edm::propagate_const<std::unique_ptr<edm::BranchIDLists>> branchIDLists_;
0338       edm::propagate_const<TTree*> eventHistoryTree_;
0339       edm::History history_;
0340       edm::History const* pHistory_;
0341     };
0342 
0343     BranchMapReaderStrategyV11::BranchMapReaderStrategyV11(TFile* file, int fileVersion)
0344         : Strategy(file, fileVersion), eventHistoryTree_(nullptr), pHistory_(&history_) {
0345       updateFile(file);
0346     }
0347 
0348     bool BranchMapReaderStrategyV11::updateEvent(Long_t newevent) {
0349       //      std::cout << "v11 updateevent " << newevent << std::endl;
0350       if (newevent != eventEntry_) {
0351         eventEntry_ = newevent;
0352         mapperFilled_ = false;
0353       }
0354       return true;
0355     }
0356 
0357     bool BranchMapReaderStrategyV11::updateLuminosityBlock(Long_t newlumi) {
0358       if (newlumi != luminosityBlockEntry_) {
0359         luminosityBlockEntry_ = newlumi;
0360         mapperFilled_ = false;
0361       }
0362       return true;
0363     }
0364 
0365     bool BranchMapReaderStrategyV11::updateRun(Long_t newRun) {
0366       if (newRun != runEntry_) {
0367         runEntry_ = newRun;
0368         mapperFilled_ = false;
0369       }
0370       return true;
0371     }
0372 
0373     bool BranchMapReaderStrategyV11::updateFile(TFile* file) {
0374       Strategy::updateFile(file);
0375       mapperFilled_ = false;
0376       TTree* metaDataTree = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::metaDataTreeName().c_str()));
0377 
0378       if (nullptr == metaDataTree) {
0379         throw edm::Exception(edm::errors::EventCorruption)
0380             << "No " << edm::poolNames::metaDataTreeName() << " TTree in file";
0381       }
0382       branchIDLists_ = std::make_unique<edm::BranchIDLists>();
0383       edm::BranchIDLists* branchIDListsPtr = branchIDLists_.get();
0384       if (metaDataTree->FindBranch(edm::poolNames::branchIDListBranchName().c_str()) != nullptr) {
0385         TBranch* b = metaDataTree->GetBranch(edm::poolNames::branchIDListBranchName().c_str());
0386         b->SetAddress(&branchIDListsPtr);
0387         b->GetEntry(0);
0388         //         std::cout << "--> " << branchIDLists_->size() << std::endl;
0389       } else {
0390         throw edm::Exception(edm::errors::EventCorruption) << "FindBranch of branchIDList failed";
0391         return false;
0392       }
0393 
0394       eventHistoryTree_ = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::eventHistoryTreeName().c_str()));
0395 
0396       branchDescriptionMap_.clear();
0397       bDesc_.clear();
0398 
0399       edm::ProductRegistry reg;
0400       edm::ProductRegistry* pReg = &reg;
0401       TBranch* br = getBranchRegistry(&pReg);
0402 
0403       if (nullptr != br) {
0404         edm::ProductRegistry::ProductList& prodList = reg.productListUpdator();
0405 
0406         for (auto& item : prodList) {
0407           edm::BranchDescription& prod = item.second;
0408           if (edm::InEvent == prod.branchType()) {
0409             // call to regenerate branchName
0410             prod.init();
0411             branchDescriptionMap_.insert(bidToDesc::value_type(prod.branchID(), prod));
0412             //             std::cout << "v11 updatefile " << prod.branchID() << std::endl;
0413           }
0414         }
0415       }
0416       reg.setFrozen(false);
0417       return nullptr != br;
0418     }
0419 
0420     bool BranchMapReaderStrategyV11::updateMap() {
0421       if (!mapperFilled_) {
0422         TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(edm::poolNames::eventHistoryBranchName().c_str());
0423         if (!eventHistoryBranch) {
0424           throw edm::Exception(edm::errors::EventCorruption) << "Failed to find history branch in event history tree";
0425           return false;
0426         }
0427         // yes, SetAddress really does need to be called every time...
0428         eventHistoryBranch->SetAddress(&pHistory_);
0429         eventHistoryTree_->GetEntry(eventEntry_);
0430         mapperFilled_ = true;
0431       }
0432       return true;
0433     }
0434 
0435     edm::BranchID BranchMapReaderStrategyV11::productToBranchID(edm::ProductID const& pid) {
0436       updateMap();
0437       return edm::productIDToBranchID(pid, *branchIDLists_, history_.branchListIndexes());
0438     }
0439 
0440     class BranchMapReaderStrategyV17 : public Strategy {
0441     public:
0442       BranchMapReaderStrategyV17(TFile* file, int fileVersion);
0443       bool updateFile(TFile* file) override;
0444       bool updateEvent(Long_t eventEntry) override;
0445       bool updateLuminosityBlock(Long_t luminosityBlockEntry) override;
0446       bool updateRun(Long_t runEntry) override;
0447       bool updateMap() override;
0448       edm::BranchID productToBranchID(edm::ProductID const& pid) override;
0449       edm::BranchListIndexes const& branchListIndexes() const override { return branchListIndexes_; }
0450 
0451     private:
0452       edm::propagate_const<std::unique_ptr<edm::BranchIDLists>> branchIDLists_;
0453       edm::propagate_const<TTree*> eventsTree_;
0454       edm::BranchListIndexes branchListIndexes_;
0455       edm::propagate_const<edm::BranchListIndexes*> pBranchListIndexes_;
0456     };
0457 
0458     BranchMapReaderStrategyV17::BranchMapReaderStrategyV17(TFile* file, int fileVersion)
0459         : Strategy(file, fileVersion), eventsTree_(nullptr), pBranchListIndexes_(&branchListIndexes_) {
0460       updateFile(file);
0461     }
0462 
0463     bool BranchMapReaderStrategyV17::updateEvent(Long_t newevent) {
0464       //      std::cout << "v11 updateevent " << newevent << std::endl;
0465       if (newevent != eventEntry_) {
0466         eventEntry_ = newevent;
0467         mapperFilled_ = false;
0468       }
0469       return true;
0470     }
0471 
0472     bool BranchMapReaderStrategyV17::updateLuminosityBlock(Long_t newlumi) {
0473       if (newlumi != luminosityBlockEntry_) {
0474         luminosityBlockEntry_ = newlumi;
0475         mapperFilled_ = false;
0476       }
0477       return true;
0478     }
0479 
0480     bool BranchMapReaderStrategyV17::updateRun(Long_t newRun) {
0481       if (newRun != runEntry_) {
0482         runEntry_ = newRun;
0483         mapperFilled_ = false;
0484       }
0485       return true;
0486     }
0487 
0488     bool BranchMapReaderStrategyV17::updateFile(TFile* file) {
0489       Strategy::updateFile(file);
0490       mapperFilled_ = false;
0491       TTree* metaDataTree = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::metaDataTreeName().c_str()));
0492       if (nullptr == metaDataTree) {
0493         throw edm::Exception(edm::errors::EventCorruption)
0494             << "No " << edm::poolNames::metaDataTreeName() << " TTree in file";
0495       }
0496 
0497       thinnedAssociationsHelper_ = std::make_unique<edm::ThinnedAssociationsHelper>();
0498       edm::ThinnedAssociationsHelper* thinnedAssociationsHelperPtr = thinnedAssociationsHelper_.get();
0499       if (metaDataTree->FindBranch(edm::poolNames::thinnedAssociationsHelperBranchName().c_str()) != nullptr) {
0500         TBranch* b = metaDataTree->GetBranch(edm::poolNames::thinnedAssociationsHelperBranchName().c_str());
0501         b->SetAddress(&thinnedAssociationsHelperPtr);
0502         b->GetEntry(0);
0503       }
0504 
0505       branchIDLists_ = std::make_unique<edm::BranchIDLists>();
0506       edm::BranchIDLists* branchIDListsPtr = branchIDLists_.get();
0507       if (metaDataTree->FindBranch(edm::poolNames::branchIDListBranchName().c_str()) != nullptr) {
0508         TBranch* b = metaDataTree->GetBranch(edm::poolNames::branchIDListBranchName().c_str());
0509         b->SetAddress(&branchIDListsPtr);
0510         b->GetEntry(0);
0511         //         std::cout << "--> " << branchIDLists_->size() << std::endl;
0512       } else {
0513         throw edm::Exception(edm::errors::EventCorruption) << "FindBranch of branchIDList failed";
0514         return false;
0515       }
0516 
0517       eventsTree_ = dynamic_cast<TTree*>(currentFile_->Get(edm::poolNames::eventTreeName().c_str()));
0518 
0519       branchDescriptionMap_.clear();
0520       bDesc_.clear();
0521 
0522       edm::ProductRegistry reg;
0523       edm::ProductRegistry* pReg = &reg;
0524       TBranch* br = getBranchRegistry(&pReg);
0525 
0526       if (nullptr != br) {
0527         edm::ProductRegistry::ProductList& prodList = reg.productListUpdator();
0528 
0529         for (auto& item : prodList) {
0530           edm::BranchDescription& prod = item.second;
0531           if (edm::InEvent == prod.branchType()) {
0532             // call to regenerate branchName
0533             prod.init();
0534             branchDescriptionMap_.insert(bidToDesc::value_type(prod.branchID(), prod));
0535             //             std::cout << "v11 updatefile " << prod.branchID() << std::endl;
0536           }
0537         }
0538       }
0539       reg.setFrozen(false);
0540       return nullptr != br;
0541     }
0542 
0543     bool BranchMapReaderStrategyV17::updateMap() {
0544       if (!mapperFilled_) {
0545         TBranch* branchListIndexesBranch =
0546             eventsTree_->GetBranch(edm::poolNames::branchListIndexesBranchName().c_str());
0547         if (!branchListIndexesBranch) {
0548           throw edm::Exception(edm::errors::EventCorruption)
0549               << "Failed to find branch list indexes branch in event tree";
0550           return false;
0551         }
0552         // yes, SetAddress really does need to be called every time...
0553         branchListIndexesBranch->SetAddress(&pBranchListIndexes_);
0554         branchListIndexesBranch->GetEntry(eventEntry_);
0555         mapperFilled_ = true;
0556       }
0557       return true;
0558     }
0559 
0560     edm::BranchID BranchMapReaderStrategyV17::productToBranchID(edm::ProductID const& pid) {
0561       updateMap();
0562       return edm::productIDToBranchID(pid, *branchIDLists_, branchListIndexes_);
0563     }
0564   }  // namespace internal
0565 
0566   //
0567   // constants, enums and typedefs
0568   //
0569 
0570   //
0571   // static data member definitions
0572   //
0573 
0574   //
0575   // constructors and destructor
0576   //
0577 
0578   BranchMapReader::BranchMapReader(TFile* file) : fileVersion_(-1) {
0579     if (nullptr == file) {
0580       throw cms::Exception("NoFile") << "The TFile pointer is null";
0581     }
0582     strategy_ = newStrategy(file, getFileVersion(file));
0583   }
0584 
0585   //
0586   // member functions
0587   //
0588 
0589   int BranchMapReader::getFileVersion(TFile* file) {
0590     TTree* metaDataTree = dynamic_cast<TTree*>(file->Get(edm::poolNames::metaDataTreeName().c_str()));
0591     if (nullptr == metaDataTree) {
0592       return 0;
0593     }
0594 
0595     edm::FileFormatVersion v;
0596     edm::FileFormatVersion* pV = &v;
0597     TBranch* bVer = metaDataTree->GetBranch(edm::poolNames::fileFormatVersionBranchName().c_str());
0598     if (nullptr == bVer) {
0599       return 0;
0600     }
0601     bVer->SetAddress(&pV);
0602     bVer->GetEntry(0);
0603     fileVersion_ = v.value();
0604     return v.value();
0605   }
0606 
0607   bool BranchMapReader::updateEvent(Long_t newevent) { return strategy_->updateEvent(newevent); }
0608 
0609   bool BranchMapReader::updateLuminosityBlock(Long_t newlumi) { return strategy_->updateLuminosityBlock(newlumi); }
0610 
0611   bool BranchMapReader::updateRun(Long_t newRun) { return strategy_->updateRun(newRun); }
0612 
0613   bool BranchMapReader::updateFile(TFile* file) {
0614     if (nullptr == strategy_.get()) {
0615       strategy_ = newStrategy(file, getFileVersion(file));
0616       return true;
0617     }
0618 
0619     TFile* currentFile(strategy_->currentFile_);
0620     bool isNew(file != currentFile);
0621 
0622     if (!isNew) {
0623       //could still have a new TFile which just happens to share the same memory address as the previous file
0624       //will assume that if the Event tree's address and UUID are the same as before then we do not have
0625       // to treat this like a new file
0626       TTree* eventTreeTemp = dynamic_cast<TTree*>(currentFile->Get(edm::poolNames::eventTreeName().c_str()));
0627       isNew = eventTreeTemp != strategy_->eventTree_ || strategy_->fileUUID_ != currentFile->GetUUID();
0628     }
0629     if (isNew) {
0630       int fileVersion = getFileVersion(file);
0631       if (fileVersion != strategy_->fileVersion_) {
0632         strategy_ = newStrategy(file, fileVersion);
0633       } else {
0634         strategy_->updateFile(file);
0635       }
0636     }
0637     return isNew;
0638   }
0639 
0640   edm::BranchDescription const& BranchMapReader::productToBranch(edm::ProductID const& pid) {
0641     return strategy_->productToBranch(pid);
0642   }
0643 
0644   std::vector<edm::BranchDescription> const& BranchMapReader::getBranchDescriptions() {
0645     return strategy_->getBranchDescriptions();
0646   }
0647 
0648   std::unique_ptr<internal::BMRStrategy> BranchMapReader::newStrategy(TFile* file, int fileVersion) {
0649     std::unique_ptr<internal::BMRStrategy> s;
0650 
0651     if (fileVersion >= 17) {
0652       s = std::make_unique<internal::BranchMapReaderStrategyV17>(file, fileVersion);
0653     } else if (fileVersion >= 11) {
0654       s = std::make_unique<internal::BranchMapReaderStrategyV11>(file, fileVersion);
0655     } else if (fileVersion >= 8) {
0656       s = std::make_unique<internal::BranchMapReaderStrategyV8>(file, fileVersion);
0657     } else if (fileVersion >= 7) {
0658       s = std::make_unique<internal::BranchMapReaderStrategyV7>(file, fileVersion);
0659     } else {
0660       s = std::make_unique<internal::BranchMapReaderStrategyV1>(file, fileVersion);
0661     }
0662     return s;
0663   }
0664 }  // namespace fwlite