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