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