00001
00002
00003
00004 #include "RootFile.h"
00005 #include "BranchMapperWithReader.h"
00006 #include "DuplicateChecker.h"
00007 #include "InputFile.h"
00008 #include "ProvenanceAdaptor.h"
00009
00010 #include "DataFormats/Common/interface/EDProduct.h"
00011 #include "DataFormats/Common/interface/RefCoreStreamer.h"
00012 #include "DataFormats/Provenance/interface/BranchDescription.h"
00013 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
00014 #include "DataFormats/Provenance/interface/BranchType.h"
00015 #include "DataFormats/Provenance/interface/EventEntryInfo.h"
00016 #include "DataFormats/Provenance/interface/History.h"
00017 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
00018 #include "DataFormats/Provenance/interface/ParentageRegistry.h"
00019 #include "DataFormats/Provenance/interface/ProcessConfigurationRegistry.h"
00020 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00021 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00022 #include "DataFormats/Provenance/interface/RunID.h"
00023 #include "FWCore/Framework/interface/FileBlock.h"
00024 #include "FWCore/Framework/interface/EventPrincipal.h"
00025 #include "FWCore/Framework/interface/GroupSelector.h"
00026 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00027 #include "FWCore/Framework/interface/RunPrincipal.h"
00028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00029 #include "FWCore/ParameterSet/interface/FillProductRegistryTransients.h"
00030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00031 #include "FWCore/ParameterSet/interface/Registry.h"
00032 #include "FWCore/ServiceRegistry/interface/Service.h"
00033 #include "FWCore/Sources/interface/EventSkipperByID.h"
00034 #include "FWCore/Utilities/interface/Algorithms.h"
00035 #include "FWCore/Utilities/interface/do_nothing_deleter.h"
00036 #include "FWCore/Utilities/interface/EDMException.h"
00037 #include "FWCore/Utilities/interface/FriendlyName.h"
00038 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
00039
00040
00041 #include "DataFormats/Provenance/interface/BranchEntryDescription.h"
00042 #include "DataFormats/Provenance/interface/EntryDescriptionRegistry.h"
00043 #include "DataFormats/Provenance/interface/EventAux.h"
00044 #include "DataFormats/Provenance/interface/LuminosityBlockAux.h"
00045 #include "DataFormats/Provenance/interface/RunAux.h"
00046 #include "DataFormats/Provenance/interface/RunLumiEntryInfo.h"
00047 #include "FWCore/ParameterSet/interface/ParameterSetConverter.h"
00048
00049 #include "TROOT.h"
00050 #include "Rtypes.h"
00051 #include "TClass.h"
00052 #include "TTree.h"
00053 #include "TTreeCache.h"
00054
00055 #include <algorithm>
00056 #include <map>
00057 #include <list>
00058
00059 namespace edm {
00060 namespace {
00061 int
00062 forcedRunOffset(RunNumber_t const& forcedRunNumber, IndexIntoFile::IndexIntoFileItr inxBegin, IndexIntoFile::IndexIntoFileItr inxEnd) {
00063 if(inxBegin == inxEnd) return 0;
00064 int defaultOffset = (inxBegin.run() != 0 ? 0 : 1);
00065 int offset = (forcedRunNumber != 0U ? forcedRunNumber - inxBegin.run() : defaultOffset);
00066 if(offset < 0) {
00067 throw Exception(errors::Configuration)
00068 << "The value of the 'setRunNumber' parameter must not be\n"
00069 << "less than the first run number in the first input file.\n"
00070 << "'setRunNumber' was " << forcedRunNumber <<", while the first run was "
00071 << forcedRunNumber - offset << ".\n";
00072 }
00073 return offset;
00074 }
00075 }
00076
00077
00078 class RootFileEventFinder : public IndexIntoFile::EventFinder {
00079 public:
00080 explicit RootFileEventFinder(RootTree& eventTree) : eventTree_(eventTree) {}
00081 virtual ~RootFileEventFinder() {}
00082 virtual
00083 EventNumber_t getEventNumberOfEntry(roottree::EntryNumber entry) const {
00084 roottree::EntryNumber saveEntry = eventTree_.entryNumber();
00085 eventTree_.setEntryNumber(entry);
00086 EventAuxiliary eventAux;
00087 EventAuxiliary *pEvAux = &eventAux;
00088 eventTree_.fillAux<EventAuxiliary>(pEvAux);
00089 eventTree_.setEntryNumber(saveEntry);
00090 return eventAux.event();
00091 }
00092
00093 private:
00094 RootTree& eventTree_;
00095 };
00096
00097
00098
00099 RootFile::RootFile(std::string const& fileName,
00100 ProcessConfiguration const& processConfiguration,
00101 std::string const& logicalFileName,
00102 boost::shared_ptr<InputFile> filePtr,
00103 boost::shared_ptr<EventSkipperByID> eventSkipperByID,
00104 bool skipAnyEvents,
00105 int remainingEvents,
00106 int remainingLumis,
00107 unsigned int treeCacheSize,
00108 int treeMaxVirtualSize,
00109 InputSource::ProcessingMode processingMode,
00110 RunNumber_t const& forcedRunNumber,
00111 bool noEventSort,
00112 GroupSelectorRules const& groupSelectorRules,
00113 bool secondaryFile,
00114 boost::shared_ptr<DuplicateChecker> duplicateChecker,
00115 bool dropDescendants,
00116 std::vector<boost::shared_ptr<IndexIntoFile> > const& indexesIntoFiles,
00117 std::vector<boost::shared_ptr<IndexIntoFile> >::size_type currentIndexIntoFile,
00118 std::vector<ProcessHistoryID>& orderedProcessHistoryIDs,
00119 bool usingGoToEvent) :
00120 file_(fileName),
00121 logicalFile_(logicalFileName),
00122 processConfiguration_(processConfiguration),
00123 filePtr_(filePtr),
00124 eventSkipperByID_(eventSkipperByID),
00125 fileFormatVersion_(),
00126 fid_(),
00127 indexIntoFileSharedPtr_(new IndexIntoFile),
00128 indexIntoFile_(*indexIntoFileSharedPtr_),
00129 orderedProcessHistoryIDs_(orderedProcessHistoryIDs),
00130 indexIntoFileBegin_(indexIntoFile_.begin(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder)),
00131 indexIntoFileEnd_(indexIntoFileBegin_),
00132 indexIntoFileIter_(indexIntoFileBegin_),
00133 eventProcessHistoryIDs_(),
00134 eventProcessHistoryIter_(eventProcessHistoryIDs_.begin()),
00135 skipAnyEvents_(skipAnyEvents),
00136 noEventSort_(noEventSort),
00137 whyNotFastClonable_(0),
00138 hasNewlyDroppedBranch_(),
00139 branchListIndexesUnchanged_(false),
00140 eventAux_(),
00141 eventTree_(filePtr_, InEvent, treeMaxVirtualSize, treeCacheSize, roottree::defaultLearningEntries),
00142 lumiTree_(filePtr_, InLumi, treeMaxVirtualSize, roottree::defaultNonEventCacheSize, roottree::defaultNonEventLearningEntries),
00143 runTree_(filePtr_, InRun, treeMaxVirtualSize, roottree::defaultNonEventCacheSize, roottree::defaultNonEventLearningEntries),
00144 treePointers_(),
00145 lastEventEntryNumberRead_(-1LL),
00146 productRegistry_(),
00147 branchIDLists_(),
00148 processingMode_(processingMode),
00149 forcedRunOffset_(0),
00150 newBranchToOldBranch_(),
00151 eventHistoryTree_(0),
00152 eventSelectionIDs_(new EventSelectionIDVector),
00153 branchListIndexes_(new BranchListIndexes),
00154 history_(),
00155 branchChildren_(new BranchChildren),
00156 duplicateChecker_(duplicateChecker),
00157 provenanceAdaptor_() {
00158
00159 hasNewlyDroppedBranch_.assign(false);
00160
00161 treePointers_[InEvent] = &eventTree_;
00162 treePointers_[InLumi] = &lumiTree_;
00163 treePointers_[InRun] = &runTree_;
00164
00165
00166 TTree *metaDataTree = dynamic_cast<TTree *>(filePtr_->Get(poolNames::metaDataTreeName().c_str()));
00167 if(!metaDataTree)
00168 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::metaDataTreeName()
00169 << " in the input file.\n";
00170
00171
00172
00173
00174 FileFormatVersion *fftPtr = &fileFormatVersion_;
00175 if(metaDataTree->FindBranch(poolNames::fileFormatVersionBranchName().c_str()) != 0) {
00176 TBranch *fft = metaDataTree->GetBranch(poolNames::fileFormatVersionBranchName().c_str());
00177 fft->SetAddress(&fftPtr);
00178 roottree::getEntry(fft, 0);
00179 metaDataTree->SetBranchAddress(poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
00180 }
00181
00182 setRefCoreStreamer(0, !fileFormatVersion().splitProductIDs(), !fileFormatVersion().productIDIsInt());
00183
00184 FileID *fidPtr = &fid_;
00185 if(metaDataTree->FindBranch(poolNames::fileIdentifierBranchName().c_str()) != 0) {
00186 metaDataTree->SetBranchAddress(poolNames::fileIdentifierBranchName().c_str(), &fidPtr);
00187 }
00188
00189 IndexIntoFile *iifPtr = &indexIntoFile_;
00190 if(metaDataTree->FindBranch(poolNames::indexIntoFileBranchName().c_str()) != 0) {
00191 metaDataTree->SetBranchAddress(poolNames::indexIntoFileBranchName().c_str(), &iifPtr);
00192 }
00193
00194
00195
00196 ProductRegistry inputProdDescReg;
00197 ProductRegistry *ppReg = &inputProdDescReg;
00198 metaDataTree->SetBranchAddress(poolNames::productDescriptionBranchName().c_str(), (&ppReg));
00199
00200 typedef std::map<ParameterSetID, ParameterSetBlob> PsetMap;
00201 PsetMap psetMap;
00202 PsetMap *psetMapPtr = &psetMap;
00203 if(metaDataTree->FindBranch(poolNames::parameterSetMapBranchName().c_str()) != 0) {
00204
00205 assert(!fileFormatVersion().parameterSetsTree());
00206 metaDataTree->SetBranchAddress(poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
00207 } else {
00208 assert(fileFormatVersion().parameterSetsTree());
00209 TTree* psetTree = dynamic_cast<TTree *>(filePtr_->Get(poolNames::parameterSetsTreeName().c_str()));
00210 if(0 == psetTree) {
00211 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::parameterSetsTreeName()
00212 << " in the input file.\n";
00213 }
00214
00215 typedef std::pair<ParameterSetID, ParameterSetBlob> IdToBlobs;
00216 IdToBlobs idToBlob;
00217 IdToBlobs* pIdToBlob = &idToBlob;
00218 psetTree->SetBranchAddress(poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
00219
00220 std::auto_ptr<TTreeCache> psetTreeCache = roottree::trainCache(psetTree, *filePtr_, roottree::defaultNonEventCacheSize, "*");
00221 filePtr_->SetCacheRead(psetTreeCache.get());
00222 for(Long64_t i = 0; i != psetTree->GetEntries(); ++i) {
00223 psetTree->GetEntry(i);
00224 psetMap.insert(idToBlob);
00225 }
00226 filePtr_->SetCacheRead(0);
00227 }
00228
00229
00230 ProcessHistoryRegistry::collection_type pHistMap;
00231 ProcessHistoryRegistry::collection_type *pHistMapPtr = &pHistMap;
00232 if(metaDataTree->FindBranch(poolNames::processHistoryMapBranchName().c_str()) != 0) {
00233 metaDataTree->SetBranchAddress(poolNames::processHistoryMapBranchName().c_str(), &pHistMapPtr);
00234 }
00235
00236 ProcessHistoryRegistry::vector_type pHistVector;
00237 ProcessHistoryRegistry::vector_type *pHistVectorPtr = &pHistVector;
00238 if(metaDataTree->FindBranch(poolNames::processHistoryBranchName().c_str()) != 0) {
00239 metaDataTree->SetBranchAddress(poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
00240 }
00241
00242 ProcessConfigurationVector procConfigVector;
00243 ProcessConfigurationVector* procConfigVectorPtr = &procConfigVector;
00244 if(metaDataTree->FindBranch(poolNames::processConfigurationBranchName().c_str()) != 0) {
00245 metaDataTree->SetBranchAddress(poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
00246 }
00247
00248 std::auto_ptr<BranchIDListRegistry::collection_type> branchIDListsAPtr(new BranchIDListRegistry::collection_type);
00249 BranchIDListRegistry::collection_type *branchIDListsPtr = branchIDListsAPtr.get();
00250 if(metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) != 0) {
00251 metaDataTree->SetBranchAddress(poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
00252 }
00253
00254 BranchChildren* branchChildrenBuffer = branchChildren_.get();
00255 if(metaDataTree->FindBranch(poolNames::productDependenciesBranchName().c_str()) != 0) {
00256 metaDataTree->SetBranchAddress(poolNames::productDependenciesBranchName().c_str(), &branchChildrenBuffer);
00257 }
00258
00259
00260 std::vector<EventProcessHistoryID> *eventHistoryIDsPtr = &eventProcessHistoryIDs_;
00261 if(metaDataTree->FindBranch(poolNames::eventHistoryBranchName().c_str()) != 0) {
00262 metaDataTree->SetBranchAddress(poolNames::eventHistoryBranchName().c_str(), &eventHistoryIDsPtr);
00263 }
00264
00265 if(metaDataTree->FindBranch(poolNames::moduleDescriptionMapBranchName().c_str()) != 0) {
00266 if(metaDataTree->GetBranch(poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
00267 metaDataTree->SetBranchStatus((poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), 0);
00268 } else {
00269 metaDataTree->SetBranchStatus(poolNames::moduleDescriptionMapBranchName().c_str(), 0);
00270 }
00271 }
00272
00273
00274 roottree::getEntry(metaDataTree, 0);
00275
00276 eventProcessHistoryIter_ = eventProcessHistoryIDs_.begin();
00277
00278
00279 readEventHistoryTree();
00280
00281 ParameterSetConverter::ParameterSetIdConverter psetIdConverter;
00282 if(!fileFormatVersion().triggerPathsTracked()) {
00283 ParameterSetConverter converter(psetMap, psetIdConverter, fileFormatVersion().parameterSetsByReference());
00284 } else {
00285
00286 pset::Registry& psetRegistry = *pset::Registry::instance();
00287 for(PsetMap::const_iterator i = psetMap.begin(), iEnd = psetMap.end(); i != iEnd; ++i) {
00288 ParameterSet pset(i->second.pset());
00289 pset.setID(i->first);
00290 psetRegistry.insertMapped(pset);
00291 }
00292 }
00293 if(!fileFormatVersion().splitProductIDs()) {
00294
00295 provenanceAdaptor_.reset(new ProvenanceAdaptor(
00296 inputProdDescReg, pHistMap, pHistVector, procConfigVector, psetIdConverter, true));
00297
00298 branchIDLists_ = provenanceAdaptor_->branchIDLists();
00299 } else {
00300 if(!fileFormatVersion().triggerPathsTracked()) {
00301
00302 provenanceAdaptor_.reset(new ProvenanceAdaptor(
00303 inputProdDescReg, pHistMap, pHistVector, procConfigVector, psetIdConverter, false));
00304 }
00305
00306 if(metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) == 0) {
00307 throw Exception(errors::EventCorruption)
00308 << "Failed to find branchIDLists branch in metaData tree.\n";
00309 }
00310 branchIDLists_.reset(branchIDListsAPtr.release());
00311 }
00312
00313
00314 ProcessHistoryRegistry::instance()->insertCollection(pHistVector);
00315 ProcessConfigurationRegistry::instance()->insertCollection(procConfigVector);
00316
00317 eventTree_.trainCache(BranchTypeToAuxiliaryBranchName(InEvent).c_str());
00318
00319 validateFile(secondaryFile, usingGoToEvent);
00320
00321
00322 readParentageTree();
00323
00324 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
00325 whyNotFastClonable_ += FileBlock::EventsOrLumisSelectedByID;
00326 }
00327
00328 initializeDuplicateChecker(indexesIntoFiles, currentIndexIntoFile);
00329 indexIntoFileIter_ = indexIntoFileBegin_ = indexIntoFile_.begin(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder);
00330 indexIntoFileEnd_ = indexIntoFile_.end(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder);
00331 forcedRunOffset_ = forcedRunOffset(forcedRunNumber, indexIntoFileBegin_, indexIntoFileEnd_);
00332 eventProcessHistoryIter_ = eventProcessHistoryIDs_.begin();
00333
00334
00335 ProductRegistry::ProductList const& pList = inputProdDescReg.productList();
00336 for(ProductRegistry::ProductList::const_iterator it = pList.begin(), itEnd = pList.end();
00337 it != itEnd; ++it) {
00338 BranchDescription const& prod = it->second;
00339 treePointers_[prod.branchType()]->setPresence(prod);
00340 }
00341
00342 fillProductRegistryTransients(procConfigVector, inputProdDescReg);
00343
00344 std::auto_ptr<ProductRegistry> newReg(new ProductRegistry);
00345
00346
00347 {
00348 ProductRegistry::ProductList const& prodList = inputProdDescReg.productList();
00349 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
00350 it != itEnd; ++it) {
00351 BranchDescription const& prod = it->second;
00352 std::string newFriendlyName = friendlyname::friendlyName(prod.className());
00353 if(newFriendlyName == prod.friendlyClassName()) {
00354 newReg->copyProduct(prod);
00355 } else {
00356 if(fileFormatVersion().splitProductIDs()) {
00357 throw Exception(errors::UnimplementedFeature)
00358 << "Cannot change friendly class name algorithm without more development work\n"
00359 << "to update BranchIDLists. Contact the framework group.\n";
00360 }
00361 BranchDescription newBD(prod);
00362 newBD.updateFriendlyClassName();
00363 newReg->copyProduct(newBD);
00364 newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), prod.branchName()));
00365 }
00366 }
00367 dropOnInput(*newReg, groupSelectorRules, dropDescendants, secondaryFile);
00368
00369 newReg->setFrozen();
00370 productRegistry_.reset(newReg.release());
00371 }
00372
00373
00374
00375 ProductRegistry::ProductList const& prodList = productRegistry()->productList();
00376 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
00377 it != itEnd; ++it) {
00378 BranchDescription const& prod = it->second;
00379 treePointers_[prod.branchType()]->addBranch(it->first, prod,
00380 newBranchToOldBranch(prod.branchName()));
00381 }
00382
00383
00384 setIfFastClonable(remainingEvents, remainingLumis);
00385
00386
00387 if(!secondaryFile) {
00388 branchListIndexesUnchanged_ = BranchIDListHelper::updateFromInput(*branchIDLists_, file_);
00389 }
00390
00391 setRefCoreStreamer(true);
00392
00393
00394 indexIntoFile_.doneFileInitialization();
00395
00396
00397 eventTree_.resetTraining();
00398
00399
00400 runTree_.trainCache("*");
00401 lumiTree_.trainCache("*");
00402 }
00403
00404 RootFile::~RootFile() {
00405 }
00406
00407 void
00408 RootFile::readEntryDescriptionTree() {
00409
00410 if(!fileFormatVersion().perEventProductIDs()) return;
00411 TTree* entryDescriptionTree = dynamic_cast<TTree*>(filePtr_->Get(poolNames::entryDescriptionTreeName().c_str()));
00412 if(!entryDescriptionTree)
00413 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::entryDescriptionTreeName()
00414 << " in the input file.\n";
00415
00416
00417 EntryDescriptionID idBuffer;
00418 EntryDescriptionID* pidBuffer = &idBuffer;
00419 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), &pidBuffer);
00420
00421 EntryDescriptionRegistry& oldregistry = *EntryDescriptionRegistry::instance();
00422
00423 EventEntryDescription entryDescriptionBuffer;
00424 EventEntryDescription *pEntryDescriptionBuffer = &entryDescriptionBuffer;
00425 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), &pEntryDescriptionBuffer);
00426
00427
00428 ParentageRegistry& registry = *ParentageRegistry::instance();
00429
00430 for(Long64_t i = 0, numEntries = entryDescriptionTree->GetEntries(); i < numEntries; ++i) {
00431 roottree::getEntry(entryDescriptionTree, i);
00432 if(idBuffer != entryDescriptionBuffer.id())
00433 throw Exception(errors::EventCorruption) << "Corruption of EntryDescription tree detected.\n";
00434 oldregistry.insertMapped(entryDescriptionBuffer);
00435 Parentage parents;
00436 parents.parents() = entryDescriptionBuffer.parents();
00437 registry.insertMapped(parents);
00438 }
00439 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), 0);
00440 entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), 0);
00441 }
00442
00443 void
00444 RootFile::readParentageTree() {
00445 if(!fileFormatVersion().splitProductIDs()) {
00446
00447 readEntryDescriptionTree();
00448 return;
00449 }
00450
00451 TTree* parentageTree = dynamic_cast<TTree*>(filePtr_->Get(poolNames::parentageTreeName().c_str()));
00452 if(!parentageTree)
00453 throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::parentageTreeName()
00454 << " in the input file.\n";
00455
00456 Parentage parentageBuffer;
00457 Parentage *pParentageBuffer = &parentageBuffer;
00458 parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), &pParentageBuffer);
00459
00460 ParentageRegistry& registry = *ParentageRegistry::instance();
00461
00462 for(Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
00463 roottree::getEntry(parentageTree, i);
00464 registry.insertMapped(parentageBuffer);
00465 }
00466 parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), 0);
00467 }
00468
00469 void
00470 RootFile::setIfFastClonable(int remainingEvents, int remainingLumis) {
00471 if(!fileFormatVersion().splitProductIDs()) {
00472 whyNotFastClonable_ += FileBlock::FileTooOld;
00473 return;
00474 }
00475 if(processingMode_ != InputSource::RunsLumisAndEvents) {
00476 whyNotFastClonable_ += FileBlock::NotProcessingEvents;
00477 return;
00478 }
00479
00480 IndexIntoFile::IndexIntoFileItr it = indexIntoFileBegin_;
00481 while(it != indexIntoFileEnd_ && it.getEntryType() != IndexIntoFile::kEvent) {
00482 ++it;
00483 }
00484 if(it == indexIntoFileEnd_) {
00485 whyNotFastClonable_ += FileBlock::NoEventsInFile;
00486 return;
00487 }
00488
00489
00490 IndexIntoFile::SortOrder sortOrder = IndexIntoFile::numericalOrder;
00491 if(noEventSort_) sortOrder = IndexIntoFile::firstAppearanceOrder;
00492 if(!indexIntoFile_.iterationWillBeInEntryOrder(sortOrder)) {
00493 whyNotFastClonable_ += FileBlock::EventsToBeSorted;
00494 }
00495 if(skipAnyEvents_) {
00496 whyNotFastClonable_ += FileBlock::InitialEventsSkipped;
00497 }
00498 if(remainingEvents >= 0 && eventTree_.entries() > remainingEvents) {
00499 whyNotFastClonable_ += FileBlock::MaxEventsTooSmall;
00500 }
00501 if(remainingLumis >= 0 && lumiTree_.entries() > remainingLumis) {
00502 whyNotFastClonable_ += FileBlock::MaxLumisTooSmall;
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512 if(duplicateChecker_ &&
00513 !duplicateChecker_->checkDisabled() &&
00514 !duplicateChecker_->noDuplicatesInFile()) {
00515 whyNotFastClonable_ += FileBlock::DuplicateEventsRemoved;
00516 }
00517 }
00518
00519 boost::shared_ptr<FileBlock>
00520 RootFile::createFileBlock() const {
00521 return boost::shared_ptr<FileBlock>(new FileBlock(fileFormatVersion(),
00522 eventTree_.tree(),
00523 eventTree_.metaTree(),
00524 lumiTree_.tree(),
00525 lumiTree_.metaTree(),
00526 runTree_.tree(),
00527 runTree_.metaTree(),
00528 whyNotFastClonable(),
00529 hasNewlyDroppedBranch(),
00530 file_,
00531 branchListIndexesUnchanged(),
00532 branchChildren_));
00533 }
00534
00535 std::string const&
00536 RootFile::newBranchToOldBranch(std::string const& newBranch) const {
00537 std::map<std::string, std::string>::const_iterator it = newBranchToOldBranch_.find(newBranch);
00538 if(it != newBranchToOldBranch_.end()) {
00539 return it->second;
00540 }
00541 return newBranch;
00542 }
00543
00544 IndexIntoFile::IndexIntoFileItr
00545 RootFile::indexIntoFileIter() const {
00546 return indexIntoFileIter_;
00547 }
00548
00549 void
00550 RootFile::setPosition(IndexIntoFile::IndexIntoFileItr const& position) {
00551 indexIntoFileIter_.copyPosition(position);
00552 }
00553
00554 bool
00555 RootFile::skipThisEntry() {
00556 if(indexIntoFileIter_ == indexIntoFileEnd_) {
00557 return false;
00558 }
00559 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
00560
00561
00562 if(eventSkipperByID_->skipIt(indexIntoFileIter_.run(), indexIntoFileIter_.lumi(), 0U)) {
00563 return true;
00564 }
00565
00566
00567 if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent) {
00568 fillEventAuxiliary();
00569 if(eventSkipperByID_->skipIt(indexIntoFileIter_.run(),
00570 indexIntoFileIter_.lumi(),
00571 eventAux_.id().event())) {
00572 return true;
00573 }
00574 }
00575
00576
00577 if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun &&
00578 eventSkipperByID_->skippingLumis()) {
00579 IndexIntoFile::IndexIntoFileItr iterLumi = indexIntoFileIter_;
00580
00581
00582 if(iterLumi.peekAheadAtLumi() == IndexIntoFile::invalidLumi) {
00583 return true;
00584 }
00585
00586 do {
00587 if(!eventSkipperByID_->skipIt(iterLumi.run(), iterLumi.peekAheadAtLumi(), 0U)) {
00588 return false;
00589 }
00590 }
00591 while(iterLumi.skipLumiInRun());
00592 return true;
00593 }
00594 }
00595 return false;
00596 }
00597
00598 IndexIntoFile::EntryType
00599 RootFile::getEntryTypeWithSkipping() {
00600 while(skipThisEntry()) {
00601 if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun) {
00602 indexIntoFileIter_.advanceToNextRun();
00603 }
00604 else if(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi) {
00605 indexIntoFileIter_.advanceToNextLumiOrRun();
00606 }
00607 else {
00608 ++indexIntoFileIter_;
00609 }
00610 }
00611 return indexIntoFileIter_.getEntryType();
00612 }
00613
00614 bool
00615 RootFile::isDuplicateEvent() {
00616 assert (indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent);
00617 if(duplicateChecker_.get() == 0) {
00618 return false;
00619 }
00620 fillEventAuxiliary();
00621 return duplicateChecker_->isDuplicateAndCheckActive(indexIntoFileIter_.processHistoryIDIndex(),
00622 indexIntoFileIter_.run(), indexIntoFileIter_.lumi(), eventAux_.id().event(), file_);
00623 }
00624
00625 IndexIntoFile::EntryType
00626 RootFile::getNextEntryTypeWanted() {
00627 IndexIntoFile::EntryType entryType = getEntryTypeWithSkipping();
00628 if(entryType == IndexIntoFile::kEnd) {
00629 return IndexIntoFile::kEnd;
00630 }
00631 if(entryType == IndexIntoFile::kRun) {
00632 return IndexIntoFile::kRun;
00633 } else if(processingMode_ == InputSource::Runs) {
00634 indexIntoFileIter_.advanceToNextRun();
00635 return getNextEntryTypeWanted();
00636 }
00637 if(entryType == IndexIntoFile::kLumi) {
00638 return IndexIntoFile::kLumi;
00639 } else if(processingMode_ == InputSource::RunsAndLumis) {
00640 indexIntoFileIter_.advanceToNextLumiOrRun();
00641 return getNextEntryTypeWanted();
00642 }
00643 if(isDuplicateEvent()) {
00644 ++indexIntoFileIter_;
00645 return getNextEntryTypeWanted();
00646 }
00647 return IndexIntoFile::kEvent;
00648 }
00649
00650 bool
00651 RootFile::wasLastEventJustRead() const {
00652 IndexIntoFile::IndexIntoFileItr itr(indexIntoFileIter_);
00653 itr.advanceToEvent();
00654 return itr.getEntryType() == IndexIntoFile::kEnd;
00655 }
00656
00657 bool
00658 RootFile::wasFirstEventJustRead() const {
00659 IndexIntoFile::IndexIntoFileItr itr(indexIntoFileIter_);
00660 int phIndex;
00661 RunNumber_t run;
00662 LuminosityBlockNumber_t lumi;
00663 IndexIntoFile::EntryNumber_t eventEntry;
00664 itr.skipEventBackward(phIndex,
00665 run,
00666 lumi,
00667 eventEntry);
00668 itr.skipEventBackward(phIndex,
00669 run,
00670 lumi,
00671 eventEntry);
00672 return eventEntry == IndexIntoFile::invalidEntry;
00673 }
00674
00675 namespace {
00676 typedef IndexIntoFile::EntryNumber_t EntryNumber_t;
00677 struct RunItem {
00678 RunItem(ProcessHistoryID const& phid, RunNumber_t const& run) :
00679 phid_(phid), run_(run) {}
00680 ProcessHistoryID phid_;
00681 RunNumber_t run_;
00682 };
00683 struct RunItemSortByRun {
00684 bool operator()(RunItem const& a, RunItem const& b) const {
00685 return a.run_ < b.run_;
00686 }
00687 };
00688 struct RunItemSortByRunPhid {
00689 bool operator()(RunItem const& a, RunItem const& b) const {
00690 return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.phid_ < b.phid_);
00691 }
00692 };
00693 struct LumiItem {
00694 LumiItem(ProcessHistoryID const& phid, RunNumber_t const& run,
00695 LuminosityBlockNumber_t const& lumi, EntryNumber_t const& entry) :
00696 phid_(phid), run_(run), lumi_(lumi), firstEventEntry_(entry),
00697 lastEventEntry_(entry == -1LL ? -1LL : entry + 1) {}
00698 ProcessHistoryID phid_;
00699 RunNumber_t run_;
00700 LuminosityBlockNumber_t lumi_;
00701 EntryNumber_t firstEventEntry_;
00702 EntryNumber_t lastEventEntry_;
00703 };
00704 struct LumiItemSortByRunLumi {
00705 bool operator()(LumiItem const& a, LumiItem const& b) const {
00706 return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.lumi_ < b.lumi_);
00707 }
00708 };
00709 struct LumiItemSortByRunLumiPhid {
00710 bool operator()(LumiItem const& a, LumiItem const& b) const {
00711 if(a.run_ < b.run_) return true;
00712 if(b.run_ < a.run_) return false;
00713 if(a.lumi_ < b.lumi_) return true;
00714 if(b.lumi_ < a.lumi_) return false;
00715 return a.phid_ < b.phid_;
00716 }
00717 };
00718 }
00719
00720 void
00721 RootFile::fillIndexIntoFile() {
00722
00723
00724
00725
00726
00727
00728
00729 assert(!fileFormatVersion().hasIndexIntoFile());
00730
00731 typedef std::list<LumiItem> LumiList;
00732 LumiList lumis;
00733
00734 typedef std::set<LuminosityBlockID> RunLumiSet;
00735 RunLumiSet runLumiSet;
00736
00737 typedef std::list<RunItem> RunList;
00738 RunList runs;
00739
00740 typedef std::set<RunNumber_t> RunSet;
00741 RunSet runSet;
00742
00743 typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
00744 RunItemSet runItemSet;
00745
00746 typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
00747 PHIDMap phidMap;
00748
00749 RunNumber_t prevRun = 0;
00750 LuminosityBlockNumber_t prevLumi = 0;
00751 ProcessHistoryID prevPhid;
00752
00753 indexIntoFile_.unsortedEventNumbers().clear();
00754 indexIntoFile_.unsortedEventNumbers().reserve(eventTree_.entries());
00755
00756
00757 while(eventTree_.next()) {
00758 bool newRun = false;
00759 bool newLumi = false;
00760 fillThisEventAuxiliary();
00761 fillHistory();
00762
00763
00764
00765
00766 indexIntoFile_.unsortedEventNumbers().push_back(eventAux().event());
00767
00768 if(prevPhid != eventAux().processHistoryID() || prevRun != eventAux().run()) {
00769 newRun = newLumi = true;
00770 } else if(prevLumi != eventAux().luminosityBlock()) {
00771 newLumi = true;
00772 }
00773 prevPhid = eventAux().processHistoryID();
00774 prevRun = eventAux().run();
00775 prevLumi = eventAux().luminosityBlock();
00776 if(newLumi) {
00777 lumis.push_back(LumiItem(eventAux().processHistoryID(),
00778 eventAux().run(), eventAux().luminosityBlock(), eventTree_.entryNumber()));
00779 runLumiSet.insert(LuminosityBlockID(eventAux().run(), eventAux().luminosityBlock()));
00780 } else {
00781 LumiItem& currentLumi = lumis.back();
00782 assert(currentLumi.lastEventEntry_ == eventTree_.entryNumber());
00783 ++currentLumi.lastEventEntry_;
00784 }
00785 if(newRun) {
00786
00787 RunItem item(eventAux().processHistoryID(), eventAux().run());
00788 if(runItemSet.insert(item).second) {
00789 runs.push_back(item);
00790 runSet.insert(eventAux().run());
00791 phidMap.insert(std::make_pair(eventAux().run(), eventAux().processHistoryID()));
00792 }
00793 }
00794 }
00795
00796 eventTree_.setEntryNumber(-1);
00797 eventAux_ = EventAuxiliary();
00798 lastEventEntryNumberRead_ = -1LL;
00799
00800
00801
00802 typedef std::map<RunNumber_t, EntryNumber_t> RunMap;
00803 RunMap runMap;
00804
00805 typedef std::vector<RunItem> RunVector;
00806 RunVector emptyRuns;
00807
00808 if(runTree_.isValid()) {
00809 while(runTree_.next()) {
00810
00811 boost::shared_ptr<RunAuxiliary> runAux = fillRunAuxiliary();
00812 if(runSet.insert(runAux->run()).second) {
00813
00814 emptyRuns.push_back(RunItem(runAux->processHistoryID(), runAux->run()));
00815 }
00816 runMap.insert(std::make_pair(runAux->run(), runTree_.entryNumber()));
00817 phidMap.insert(std::make_pair(runAux->run(), runAux->processHistoryID()));
00818 }
00819
00820 runTree_.setEntryNumber(-1);
00821 }
00822
00823
00824 RunItemSortByRun runItemSortByRun;
00825 stable_sort_all(emptyRuns, runItemSortByRun);
00826
00827 RunList::iterator itRuns = runs.begin(), endRuns = runs.end();
00828 for (RunVector::const_iterator i = emptyRuns.begin(), iEnd = emptyRuns.end(); i != iEnd; ++i) {
00829 for (; itRuns != endRuns; ++itRuns) {
00830 if(runItemSortByRun(*i, *itRuns)) {
00831 break;
00832 }
00833 }
00834 runs.insert(itRuns, *i);
00835 }
00836
00837
00838
00839 typedef std::vector<LumiItem> LumiVector;
00840 LumiVector emptyLumis;
00841
00842 typedef std::map<LuminosityBlockID, EntryNumber_t> RunLumiMap;
00843 RunLumiMap runLumiMap;
00844
00845 if(lumiTree_.isValid()) {
00846 while(lumiTree_.next()) {
00847
00848 boost::shared_ptr<LuminosityBlockAuxiliary> lumiAux = fillLumiAuxiliary();
00849 LuminosityBlockID lumiID = LuminosityBlockID(lumiAux->run(), lumiAux->luminosityBlock());
00850 if(runLumiSet.insert(lumiID).second) {
00851
00852
00853
00854
00855 PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
00856 assert(iPhidMap != phidMap.end());
00857 emptyLumis.push_back(LumiItem(iPhidMap->second, lumiAux->run(), lumiAux->luminosityBlock(), -1LL));
00858 }
00859 runLumiMap.insert(std::make_pair(lumiID, lumiTree_.entryNumber()));
00860 }
00861
00862 lumiTree_.setEntryNumber(-1);
00863 }
00864
00865
00866 LumiItemSortByRunLumi lumiItemSortByRunLumi;
00867 stable_sort_all(emptyLumis, lumiItemSortByRunLumi);
00868
00869 LumiList::iterator itLumis = lumis.begin(), endLumis = lumis.end();
00870 for (LumiVector::const_iterator i = emptyLumis.begin(), iEnd = emptyLumis.end(); i != iEnd; ++i) {
00871 for (; itLumis != endLumis; ++itLumis) {
00872 if(lumiItemSortByRunLumi(*i, *itLumis)) {
00873 break;
00874 }
00875 }
00876 lumis.insert(itLumis, *i);
00877 }
00878
00879
00880
00881 typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
00882 RunCountMap runCountMap;
00883 std::vector<ProcessHistoryID>& phids = indexIntoFile_.setProcessHistoryIDs();
00884 assert(phids.empty());
00885 std::vector<IndexIntoFile::RunOrLumiEntry>& entries = indexIntoFile_.setRunOrLumiEntries();
00886 assert(entries.empty());
00887 int rcount = 0;
00888 for (RunList::iterator it = runs.begin(), itEnd = runs.end(); it != itEnd; ++it) {
00889 RunCountMap::const_iterator countMapItem = runCountMap.find(*it);
00890 if(countMapItem == runCountMap.end()) {
00891 countMapItem = runCountMap.insert(std::make_pair(*it, rcount)).first;
00892 assert(countMapItem != runCountMap.end());
00893 ++rcount;
00894 }
00895 std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, it->phid_);
00896 if(phidItem == phids.end()) {
00897 phids.push_back(it->phid_);
00898 phidItem = phids.end() - 1;
00899 }
00900 entries.push_back(IndexIntoFile::RunOrLumiEntry(
00901 countMapItem->second,
00902 -1LL,
00903 runMap[it->run_],
00904 phidItem - phids.begin(),
00905 it->run_,
00906 0U,
00907 -1LL,
00908 -1LL));
00909 }
00910
00911
00912 typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
00913 LumiCountMap lumiCountMap;
00914 int lcount = 0;
00915 for (LumiList::iterator it = lumis.begin(), itEnd = lumis.end(); it != itEnd; ++it) {
00916 RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(it->phid_, it->run_));
00917 assert(runCountMapItem != runCountMap.end());
00918 LumiCountMap::const_iterator countMapItem = lumiCountMap.find(*it);
00919 if(countMapItem == lumiCountMap.end()) {
00920 countMapItem = lumiCountMap.insert(std::make_pair(*it, lcount)).first;
00921 assert(countMapItem != lumiCountMap.end());
00922 ++lcount;
00923 }
00924 std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, it->phid_);
00925 assert(phidItem != phids.end());
00926 entries.push_back(IndexIntoFile::RunOrLumiEntry(
00927 runCountMapItem->second,
00928 countMapItem->second,
00929 runLumiMap[LuminosityBlockID(it->run_, it->lumi_)],
00930 phidItem - phids.begin(),
00931 it->run_,
00932 it->lumi_,
00933 it->firstEventEntry_,
00934 it->lastEventEntry_));
00935 }
00936 stable_sort_all(entries);
00937 }
00938
00939 void
00940 RootFile::validateFile(bool secondaryFile, bool usingGoToEvent) {
00941 if(!fid_.isValid()) {
00942 fid_ = FileID(createGlobalIdentifier());
00943 }
00944 if(!eventTree_.isValid()) {
00945 throw Exception(errors::EventCorruption) <<
00946 "'Events' tree is corrupted or not present\n" << "in the input file.\n";
00947 }
00948
00949 if(fileFormatVersion().hasIndexIntoFile()) {
00950 if(runTree().entries() > 0) {
00951 assert(!indexIntoFile_.empty());
00952 }
00953 }
00954 else {
00955 assert(indexIntoFile_.empty());
00956 fillIndexIntoFile();
00957 }
00958
00959 indexIntoFile_.fixIndexes(orderedProcessHistoryIDs_);
00960 indexIntoFile_.setNumberOfEvents(eventTree_.entries());
00961 indexIntoFile_.setEventFinder(boost::shared_ptr<IndexIntoFile::EventFinder>(new RootFileEventFinder(eventTree_)));
00962
00963
00964 bool needEventNumbers = false;
00965 bool needIndexesForDuplicateChecker = duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled();
00966 if(secondaryFile || needIndexesForDuplicateChecker || usingGoToEvent) {
00967 needEventNumbers = true;
00968 }
00969 bool needEventEntries = false;
00970 if(secondaryFile || !noEventSort_) {
00971
00972 needEventEntries = true;
00973 }
00974 indexIntoFile_.fillEventNumbersOrEntries(needEventNumbers, needEventEntries);
00975 }
00976
00977 void
00978 RootFile::reportOpened(std::string const& inputType) {
00979
00980 std::string const label = "source";
00981 std::string moduleName = "PoolSource";
00982 filePtr_->inputFileOpened(
00983 logicalFile_,
00984 inputType,
00985 moduleName,
00986 label,
00987 fid_.fid(),
00988 eventTree_.branchNames());
00989 }
00990
00991 void
00992 RootFile::close() {
00993
00994 eventHistoryTree_ = 0;
00995 for(RootTreePtrArray::iterator it = treePointers_.begin(), itEnd = treePointers_.end(); it != itEnd; ++it) {
00996 (*it)->close();
00997 (*it) = 0;
00998 }
00999 filePtr_->Close();
01000 filePtr_.reset();
01001 }
01002
01003 void
01004 RootFile::fillThisEventAuxiliary() {
01005 if(lastEventEntryNumberRead_ == eventTree_.entryNumber()) {
01006
01007 return;
01008 }
01009 if(fileFormatVersion().newAuxiliary()) {
01010 EventAuxiliary *pEvAux = &eventAux_;
01011 eventTree_.fillAux<EventAuxiliary>(pEvAux);
01012 } else {
01013
01014 EventAux eventAux;
01015 EventAux *pEvAux = &eventAux;
01016 eventTree_.fillAux<EventAux>(pEvAux);
01017 conversion(eventAux, eventAux_);
01018 }
01019 lastEventEntryNumberRead_ = eventTree_.entryNumber();
01020 }
01021
01022 void
01023 RootFile::fillEventAuxiliary() {
01024 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
01025 fillThisEventAuxiliary();
01026 }
01027
01028 void
01029 RootFile::fillHistory() {
01030
01031
01032
01033
01034 if(fileFormatVersion().eventHistoryBranch()) {
01035
01036 EventID id(eventAux().id().run(), 0, eventAux().id().event());
01037 if(eventProcessHistoryIter_->eventID() != id) {
01038 EventProcessHistoryID target(id, ProcessHistoryID());
01039 eventProcessHistoryIter_ = lower_bound_all(eventProcessHistoryIDs_, target);
01040 assert(eventProcessHistoryIter_->eventID() == id);
01041 }
01042 eventAux_.setProcessHistoryID(eventProcessHistoryIter_->processHistoryID());
01043 ++eventProcessHistoryIter_;
01044 } else if(fileFormatVersion().eventHistoryTree()) {
01045
01046 History* pHistory = history_.get();
01047 TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(poolNames::eventHistoryBranchName().c_str());
01048 if(!eventHistoryBranch) {
01049 throw Exception(errors::EventCorruption)
01050 << "Failed to find history branch in event history tree.\n";
01051 }
01052 eventHistoryBranch->SetAddress(&pHistory);
01053 roottree::getEntry(eventHistoryTree_, eventTree_.entryNumber());
01054 eventAux_.setProcessHistoryID(history_->processHistoryID());
01055 eventSelectionIDs_.reset(&history_->eventSelectionIDs(), do_nothing_deleter());
01056 branchListIndexes_.reset(&history_->branchListIndexes(), do_nothing_deleter());
01057 } else if(fileFormatVersion().noMetaDataTrees()) {
01058
01059 EventSelectionIDVector* pESV = eventSelectionIDs_.get();
01060 TBranch* eventSelectionIDBranch = eventTree_.tree()->GetBranch(poolNames::eventSelectionsBranchName().c_str());
01061 assert(eventSelectionIDBranch != 0);
01062 eventTree_.fillBranchEntry(eventSelectionIDBranch, pESV);
01063 BranchListIndexes* pBLI = branchListIndexes_.get();
01064 TBranch* branchListIndexesBranch = eventTree_.tree()->GetBranch(poolNames::branchListIndexesBranchName().c_str());
01065 assert(branchListIndexesBranch != 0);
01066 eventTree_.fillBranchEntry(branchListIndexesBranch, pBLI);
01067 }
01068 if(provenanceAdaptor_) {
01069 eventAux_.setProcessHistoryID(provenanceAdaptor_->convertID(eventAux().processHistoryID()));
01070 for(EventSelectionIDVector::iterator i = eventSelectionIDs_->begin(), e = eventSelectionIDs_->end(); i != e; ++i) {
01071 (*i) = provenanceAdaptor_->convertID(*i);
01072 }
01073 }
01074 if(!fileFormatVersion().splitProductIDs()) {
01075
01076 provenanceAdaptor_->branchListIndexes(*branchListIndexes_);
01077 }
01078 }
01079
01080 boost::shared_ptr<LuminosityBlockAuxiliary>
01081 RootFile::fillLumiAuxiliary() {
01082 boost::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary(new LuminosityBlockAuxiliary);
01083 if(fileFormatVersion().newAuxiliary()) {
01084 LuminosityBlockAuxiliary *pLumiAux = lumiAuxiliary.get();
01085 lumiTree_.fillAux<LuminosityBlockAuxiliary>(pLumiAux);
01086 } else {
01087 LuminosityBlockAux lumiAux;
01088 LuminosityBlockAux *pLumiAux = &lumiAux;
01089 lumiTree_.fillAux<LuminosityBlockAux>(pLumiAux);
01090 conversion(lumiAux, *lumiAuxiliary);
01091 }
01092 if(provenanceAdaptor_) {
01093 lumiAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
01094 }
01095 if(lumiAuxiliary->luminosityBlock() == 0 && !fileFormatVersion().runsAndLumis()) {
01096 lumiAuxiliary->id() = LuminosityBlockID(RunNumber_t(1), LuminosityBlockNumber_t(1));
01097 }
01098 return lumiAuxiliary;
01099 }
01100
01101 boost::shared_ptr<RunAuxiliary>
01102 RootFile::fillRunAuxiliary() {
01103 boost::shared_ptr<RunAuxiliary> runAuxiliary(new RunAuxiliary);
01104 if(fileFormatVersion().newAuxiliary()) {
01105 RunAuxiliary *pRunAux = runAuxiliary.get();
01106 runTree_.fillAux<RunAuxiliary>(pRunAux);
01107 } else {
01108 RunAux runAux;
01109 RunAux *pRunAux = &runAux;
01110 runTree_.fillAux<RunAux>(pRunAux);
01111 conversion(runAux, *runAuxiliary);
01112 }
01113 if(provenanceAdaptor_) {
01114 runAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
01115 }
01116 return runAuxiliary;
01117 }
01118
01119 bool
01120 RootFile::skipEvents(int& offset) {
01121 while (offset > 0 && indexIntoFileIter_ != indexIntoFileEnd_) {
01122
01123 int phIndexOfSkippedEvent = IndexIntoFile::invalidIndex;
01124 RunNumber_t runOfSkippedEvent = IndexIntoFile::invalidRun;
01125 LuminosityBlockNumber_t lumiOfSkippedEvent = IndexIntoFile::invalidLumi;
01126 IndexIntoFile::EntryNumber_t skippedEventEntry = IndexIntoFile::invalidEntry;
01127
01128 indexIntoFileIter_.skipEventForward(phIndexOfSkippedEvent,
01129 runOfSkippedEvent,
01130 lumiOfSkippedEvent,
01131 skippedEventEntry);
01132
01133
01134 if(skippedEventEntry == IndexIntoFile::invalidEntry) break;
01135
01136 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
01137 eventTree_.setEntryNumber(skippedEventEntry);
01138 fillThisEventAuxiliary();
01139 if(eventSkipperByID_->skipIt(runOfSkippedEvent, lumiOfSkippedEvent, eventAux_.id().event())) {
01140 continue;
01141 }
01142 }
01143 if(duplicateChecker_ &&
01144 !duplicateChecker_->checkDisabled() &&
01145 !duplicateChecker_->noDuplicatesInFile()) {
01146
01147 eventTree_.setEntryNumber(skippedEventEntry);
01148 fillThisEventAuxiliary();
01149 if(duplicateChecker_->isDuplicateAndCheckActive(phIndexOfSkippedEvent,
01150 runOfSkippedEvent,
01151 lumiOfSkippedEvent,
01152 eventAux_.id().event(),
01153 file_)) {
01154 continue;
01155 }
01156 }
01157 --offset;
01158 }
01159
01160 while(offset < 0) {
01161
01162 if(duplicateChecker_) {
01163 duplicateChecker_->disable();
01164 }
01165
01166 int phIndexOfEvent = IndexIntoFile::invalidIndex;
01167 RunNumber_t runOfEvent = IndexIntoFile::invalidRun;
01168 LuminosityBlockNumber_t lumiOfEvent = IndexIntoFile::invalidLumi;
01169 EntryNumber_t eventEntry = IndexIntoFile::invalidEntry;
01170
01171 indexIntoFileIter_.skipEventBackward(phIndexOfEvent,
01172 runOfEvent,
01173 lumiOfEvent,
01174 eventEntry);
01175
01176 if(eventEntry == IndexIntoFile::invalidEntry) break;
01177
01178 if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
01179 eventTree_.setEntryNumber(eventEntry);
01180 fillEventAuxiliary();
01181 if(eventSkipperByID_->skipIt(runOfEvent, lumiOfEvent, eventAux_.id().event())) {
01182 continue;
01183 }
01184 }
01185 ++offset;
01186 }
01187 return (indexIntoFileIter_ == indexIntoFileEnd_);
01188 }
01189
01190 bool
01191 RootFile::goToEvent(EventID const& eventID) {
01192
01193 indexIntoFile_.fillEventNumbers();
01194
01195 if(duplicateChecker_) {
01196 duplicateChecker_->disable();
01197 }
01198
01199 IndexIntoFile::SortOrder sortOrder = IndexIntoFile::numericalOrder;
01200 if(noEventSort_) sortOrder = IndexIntoFile::firstAppearanceOrder;
01201
01202 IndexIntoFile::IndexIntoFileItr iter =
01203 indexIntoFile_.findPosition(sortOrder, eventID.run(), eventID.luminosityBlock(), eventID.event());
01204
01205 if(iter == indexIntoFile_.end(sortOrder)) {
01206 return false;
01207 }
01208 indexIntoFileIter_ = iter;
01209 return true;
01210 }
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 EventPrincipal*
01226 RootFile::readEvent(EventPrincipal& cache, boost::shared_ptr<RootFile> rootFilePtr, boost::shared_ptr<LuminosityBlockPrincipal> lb) {
01227 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01228 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kEvent);
01229
01230 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
01231 EventPrincipal* ep = readCurrentEvent(cache, rootFilePtr, lb);
01232
01233 assert(ep != 0);
01234 assert(eventAux().run() == indexIntoFileIter_.run() + forcedRunOffset_);
01235 assert(eventAux().luminosityBlock() == indexIntoFileIter_.lumi());
01236
01237 ++indexIntoFileIter_;
01238 return ep;
01239 }
01240
01241
01242 EventPrincipal*
01243 RootFile::readCurrentEvent(EventPrincipal& cache,
01244 boost::shared_ptr<RootFile> rootFilePtr,
01245 boost::shared_ptr<LuminosityBlockPrincipal> lb) {
01246 if(!eventTree_.current()) {
01247 return 0;
01248 }
01249 fillThisEventAuxiliary();
01250 if(!fileFormatVersion().lumiInEventID()) {
01251
01252 const_cast<EventID&>(eventAux_.id()).setLuminosityBlockNumber(eventAux_.oldLuminosityBlock());
01253 eventAux_.resetObsoleteInfo();
01254 }
01255 fillHistory();
01256 overrideRunNumber(eventAux_.id(), eventAux().isRealData());
01257
01258 std::auto_ptr<EventAuxiliary> aux(new EventAuxiliary(eventAux()));
01259
01260 cache.fillEventPrincipal(aux,
01261 lb,
01262 eventSelectionIDs_,
01263 branchListIndexes_,
01264 makeBranchMapper(eventTree_, InEvent),
01265 eventTree_.makeDelayedReader(fileFormatVersion(), rootFilePtr));
01266
01267
01268 filePtr_->eventReadFromFile(eventID().run(), eventID().event());
01269 return &cache;
01270 }
01271
01272 void
01273 RootFile::setAtEventEntry(IndexIntoFile::EntryNumber_t entry) {
01274 eventTree_.setEntryNumber(entry);
01275 }
01276
01277 boost::shared_ptr<RunAuxiliary>
01278 RootFile::readRunAuxiliary_() {
01279 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01280 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun);
01281
01282 if(!runTree_.isValid()) {
01283
01284
01285 if(eventTree_.next()) {
01286 fillThisEventAuxiliary();
01287
01288 eventTree_.previous();
01289 }
01290 RunID run = RunID(indexIntoFileIter_.run());
01291 overrideRunNumber(run);
01292 return boost::shared_ptr<RunAuxiliary>(new RunAuxiliary(run.run(), eventAux().time(), Timestamp::invalidTimestamp()));
01293 }
01294
01295 runTree_.setEntryNumber(indexIntoFileIter_.entry());
01296 boost::shared_ptr<RunAuxiliary> runAuxiliary = fillRunAuxiliary();
01297 assert(runAuxiliary->run() == indexIntoFileIter_.run());
01298 overrideRunNumber(runAuxiliary->id());
01299 filePtr_->reportInputRunNumber(runAuxiliary->run());
01300 if(runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
01301
01302 if(eventTree_.next()) {
01303 fillThisEventAuxiliary();
01304
01305 eventTree_.previous();
01306 }
01307 runAuxiliary->setBeginTime(eventAux().time());
01308 runAuxiliary->setEndTime(Timestamp::invalidTimestamp());
01309 }
01310 ProcessHistoryID phid = indexIntoFile_.processHistoryID(indexIntoFileIter_.processHistoryIDIndex());
01311 if(fileFormatVersion().processHistorySameWithinRun()) {
01312 assert(runAuxiliary->processHistoryID() == phid);
01313 } else {
01314 runAuxiliary->setProcessHistoryID(phid);
01315 }
01316 return runAuxiliary;
01317 }
01318
01319 boost::shared_ptr<RunPrincipal>
01320 RootFile::readRun_(boost::shared_ptr<RunPrincipal> rpCache) {
01321 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01322 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kRun);
01323
01324 if(!runTree_.isValid()) {
01325 ++indexIntoFileIter_;
01326 return rpCache;
01327 }
01328
01329 rpCache->fillRunPrincipal(makeBranchMapper(runTree_, InRun), runTree_.makeDelayedReader(fileFormatVersion()));
01330
01331 rpCache->readImmediate();
01332 ++indexIntoFileIter_;
01333 return rpCache;
01334 }
01335
01336 boost::shared_ptr<LuminosityBlockAuxiliary>
01337 RootFile::readLuminosityBlockAuxiliary_() {
01338 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01339 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi);
01340
01341 if(!lumiTree_.isValid()) {
01342 if(eventTree_.next()) {
01343 fillThisEventAuxiliary();
01344
01345 eventTree_.previous();
01346 }
01347
01348 LuminosityBlockID lumi = LuminosityBlockID(indexIntoFileIter_.run(), indexIntoFileIter_.lumi());
01349 overrideRunNumber(lumi);
01350 return boost::shared_ptr<LuminosityBlockAuxiliary>(new LuminosityBlockAuxiliary(lumi.run(), lumi.luminosityBlock(), eventAux().time(), Timestamp::invalidTimestamp()));
01351 }
01352
01353 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
01354 boost::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary = fillLumiAuxiliary();
01355 assert(lumiAuxiliary->run() == indexIntoFileIter_.run());
01356 assert(lumiAuxiliary->luminosityBlock() == indexIntoFileIter_.lumi());
01357 overrideRunNumber(lumiAuxiliary->id());
01358 filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
01359
01360 if(lumiAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
01361
01362 if(eventTree_.next()) {
01363 fillThisEventAuxiliary();
01364
01365 eventTree_.previous();
01366 }
01367 lumiAuxiliary->setBeginTime(eventAux().time());
01368 lumiAuxiliary->setEndTime(Timestamp::invalidTimestamp());
01369 }
01370 if(fileFormatVersion().processHistorySameWithinRun()) {
01371 ProcessHistoryID phid = indexIntoFile_.processHistoryID(indexIntoFileIter_.processHistoryIDIndex());
01372 assert(lumiAuxiliary->processHistoryID() == phid);
01373 } else {
01374 ProcessHistoryID phid = indexIntoFile_.processHistoryID(indexIntoFileIter_.processHistoryIDIndex());
01375 lumiAuxiliary->setProcessHistoryID(phid);
01376 }
01377 return lumiAuxiliary;
01378 }
01379
01380 boost::shared_ptr<LuminosityBlockPrincipal>
01381 RootFile::readLumi(boost::shared_ptr<LuminosityBlockPrincipal> lbCache) {
01382 assert(indexIntoFileIter_ != indexIntoFileEnd_);
01383 assert(indexIntoFileIter_.getEntryType() == IndexIntoFile::kLumi);
01384
01385 if(!lumiTree_.isValid()) {
01386 ++indexIntoFileIter_;
01387 return lbCache;
01388 }
01389
01390 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
01391 lbCache->fillLuminosityBlockPrincipal(makeBranchMapper(lumiTree_, InLumi),
01392 lumiTree_.makeDelayedReader(fileFormatVersion()));
01393
01394 lbCache->readImmediate();
01395 ++indexIntoFileIter_;
01396 return lbCache;
01397 }
01398
01399 bool
01400 RootFile::setEntryAtEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) {
01401 indexIntoFileIter_ = indexIntoFile_.findEventPosition(run, lumi, event);
01402 if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
01403 eventTree_.setEntryNumber(indexIntoFileIter_.entry());
01404 return true;
01405 }
01406
01407 bool
01408 RootFile::setEntryAtLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) {
01409 indexIntoFileIter_ = indexIntoFile_.findLumiPosition(run, lumi);
01410 if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
01411 lumiTree_.setEntryNumber(indexIntoFileIter_.entry());
01412 return true;
01413 }
01414
01415 bool
01416 RootFile::setEntryAtRun(RunNumber_t run) {
01417 indexIntoFileIter_ = indexIntoFile_.findRunPosition(run);
01418 if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
01419 runTree_.setEntryNumber(indexIntoFileIter_.entry());
01420 return true;
01421 }
01422
01423 void
01424 RootFile::overrideRunNumber(RunID& id) {
01425 if(forcedRunOffset_ != 0) {
01426 id = RunID(id.run() + forcedRunOffset_);
01427 }
01428 if(id < RunID::firstValidRun()) id = RunID::firstValidRun();
01429 }
01430
01431 void
01432 RootFile::overrideRunNumber(LuminosityBlockID& id) {
01433 if(forcedRunOffset_ != 0) {
01434 id = LuminosityBlockID(id.run() + forcedRunOffset_, id.luminosityBlock());
01435 }
01436 if(RunID(id.run()) < RunID::firstValidRun()) id = LuminosityBlockID(RunID::firstValidRun().run(), id.luminosityBlock());
01437 }
01438
01439 void
01440 RootFile::overrideRunNumber(EventID& id, bool isRealData) {
01441 if(forcedRunOffset_ != 0) {
01442 if(isRealData) {
01443 throw Exception(errors::Configuration, "RootFile::RootFile()")
01444 << "The 'setRunNumber' parameter of PoolSource cannot be used with real data.\n";
01445 }
01446 id = EventID(id.run() + forcedRunOffset_, id.luminosityBlock(), id.event());
01447 }
01448 if(RunID(id.run()) < RunID::firstValidRun()) {
01449 id = EventID(RunID::firstValidRun().run(), LuminosityBlockID::firstValidLuminosityBlock().luminosityBlock(), id.event());
01450 }
01451 }
01452
01453
01454 void
01455 RootFile::readEventHistoryTree() {
01456
01457 if(fileFormatVersion().eventHistoryTree()) {
01458 history_.reset(new History);
01459 eventHistoryTree_ = dynamic_cast<TTree*>(filePtr_->Get(poolNames::eventHistoryTreeName().c_str()));
01460 if(!eventHistoryTree_) {
01461 throw Exception(errors::EventCorruption)
01462 << "Failed to find the event history tree.\n";
01463 }
01464 }
01465 }
01466
01467 void
01468 RootFile::initializeDuplicateChecker(
01469 std::vector<boost::shared_ptr<IndexIntoFile> > const& indexesIntoFiles,
01470 std::vector<boost::shared_ptr<IndexIntoFile> >::size_type currentIndexIntoFile) {
01471 if(duplicateChecker_) {
01472 if(eventTree_.next()) {
01473 fillThisEventAuxiliary();
01474 duplicateChecker_->inputFileOpened(eventAux().isRealData(),
01475 indexIntoFile_,
01476 indexesIntoFiles,
01477 currentIndexIntoFile);
01478 }
01479 eventTree_.setEntryNumber(-1);
01480 }
01481 }
01482
01483 void
01484 RootFile::dropOnInput (ProductRegistry& reg, GroupSelectorRules const& rules, bool dropDescendants, bool secondaryFile) {
01485
01486 GroupSelector groupSelector;
01487 groupSelector.initialize(rules, reg.allBranchDescriptions());
01488
01489 ProductRegistry::ProductList& prodList = reg.productListUpdator();
01490
01491 std::set<BranchID> branchesToDrop;
01492 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
01493 it != itEnd; ++it) {
01494 BranchDescription const& prod = it->second;
01495 if(!groupSelector.selected(prod)) {
01496 if(dropDescendants) {
01497 branchChildren_->appendToDescendants(prod.branchID(), branchesToDrop);
01498 } else {
01499 branchesToDrop.insert(prod.branchID());
01500 }
01501 }
01502 }
01503
01504
01505 std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
01506 for(ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
01507 BranchDescription const& prod = it->second;
01508 bool drop = branchesToDrop.find(prod.branchID()) != branchesToDropEnd;
01509 if(drop) {
01510 if(groupSelector.selected(prod)) {
01511 LogWarning("RootFile")
01512 << "Branch '" << prod.branchName() << "' is being dropped from the input\n"
01513 << "of file '" << file_ << "' because it is dependent on a branch\n"
01514 << "that was explicitly dropped.\n";
01515 }
01516 treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
01517 hasNewlyDroppedBranch_[prod.branchType()] = true;
01518 ProductRegistry::ProductList::iterator icopy = it;
01519 ++it;
01520 prodList.erase(icopy);
01521 } else {
01522 ++it;
01523 }
01524 }
01525
01526
01527 if(secondaryFile) {
01528 for(ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
01529 BranchDescription const& prod = it->second;
01530 if(prod.branchType() != InEvent) {
01531 TClass *cp = gROOT->GetClass(prod.wrappedName().c_str());
01532 boost::shared_ptr<EDProduct> dummy(static_cast<EDProduct *>(cp->New()));
01533 if(dummy->isMergeable()) {
01534 treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
01535 ProductRegistry::ProductList::iterator icopy = it;
01536 ++it;
01537 prodList.erase(icopy);
01538 } else {
01539 ++it;
01540 }
01541 }
01542 else ++it;
01543 }
01544 }
01545 }
01546
01547
01548
01549 namespace {
01550 boost::shared_ptr<BranchMapper>
01551 makeBranchMapperInRelease180(RootTree& rootTree, BranchType const& type, ProductRegistry const& preg) {
01552 boost::shared_ptr<BranchMapperWithReader> mapper(new BranchMapperWithReader());
01553 mapper->setDelayedRead(false);
01554
01555 for(ProductRegistry::ProductList::const_iterator it = preg.productList().begin(),
01556 itEnd = preg.productList().end(); it != itEnd; ++it) {
01557 if(type == it->second.branchType() && !it->second.transient()) {
01558 TBranch *br = rootTree.branches().find(it->first)->second.provenanceBranch_;
01559 std::auto_ptr<BranchEntryDescription> pb(new BranchEntryDescription);
01560 BranchEntryDescription* ppb = pb.get();
01561 br->SetAddress(&ppb);
01562 roottree::getEntry(br, rootTree.entryNumber());
01563 ProductStatus status = (ppb->creatorStatus() == BranchEntryDescription::Success ? productstatus::present() : productstatus::neverCreated());
01564
01565 ProductProvenance entry(it->second.branchID(), status, ParentageID());
01566 mapper->insert(entry);
01567 mapper->insertIntoMap(it->second.oldProductID(), it->second.branchID());
01568 }
01569 }
01570 return mapper;
01571 }
01572
01573 boost::shared_ptr<BranchMapper>
01574 makeBranchMapperInRelease200(RootTree& rootTree, BranchType const& type, ProductRegistry const& preg) {
01575 rootTree.fillStatus();
01576 boost::shared_ptr<BranchMapperWithReader> mapper(new BranchMapperWithReader());
01577 mapper->setDelayedRead(false);
01578 for(ProductRegistry::ProductList::const_iterator it = preg.productList().begin(),
01579 itEnd = preg.productList().end(); it != itEnd; ++it) {
01580 if(type == it->second.branchType() && !it->second.transient()) {
01581 std::vector<ProductStatus>::size_type index = it->second.oldProductID().oldID() - 1;
01582
01583 ProductProvenance entry(it->second.branchID(), rootTree.productStatuses()[index], ParentageID());
01584 mapper->insert(entry);
01585 mapper->insertIntoMap(it->second.oldProductID(), it->second.branchID());
01586 }
01587 }
01588 return mapper;
01589 }
01590
01591 boost::shared_ptr<BranchMapper>
01592 makeBranchMapperInRelease210(RootTree& rootTree, BranchType const& type) {
01593 boost::shared_ptr<BranchMapperWithReader> mapper(new BranchMapperWithReader());
01594 mapper->setDelayedRead(false);
01595 if(type == InEvent) {
01596 std::auto_ptr<std::vector<EventEntryInfo> > infoVector(new std::vector<EventEntryInfo>);
01597 std::vector<EventEntryInfo> *pInfoVector = infoVector.get();
01598 rootTree.branchEntryInfoBranch()->SetAddress(&pInfoVector);
01599 setRefCoreStreamer(0, true, false);
01600 roottree::getEntry(rootTree.branchEntryInfoBranch(), rootTree.entryNumber());
01601 setRefCoreStreamer(true);
01602 for(std::vector<EventEntryInfo>::const_iterator it = infoVector->begin(), itEnd = infoVector->end();
01603 it != itEnd; ++it) {
01604 EventEntryDescription eed;
01605 EntryDescriptionRegistry::instance()->getMapped(it->entryDescriptionID(), eed);
01606 Parentage parentage(eed.parents());
01607 ProductProvenance entry(it->branchID(), it->productStatus(), parentage.id());
01608 mapper->insert(entry);
01609 mapper->insertIntoMap(it->productID(), it->branchID());
01610 }
01611 } else {
01612 std::auto_ptr<std::vector<RunLumiEntryInfo> > infoVector(new std::vector<RunLumiEntryInfo>);
01613 std::vector<RunLumiEntryInfo> *pInfoVector = infoVector.get();
01614 rootTree.branchEntryInfoBranch()->SetAddress(&pInfoVector);
01615 setRefCoreStreamer(0, true, false);
01616 roottree::getEntry(rootTree.branchEntryInfoBranch(), rootTree.entryNumber());
01617 setRefCoreStreamer(true);
01618 for(std::vector<RunLumiEntryInfo>::const_iterator it = infoVector->begin(), itEnd = infoVector->end();
01619 it != itEnd; ++it) {
01620 ProductProvenance entry(it->branchID(), it->productStatus(), ParentageID());
01621 mapper->insert(entry);
01622 }
01623 }
01624 return mapper;
01625 }
01626
01627 boost::shared_ptr<BranchMapper>
01628 makeBranchMapperInRelease300(RootTree& rootTree) {
01629 boost::shared_ptr<BranchMapperWithReader> mapper(
01630 new BranchMapperWithReader(&rootTree));
01631 mapper->setDelayedRead(true);
01632 return mapper;
01633 }
01634 }
01635
01636 boost::shared_ptr<BranchMapper>
01637 RootFile::makeBranchMapper(RootTree& rootTree, BranchType const& type) const {
01638 if(fileFormatVersion().splitProductIDs()) {
01639 return makeBranchMapperInRelease300(rootTree);
01640 } else if(fileFormatVersion().perEventProductIDs()) {
01641 return makeBranchMapperInRelease210(rootTree, type);
01642 } else if(fileFormatVersion().eventHistoryTree()) {
01643 return makeBranchMapperInRelease200(rootTree, type, *productRegistry_);
01644 } else {
01645 return makeBranchMapperInRelease180(rootTree, type, *productRegistry_);
01646 }
01647 }
01648
01649 }